@agentrun/sdk 0.0.3 → 0.0.4
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 +20 -15
- package/dist/agent-runtime/api/index.cjs +907 -0
- package/dist/agent-runtime/api/index.cjs.map +1 -0
- package/dist/agent-runtime/api/index.d.cts +193 -0
- package/dist/agent-runtime/api/index.d.ts +193 -0
- package/dist/agent-runtime/api/index.js +882 -0
- package/dist/agent-runtime/api/index.js.map +1 -0
- package/dist/agent-runtime/index.cjs +2528 -0
- package/dist/agent-runtime/index.cjs.map +1 -0
- package/dist/agent-runtime/index.d.cts +778 -0
- package/dist/agent-runtime/index.d.ts +778 -0
- package/dist/agent-runtime/index.js +2496 -0
- package/dist/agent-runtime/index.js.map +1 -0
- package/dist/base-K1GMfJbH.d.ts +59 -0
- package/dist/base-xcWt5bua.d.cts +59 -0
- package/dist/client-DHXxjuo3.d.ts +58 -0
- package/dist/client-DPUTs69s.d.cts +58 -0
- package/dist/config-07gMelJP.d.cts +125 -0
- package/dist/config-07gMelJP.d.ts +125 -0
- package/dist/control-api-BWD4eua5.d.cts +27 -0
- package/dist/control-api-d-82Sgpr.d.ts +27 -0
- package/dist/credential/api/index.cjs +655 -0
- package/dist/credential/api/index.cjs.map +1 -0
- package/dist/credential/api/index.d.cts +93 -0
- package/dist/credential/api/index.d.ts +93 -0
- package/dist/credential/api/index.js +630 -0
- package/dist/credential/api/index.js.map +1 -0
- package/dist/credential/index.cjs +1286 -0
- package/dist/credential/index.cjs.map +1 -0
- package/dist/credential/index.d.cts +246 -0
- package/dist/credential/index.d.ts +246 -0
- package/dist/credential/index.js +1263 -0
- package/dist/credential/index.js.map +1 -0
- package/dist/data-api-B-4h9_Vf.d.ts +166 -0
- package/dist/data-api-DsG-8JRQ.d.cts +166 -0
- package/dist/exception-DM9H2Rpo.d.cts +68 -0
- package/dist/exception-DM9H2Rpo.d.ts +68 -0
- package/dist/index.cjs +29281 -1427
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +38 -4485
- package/dist/index.d.ts +38 -4485
- package/dist/index.js +29259 -1426
- package/dist/index.js.map +1 -1
- package/dist/integration/builtin/index.cjs +9399 -0
- package/dist/integration/builtin/index.cjs.map +1 -0
- package/dist/integration/builtin/index.d.cts +692 -0
- package/dist/integration/builtin/index.d.ts +692 -0
- package/dist/integration/builtin/index.js +9363 -0
- package/dist/integration/builtin/index.js.map +1 -0
- package/dist/integration/index.cjs +9524 -0
- package/dist/integration/index.cjs.map +1 -0
- package/dist/integration/index.d.cts +98 -0
- package/dist/integration/index.d.ts +98 -0
- package/dist/integration/index.js +9481 -0
- package/dist/integration/index.js.map +1 -0
- package/dist/integration/mastra/index.cjs +9383 -0
- package/dist/integration/mastra/index.cjs.map +1 -0
- package/dist/integration/mastra/index.d.cts +186 -0
- package/dist/integration/mastra/index.d.ts +186 -0
- package/dist/integration/mastra/index.js +9348 -0
- package/dist/integration/mastra/index.js.map +1 -0
- package/dist/model/index.cjs +2392 -0
- package/dist/model/index.cjs.map +1 -0
- package/dist/model/index.d.cts +97 -0
- package/dist/model/index.d.ts +97 -0
- package/dist/model/index.js +2368 -0
- package/dist/model/index.js.map +1 -0
- package/dist/model--I90nCqy.d.cts +66 -0
- package/dist/model--I90nCqy.d.ts +66 -0
- package/dist/model-BV7A6Trb.d.cts +512 -0
- package/dist/model-DGBy-o_L.d.cts +176 -0
- package/dist/model-DGBy-o_L.d.ts +176 -0
- package/dist/model-RiiiZnou.d.ts +512 -0
- package/dist/model-service-D-P2FZNi.d.ts +540 -0
- package/dist/model-service-VpzBb7rV.d.cts +540 -0
- package/dist/resource-CQovFUeh.d.cts +44 -0
- package/dist/resource-DnE_DEka.d.ts +44 -0
- package/dist/sandbox/index.cjs +3557 -0
- package/dist/sandbox/index.cjs.map +1 -0
- package/dist/sandbox/index.d.cts +1598 -0
- package/dist/sandbox/index.d.ts +1598 -0
- package/dist/sandbox/index.js +3532 -0
- package/dist/sandbox/index.js.map +1 -0
- package/dist/server/adapter/index.cjs +24886 -0
- package/dist/server/adapter/index.cjs.map +1 -0
- package/dist/server/adapter/index.d.cts +68 -0
- package/dist/server/adapter/index.d.ts +68 -0
- package/dist/server/adapter/index.js +24883 -0
- package/dist/server/adapter/index.js.map +1 -0
- package/dist/server/core/index.cjs +313 -0
- package/dist/server/core/index.cjs.map +1 -0
- package/dist/server/core/index.d.cts +58 -0
- package/dist/server/core/index.d.ts +58 -0
- package/dist/server/core/index.js +309 -0
- package/dist/server/core/index.js.map +1 -0
- package/dist/server/index.cjs +25098 -0
- package/dist/server/index.cjs.map +1 -0
- package/dist/server/index.d.cts +73 -0
- package/dist/server/index.d.ts +73 -0
- package/dist/server/index.js +25067 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/protocol/index.cjs +1057 -0
- package/dist/server/protocol/index.cjs.map +1 -0
- package/dist/server/protocol/index.d.cts +135 -0
- package/dist/server/protocol/index.d.ts +135 -0
- package/dist/server/protocol/index.js +1053 -0
- package/dist/server/protocol/index.js.map +1 -0
- package/dist/tool-CG0LY-ov.d.cts +155 -0
- package/dist/tool-JJHam0ms.d.ts +155 -0
- package/dist/toolset/api/index.cjs +754 -0
- package/dist/toolset/api/index.cjs.map +1 -0
- package/dist/toolset/api/index.d.cts +207 -0
- package/dist/toolset/api/index.d.ts +207 -0
- package/dist/toolset/api/index.js +727 -0
- package/dist/toolset/api/index.js.map +1 -0
- package/dist/toolset/index.cjs +1945 -0
- package/dist/toolset/index.cjs.map +1 -0
- package/dist/toolset/index.d.cts +182 -0
- package/dist/toolset/index.d.ts +182 -0
- package/dist/toolset/index.js +1920 -0
- package/dist/toolset/index.js.map +1 -0
- package/dist/toolset-BYDvhwRp.d.cts +394 -0
- package/dist/toolset-CSRsJxCb.d.ts +394 -0
- package/dist/utils/index.cjs +994 -0
- package/dist/utils/index.cjs.map +1 -0
- package/dist/utils/index.d.cts +30 -0
- package/dist/utils/index.d.ts +30 -0
- package/dist/utils/index.js +951 -0
- package/dist/utils/index.js.map +1 -0
- package/package.json +65 -13
|
@@ -0,0 +1,1053 @@
|
|
|
1
|
+
import { v4 } from 'uuid';
|
|
2
|
+
|
|
3
|
+
// src/utils/log.ts
|
|
4
|
+
var LOG_LEVELS = {
|
|
5
|
+
debug: 0,
|
|
6
|
+
info: 1,
|
|
7
|
+
warn: 2,
|
|
8
|
+
error: 3
|
|
9
|
+
};
|
|
10
|
+
var COLORS = {
|
|
11
|
+
reset: "\x1B[0m",
|
|
12
|
+
bright: "\x1B[1m",
|
|
13
|
+
dim: "\x1B[2m",
|
|
14
|
+
italic: "\x1B[3m",
|
|
15
|
+
blue: "\x1B[34m",
|
|
16
|
+
cyan: "\x1B[36m",
|
|
17
|
+
yellow: "\x1B[33m",
|
|
18
|
+
red: "\x1B[31m"
|
|
19
|
+
};
|
|
20
|
+
var Logger = class {
|
|
21
|
+
level = "info";
|
|
22
|
+
// match Python logger name
|
|
23
|
+
prefix = "agentrun-logger";
|
|
24
|
+
setLevel(level) {
|
|
25
|
+
this.level = level;
|
|
26
|
+
}
|
|
27
|
+
shouldLog(level) {
|
|
28
|
+
return LOG_LEVELS[level] >= LOG_LEVELS[this.level];
|
|
29
|
+
}
|
|
30
|
+
getColor(level) {
|
|
31
|
+
switch (level) {
|
|
32
|
+
case "debug":
|
|
33
|
+
return COLORS.cyan;
|
|
34
|
+
case "info":
|
|
35
|
+
return COLORS.blue;
|
|
36
|
+
case "warn":
|
|
37
|
+
return COLORS.yellow;
|
|
38
|
+
case "error":
|
|
39
|
+
return COLORS.red;
|
|
40
|
+
default:
|
|
41
|
+
return COLORS.reset;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
// format timestamp like Python: YYYY-MM-DD HH:mm:ss,SSS
|
|
45
|
+
formatTimestamp(d = /* @__PURE__ */ new Date()) {
|
|
46
|
+
const pad = (n, sz = 2) => n.toString().padStart(sz, "0");
|
|
47
|
+
const year = d.getFullYear();
|
|
48
|
+
const month = pad(d.getMonth() + 1);
|
|
49
|
+
const day = pad(d.getDate());
|
|
50
|
+
const hour = pad(d.getHours());
|
|
51
|
+
const minute = pad(d.getMinutes());
|
|
52
|
+
const second = pad(d.getSeconds());
|
|
53
|
+
const ms = pad(d.getMilliseconds(), 3);
|
|
54
|
+
return `${year}-${month}-${day} ${hour}:${minute}:${second},${ms}`;
|
|
55
|
+
}
|
|
56
|
+
// attempt to infer caller file and line by parsing Error.stack
|
|
57
|
+
// helper: parse a single stack frame into {filepath, line, functionName}
|
|
58
|
+
parseFrame(frame) {
|
|
59
|
+
const m = frame.match(/^(?:at\s+)?(?:(.+?)\s+\()?(.*?):(\d+):(\d+)\)?$/);
|
|
60
|
+
if (!m) return null;
|
|
61
|
+
return {
|
|
62
|
+
functionName: m[1] ? m[1].trim() : void 0,
|
|
63
|
+
filepath: m[2],
|
|
64
|
+
line: parseInt(m[3], 10)
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
// get caller by fixed stack offset (used in public log methods)
|
|
68
|
+
getCallerByOffset() {
|
|
69
|
+
const err = new Error();
|
|
70
|
+
const stack = err.stack;
|
|
71
|
+
if (!stack) return {};
|
|
72
|
+
const lines = stack.split("\n").map((l) => l.trim());
|
|
73
|
+
for (let i = 3; i < lines.length; i++) {
|
|
74
|
+
let parsed = this.parseFrame(lines[i]);
|
|
75
|
+
if (!parsed) {
|
|
76
|
+
const m = lines[i].match(/(\/[^:\s]+:\d+:\d+)/);
|
|
77
|
+
if (m) {
|
|
78
|
+
const parts = m[1].split(":");
|
|
79
|
+
parts.pop();
|
|
80
|
+
const ln = Number(parts.pop());
|
|
81
|
+
const fp2 = parts.join(":");
|
|
82
|
+
parsed = { filepath: fp2, line: ln, functionName: void 0 };
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
if (!parsed) continue;
|
|
86
|
+
const fp = parsed.filepath;
|
|
87
|
+
if (fp.includes("node_modules") || fp.includes("internal") || fp.includes("<anonymous>") || fp.includes("native"))
|
|
88
|
+
continue;
|
|
89
|
+
return { filepath: parsed.filepath, line: parsed.line };
|
|
90
|
+
}
|
|
91
|
+
const cwd = process.cwd();
|
|
92
|
+
for (let i = 0; i < lines.length; i++) {
|
|
93
|
+
let parsed = this.parseFrame(lines[i]);
|
|
94
|
+
if (!parsed) {
|
|
95
|
+
const m = lines[i].match(/(\/[^:\s]+:\d+:\d+)/);
|
|
96
|
+
if (m) {
|
|
97
|
+
const parts = m[1].split(":");
|
|
98
|
+
parts.pop();
|
|
99
|
+
const ln = Number(parts.pop());
|
|
100
|
+
const fp2 = parts.join(":");
|
|
101
|
+
parsed = { filepath: fp2, line: ln, functionName: void 0 };
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
if (!parsed) continue;
|
|
105
|
+
const fp = parsed.filepath;
|
|
106
|
+
if (fp.includes("node_modules") || fp.includes("internal") || fp.includes("<anonymous>") || fp.includes("native"))
|
|
107
|
+
continue;
|
|
108
|
+
if (fp.includes("/src/utils/log.ts")) continue;
|
|
109
|
+
if (fp.startsWith(cwd)) return { filepath: parsed.filepath, line: parsed.line };
|
|
110
|
+
}
|
|
111
|
+
for (let i = 0; i < lines.length; i++) {
|
|
112
|
+
let parsed = this.parseFrame(lines[i]);
|
|
113
|
+
if (!parsed) {
|
|
114
|
+
const m = lines[i].match(/(\/[^:\s]+:\d+:\d+)/);
|
|
115
|
+
if (m) {
|
|
116
|
+
const parts = m[1].split(":");
|
|
117
|
+
parts.pop();
|
|
118
|
+
const ln = Number(parts.pop());
|
|
119
|
+
const fp2 = parts.join(":");
|
|
120
|
+
parsed = { filepath: fp2, line: ln, functionName: void 0 };
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
if (!parsed) continue;
|
|
124
|
+
const fp = parsed.filepath;
|
|
125
|
+
if (fp.includes("node_modules") || fp.includes("internal") || fp.includes("<anonymous>") || fp.includes("native"))
|
|
126
|
+
continue;
|
|
127
|
+
if (fp.includes("/src/utils/log.ts")) continue;
|
|
128
|
+
return { filepath: parsed.filepath, line: parsed.line };
|
|
129
|
+
}
|
|
130
|
+
return {};
|
|
131
|
+
}
|
|
132
|
+
formatMessage(level, message, filepath, line) {
|
|
133
|
+
const timestamp = this.formatTimestamp();
|
|
134
|
+
const color = this.getColor(level);
|
|
135
|
+
const reset = COLORS.reset;
|
|
136
|
+
const levelName = level === "warn" ? "WARNING" : level.toUpperCase();
|
|
137
|
+
const levelStr = `${COLORS.bright}${color}${levelName}${reset}`;
|
|
138
|
+
const nameStr = `${color}[${this.prefix}]${reset}`;
|
|
139
|
+
const tsStr = `${color} ${timestamp}${reset}`;
|
|
140
|
+
const pathInfo = filepath && line !== void 0 ? ` ${COLORS.dim}${COLORS.italic}${filepath}:${line}${reset}` : "";
|
|
141
|
+
const msg = level === "debug" ? `${COLORS.dim}${message}${reset}` : message;
|
|
142
|
+
return `
|
|
143
|
+
${levelStr} ${nameStr}${tsStr}${pathInfo}
|
|
144
|
+
${msg}
|
|
145
|
+
`;
|
|
146
|
+
}
|
|
147
|
+
debug(message, ...args) {
|
|
148
|
+
if (this.shouldLog("debug")) {
|
|
149
|
+
const caller = this.getCallerByOffset();
|
|
150
|
+
console.debug(this.formatMessage("debug", message, caller.filepath, caller.line), ...args);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
info(message, ...args) {
|
|
154
|
+
if (this.shouldLog("info")) {
|
|
155
|
+
const caller = this.getCallerByOffset();
|
|
156
|
+
console.info(this.formatMessage("info", message, caller.filepath, caller.line), ...args);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
warn(message, ...args) {
|
|
160
|
+
if (this.shouldLog("warn")) {
|
|
161
|
+
const caller = this.getCallerByOffset();
|
|
162
|
+
console.warn(this.formatMessage("warn", message, caller.filepath, caller.line), ...args);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
error(message, ...args) {
|
|
166
|
+
if (this.shouldLog("error")) {
|
|
167
|
+
const caller = this.getCallerByOffset();
|
|
168
|
+
console.error(this.formatMessage("error", message, caller.filepath, caller.line), ...args);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
};
|
|
172
|
+
var logger = new Logger();
|
|
173
|
+
if (![void 0, null, "", "False", "FALSE", "false", "0"].includes(process.env["AGENTRUN_SDK_DEBUG"])) {
|
|
174
|
+
logger.setLevel("debug");
|
|
175
|
+
if (!globalThis._AGENTRUN_DEBUG_LOGGED) {
|
|
176
|
+
logger.warn("\u542F\u7528 AgentRun SDK \u8C03\u8BD5\u65E5\u5FD7\uFF0C \u79FB\u9664 AGENTRUN_SDK_DEBUG \u73AF\u5883\u53D8\u91CF\u4EE5\u5173\u95ED");
|
|
177
|
+
globalThis._AGENTRUN_DEBUG_LOGGED = true;
|
|
178
|
+
}
|
|
179
|
+
} else {
|
|
180
|
+
logger.setLevel("info");
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// src/utils/version-check.ts
|
|
184
|
+
var VERSION = "0.0.4" ;
|
|
185
|
+
if (!process.env.DISABLE_BREAKING_CHANGES_WARNING && !globalThis._AGENTRUN_VERSION_WARNING_SHOWN) {
|
|
186
|
+
globalThis._AGENTRUN_VERSION_WARNING_SHOWN = true;
|
|
187
|
+
logger.warn(
|
|
188
|
+
`\u5F53\u524D\u60A8\u6B63\u5728\u4F7F\u7528 AgentRun Python SDK \u7248\u672C ${VERSION}\u3002\u65E9\u671F\u7248\u672C\u901A\u5E38\u5305\u542B\u8BB8\u591A\u65B0\u529F\u80FD\uFF0C\u8FD9\u4E9B\u529F\u80FD\x1B[1;33m \u53EF\u80FD\u5F15\u5165\u4E0D\u517C\u5BB9\u7684\u53D8\u66F4 \x1B[0m\u3002\u4E3A\u907F\u514D\u6F5C\u5728\u95EE\u9898\uFF0C\u6211\u4EEC\u5F3A\u70C8\u5EFA\u8BAE\x1B[1;32m \u5C06\u4F9D\u8D56\u9501\u5B9A\u4E3A\u6B64\u7248\u672C \x1B[0m\u3002
|
|
189
|
+
You are currently using AgentRun Python SDK version ${VERSION}. Early versions often include many new features, which\x1B[1;33m may introduce breaking changes\x1B[0m. To avoid potential issues, we strongly recommend \x1B[1;32mpinning the dependency to this version\x1B[0m.
|
|
190
|
+
\x1B[2;3m pip install 'agentrun-sdk==${VERSION}' \x1B[0m
|
|
191
|
+
|
|
192
|
+
\u589E\u52A0\x1B[2;3m DISABLE_BREAKING_CHANGES_WARNING=1 \x1B[0m\u5230\u60A8\u7684\u73AF\u5883\u53D8\u91CF\u4EE5\u5173\u95ED\u6B64\u8B66\u544A\u3002
|
|
193
|
+
Add\x1B[2;3m DISABLE_BREAKING_CHANGES_WARNING=1 \x1B[0mto your environment variables to disable this warning.
|
|
194
|
+
|
|
195
|
+
Releases:\x1B[2;3m https://github.com/Serverless-Devs/agentrun-sdk-python/releases\x1B[0m`
|
|
196
|
+
);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
// src/server/core/model.ts
|
|
200
|
+
var MessageRole = /* @__PURE__ */ ((MessageRole3) => {
|
|
201
|
+
MessageRole3["SYSTEM"] = "system";
|
|
202
|
+
MessageRole3["USER"] = "user";
|
|
203
|
+
MessageRole3["ASSISTANT"] = "assistant";
|
|
204
|
+
MessageRole3["TOOL"] = "tool";
|
|
205
|
+
return MessageRole3;
|
|
206
|
+
})(MessageRole || {});
|
|
207
|
+
|
|
208
|
+
// src/server/protocol/base.ts
|
|
209
|
+
var ProtocolHandler = class {
|
|
210
|
+
/**
|
|
211
|
+
* Check if a request matches this protocol
|
|
212
|
+
*/
|
|
213
|
+
matches(req) {
|
|
214
|
+
const prefix = this.getPrefix();
|
|
215
|
+
return this.getRoutes().some(
|
|
216
|
+
(route) => route.method === req.method && this.matchPath(prefix + route.path, req.url)
|
|
217
|
+
);
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Handle a request
|
|
221
|
+
*/
|
|
222
|
+
async handle(req, invoker) {
|
|
223
|
+
const prefix = this.getPrefix();
|
|
224
|
+
const route = this.getRoutes().find(
|
|
225
|
+
(r) => r.method === req.method && this.matchPath(prefix + r.path, req.url)
|
|
226
|
+
);
|
|
227
|
+
if (!route) {
|
|
228
|
+
return {
|
|
229
|
+
status: 404,
|
|
230
|
+
headers: { "Content-Type": "application/json" },
|
|
231
|
+
body: JSON.stringify({ error: "Not Found" })
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
try {
|
|
235
|
+
return await route.handler(req, invoker);
|
|
236
|
+
} catch (error) {
|
|
237
|
+
return this.createErrorResponse(error, 500);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* Create error response
|
|
242
|
+
*/
|
|
243
|
+
createErrorResponse(error, status = 500) {
|
|
244
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
245
|
+
return {
|
|
246
|
+
status,
|
|
247
|
+
headers: { "Content-Type": "application/json" },
|
|
248
|
+
body: JSON.stringify({
|
|
249
|
+
error: {
|
|
250
|
+
message,
|
|
251
|
+
type: "server_error"
|
|
252
|
+
}
|
|
253
|
+
})
|
|
254
|
+
};
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* Match path with simple pattern matching
|
|
258
|
+
* Supports exact match and prefix match with trailing slash
|
|
259
|
+
*/
|
|
260
|
+
matchPath(pattern, path) {
|
|
261
|
+
const normalizedPattern = pattern.replace(/\/+$/, "");
|
|
262
|
+
const normalizedPath = path.replace(/\/+$/, "").split("?")[0];
|
|
263
|
+
return normalizedPattern === normalizedPath;
|
|
264
|
+
}
|
|
265
|
+
};
|
|
266
|
+
|
|
267
|
+
// src/server/protocol/openai.ts
|
|
268
|
+
var OpenAIProtocolHandler = class extends ProtocolHandler {
|
|
269
|
+
constructor(config) {
|
|
270
|
+
super();
|
|
271
|
+
this.config = config;
|
|
272
|
+
}
|
|
273
|
+
name = "openai";
|
|
274
|
+
getPrefix() {
|
|
275
|
+
return this.config?.prefix ?? "/openai/v1";
|
|
276
|
+
}
|
|
277
|
+
getRoutes() {
|
|
278
|
+
return [
|
|
279
|
+
{
|
|
280
|
+
method: "POST",
|
|
281
|
+
path: "/chat/completions",
|
|
282
|
+
handler: this.handleChatCompletions.bind(this)
|
|
283
|
+
},
|
|
284
|
+
{
|
|
285
|
+
method: "GET",
|
|
286
|
+
path: "/models",
|
|
287
|
+
handler: this.handleListModels.bind(this)
|
|
288
|
+
}
|
|
289
|
+
];
|
|
290
|
+
}
|
|
291
|
+
/**
|
|
292
|
+
* Handle POST /chat/completions
|
|
293
|
+
*/
|
|
294
|
+
async handleChatCompletions(req, invoker) {
|
|
295
|
+
try {
|
|
296
|
+
const { agentRequest, context } = this.parseRequest(req.body);
|
|
297
|
+
if (agentRequest.stream) {
|
|
298
|
+
return {
|
|
299
|
+
status: 200,
|
|
300
|
+
headers: {
|
|
301
|
+
"Content-Type": "text/event-stream",
|
|
302
|
+
"Cache-Control": "no-cache",
|
|
303
|
+
Connection: "keep-alive"
|
|
304
|
+
},
|
|
305
|
+
body: this.formatStream(invoker.invoke(agentRequest), context)
|
|
306
|
+
};
|
|
307
|
+
}
|
|
308
|
+
const events = [];
|
|
309
|
+
for await (const event of invoker.invoke(agentRequest)) {
|
|
310
|
+
events.push(event);
|
|
311
|
+
}
|
|
312
|
+
return {
|
|
313
|
+
status: 200,
|
|
314
|
+
headers: { "Content-Type": "application/json" },
|
|
315
|
+
body: JSON.stringify(this.formatNonStream(events, context))
|
|
316
|
+
};
|
|
317
|
+
} catch (error) {
|
|
318
|
+
return this.createErrorResponse(error, 400);
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
/**
|
|
322
|
+
* Handle GET /models
|
|
323
|
+
*/
|
|
324
|
+
async handleListModels() {
|
|
325
|
+
const modelName = this.config?.modelName ?? "agentrun";
|
|
326
|
+
return {
|
|
327
|
+
status: 200,
|
|
328
|
+
headers: { "Content-Type": "application/json" },
|
|
329
|
+
body: JSON.stringify({
|
|
330
|
+
object: "list",
|
|
331
|
+
data: [
|
|
332
|
+
{
|
|
333
|
+
id: modelName,
|
|
334
|
+
object: "model",
|
|
335
|
+
created: Math.floor(Date.now() / 1e3),
|
|
336
|
+
owned_by: "agentrun"
|
|
337
|
+
}
|
|
338
|
+
]
|
|
339
|
+
})
|
|
340
|
+
};
|
|
341
|
+
}
|
|
342
|
+
/**
|
|
343
|
+
* Parse OpenAI format request to AgentRequest
|
|
344
|
+
*/
|
|
345
|
+
parseRequest(body) {
|
|
346
|
+
if (!body.messages || !Array.isArray(body.messages)) {
|
|
347
|
+
throw new Error("Missing required field: messages");
|
|
348
|
+
}
|
|
349
|
+
const context = {
|
|
350
|
+
id: `chatcmpl-${this.generateId()}`,
|
|
351
|
+
model: body.model || this.config?.modelName || "agentrun",
|
|
352
|
+
created: Math.floor(Date.now() / 1e3)
|
|
353
|
+
};
|
|
354
|
+
const messages = this.parseMessages(body.messages);
|
|
355
|
+
const tools = this.parseTools(body.tools);
|
|
356
|
+
const agentRequest = {
|
|
357
|
+
protocol: "openai",
|
|
358
|
+
messages,
|
|
359
|
+
stream: body.stream ?? false,
|
|
360
|
+
model: context.model,
|
|
361
|
+
tools: tools || void 0,
|
|
362
|
+
metadata: body.metadata
|
|
363
|
+
};
|
|
364
|
+
return { agentRequest, context };
|
|
365
|
+
}
|
|
366
|
+
/**
|
|
367
|
+
* Parse OpenAI messages to internal Message format
|
|
368
|
+
*/
|
|
369
|
+
parseMessages(messages) {
|
|
370
|
+
return messages.map((m) => {
|
|
371
|
+
const msg = m;
|
|
372
|
+
return {
|
|
373
|
+
id: msg.id,
|
|
374
|
+
role: msg.role,
|
|
375
|
+
content: msg.content,
|
|
376
|
+
name: msg.name,
|
|
377
|
+
toolCallId: msg.tool_call_id,
|
|
378
|
+
toolCalls: msg.tool_calls ? msg.tool_calls.map((tc) => {
|
|
379
|
+
const call = tc;
|
|
380
|
+
return {
|
|
381
|
+
id: call.id,
|
|
382
|
+
type: call.type,
|
|
383
|
+
function: call.function
|
|
384
|
+
};
|
|
385
|
+
}) : void 0
|
|
386
|
+
};
|
|
387
|
+
});
|
|
388
|
+
}
|
|
389
|
+
/**
|
|
390
|
+
* Parse OpenAI tools format
|
|
391
|
+
*/
|
|
392
|
+
parseTools(tools) {
|
|
393
|
+
if (!tools || !Array.isArray(tools)) {
|
|
394
|
+
return null;
|
|
395
|
+
}
|
|
396
|
+
return tools.map((t) => {
|
|
397
|
+
const tool = t;
|
|
398
|
+
return {
|
|
399
|
+
type: tool.type || "function",
|
|
400
|
+
function: tool.function
|
|
401
|
+
};
|
|
402
|
+
});
|
|
403
|
+
}
|
|
404
|
+
/**
|
|
405
|
+
* Format streaming response (SSE)
|
|
406
|
+
*/
|
|
407
|
+
async *formatStream(events, context) {
|
|
408
|
+
let sentRole = false;
|
|
409
|
+
let hasText = false;
|
|
410
|
+
let toolCallIndex = -1;
|
|
411
|
+
const toolCallStates = /* @__PURE__ */ new Map();
|
|
412
|
+
let hasToolCalls = false;
|
|
413
|
+
for await (const event of events) {
|
|
414
|
+
if (event.event === "RAW" /* RAW */) {
|
|
415
|
+
const raw = event.data?.raw;
|
|
416
|
+
if (raw) {
|
|
417
|
+
yield raw.endsWith("\n\n") ? raw : raw.replace(/\n+$/, "") + "\n\n";
|
|
418
|
+
}
|
|
419
|
+
continue;
|
|
420
|
+
}
|
|
421
|
+
if (event.event === "TEXT" /* TEXT */) {
|
|
422
|
+
const delta = {};
|
|
423
|
+
if (!sentRole) {
|
|
424
|
+
delta.role = "assistant";
|
|
425
|
+
sentRole = true;
|
|
426
|
+
}
|
|
427
|
+
const content = event.data?.delta;
|
|
428
|
+
if (content) {
|
|
429
|
+
delta.content = content;
|
|
430
|
+
hasText = true;
|
|
431
|
+
}
|
|
432
|
+
yield this.buildChunk(context, { delta });
|
|
433
|
+
continue;
|
|
434
|
+
}
|
|
435
|
+
if (event.event === "TOOL_CALL_CHUNK" /* TOOL_CALL_CHUNK */) {
|
|
436
|
+
const toolId = event.data?.id;
|
|
437
|
+
const toolName = event.data?.name;
|
|
438
|
+
const argsDelta = event.data?.args_delta || event.data?.argsDelta;
|
|
439
|
+
if (toolId && !toolCallStates.has(toolId)) {
|
|
440
|
+
toolCallIndex++;
|
|
441
|
+
toolCallStates.set(toolId, { index: toolCallIndex, started: true });
|
|
442
|
+
hasToolCalls = true;
|
|
443
|
+
yield this.buildChunk(context, {
|
|
444
|
+
delta: {
|
|
445
|
+
tool_calls: [
|
|
446
|
+
{
|
|
447
|
+
index: toolCallIndex,
|
|
448
|
+
id: toolId,
|
|
449
|
+
type: "function",
|
|
450
|
+
function: { name: toolName || "", arguments: "" }
|
|
451
|
+
}
|
|
452
|
+
]
|
|
453
|
+
}
|
|
454
|
+
});
|
|
455
|
+
}
|
|
456
|
+
if (argsDelta) {
|
|
457
|
+
const state = toolCallStates.get(toolId);
|
|
458
|
+
const currentIndex = state?.index ?? toolCallIndex;
|
|
459
|
+
yield this.buildChunk(context, {
|
|
460
|
+
delta: {
|
|
461
|
+
tool_calls: [
|
|
462
|
+
{
|
|
463
|
+
index: currentIndex,
|
|
464
|
+
function: { arguments: argsDelta }
|
|
465
|
+
}
|
|
466
|
+
]
|
|
467
|
+
}
|
|
468
|
+
});
|
|
469
|
+
}
|
|
470
|
+
continue;
|
|
471
|
+
}
|
|
472
|
+
if (event.event === "ERROR" /* ERROR */) {
|
|
473
|
+
yield this.buildChunk(context, {
|
|
474
|
+
delta: {},
|
|
475
|
+
finish_reason: "error"
|
|
476
|
+
});
|
|
477
|
+
continue;
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
const finishReason = hasToolCalls ? "tool_calls" : hasText ? "stop" : "stop";
|
|
481
|
+
yield this.buildChunk(context, { delta: {}, finish_reason: finishReason });
|
|
482
|
+
yield "data: [DONE]\n\n";
|
|
483
|
+
}
|
|
484
|
+
/**
|
|
485
|
+
* Build SSE chunk
|
|
486
|
+
*/
|
|
487
|
+
buildChunk(context, choice) {
|
|
488
|
+
const chunk = {
|
|
489
|
+
id: context.id,
|
|
490
|
+
object: "chat.completion.chunk",
|
|
491
|
+
created: context.created,
|
|
492
|
+
model: context.model,
|
|
493
|
+
choices: [
|
|
494
|
+
{
|
|
495
|
+
index: 0,
|
|
496
|
+
delta: choice.delta || {},
|
|
497
|
+
finish_reason: choice.finish_reason ?? null
|
|
498
|
+
}
|
|
499
|
+
]
|
|
500
|
+
};
|
|
501
|
+
return `data: ${JSON.stringify(chunk)}
|
|
502
|
+
|
|
503
|
+
`;
|
|
504
|
+
}
|
|
505
|
+
/**
|
|
506
|
+
* Format non-streaming response
|
|
507
|
+
*/
|
|
508
|
+
formatNonStream(events, context) {
|
|
509
|
+
let content = "";
|
|
510
|
+
const toolCalls = [];
|
|
511
|
+
for (const event of events) {
|
|
512
|
+
if (event.event === "TEXT" /* TEXT */) {
|
|
513
|
+
content += event.data?.delta || "";
|
|
514
|
+
} else if (event.event === "TOOL_CALL_CHUNK" /* TOOL_CALL_CHUNK */) {
|
|
515
|
+
const toolId = event.data?.id;
|
|
516
|
+
const toolName = event.data?.name;
|
|
517
|
+
const argsDelta = event.data?.args_delta || event.data?.argsDelta;
|
|
518
|
+
let toolCall = toolCalls.find((tc) => tc.id === toolId);
|
|
519
|
+
if (!toolCall && toolId) {
|
|
520
|
+
toolCall = {
|
|
521
|
+
id: toolId,
|
|
522
|
+
type: "function",
|
|
523
|
+
function: { name: toolName || "", arguments: "" }
|
|
524
|
+
};
|
|
525
|
+
toolCalls.push(toolCall);
|
|
526
|
+
}
|
|
527
|
+
if (toolCall && argsDelta) {
|
|
528
|
+
toolCall.function.arguments += argsDelta;
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
const message = {
|
|
533
|
+
role: "assistant",
|
|
534
|
+
content: content || null
|
|
535
|
+
};
|
|
536
|
+
if (toolCalls.length > 0) {
|
|
537
|
+
message.tool_calls = toolCalls.map((tc, idx) => ({
|
|
538
|
+
index: idx,
|
|
539
|
+
id: tc.id,
|
|
540
|
+
type: tc.type,
|
|
541
|
+
function: tc.function
|
|
542
|
+
}));
|
|
543
|
+
}
|
|
544
|
+
return {
|
|
545
|
+
id: context.id,
|
|
546
|
+
object: "chat.completion",
|
|
547
|
+
created: context.created,
|
|
548
|
+
model: context.model,
|
|
549
|
+
choices: [
|
|
550
|
+
{
|
|
551
|
+
index: 0,
|
|
552
|
+
message,
|
|
553
|
+
finish_reason: toolCalls.length > 0 ? "tool_calls" : "stop"
|
|
554
|
+
}
|
|
555
|
+
],
|
|
556
|
+
usage: {
|
|
557
|
+
prompt_tokens: 0,
|
|
558
|
+
completion_tokens: 0,
|
|
559
|
+
total_tokens: 0
|
|
560
|
+
}
|
|
561
|
+
};
|
|
562
|
+
}
|
|
563
|
+
/**
|
|
564
|
+
* Generate unique ID
|
|
565
|
+
*/
|
|
566
|
+
generateId() {
|
|
567
|
+
return `${Date.now()}-${Math.random().toString(36).slice(2, 9)}`;
|
|
568
|
+
}
|
|
569
|
+
};
|
|
570
|
+
var AGUI_EVENT_TYPES = {
|
|
571
|
+
RUN_STARTED: "RUN_STARTED",
|
|
572
|
+
RUN_FINISHED: "RUN_FINISHED",
|
|
573
|
+
RUN_ERROR: "RUN_ERROR",
|
|
574
|
+
TEXT_MESSAGE_START: "TEXT_MESSAGE_START",
|
|
575
|
+
TEXT_MESSAGE_CONTENT: "TEXT_MESSAGE_CONTENT",
|
|
576
|
+
TEXT_MESSAGE_END: "TEXT_MESSAGE_END",
|
|
577
|
+
TOOL_CALL_START: "TOOL_CALL_START",
|
|
578
|
+
TOOL_CALL_ARGS: "TOOL_CALL_ARGS",
|
|
579
|
+
TOOL_CALL_END: "TOOL_CALL_END",
|
|
580
|
+
TOOL_CALL_RESULT: "TOOL_CALL_RESULT",
|
|
581
|
+
STATE_SNAPSHOT: "STATE_SNAPSHOT",
|
|
582
|
+
STATE_DELTA: "STATE_DELTA",
|
|
583
|
+
MESSAGES_SNAPSHOT: "MESSAGES_SNAPSHOT",
|
|
584
|
+
STEP_STARTED: "STEP_STARTED",
|
|
585
|
+
STEP_FINISHED: "STEP_FINISHED",
|
|
586
|
+
CUSTOM: "CUSTOM",
|
|
587
|
+
RAW: "RAW"
|
|
588
|
+
};
|
|
589
|
+
var StreamState = class {
|
|
590
|
+
text = {
|
|
591
|
+
started: false,
|
|
592
|
+
ended: false,
|
|
593
|
+
messageId: v4()
|
|
594
|
+
};
|
|
595
|
+
toolCalls = /* @__PURE__ */ new Map();
|
|
596
|
+
toolResultChunks = /* @__PURE__ */ new Map();
|
|
597
|
+
hasError = false;
|
|
598
|
+
/**
|
|
599
|
+
* End all open tool calls
|
|
600
|
+
*/
|
|
601
|
+
*endAllToolCalls(exclude) {
|
|
602
|
+
for (const [toolId, state] of this.toolCalls) {
|
|
603
|
+
if (exclude && toolId === exclude) continue;
|
|
604
|
+
if (state.started && !state.ended) {
|
|
605
|
+
yield { type: AGUI_EVENT_TYPES.TOOL_CALL_END, toolCallId: toolId };
|
|
606
|
+
state.ended = true;
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
}
|
|
610
|
+
/**
|
|
611
|
+
* Ensure text message has started
|
|
612
|
+
*/
|
|
613
|
+
*ensureTextStarted() {
|
|
614
|
+
if (!this.text.started || this.text.ended) {
|
|
615
|
+
if (this.text.ended) {
|
|
616
|
+
this.text = { started: false, ended: false, messageId: v4() };
|
|
617
|
+
}
|
|
618
|
+
yield {
|
|
619
|
+
type: AGUI_EVENT_TYPES.TEXT_MESSAGE_START,
|
|
620
|
+
messageId: this.text.messageId,
|
|
621
|
+
role: "assistant"
|
|
622
|
+
};
|
|
623
|
+
this.text.started = true;
|
|
624
|
+
this.text.ended = false;
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
/**
|
|
628
|
+
* End text message if open
|
|
629
|
+
*/
|
|
630
|
+
*endTextIfOpen() {
|
|
631
|
+
if (this.text.started && !this.text.ended) {
|
|
632
|
+
yield {
|
|
633
|
+
type: AGUI_EVENT_TYPES.TEXT_MESSAGE_END,
|
|
634
|
+
messageId: this.text.messageId
|
|
635
|
+
};
|
|
636
|
+
this.text.ended = true;
|
|
637
|
+
}
|
|
638
|
+
}
|
|
639
|
+
/**
|
|
640
|
+
* Cache tool result chunk
|
|
641
|
+
*/
|
|
642
|
+
cacheToolResultChunk(toolId, delta) {
|
|
643
|
+
if (!toolId || delta === null || delta === void 0) return;
|
|
644
|
+
if (delta) {
|
|
645
|
+
const chunks = this.toolResultChunks.get(toolId) || [];
|
|
646
|
+
chunks.push(delta);
|
|
647
|
+
this.toolResultChunks.set(toolId, chunks);
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
/**
|
|
651
|
+
* Pop and concatenate cached tool result chunks
|
|
652
|
+
*/
|
|
653
|
+
popToolResultChunks(toolId) {
|
|
654
|
+
const chunks = this.toolResultChunks.get(toolId) || [];
|
|
655
|
+
this.toolResultChunks.delete(toolId);
|
|
656
|
+
return chunks.join("");
|
|
657
|
+
}
|
|
658
|
+
};
|
|
659
|
+
var DEFAULT_PREFIX = "/ag-ui";
|
|
660
|
+
var AGUIProtocolHandler = class extends ProtocolHandler {
|
|
661
|
+
constructor(config) {
|
|
662
|
+
super();
|
|
663
|
+
this.config = config;
|
|
664
|
+
}
|
|
665
|
+
name = "agui";
|
|
666
|
+
getPrefix() {
|
|
667
|
+
return this.config?.prefix ?? DEFAULT_PREFIX;
|
|
668
|
+
}
|
|
669
|
+
getRoutes() {
|
|
670
|
+
return [
|
|
671
|
+
{
|
|
672
|
+
method: "POST",
|
|
673
|
+
path: "/agent",
|
|
674
|
+
handler: this.handleAgent.bind(this)
|
|
675
|
+
}
|
|
676
|
+
];
|
|
677
|
+
}
|
|
678
|
+
/**
|
|
679
|
+
* Handle POST /agent
|
|
680
|
+
*/
|
|
681
|
+
async handleAgent(req, invoker) {
|
|
682
|
+
try {
|
|
683
|
+
const { agentRequest, context } = this.parseRequest(req.body);
|
|
684
|
+
return {
|
|
685
|
+
status: 200,
|
|
686
|
+
headers: {
|
|
687
|
+
"Content-Type": "text/event-stream",
|
|
688
|
+
"Cache-Control": "no-cache",
|
|
689
|
+
Connection: "keep-alive"
|
|
690
|
+
},
|
|
691
|
+
body: this.formatStream(invoker.invoke(agentRequest), context)
|
|
692
|
+
};
|
|
693
|
+
} catch (error) {
|
|
694
|
+
return {
|
|
695
|
+
status: 200,
|
|
696
|
+
headers: {
|
|
697
|
+
"Content-Type": "text/event-stream",
|
|
698
|
+
"Cache-Control": "no-cache",
|
|
699
|
+
Connection: "keep-alive"
|
|
700
|
+
},
|
|
701
|
+
body: this.errorStream(error instanceof Error ? error.message : String(error))
|
|
702
|
+
};
|
|
703
|
+
}
|
|
704
|
+
}
|
|
705
|
+
/**
|
|
706
|
+
* Parse AG-UI request
|
|
707
|
+
*/
|
|
708
|
+
parseRequest(body) {
|
|
709
|
+
const context = {
|
|
710
|
+
threadId: body.threadId || v4(),
|
|
711
|
+
runId: body.runId || v4()
|
|
712
|
+
};
|
|
713
|
+
const messages = this.parseMessages(body.messages || []);
|
|
714
|
+
const tools = this.parseTools(body.tools);
|
|
715
|
+
const agentRequest = {
|
|
716
|
+
protocol: "agui",
|
|
717
|
+
messages,
|
|
718
|
+
stream: true,
|
|
719
|
+
// AG-UI always streams
|
|
720
|
+
tools: tools || void 0,
|
|
721
|
+
model: body.model,
|
|
722
|
+
metadata: body.metadata
|
|
723
|
+
};
|
|
724
|
+
return { agentRequest, context };
|
|
725
|
+
}
|
|
726
|
+
/**
|
|
727
|
+
* Parse messages list
|
|
728
|
+
*/
|
|
729
|
+
parseMessages(rawMessages) {
|
|
730
|
+
const messages = [];
|
|
731
|
+
for (const msg of rawMessages) {
|
|
732
|
+
if (typeof msg !== "object" || msg === null) continue;
|
|
733
|
+
const roleStr = msg.role || "user";
|
|
734
|
+
let role;
|
|
735
|
+
if (Object.values(MessageRole).includes(roleStr)) {
|
|
736
|
+
role = roleStr;
|
|
737
|
+
} else {
|
|
738
|
+
role = "user" /* USER */;
|
|
739
|
+
}
|
|
740
|
+
let toolCalls;
|
|
741
|
+
const rawToolCalls = msg.toolCalls;
|
|
742
|
+
if (rawToolCalls && Array.isArray(rawToolCalls)) {
|
|
743
|
+
toolCalls = rawToolCalls.map((tc) => ({
|
|
744
|
+
id: tc.id || "",
|
|
745
|
+
type: tc.type || "function",
|
|
746
|
+
function: tc.function || {
|
|
747
|
+
name: "",
|
|
748
|
+
arguments: ""
|
|
749
|
+
}
|
|
750
|
+
}));
|
|
751
|
+
}
|
|
752
|
+
messages.push({
|
|
753
|
+
id: msg.id,
|
|
754
|
+
role,
|
|
755
|
+
content: msg.content,
|
|
756
|
+
name: msg.name,
|
|
757
|
+
toolCalls,
|
|
758
|
+
toolCallId: msg.toolCallId
|
|
759
|
+
});
|
|
760
|
+
}
|
|
761
|
+
return messages;
|
|
762
|
+
}
|
|
763
|
+
/**
|
|
764
|
+
* Parse tools list
|
|
765
|
+
*/
|
|
766
|
+
parseTools(rawTools) {
|
|
767
|
+
if (!rawTools || !Array.isArray(rawTools)) return null;
|
|
768
|
+
const tools = [];
|
|
769
|
+
for (const tool of rawTools) {
|
|
770
|
+
if (typeof tool !== "object" || tool === null) continue;
|
|
771
|
+
tools.push({
|
|
772
|
+
type: tool.type || "function",
|
|
773
|
+
function: tool.function || { name: "" }
|
|
774
|
+
});
|
|
775
|
+
}
|
|
776
|
+
return tools.length > 0 ? tools : null;
|
|
777
|
+
}
|
|
778
|
+
/**
|
|
779
|
+
* Format event stream as AG-UI SSE format
|
|
780
|
+
*/
|
|
781
|
+
async *formatStream(events, context) {
|
|
782
|
+
const state = new StreamState();
|
|
783
|
+
yield this.encode({ type: AGUI_EVENT_TYPES.RUN_STARTED, ...context });
|
|
784
|
+
for await (const event of events) {
|
|
785
|
+
if (state.hasError) continue;
|
|
786
|
+
if (event.event === "ERROR" /* ERROR */) {
|
|
787
|
+
state.hasError = true;
|
|
788
|
+
}
|
|
789
|
+
for (const aguiEvent of this.processEvent(event, context, state)) {
|
|
790
|
+
yield this.encode(aguiEvent);
|
|
791
|
+
}
|
|
792
|
+
}
|
|
793
|
+
if (state.hasError) return;
|
|
794
|
+
for (const event of state.endAllToolCalls()) {
|
|
795
|
+
yield this.encode(event);
|
|
796
|
+
}
|
|
797
|
+
for (const event of state.endTextIfOpen()) {
|
|
798
|
+
yield this.encode(event);
|
|
799
|
+
}
|
|
800
|
+
yield this.encode({ type: AGUI_EVENT_TYPES.RUN_FINISHED, ...context });
|
|
801
|
+
}
|
|
802
|
+
/**
|
|
803
|
+
* Process single event and yield AG-UI events
|
|
804
|
+
*/
|
|
805
|
+
*processEvent(event, context, state) {
|
|
806
|
+
if (event.event === "RAW" /* RAW */) {
|
|
807
|
+
const raw = event.data?.raw;
|
|
808
|
+
if (raw) {
|
|
809
|
+
yield { __raw: raw };
|
|
810
|
+
}
|
|
811
|
+
return;
|
|
812
|
+
}
|
|
813
|
+
if (event.event === "TEXT" /* TEXT */) {
|
|
814
|
+
yield* state.endAllToolCalls();
|
|
815
|
+
yield* state.ensureTextStarted();
|
|
816
|
+
const aguiEvent = {
|
|
817
|
+
type: AGUI_EVENT_TYPES.TEXT_MESSAGE_CONTENT,
|
|
818
|
+
messageId: state.text.messageId,
|
|
819
|
+
delta: event.data?.delta || ""
|
|
820
|
+
};
|
|
821
|
+
if (event.addition) {
|
|
822
|
+
yield this.applyAddition(aguiEvent, event.addition, event.additionMergeOptions);
|
|
823
|
+
} else {
|
|
824
|
+
yield aguiEvent;
|
|
825
|
+
}
|
|
826
|
+
return;
|
|
827
|
+
}
|
|
828
|
+
if (event.event === "TOOL_CALL_CHUNK" /* TOOL_CALL_CHUNK */) {
|
|
829
|
+
const toolId = event.data?.id || "";
|
|
830
|
+
const toolName = event.data?.name || "";
|
|
831
|
+
yield* state.endTextIfOpen();
|
|
832
|
+
const currentState = state.toolCalls.get(toolId);
|
|
833
|
+
if (toolId && (!currentState || currentState.ended)) {
|
|
834
|
+
yield {
|
|
835
|
+
type: AGUI_EVENT_TYPES.TOOL_CALL_START,
|
|
836
|
+
toolCallId: toolId,
|
|
837
|
+
toolCallName: toolName
|
|
838
|
+
};
|
|
839
|
+
state.toolCalls.set(toolId, {
|
|
840
|
+
name: toolName,
|
|
841
|
+
started: true,
|
|
842
|
+
ended: false,
|
|
843
|
+
hasResult: false,
|
|
844
|
+
isHitl: false
|
|
845
|
+
});
|
|
846
|
+
}
|
|
847
|
+
yield {
|
|
848
|
+
type: AGUI_EVENT_TYPES.TOOL_CALL_ARGS,
|
|
849
|
+
toolCallId: toolId,
|
|
850
|
+
delta: event.data?.args_delta || event.data?.argsDelta || ""
|
|
851
|
+
};
|
|
852
|
+
return;
|
|
853
|
+
}
|
|
854
|
+
if (event.event === "TOOL_CALL" /* TOOL_CALL */) {
|
|
855
|
+
const toolId = event.data?.id || "";
|
|
856
|
+
const toolName = event.data?.name || "";
|
|
857
|
+
const toolArgs = event.data?.args || "";
|
|
858
|
+
yield* state.endTextIfOpen();
|
|
859
|
+
const currentState = state.toolCalls.get(toolId);
|
|
860
|
+
if (toolId && (!currentState || currentState.ended)) {
|
|
861
|
+
yield {
|
|
862
|
+
type: AGUI_EVENT_TYPES.TOOL_CALL_START,
|
|
863
|
+
toolCallId: toolId,
|
|
864
|
+
toolCallName: toolName
|
|
865
|
+
};
|
|
866
|
+
state.toolCalls.set(toolId, {
|
|
867
|
+
name: toolName,
|
|
868
|
+
started: true,
|
|
869
|
+
ended: false,
|
|
870
|
+
hasResult: false,
|
|
871
|
+
isHitl: false
|
|
872
|
+
});
|
|
873
|
+
}
|
|
874
|
+
if (toolArgs) {
|
|
875
|
+
yield {
|
|
876
|
+
type: AGUI_EVENT_TYPES.TOOL_CALL_ARGS,
|
|
877
|
+
toolCallId: toolId,
|
|
878
|
+
delta: toolArgs
|
|
879
|
+
};
|
|
880
|
+
}
|
|
881
|
+
return;
|
|
882
|
+
}
|
|
883
|
+
if (event.event === "TOOL_RESULT_CHUNK" /* TOOL_RESULT_CHUNK */) {
|
|
884
|
+
const toolId = event.data?.id || "";
|
|
885
|
+
const delta = event.data?.delta || "";
|
|
886
|
+
state.cacheToolResultChunk(toolId, delta);
|
|
887
|
+
return;
|
|
888
|
+
}
|
|
889
|
+
if (event.event === "HITL" /* HITL */) {
|
|
890
|
+
const hitlId = event.data?.id || "";
|
|
891
|
+
const toolCallId = event.data?.tool_call_id || event.data?.toolCallId || "";
|
|
892
|
+
const hitlType = event.data?.type || "confirmation";
|
|
893
|
+
const prompt = event.data?.prompt || "";
|
|
894
|
+
yield* state.endTextIfOpen();
|
|
895
|
+
if (toolCallId && state.toolCalls.has(toolCallId)) {
|
|
896
|
+
const toolState = state.toolCalls.get(toolCallId);
|
|
897
|
+
if (toolState.started && !toolState.ended) {
|
|
898
|
+
yield { type: AGUI_EVENT_TYPES.TOOL_CALL_END, toolCallId };
|
|
899
|
+
toolState.ended = true;
|
|
900
|
+
}
|
|
901
|
+
toolState.isHitl = true;
|
|
902
|
+
toolState.hasResult = false;
|
|
903
|
+
return;
|
|
904
|
+
}
|
|
905
|
+
const argsDict = { type: hitlType, prompt };
|
|
906
|
+
if (event.data?.options) argsDict.options = event.data.options;
|
|
907
|
+
if (event.data?.default !== void 0) argsDict.default = event.data.default;
|
|
908
|
+
if (event.data?.timeout !== void 0) argsDict.timeout = event.data.timeout;
|
|
909
|
+
if (event.data?.schema) argsDict.schema = event.data.schema;
|
|
910
|
+
const actualId = toolCallId || hitlId;
|
|
911
|
+
yield {
|
|
912
|
+
type: AGUI_EVENT_TYPES.TOOL_CALL_START,
|
|
913
|
+
toolCallId: actualId,
|
|
914
|
+
toolCallName: `hitl_${hitlType}`
|
|
915
|
+
};
|
|
916
|
+
yield {
|
|
917
|
+
type: AGUI_EVENT_TYPES.TOOL_CALL_ARGS,
|
|
918
|
+
toolCallId: actualId,
|
|
919
|
+
delta: JSON.stringify(argsDict)
|
|
920
|
+
};
|
|
921
|
+
yield { type: AGUI_EVENT_TYPES.TOOL_CALL_END, toolCallId: actualId };
|
|
922
|
+
state.toolCalls.set(actualId, {
|
|
923
|
+
name: `hitl_${hitlType}`,
|
|
924
|
+
started: true,
|
|
925
|
+
ended: true,
|
|
926
|
+
hasResult: false,
|
|
927
|
+
isHitl: true
|
|
928
|
+
});
|
|
929
|
+
return;
|
|
930
|
+
}
|
|
931
|
+
if (event.event === "TOOL_RESULT" /* TOOL_RESULT */) {
|
|
932
|
+
const toolId = event.data?.id || "";
|
|
933
|
+
const toolName = event.data?.name || "";
|
|
934
|
+
yield* state.endTextIfOpen();
|
|
935
|
+
let toolState = state.toolCalls.get(toolId);
|
|
936
|
+
if (toolId && !toolState) {
|
|
937
|
+
yield {
|
|
938
|
+
type: AGUI_EVENT_TYPES.TOOL_CALL_START,
|
|
939
|
+
toolCallId: toolId,
|
|
940
|
+
toolCallName: toolName
|
|
941
|
+
};
|
|
942
|
+
toolState = {
|
|
943
|
+
name: toolName,
|
|
944
|
+
started: true,
|
|
945
|
+
ended: false,
|
|
946
|
+
hasResult: false,
|
|
947
|
+
isHitl: false
|
|
948
|
+
};
|
|
949
|
+
state.toolCalls.set(toolId, toolState);
|
|
950
|
+
}
|
|
951
|
+
if (toolState && toolState.started && !toolState.ended) {
|
|
952
|
+
yield { type: AGUI_EVENT_TYPES.TOOL_CALL_END, toolCallId: toolId };
|
|
953
|
+
toolState.ended = true;
|
|
954
|
+
}
|
|
955
|
+
let finalResult = (event.data?.content || event.data?.result) ?? "";
|
|
956
|
+
if (toolId) {
|
|
957
|
+
const cachedChunks = state.popToolResultChunks(toolId);
|
|
958
|
+
if (cachedChunks) {
|
|
959
|
+
finalResult = cachedChunks + finalResult;
|
|
960
|
+
}
|
|
961
|
+
}
|
|
962
|
+
yield {
|
|
963
|
+
type: AGUI_EVENT_TYPES.TOOL_CALL_RESULT,
|
|
964
|
+
messageId: event.data?.message_id || event.data?.messageId || `tool-result-${toolId}`,
|
|
965
|
+
toolCallId: toolId,
|
|
966
|
+
content: finalResult,
|
|
967
|
+
role: "tool"
|
|
968
|
+
};
|
|
969
|
+
return;
|
|
970
|
+
}
|
|
971
|
+
if (event.event === "ERROR" /* ERROR */) {
|
|
972
|
+
yield {
|
|
973
|
+
type: AGUI_EVENT_TYPES.RUN_ERROR,
|
|
974
|
+
message: event.data?.message || "",
|
|
975
|
+
code: event.data?.code
|
|
976
|
+
};
|
|
977
|
+
return;
|
|
978
|
+
}
|
|
979
|
+
if (event.event === "STATE" /* STATE */) {
|
|
980
|
+
if ("snapshot" in (event.data || {})) {
|
|
981
|
+
yield {
|
|
982
|
+
type: AGUI_EVENT_TYPES.STATE_SNAPSHOT,
|
|
983
|
+
snapshot: event.data?.snapshot || {}
|
|
984
|
+
};
|
|
985
|
+
} else if ("delta" in (event.data || {})) {
|
|
986
|
+
yield {
|
|
987
|
+
type: AGUI_EVENT_TYPES.STATE_DELTA,
|
|
988
|
+
delta: event.data?.delta || []
|
|
989
|
+
};
|
|
990
|
+
} else {
|
|
991
|
+
yield {
|
|
992
|
+
type: AGUI_EVENT_TYPES.STATE_SNAPSHOT,
|
|
993
|
+
snapshot: event.data || {}
|
|
994
|
+
};
|
|
995
|
+
}
|
|
996
|
+
return;
|
|
997
|
+
}
|
|
998
|
+
if (event.event === "CUSTOM" /* CUSTOM */) {
|
|
999
|
+
yield {
|
|
1000
|
+
type: AGUI_EVENT_TYPES.CUSTOM,
|
|
1001
|
+
name: event.data?.name || "custom",
|
|
1002
|
+
value: event.data?.value
|
|
1003
|
+
};
|
|
1004
|
+
return;
|
|
1005
|
+
}
|
|
1006
|
+
yield {
|
|
1007
|
+
type: AGUI_EVENT_TYPES.CUSTOM,
|
|
1008
|
+
name: event.event || "unknown",
|
|
1009
|
+
value: event.data
|
|
1010
|
+
};
|
|
1011
|
+
}
|
|
1012
|
+
/**
|
|
1013
|
+
* Encode event to SSE format
|
|
1014
|
+
*/
|
|
1015
|
+
encode(event) {
|
|
1016
|
+
if ("__raw" in event) {
|
|
1017
|
+
const raw = event.__raw;
|
|
1018
|
+
return raw.endsWith("\n\n") ? raw : raw.replace(/\n+$/, "") + "\n\n";
|
|
1019
|
+
}
|
|
1020
|
+
return `data: ${JSON.stringify(event)}
|
|
1021
|
+
|
|
1022
|
+
`;
|
|
1023
|
+
}
|
|
1024
|
+
/**
|
|
1025
|
+
* Apply addition fields
|
|
1026
|
+
*/
|
|
1027
|
+
applyAddition(eventData, addition, mergeOptions) {
|
|
1028
|
+
if (!addition) return eventData;
|
|
1029
|
+
const result = { ...eventData };
|
|
1030
|
+
for (const [key, value] of Object.entries(addition)) {
|
|
1031
|
+
if (mergeOptions?.noNewField && !(key in eventData)) continue;
|
|
1032
|
+
result[key] = value;
|
|
1033
|
+
}
|
|
1034
|
+
return result;
|
|
1035
|
+
}
|
|
1036
|
+
/**
|
|
1037
|
+
* Generate error stream
|
|
1038
|
+
*/
|
|
1039
|
+
async *errorStream(message) {
|
|
1040
|
+
const threadId = v4();
|
|
1041
|
+
const runId = v4();
|
|
1042
|
+
yield this.encode({ type: AGUI_EVENT_TYPES.RUN_STARTED, threadId, runId });
|
|
1043
|
+
yield this.encode({
|
|
1044
|
+
type: AGUI_EVENT_TYPES.RUN_ERROR,
|
|
1045
|
+
message,
|
|
1046
|
+
code: "REQUEST_ERROR"
|
|
1047
|
+
});
|
|
1048
|
+
}
|
|
1049
|
+
};
|
|
1050
|
+
|
|
1051
|
+
export { AGUIProtocolHandler, AGUI_EVENT_TYPES, OpenAIProtocolHandler };
|
|
1052
|
+
//# sourceMappingURL=index.js.map
|
|
1053
|
+
//# sourceMappingURL=index.js.map
|