@jellyos/agent 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/README.md +375 -0
  2. package/bin/jellyagent +31 -0
  3. package/dist/api/ExtensionAPI.d.ts +92 -0
  4. package/dist/api/ExtensionAPI.d.ts.map +1 -0
  5. package/dist/api/ExtensionAPI.js +15 -0
  6. package/dist/api/ExtensionAPI.js.map +1 -0
  7. package/dist/api/Registry.d.ts +54 -0
  8. package/dist/api/Registry.d.ts.map +1 -0
  9. package/dist/api/Registry.js +101 -0
  10. package/dist/api/Registry.js.map +1 -0
  11. package/dist/cli.d.ts +6 -0
  12. package/dist/cli.d.ts.map +1 -0
  13. package/dist/cli.js +134 -0
  14. package/dist/cli.js.map +1 -0
  15. package/dist/index.d.ts +18 -0
  16. package/dist/index.d.ts.map +1 -0
  17. package/dist/index.js +24 -0
  18. package/dist/index.js.map +1 -0
  19. package/dist/loader.d.ts +23 -0
  20. package/dist/loader.d.ts.map +1 -0
  21. package/dist/loader.js +84 -0
  22. package/dist/loader.js.map +1 -0
  23. package/dist/runner/AgentRunner.d.ts +66 -0
  24. package/dist/runner/AgentRunner.d.ts.map +1 -0
  25. package/dist/runner/AgentRunner.js +179 -0
  26. package/dist/runner/AgentRunner.js.map +1 -0
  27. package/dist/runner/ModelClient.d.ts +77 -0
  28. package/dist/runner/ModelClient.d.ts.map +1 -0
  29. package/dist/runner/ModelClient.js +224 -0
  30. package/dist/runner/ModelClient.js.map +1 -0
  31. package/dist/runner/SwarmRouter.d.ts +58 -0
  32. package/dist/runner/SwarmRouter.d.ts.map +1 -0
  33. package/dist/runner/SwarmRouter.js +153 -0
  34. package/dist/runner/SwarmRouter.js.map +1 -0
  35. package/dist/runner/ToolDispatcher.d.ts +19 -0
  36. package/dist/runner/ToolDispatcher.d.ts.map +1 -0
  37. package/dist/runner/ToolDispatcher.js +64 -0
  38. package/dist/runner/ToolDispatcher.js.map +1 -0
  39. package/dist/session/SessionManager.d.ts +23 -0
  40. package/dist/session/SessionManager.d.ts.map +1 -0
  41. package/dist/session/SessionManager.js +50 -0
  42. package/dist/session/SessionManager.js.map +1 -0
  43. package/dist/tui/App.d.ts +18 -0
  44. package/dist/tui/App.d.ts.map +1 -0
  45. package/dist/tui/App.js +188 -0
  46. package/dist/tui/App.js.map +1 -0
  47. package/dist/tui/REPL.d.ts +22 -0
  48. package/dist/tui/REPL.d.ts.map +1 -0
  49. package/dist/tui/REPL.js +46 -0
  50. package/dist/tui/REPL.js.map +1 -0
  51. package/dist/tui/StatusBar.d.ts +16 -0
  52. package/dist/tui/StatusBar.d.ts.map +1 -0
  53. package/dist/tui/StatusBar.js +15 -0
  54. package/dist/tui/StatusBar.js.map +1 -0
  55. package/dist/tui/theme.d.ts +30 -0
  56. package/dist/tui/theme.d.ts.map +1 -0
  57. package/dist/tui/theme.js +41 -0
  58. package/dist/tui/theme.js.map +1 -0
  59. package/package.json +59 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Registry.js","sourceRoot":"","sources":["../../src/api/Registry.ts"],"names":[],"mappings":"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"}
package/dist/cli.d.ts ADDED
@@ -0,0 +1,6 @@
1
+ /**
2
+ * cli.ts — JellyOS entry point.
3
+ * Completely standalone — all outbound, no inbound ports exposed.
4
+ */
5
+ export {};
6
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
package/dist/cli.js ADDED
@@ -0,0 +1,134 @@
1
+ /**
2
+ * cli.ts — JellyOS entry point.
3
+ * Completely standalone — all outbound, no inbound ports exposed.
4
+ */
5
+ import { readFileSync, existsSync } from "node:fs";
6
+ import { resolve, join } from "node:path";
7
+ import { homedir } from "node:os";
8
+ import { render } from "ink";
9
+ import React from "react";
10
+ import { config as loadDotenv } from "dotenv";
11
+ import { Registry } from "./api/Registry.js";
12
+ import { loadExtension } from "./loader.js";
13
+ import { App } from "./tui/App.js";
14
+ import { T } from "./tui/theme.js";
15
+ // ── Load env vars from ~/.jelly/.env ─────────────────────────────────────────
16
+ const JELLY_HOME = process.env.JELLYOS_HOME ?? join(homedir(), ".jelly");
17
+ const envPath = join(JELLY_HOME, ".env");
18
+ if (existsSync(envPath))
19
+ loadDotenv({ path: envPath, override: false });
20
+ // ── Parse CLI args ────────────────────────────────────────────────────────────
21
+ const args = process.argv.slice(2);
22
+ const subcmd = args[0];
23
+ if (subcmd === "setup") {
24
+ console.log(T.accent("JellyOS setup — run setup.sh for full setup."));
25
+ console.log(T.muted(`Home: ${JELLY_HOME}`));
26
+ process.exit(0);
27
+ }
28
+ if (subcmd === "config") {
29
+ console.log(T.accent("JellyOS Config"));
30
+ console.log(T.muted(`Config file: ${envPath}`));
31
+ if (existsSync(envPath)) {
32
+ for (const line of readFileSync(envPath, "utf-8").split("\n")) {
33
+ const m = line.match(/^([A-Z_]+)=(.*)$/);
34
+ if (!m)
35
+ continue;
36
+ const masked = m[2].length > 8 ? m[2].slice(0, 4) + "****" + m[2].slice(-4) : "****";
37
+ console.log(` ${m[1].padEnd(28)} ${masked}`);
38
+ }
39
+ }
40
+ else {
41
+ console.log(T.warn("No config found. Run jellyos setup first."));
42
+ }
43
+ process.exit(0);
44
+ }
45
+ // ── Resolve extension + prompt ────────────────────────────────────────────────
46
+ let extensionPath = null;
47
+ let promptPath = null;
48
+ for (let i = 0; i < args.length; i++) {
49
+ if (args[i] === "--extension" && args[i + 1])
50
+ extensionPath = args[i + 1];
51
+ if (args[i] === "--prompt" && args[i + 1])
52
+ promptPath = args[i + 1];
53
+ }
54
+ if (!extensionPath) {
55
+ for (const c of ["extensions/jellyos.ts", "extensions/jellyos.js", "extension.ts", "extension.js"]) {
56
+ const abs = resolve(c);
57
+ if (existsSync(abs)) {
58
+ extensionPath = abs;
59
+ break;
60
+ }
61
+ }
62
+ }
63
+ let systemPrompt = "";
64
+ if (promptPath && existsSync(promptPath)) {
65
+ systemPrompt = readFileSync(promptPath, "utf-8");
66
+ }
67
+ else {
68
+ const dp = resolve("prompts/jellyos.md");
69
+ if (existsSync(dp))
70
+ systemPrompt = readFileSync(dp, "utf-8");
71
+ }
72
+ function loadContext() {
73
+ const ctxPath = join(JELLY_HOME, "context.json");
74
+ if (!existsSync(ctxPath))
75
+ return { effectLevel: "normal", chain: "ethereum" };
76
+ try {
77
+ const ctx = JSON.parse(readFileSync(ctxPath, "utf-8"));
78
+ return { effectLevel: ctx.effect_level ?? "normal", chain: ctx.active_chain ?? "ethereum" };
79
+ }
80
+ catch {
81
+ return { effectLevel: "normal", chain: "ethereum" };
82
+ }
83
+ }
84
+ // ── Boot ──────────────────────────────────────────────────────────────────────
85
+ (async () => {
86
+ console.clear();
87
+ console.log(T.accent(`
88
+ ██╗███████╗██╗ ██╗ ██╗ ██╗ ██████╗ ███████╗
89
+ ██║██╔════╝██║ ██║ ╚██╗ ██╔╝ ██╔═══██╗██╔════╝
90
+ ██║█████╗ ██║ ██║ ╚████╔╝ ██║ ██║███████╗
91
+ ██ ██║██╔══╝ ██║ ██║ ╚██╔╝ ██║ ██║╚════██║
92
+ ╚█████╔╝███████╗███████╗██║ ██║ ╚██████╔╝███████║
93
+ ╚════╝ ╚══════╝╚══════╝╚═╝ ╚═╝ ╚═════╝ ╚══════╝
94
+ `));
95
+ console.log(T.muted(" Standalone AI trading agent — all local, zero exposure\n"));
96
+ const registry = new Registry();
97
+ const { effectLevel, chain } = loadContext();
98
+ // These callbacks are forwarded into the extension API so ui.setStatus
99
+ // and ui.notify work even during the session_start hook (before Ink mounts).
100
+ let _notifyFn = null;
101
+ let _setStatusFn = null;
102
+ if (extensionPath) {
103
+ try {
104
+ console.log(T.muted(` Loading: ${extensionPath}`));
105
+ await loadExtension(extensionPath, registry, {
106
+ onNotify: (msg) => { _notifyFn?.(msg); },
107
+ onStatusUpdate: (k, v) => { _setStatusFn?.(k, v); },
108
+ });
109
+ console.log(T.success(` ✓ ${registry.listTools().length} tools · ${registry.listCommands().length} commands`));
110
+ }
111
+ catch (e) {
112
+ console.error(T.error(` ✗ Extension load failed: ${e.message}`));
113
+ process.exit(1);
114
+ }
115
+ }
116
+ else {
117
+ console.log(T.warn(" No extension found — base agent only."));
118
+ console.log(T.muted(" Run from jellyos project root or pass --extension path\n"));
119
+ }
120
+ if (!process.env.OPENROUTER_API_KEY && !process.env.ANTHROPIC_API_KEY && !process.env.OPENAI_API_KEY) {
121
+ console.log(T.warn(" No API key found. Set OPENROUTER_API_KEY in ~/.jelly/.env\n"));
122
+ }
123
+ await new Promise(r => setTimeout(r, 500));
124
+ console.clear();
125
+ render(React.createElement(App, {
126
+ registry,
127
+ systemPrompt,
128
+ effectLevel,
129
+ chain,
130
+ onNotifyReady: (fn) => { _notifyFn = fn; },
131
+ onStatusReady: (fn) => { _setStatusFn = fn; },
132
+ }), { exitOnCtrlC: false });
133
+ })();
134
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAiB,WAAW,CAAC;AACrD,OAAO,EAAE,OAAO,EAAE,MAAuB,SAAS,CAAC;AACnD,OAAO,EAAE,MAAM,EAAE,MAAwB,KAAK,CAAC;AAC/C,OAAO,KAAK,MAA6B,OAAO,CAAC;AACjD,OAAO,EAAE,MAAM,IAAI,UAAU,EAAE,MAAU,QAAQ,CAAC;AAClD,OAAO,EAAE,QAAQ,EAAE,MAAsB,mBAAmB,CAAC;AAC7D,OAAO,EAAE,aAAa,EAAE,MAAiB,aAAa,CAAC;AACvD,OAAO,EAAE,GAAG,EAAE,MAA2B,cAAc,CAAC;AACxD,OAAO,EAAE,CAAC,EAAE,MAA6B,gBAAgB,CAAC;AAE1D,gFAAgF;AAChF,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,QAAQ,CAAC,CAAC;AACzE,MAAM,OAAO,GAAM,IAAI,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;AAC5C,IAAI,UAAU,CAAC,OAAO,CAAC;IAAE,UAAU,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC;AAExE,iFAAiF;AACjF,MAAM,IAAI,GAAK,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACrC,MAAM,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;AAEvB,IAAI,MAAM,KAAK,OAAO,EAAE,CAAC;IACvB,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,8CAA8C,CAAC,CAAC,CAAC;IACtE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,UAAU,EAAE,CAAC,CAAC,CAAC;IAC5C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,IAAI,MAAM,KAAK,QAAQ,EAAE,CAAC;IACxB,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,CAAC;IACxC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,gBAAgB,OAAO,EAAE,CAAC,CAAC,CAAC;IAChD,IAAI,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QACxB,KAAK,MAAM,IAAI,IAAI,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YAC9D,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC;YACzC,IAAI,CAAC,CAAC;gBAAE,SAAS;YACjB,MAAM,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;YACrF,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,MAAM,EAAE,CAAC,CAAC;QAChD,CAAC;IACH,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,2CAA2C,CAAC,CAAC,CAAC;IACnE,CAAC;IACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,iFAAiF;AACjF,IAAI,aAAa,GAAkB,IAAI,CAAC;AACxC,IAAI,UAAU,GAAqB,IAAI,CAAC;AAExC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;IACrC,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,aAAa,IAAI,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;QAAE,aAAa,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAE,CAAC;IAC3E,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,UAAU,IAAO,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;QAAE,UAAU,GAAM,IAAI,CAAC,CAAC,GAAG,CAAC,CAAE,CAAC;AAC7E,CAAC;AAED,IAAI,CAAC,aAAa,EAAE,CAAC;IACnB,KAAK,MAAM,CAAC,IAAI,CAAC,uBAAuB,EAAE,uBAAuB,EAAE,cAAc,EAAE,cAAc,CAAC,EAAE,CAAC;QACnG,MAAM,GAAG,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;QACvB,IAAI,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YAAC,aAAa,GAAG,GAAG,CAAC;YAAC,MAAM;QAAC,CAAC;IACtD,CAAC;AACH,CAAC;AAED,IAAI,YAAY,GAAG,EAAE,CAAC;AACtB,IAAI,UAAU,IAAI,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;IACzC,YAAY,GAAG,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;AACnD,CAAC;KAAM,CAAC;IACN,MAAM,EAAE,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAAC;IACzC,IAAI,UAAU,CAAC,EAAE,CAAC;QAAE,YAAY,GAAG,YAAY,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;AAC/D,CAAC;AAED,SAAS,WAAW;IAClB,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,EAAE,cAAc,CAAC,CAAC;IACjD,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC;QAAE,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC;IAC9E,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;QACvD,OAAO,EAAE,WAAW,EAAE,GAAG,CAAC,YAAY,IAAI,QAAQ,EAAE,KAAK,EAAE,GAAG,CAAC,YAAY,IAAI,UAAU,EAAE,CAAC;IAC9F,CAAC;IAAC,MAAM,CAAC;QAAC,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC;IAAC,CAAC;AAClE,CAAC;AAED,iFAAiF;AACjF,CAAC,KAAK,IAAI,EAAE;IACV,OAAO,CAAC,KAAK,EAAE,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC;;;;;;;GAOpB,CAAC,CAAC,CAAC;IACJ,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,4DAA4D,CAAC,CAAC,CAAC;IAEnF,MAAM,QAAQ,GAAqB,IAAI,QAAQ,EAAE,CAAC;IAClD,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,GAAO,WAAW,EAAE,CAAC;IAEjD,uEAAuE;IACvE,6EAA6E;IAC7E,IAAI,SAAS,GAA+C,IAAI,CAAC;IACjE,IAAI,YAAY,GAA2C,IAAI,CAAC;IAEhE,IAAI,aAAa,EAAE,CAAC;QAClB,IAAI,CAAC;YACH,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,cAAc,aAAa,EAAE,CAAC,CAAC,CAAC;YACpD,MAAM,aAAa,CAAC,aAAa,EAAE,QAAQ,EAAE;gBAC3C,QAAQ,EAAO,CAAC,GAAG,EAAE,EAAE,GAAG,SAAS,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;gBAC7C,cAAc,EAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,GAAG,YAAY,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;aACnD,CAAC,CAAC;YACH,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,QAAQ,CAAC,SAAS,EAAE,CAAC,MAAM,YAAY,QAAQ,CAAC,YAAY,EAAE,CAAC,MAAM,WAAW,CAAC,CAAC,CAAC;QAClH,CAAC;QAAC,OAAO,CAAM,EAAE,CAAC;YAChB,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,8BAA8B,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;YAClE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,yCAAyC,CAAC,CAAC,CAAC;QAC/D,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,4DAA4D,CAAC,CAAC,CAAC;IACrF,CAAC;IAED,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE,CAAC;QACrG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,+DAA+D,CAAC,CAAC,CAAC;IACvF,CAAC;IAED,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;IAC3C,OAAO,CAAC,KAAK,EAAE,CAAC;IAEhB,MAAM,CACJ,KAAK,CAAC,aAAa,CAAC,GAAG,EAAE;QACvB,QAAQ;QACR,YAAY;QACZ,WAAW;QACX,KAAK;QACL,aAAa,EAAG,CAAC,EAAE,EAAE,EAAE,GAAG,SAAS,GAAM,EAAE,CAAC,CAAC,CAAC;QAC9C,aAAa,EAAG,CAAC,EAAE,EAAE,EAAE,GAAG,YAAY,GAAG,EAAE,CAAC,CAAC,CAAC;KAC/C,CAAC,EACF,EAAE,WAAW,EAAE,KAAK,EAAE,CACvB,CAAC;AACJ,CAAC,CAAC,EAAE,CAAC"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * @jellychain/agent — public API
3
+ *
4
+ * Extension files import from here:
5
+ * import { Type } from "@jellychain/agent"
6
+ * import type { ExtensionAPI } from "@jellychain/agent"
7
+ */
8
+ export { Type, type Static } from "@sinclair/typebox";
9
+ export type { ExtensionAPI, ExtensionModule, CommandDef, CommandContext, UIContext, ThemeContext, ToolDef, ToolContent, SkillDef, SessionEvent, SessionContext, } from "./api/ExtensionAPI.js";
10
+ export { text } from "./api/ExtensionAPI.js";
11
+ export { Registry } from "./api/Registry.js";
12
+ export { AgentRunner } from "./runner/AgentRunner.js";
13
+ export { ModelClient, resolveModelConfig } from "./runner/ModelClient.js";
14
+ export { ToolDispatcher } from "./runner/ToolDispatcher.js";
15
+ export { SessionManager } from "./session/SessionManager.js";
16
+ export { loadExtension } from "./loader.js";
17
+ export { makeTheme, T, JELLY_COLORS } from "./tui/theme.js";
18
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EAAE,IAAI,EAAE,KAAK,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAGtD,YAAY,EACV,YAAY,EACZ,eAAe,EACf,UAAU,EACV,cAAc,EACd,SAAS,EACT,YAAY,EACZ,OAAO,EACP,WAAW,EACX,QAAQ,EACR,YAAY,EACZ,cAAc,GACf,MAAM,uBAAuB,CAAC;AAG/B,OAAO,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAG7C,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAG7C,OAAO,EAAE,WAAW,EAAE,MAAS,yBAAyB,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC1E,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAG5D,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAG7D,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAG5C,OAAO,EAAE,SAAS,EAAE,CAAC,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,24 @@
1
+ /**
2
+ * @jellychain/agent — public API
3
+ *
4
+ * Extension files import from here:
5
+ * import { Type } from "@jellychain/agent"
6
+ * import type { ExtensionAPI } from "@jellychain/agent"
7
+ */
8
+ // Re-export TypeBox Type builder — drop-in for Pi's @earendil-works/pi-ai
9
+ export { Type } from "@sinclair/typebox";
10
+ // text() helper — same as what Pi provides
11
+ export { text } from "./api/ExtensionAPI.js";
12
+ // Registry (for advanced use / testing)
13
+ export { Registry } from "./api/Registry.js";
14
+ // Runner components
15
+ export { AgentRunner } from "./runner/AgentRunner.js";
16
+ export { ModelClient, resolveModelConfig } from "./runner/ModelClient.js";
17
+ export { ToolDispatcher } from "./runner/ToolDispatcher.js";
18
+ // Session
19
+ export { SessionManager } from "./session/SessionManager.js";
20
+ // Loader (for embedding the agent in other tools)
21
+ export { loadExtension } from "./loader.js";
22
+ // Theme
23
+ export { makeTheme, T, JELLY_COLORS } from "./tui/theme.js";
24
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,0EAA0E;AAC1E,OAAO,EAAE,IAAI,EAAe,MAAM,mBAAmB,CAAC;AAiBtD,2CAA2C;AAC3C,OAAO,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAE7C,wCAAwC;AACxC,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAE7C,oBAAoB;AACpB,OAAO,EAAE,WAAW,EAAE,MAAS,yBAAyB,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC1E,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAE5D,UAAU;AACV,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAE7D,kDAAkD;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,QAAQ;AACR,OAAO,EAAE,SAAS,EAAE,CAAC,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * loader.ts — loads an extension file and wires it to a Registry.
3
+ *
4
+ * Implements the full ExtensionAPI including Pi compat methods:
5
+ * ui.setStatus, ui.setTheme, ui.setHeader, ctx.hasUI,
6
+ * session_shutdown, before_agent_start
7
+ */
8
+ import { Registry } from "./api/Registry.js";
9
+ export interface LoaderOptions {
10
+ /**
11
+ * Called when the extension uses ui.setStatus(key, value).
12
+ * The App component passes a state-setter here so status badges update live.
13
+ */
14
+ onStatusUpdate?: (key: string, value: string) => void;
15
+ /**
16
+ * Called when the extension calls ui.notify(message).
17
+ * Before the TUI is mounted, the App wires this to React state.
18
+ * We store the latest notifier here so the extension can call it any time.
19
+ */
20
+ onNotify?: (message: string) => void;
21
+ }
22
+ export declare function loadExtension(extensionPath: string, registry: Registry, opts?: LoaderOptions): Promise<void>;
23
+ //# sourceMappingURL=loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../src/loader.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH,OAAO,EAAE,QAAQ,EAAE,MAAgB,mBAAmB,CAAC;AAYvD,MAAM,WAAW,aAAa;IAC5B;;;OAGG;IACH,cAAc,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAEtD;;;;OAIG;IACH,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACtC;AAED,wBAAsB,aAAa,CACjC,aAAa,EAAE,MAAM,EACrB,QAAQ,EAAE,QAAQ,EAClB,IAAI,GAAE,aAAkB,GACvB,OAAO,CAAC,IAAI,CAAC,CAgFf"}
package/dist/loader.js ADDED
@@ -0,0 +1,84 @@
1
+ /**
2
+ * loader.ts — loads an extension file and wires it to a Registry.
3
+ *
4
+ * Implements the full ExtensionAPI including Pi compat methods:
5
+ * ui.setStatus, ui.setTheme, ui.setHeader, ctx.hasUI,
6
+ * session_shutdown, before_agent_start
7
+ */
8
+ import { pathToFileURL } from "node:url";
9
+ import { resolve, extname } from "node:path";
10
+ import { existsSync } from "node:fs";
11
+ import { makeTheme } from "./tui/theme.js";
12
+ export async function loadExtension(extensionPath, registry, opts = {}) {
13
+ const abs = resolve(extensionPath);
14
+ if (!existsSync(abs)) {
15
+ throw new Error(`Extension file not found: ${abs}`);
16
+ }
17
+ const theme = makeTheme();
18
+ // Live-updateable notifier — App.tsx replaces this once mounted
19
+ let _notify = opts.onNotify ?? ((_msg) => { });
20
+ let _setStatus = opts.onStatusUpdate ?? ((_k, _v) => { });
21
+ const ui = {
22
+ notify(message) { _notify(message); },
23
+ setStatus(key, value) { _setStatus(key, value); },
24
+ setTheme(_name) { },
25
+ setHeader(_factory) { },
26
+ theme,
27
+ };
28
+ const api = {
29
+ registerCommand(name, def) {
30
+ registry.addCommand(name, def);
31
+ },
32
+ registerTool(def) {
33
+ registry.addTool(def);
34
+ },
35
+ registerSkill(def) {
36
+ registry.addSkill(def);
37
+ },
38
+ on(event, handler) {
39
+ registry.addHook(event, handler);
40
+ },
41
+ setSystemPrompt(prompt) {
42
+ registry.setSystemPrompt(prompt);
43
+ },
44
+ ui,
45
+ };
46
+ const ext = extname(abs).toLowerCase();
47
+ let mod;
48
+ if (ext === ".ts") {
49
+ // In packaged (dist) mode Node.js cannot natively import TypeScript.
50
+ // Resolution order:
51
+ // 1. Try a compiled sibling: same dir, same basename but .js extension
52
+ // 2. Try tsx/esm API (available when tsx is installed as dev-dep or globally)
53
+ // 3. Throw a clear error telling the user how to fix it
54
+ const jsPath = abs.replace(/\.ts$/, ".js");
55
+ if (existsSync(jsPath)) {
56
+ // Pre-compiled sibling exists — use it directly
57
+ mod = await import(pathToFileURL(jsPath).href);
58
+ }
59
+ else {
60
+ // Attempt tsx runtime import (tsx must be installed)
61
+ try {
62
+ const tsxMod = await import("tsx/esm/api");
63
+ mod = await tsxMod.tsImport(pathToFileURL(abs).href, import.meta.url);
64
+ }
65
+ catch {
66
+ throw new Error(`Cannot import TypeScript extension "${abs}" in packaged mode.\n` +
67
+ `Fix options:\n` +
68
+ ` 1. Compile the extension first: npx tsx --transpile-only ${abs}\n` +
69
+ ` (produces ${jsPath})\n` +
70
+ ` 2. Install tsx globally: npm install -g tsx\n` +
71
+ ` Then run: tsx bin/jellyagent --extension ${abs}`);
72
+ }
73
+ }
74
+ }
75
+ else {
76
+ mod = await import(pathToFileURL(abs).href);
77
+ }
78
+ const fn = mod.default ?? mod;
79
+ if (typeof fn !== "function") {
80
+ throw new Error(`Extension must export a default function. Got: ${typeof fn} from ${abs}`);
81
+ }
82
+ await fn(api);
83
+ }
84
+ //# sourceMappingURL=loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loader.js","sourceRoot":"","sources":["../src/loader.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,66 @@
1
+ /**
2
+ * AgentRunner — the core agentic loop.
3
+ *
4
+ * 1. Fires before_agent_start hooks (prompt injection, live context)
5
+ * 2. Streams model response (with multi-model fallback rotation)
6
+ * 3. If model returns tool calls → dispatch → feed results back → continue
7
+ * 4. Emits events so the TUI can render incrementally
8
+ */
9
+ import type { Registry } from "../api/Registry.js";
10
+ import type { SessionManager } from "../session/SessionManager.js";
11
+ import type { SessionContext } from "../api/ExtensionAPI.js";
12
+ export type RunnerEvent = {
13
+ type: "text_delta";
14
+ text: string;
15
+ } | {
16
+ type: "tool_start";
17
+ name: string;
18
+ args: string;
19
+ } | {
20
+ type: "tool_done";
21
+ name: string;
22
+ result: string;
23
+ isError: boolean;
24
+ } | {
25
+ type: "model_fallback";
26
+ from: string;
27
+ to: string;
28
+ reason: string;
29
+ } | {
30
+ type: "swarm_subtask";
31
+ task: string;
32
+ model: string;
33
+ ms: number;
34
+ remaining: number;
35
+ } | {
36
+ type: "swarm_review";
37
+ subCount: number;
38
+ } | {
39
+ type: "turn_done";
40
+ } | {
41
+ type: "error";
42
+ message: string;
43
+ };
44
+ export type RunnerEventHandler = (event: RunnerEvent) => void;
45
+ export declare class AgentRunner {
46
+ private registry;
47
+ private session;
48
+ private onEvent;
49
+ private sessionCtx;
50
+ private effectLevel;
51
+ private modelChain;
52
+ private dispatcher;
53
+ private swarmRouter;
54
+ constructor(registry: Registry, session: SessionManager, onEvent: RunnerEventHandler, sessionCtx: SessionContext, effectLevel?: string);
55
+ /**
56
+ * Live reconfigure effect level without recreating the runner.
57
+ * Called by the /effect REPL command immediately on each invocation so that
58
+ * the next user turn uses the new swarm config.
59
+ */
60
+ setEffectLevel(level: string): void;
61
+ /** Run one user turn — may invoke multiple tool rounds and model fallbacks internally */
62
+ run(userMessage: string): Promise<void>;
63
+ private runSwarm;
64
+ runSingleAgent(): Promise<void>;
65
+ }
66
+ //# sourceMappingURL=AgentRunner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AgentRunner.d.ts","sourceRoot":"","sources":["../../src/runner/AgentRunner.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAWH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAQ,oBAAoB,CAAC;AACrD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AACnE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAE7D,MAAM,MAAM,WAAW,GACnB;IAAE,IAAI,EAAE,YAAY,CAAC;IAAK,IAAI,EAAE,MAAM,CAAA;CAAE,GACxC;IAAE,IAAI,EAAE,YAAY,CAAC;IAAK,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACtD;IAAE,IAAI,EAAE,WAAW,CAAC;IAAM,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,GAC1E;IAAE,IAAI,EAAE,gBAAgB,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACpE;IAAE,IAAI,EAAE,eAAe,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,GACtF;IAAE,IAAI,EAAE,cAAc,CAAC;IAAG,QAAQ,EAAE,MAAM,CAAA;CAAE,GAC5C;IAAE,IAAI,EAAE,WAAW,CAAA;CAAE,GACrB;IAAE,IAAI,EAAE,OAAO,CAAC;IAAU,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAEhD,MAAM,MAAM,kBAAkB,GAAG,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAC;AAY9D,qBAAa,WAAW;IAMpB,OAAO,CAAC,QAAQ;IAChB,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,WAAW;IATrB,OAAO,CAAC,UAAU,CAAgB;IAClC,OAAO,CAAC,UAAU,CAAiB;IACnC,OAAO,CAAC,WAAW,CAAc;gBAGvB,QAAQ,EAAK,QAAQ,EACrB,OAAO,EAAM,cAAc,EAC3B,OAAO,EAAM,kBAAkB,EAC/B,UAAU,EAAG,cAAc,EAC3B,WAAW,GAAE,MAAiB;IAWxC;;;;OAIG;IACH,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAWnC,yFAAyF;IACnF,GAAG,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;YAqB/B,QAAQ;IAgChB,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;CA0FtC"}
@@ -0,0 +1,179 @@
1
+ /**
2
+ * AgentRunner — the core agentic loop.
3
+ *
4
+ * 1. Fires before_agent_start hooks (prompt injection, live context)
5
+ * 2. Streams model response (with multi-model fallback rotation)
6
+ * 3. If model returns tool calls → dispatch → feed results back → continue
7
+ * 4. Emits events so the TUI can render incrementally
8
+ */
9
+ import { ModelClient, resolveModelChain, } from "./ModelClient.js";
10
+ import { ToolDispatcher } from "./ToolDispatcher.js";
11
+ import { SwarmRouter } from "./SwarmRouter.js";
12
+ const MAX_TOOL_ROUNDS = 12;
13
+ /** Effect level → swarm behaviour config */
14
+ const EFFECT_SWARM = {
15
+ eco: { threshold: 999, maxAgents: 0 }, // never swarm
16
+ normal: { threshold: 999, maxAgents: 0 }, // never swarm
17
+ turbo: { threshold: 40, maxAgents: 2 },
18
+ max: { threshold: 30, maxAgents: 5 },
19
+ };
20
+ export class AgentRunner {
21
+ registry;
22
+ session;
23
+ onEvent;
24
+ sessionCtx;
25
+ effectLevel;
26
+ modelChain;
27
+ dispatcher;
28
+ swarmRouter;
29
+ constructor(registry, session, onEvent, sessionCtx, effectLevel = "normal") {
30
+ this.registry = registry;
31
+ this.session = session;
32
+ this.onEvent = onEvent;
33
+ this.sessionCtx = sessionCtx;
34
+ this.effectLevel = effectLevel;
35
+ this.modelChain = resolveModelChain();
36
+ this.dispatcher = new ToolDispatcher(registry);
37
+ const sc = EFFECT_SWARM[effectLevel] ?? EFFECT_SWARM["normal"];
38
+ this.swarmRouter = new SwarmRouter({
39
+ maxAgents: sc.maxAgents,
40
+ complexityThreshold: sc.threshold,
41
+ });
42
+ }
43
+ /**
44
+ * Live reconfigure effect level without recreating the runner.
45
+ * Called by the /effect REPL command immediately on each invocation so that
46
+ * the next user turn uses the new swarm config.
47
+ */
48
+ setEffectLevel(level) {
49
+ this.effectLevel = level;
50
+ // Rebuild model chain — eco/normal may want a different subset
51
+ this.modelChain = resolveModelChain();
52
+ const sc = EFFECT_SWARM[level] ?? EFFECT_SWARM["normal"];
53
+ this.swarmRouter = new SwarmRouter({
54
+ maxAgents: sc.maxAgents,
55
+ complexityThreshold: sc.threshold,
56
+ });
57
+ }
58
+ /** Run one user turn — may invoke multiple tool rounds and model fallbacks internally */
59
+ async run(userMessage) {
60
+ // 1. Fire before_agent_start hooks — extension injects live context, system prompt
61
+ await this.registry.fireHook("before_agent_start", this.sessionCtx);
62
+ // 2. Sync system prompt from registry (extension may have called setSystemPrompt)
63
+ this.session.setSystemPrompt(this.registry.getSystemPrompt());
64
+ // 3. Check swarm eligibility before adding to history
65
+ if (this.swarmRouter.shouldSwarm(userMessage)) {
66
+ await this.runSwarm(userMessage);
67
+ return;
68
+ }
69
+ // 4. Single-agent path — add user message to history
70
+ this.session.addMessage({ role: "user", content: userMessage });
71
+ await this.runSingleAgent();
72
+ this.onEvent({ type: "turn_done" });
73
+ }
74
+ // ── Swarm path ─────────────────────────────────────────────────────────────
75
+ async runSwarm(userMessage) {
76
+ const systemPrompt = this.registry.getSystemPrompt();
77
+ const { synthesis, subResults } = await this.swarmRouter.run(userMessage, systemPrompt, (result, remaining) => {
78
+ this.onEvent({
79
+ type: "swarm_subtask",
80
+ task: result.task,
81
+ model: result.model,
82
+ ms: result.ms,
83
+ remaining,
84
+ });
85
+ });
86
+ this.onEvent({ type: "swarm_review", subCount: subResults.length });
87
+ // Stream reviewer synthesis token-by-token (already complete — re-emit as deltas)
88
+ for (const ch of synthesis) {
89
+ this.onEvent({ type: "text_delta", text: ch });
90
+ }
91
+ // Save to session history as a single assistant message
92
+ this.session.addMessage({ role: "user", content: userMessage });
93
+ this.session.addMessage({ role: "assistant", content: synthesis });
94
+ this.onEvent({ type: "turn_done" });
95
+ }
96
+ // ── Single-agent path (also used for each sub-task in turbo/max) ────────────
97
+ async runSingleAgent() {
98
+ const openAITools = this.registry.toOpenAITools();
99
+ let rounds = 0;
100
+ while (rounds < MAX_TOOL_ROUNDS) {
101
+ rounds++;
102
+ const messages = this.session.getMessages();
103
+ let assistantText = "";
104
+ let pendingToolCalls = [];
105
+ let modelError = null;
106
+ // Try model chain — rotate on 429/5xx
107
+ for (let mi = 0; mi < this.modelChain.length; mi++) {
108
+ const cfg = this.modelChain[mi];
109
+ const client = new ModelClient(cfg);
110
+ assistantText = "";
111
+ pendingToolCalls = [];
112
+ modelError = null;
113
+ let gotError = false;
114
+ let isRateLimit = false;
115
+ for await (const chunk of client.stream(messages, openAITools)) {
116
+ if (chunk.type === "delta" && chunk.text) {
117
+ assistantText += chunk.text;
118
+ this.onEvent({ type: "text_delta", text: chunk.text });
119
+ }
120
+ else if (chunk.type === "tool_call" && chunk.tool_calls) {
121
+ pendingToolCalls = chunk.tool_calls;
122
+ }
123
+ else if (chunk.type === "error") {
124
+ modelError = chunk.error ?? "Unknown model error";
125
+ gotError = true;
126
+ // Rotate on 429 rate-limit OR any 5xx server error
127
+ isRateLimit = /429|rate.?limit/i.test(modelError)
128
+ || (chunk.status !== undefined && chunk.status >= 500);
129
+ break;
130
+ }
131
+ }
132
+ if (!gotError)
133
+ break; // success — use this model's output
134
+ // Rotate to next model on rate-limit or server errors
135
+ const nextCfg = this.modelChain[mi + 1];
136
+ if (nextCfg && isRateLimit) {
137
+ this.onEvent({
138
+ type: "model_fallback",
139
+ from: cfg.model,
140
+ to: nextCfg.model,
141
+ reason: modelError ?? "rate limit",
142
+ });
143
+ continue;
144
+ }
145
+ // Non-recoverable error or no more fallbacks
146
+ this.onEvent({ type: "error", message: modelError ?? "Model error" });
147
+ return;
148
+ }
149
+ if (modelError && assistantText === "" && pendingToolCalls.length === 0) {
150
+ this.onEvent({ type: "error", message: modelError });
151
+ return;
152
+ }
153
+ // Save assistant turn
154
+ const assistantMsg = {
155
+ role: "assistant",
156
+ content: assistantText || null,
157
+ ...(pendingToolCalls.length > 0 ? { tool_calls: pendingToolCalls } : {}),
158
+ };
159
+ this.session.addMessage(assistantMsg);
160
+ if (pendingToolCalls.length === 0)
161
+ break;
162
+ // Dispatch tool calls
163
+ for (const tc of pendingToolCalls) {
164
+ this.onEvent({ type: "tool_start", name: tc.function.name, args: tc.function.arguments });
165
+ }
166
+ const results = await this.dispatcher.dispatch(pendingToolCalls);
167
+ for (const r of results) {
168
+ this.onEvent({ type: "tool_done", name: r.name, result: r.content, isError: r.isError });
169
+ this.session.addMessage({
170
+ role: "tool",
171
+ content: r.content,
172
+ name: r.name,
173
+ tool_call_id: r.tool_call_id,
174
+ });
175
+ }
176
+ }
177
+ }
178
+ }
179
+ //# sourceMappingURL=AgentRunner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AgentRunner.js","sourceRoot":"","sources":["../../src/runner/AgentRunner.ts"],"names":[],"mappings":"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"}