1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
|
{
description = "slopbot - Zulip bot with stock price lookups and LLM replies";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
agentd = {
url = "git+file:///home/ben/src/bsima/agentd";
inputs.nixpkgs.follows = "nixpkgs";
};
};
outputs = { self, nixpkgs, agentd }:
let
system = "x86_64-linux";
pkgs = nixpkgs.legacyPackages.${system};
pythonEnv = pkgs.python3.withPackages (ps: [
ps.zulip
ps.yfinance
ps.openai
ps.requests
]);
agent = pkgs.rustPlatform.buildRustPackage {
pname = "agent";
version = "0.1.0";
src = agentd;
cargoLock.lockFile = "${agentd}/Cargo.lock";
cargoBuildFlags = [ "-p" "agent" ];
doCheck = false;
};
researchPython = pkgs.python3.withPackages (ps: [
ps.trafilatura
]);
slopSearch = pkgs.writeShellApplication {
name = "slop-search";
runtimeInputs = [ pkgs.curl pkgs.jq pkgs.python3 ];
text = ''
if [ "$#" -eq 0 ]; then
echo "usage: slop-search QUERY" >&2
exit 2
fi
if [ -z "''${KAGI_API_KEY:-}" ]; then
echo "error: KAGI_API_KEY is not set" >&2
exit 1
fi
query="$*"
encoded="$(${pkgs.python3}/bin/python -c 'import sys, urllib.parse; print(urllib.parse.urlencode({"q": " ".join(sys.argv[1:])}))' "$@")"
curl -fsS \
-H "Authorization: Bot ''${KAGI_API_KEY}" \
-H "Accept: application/json" \
"https://kagi.com/api/v0/search?''${encoded}" \
| jq -r --arg query "$query" '
"QUERY: \($query)",
"",
(.data // [])
| map(select((.t // .type // "") == "search_result" or has("url")))
| .[:8]
| to_entries[]
| "[\(.key + 1)] \(.value.title // "untitled")\nURL: \(.value.url)\nSNIPPET: \(.value.snippet // .value.description // "")\n"
'
'';
};
slopFetch = pkgs.writeShellApplication {
name = "slop-fetch";
runtimeInputs = [ pkgs.curl researchPython ];
text = ''
if [ "$#" -ne 1 ]; then
echo "usage: slop-fetch URL" >&2
exit 2
fi
url="$1"
tmp="$(mktemp)"
trap 'rm -f "$tmp"' EXIT
curl -fsSL --max-time 20 -A 'slopbot/1.0' "$url" -o "$tmp"
${researchPython}/bin/python - "$url" "$tmp" <<'PY'
import sys
import trafilatura
url, path = sys.argv[1], sys.argv[2]
html = open(path, "rb").read()
text = trafilatura.extract(html, url=url, include_comments=False, include_tables=False)
if not text:
print(f"error: could not extract readable text from {url}", file=sys.stderr)
sys.exit(1)
print(text[:12000])
PY
'';
};
slopTools = pkgs.symlinkJoin {
name = "slopbot-agent-tools";
paths = [ slopSearch slopFetch ];
};
in
{
devShells.${system}.default = pkgs.mkShell {
buildInputs = [ pythonEnv agent slopTools ];
shellHook = ''
echo "slopbot dev shell ready"
echo "Run: python main.py"
'';
};
packages.${system} = rec {
default = slopbot;
slopbot = pkgs.writeShellScriptBin "slopbot" ''
cd /home/ben/src/bsima/slopbot
export PATH=${slopTools}/bin
export SLOPBOT_AGENT=${agent}/bin/agent
export SLOPBOT_AGENT_PATH=${slopTools}/bin
exec ${pythonEnv}/bin/python ${./main.py}
'';
inherit agent slopTools slopSearch slopFetch;
};
};
}
|