@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.
- package/README.md +375 -0
- package/bin/jellyagent +31 -0
- package/dist/api/ExtensionAPI.d.ts +92 -0
- package/dist/api/ExtensionAPI.d.ts.map +1 -0
- package/dist/api/ExtensionAPI.js +15 -0
- package/dist/api/ExtensionAPI.js.map +1 -0
- package/dist/api/Registry.d.ts +54 -0
- package/dist/api/Registry.d.ts.map +1 -0
- package/dist/api/Registry.js +101 -0
- package/dist/api/Registry.js.map +1 -0
- package/dist/cli.d.ts +6 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +134 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +24 -0
- package/dist/index.js.map +1 -0
- package/dist/loader.d.ts +23 -0
- package/dist/loader.d.ts.map +1 -0
- package/dist/loader.js +84 -0
- package/dist/loader.js.map +1 -0
- package/dist/runner/AgentRunner.d.ts +66 -0
- package/dist/runner/AgentRunner.d.ts.map +1 -0
- package/dist/runner/AgentRunner.js +179 -0
- package/dist/runner/AgentRunner.js.map +1 -0
- package/dist/runner/ModelClient.d.ts +77 -0
- package/dist/runner/ModelClient.d.ts.map +1 -0
- package/dist/runner/ModelClient.js +224 -0
- package/dist/runner/ModelClient.js.map +1 -0
- package/dist/runner/SwarmRouter.d.ts +58 -0
- package/dist/runner/SwarmRouter.d.ts.map +1 -0
- package/dist/runner/SwarmRouter.js +153 -0
- package/dist/runner/SwarmRouter.js.map +1 -0
- package/dist/runner/ToolDispatcher.d.ts +19 -0
- package/dist/runner/ToolDispatcher.d.ts.map +1 -0
- package/dist/runner/ToolDispatcher.js +64 -0
- package/dist/runner/ToolDispatcher.js.map +1 -0
- package/dist/session/SessionManager.d.ts +23 -0
- package/dist/session/SessionManager.d.ts.map +1 -0
- package/dist/session/SessionManager.js +50 -0
- package/dist/session/SessionManager.js.map +1 -0
- package/dist/tui/App.d.ts +18 -0
- package/dist/tui/App.d.ts.map +1 -0
- package/dist/tui/App.js +188 -0
- package/dist/tui/App.js.map +1 -0
- package/dist/tui/REPL.d.ts +22 -0
- package/dist/tui/REPL.d.ts.map +1 -0
- package/dist/tui/REPL.js +46 -0
- package/dist/tui/REPL.js.map +1 -0
- package/dist/tui/StatusBar.d.ts +16 -0
- package/dist/tui/StatusBar.d.ts.map +1 -0
- package/dist/tui/StatusBar.js +15 -0
- package/dist/tui/StatusBar.js.map +1 -0
- package/dist/tui/theme.d.ts +30 -0
- package/dist/tui/theme.d.ts.map +1 -0
- package/dist/tui/theme.js +41 -0
- package/dist/tui/theme.js.map +1 -0
- 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 @@
|
|
|
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
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -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"}
|
package/dist/loader.d.ts
ADDED
|
@@ -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":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAW,UAAU,CAAC;AAC9C,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAQ,WAAW,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAc,SAAS,CAAC;AAE7C,OAAO,EAAE,SAAS,EAAE,MAAe,gBAAgB,CAAC;AA0BpD,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,aAAqB,EACrB,QAAkB,EAClB,OAAsB,EAAE;IAExB,MAAM,GAAG,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;IACnC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACrB,MAAM,IAAI,KAAK,CAAC,6BAA6B,GAAG,EAAE,CAAC,CAAC;IACtD,CAAC;IAED,MAAM,KAAK,GAAG,SAAS,EAAE,CAAC;IAE1B,gEAAgE;IAChE,IAAI,OAAO,GAAG,IAAI,CAAC,QAAQ,IAAI,CAAC,CAAC,IAAY,EAAE,EAAE,GAAE,CAAC,CAAC,CAAC;IACtD,IAAI,UAAU,GAAG,IAAI,CAAC,cAAc,IAAI,CAAC,CAAC,EAAU,EAAE,EAAU,EAAE,EAAE,GAAE,CAAC,CAAC,CAAC;IAEzE,MAAM,EAAE,GAAc;QACpB,MAAM,CAAC,OAAe,IAAgB,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QACzD,SAAS,CAAC,GAAW,EAAE,KAAa,IAAI,UAAU,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;QACjE,QAAQ,CAAC,KAAa,IAAoD,CAAC;QAC3E,SAAS,CAAC,QAAQ,IAA4D,CAAC;QAC/E,KAAK;KACN,CAAC;IAEF,MAAM,GAAG,GAAiB;QACxB,eAAe,CAAC,IAAY,EAAE,GAAe;YAC3C,QAAQ,CAAC,UAAU,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QACjC,CAAC;QACD,YAAY,CAAoB,GAAe;YAC7C,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACxB,CAAC;QACD,aAAa,CAAC,GAAa;YACzB,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;QACzB,CAAC;QACD,EAAE,CAAC,KAAmB,EAAE,OAA0C;YAChE,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QACnC,CAAC;QACD,eAAe,CAAC,MAAc;YAC5B,QAAQ,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;QACnC,CAAC;QACD,EAAE;KACH,CAAC;IAEF,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC;IACvC,IAAI,GAAQ,CAAC;IAEb,IAAI,GAAG,KAAK,KAAK,EAAE,CAAC;QAClB,qEAAqE;QACrE,oBAAoB;QACpB,yEAAyE;QACzE,gFAAgF;QAChF,0DAA0D;QAC1D,MAAM,MAAM,GAAG,GAAG,CAAC,OAAO,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QAC3C,IAAI,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;YACvB,gDAAgD;YAChD,GAAG,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC;QACjD,CAAC;aAAM,CAAC;YACN,qDAAqD;YACrD,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,CAAC;gBAC3C,GAAG,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACxE,CAAC;YAAC,MAAM,CAAC;gBACP,MAAM,IAAI,KAAK,CACb,uCAAuC,GAAG,uBAAuB;oBACjE,gBAAgB;oBAChB,8DAA8D,GAAG,IAAI;oBACrE,kBAAkB,MAAM,KAAK;oBAC7B,iDAAiD;oBACjD,iDAAiD,GAAG,EAAE,CACvD,CAAC;YACJ,CAAC;QACH,CAAC;IACH,CAAC;SAAM,CAAC;QACN,GAAG,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC;IAC9C,CAAC;IAED,MAAM,EAAE,GAAG,GAAG,CAAC,OAAO,IAAI,GAAG,CAAC;IAC9B,IAAI,OAAO,EAAE,KAAK,UAAU,EAAE,CAAC;QAC7B,MAAM,IAAI,KAAK,CACb,kDAAkD,OAAO,EAAE,SAAS,GAAG,EAAE,CAC1E,CAAC;IACJ,CAAC;IAED,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC;AAChB,CAAC"}
|
|
@@ -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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"}
|