@frost1994/agentic-core 1.0.0
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/LICENSE +201 -0
- package/README.md +32 -0
- package/dist/client.cjs +6 -0
- package/dist/client.cjs.map +1 -0
- package/dist/client.d.ts +149 -0
- package/dist/client.js +6 -0
- package/dist/client.js.map +1 -0
- package/dist/index-CesPelb5.js +619 -0
- package/dist/index-CesPelb5.js.map +1 -0
- package/dist/index-DHqclwK8.cjs +618 -0
- package/dist/index-DHqclwK8.cjs.map +1 -0
- package/dist/index.cjs +605 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +904 -0
- package/dist/index.js +606 -0
- package/dist/index.js.map +1 -0
- package/dist/protocol.cjs +2 -0
- package/dist/protocol.cjs.map +1 -0
- package/dist/protocol.d.ts +298 -0
- package/dist/protocol.js +2 -0
- package/dist/protocol.js.map +1 -0
- package/package.json +64 -0
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,605 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const client = require("./index-DHqclwK8.cjs");
|
|
4
|
+
class AiHttpError extends Error {
|
|
5
|
+
constructor(code, message, traceId) {
|
|
6
|
+
super(message);
|
|
7
|
+
this.name = "AiHttpError";
|
|
8
|
+
this.code = code;
|
|
9
|
+
this.traceId = traceId;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
class AiHttpClient {
|
|
13
|
+
constructor(baseUrl, headersProvider) {
|
|
14
|
+
this.baseUrl = baseUrl.replace(/\/+$/, "");
|
|
15
|
+
this.headersProvider = headersProvider;
|
|
16
|
+
}
|
|
17
|
+
async getPluginConfig(systemCode) {
|
|
18
|
+
const raw = await this.request(
|
|
19
|
+
"GET",
|
|
20
|
+
`/plugin/config?systemCode=${encodeURIComponent(systemCode)}`
|
|
21
|
+
).catch(() => null);
|
|
22
|
+
if (!raw) {
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
return {
|
|
26
|
+
systemCode: raw.systemCode ?? systemCode,
|
|
27
|
+
defaultMode: raw.defaultMode ?? "floating",
|
|
28
|
+
themeStrategy: raw.themeStrategy ?? "system",
|
|
29
|
+
themePreset: raw.themePreset ?? "light",
|
|
30
|
+
primaryColor: raw.primaryColor ?? "#409EFF",
|
|
31
|
+
defaultModelCode: raw.defaultModelCode ?? "default",
|
|
32
|
+
enableFullscreen: Boolean(raw.enableFullscreen ?? true),
|
|
33
|
+
enableDrawer: Boolean(raw.enableDrawer ?? true),
|
|
34
|
+
enableKnowledge: Boolean(raw.enableKnowledge ?? false),
|
|
35
|
+
enableText2Sql: Boolean(raw.enableText2Sql ?? true),
|
|
36
|
+
rateLimitPerHour: Number(raw.rateLimitPerHour ?? 100)
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
async listModels() {
|
|
40
|
+
const raw = await this.request("GET", "/models");
|
|
41
|
+
return raw.map((item) => ({
|
|
42
|
+
code: item.code ?? item.modelCode ?? "",
|
|
43
|
+
name: item.name ?? item.modelName ?? "",
|
|
44
|
+
supportStream: Boolean(item.supportStream ?? true),
|
|
45
|
+
supportToolCall: Boolean(item.supportToolCall ?? false),
|
|
46
|
+
bestFor: (item.bestFor ?? []).filter(Boolean),
|
|
47
|
+
maxTokens: typeof item.maxTokens === "number" ? item.maxTokens : void 0
|
|
48
|
+
})).filter((item) => item.code && item.name);
|
|
49
|
+
}
|
|
50
|
+
async createConversation(systemCode, title, modelCode) {
|
|
51
|
+
return this.request("POST", "/conversations", {
|
|
52
|
+
systemCode,
|
|
53
|
+
title: title ?? "New conversation",
|
|
54
|
+
modelCode: modelCode ?? "default"
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
async listConversations(systemCode, page = 1, size = 20) {
|
|
58
|
+
return this.request(
|
|
59
|
+
"GET",
|
|
60
|
+
`/conversations?systemCode=${encodeURIComponent(systemCode)}&page=${page}&size=${size}`
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
async getMessages(conversationId) {
|
|
64
|
+
return this.request(
|
|
65
|
+
"GET",
|
|
66
|
+
`/conversations/${encodeURIComponent(conversationId)}/messages`
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
async deleteConversation(conversationId) {
|
|
70
|
+
await this.request(
|
|
71
|
+
"DELETE",
|
|
72
|
+
`/conversations/${encodeURIComponent(conversationId)}`
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
async getSuggestions(systemCode, sceneCode) {
|
|
76
|
+
let path = `/suggestions?systemCode=${encodeURIComponent(systemCode)}`;
|
|
77
|
+
if (sceneCode) {
|
|
78
|
+
path += `&sceneCode=${encodeURIComponent(sceneCode)}`;
|
|
79
|
+
}
|
|
80
|
+
return this.request("GET", path);
|
|
81
|
+
}
|
|
82
|
+
async confirmAction(actionId, confirm) {
|
|
83
|
+
await this.request("POST", "/actions/confirm", {
|
|
84
|
+
actionId,
|
|
85
|
+
confirm
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
async listDataSources() {
|
|
89
|
+
const raw = await this.request("GET", "/data-sources");
|
|
90
|
+
return raw.map((item) => ({
|
|
91
|
+
code: item.code ?? item.sourceCode ?? "",
|
|
92
|
+
name: item.name ?? item.sourceName ?? "",
|
|
93
|
+
type: item.type ?? item.dbType ?? "",
|
|
94
|
+
description: item.description
|
|
95
|
+
})).filter((item) => item.code && item.name);
|
|
96
|
+
}
|
|
97
|
+
async listTables(dataSourceCode) {
|
|
98
|
+
const raw = await this.request(
|
|
99
|
+
"GET",
|
|
100
|
+
`/data-sources/${encodeURIComponent(dataSourceCode)}/tables`
|
|
101
|
+
);
|
|
102
|
+
return raw.map((item) => ({
|
|
103
|
+
tableName: item.tableName ?? "",
|
|
104
|
+
tableComment: item.tableComment ?? item.tableAlias ?? item.description ?? void 0,
|
|
105
|
+
columns: Array.isArray(item.columns) ? item.columns : void 0
|
|
106
|
+
})).filter((item) => item.tableName);
|
|
107
|
+
}
|
|
108
|
+
async submitFeedback(messageId, rating, comment) {
|
|
109
|
+
await this.request("POST", "/feedback", {
|
|
110
|
+
messageId,
|
|
111
|
+
rating,
|
|
112
|
+
comment
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
async health() {
|
|
116
|
+
const healthUrl = this.baseUrl.endsWith("/api/ai") ? `${this.baseUrl.slice(0, -"/api/ai".length)}/actuator/health` : `${this.baseUrl}/health`;
|
|
117
|
+
const res = await fetch(healthUrl, {
|
|
118
|
+
method: "GET",
|
|
119
|
+
headers: this.headersProvider()
|
|
120
|
+
});
|
|
121
|
+
if (!res.ok) {
|
|
122
|
+
throw new AiHttpError(res.status, `HTTP ${res.status}: ${res.statusText}`);
|
|
123
|
+
}
|
|
124
|
+
const json = await res.json();
|
|
125
|
+
if ("code" in json) {
|
|
126
|
+
if (json.code !== 200) {
|
|
127
|
+
throw new AiHttpError(json.code, json.message ?? "Unknown API error", json.traceId);
|
|
128
|
+
}
|
|
129
|
+
return json.data;
|
|
130
|
+
}
|
|
131
|
+
return {
|
|
132
|
+
status: json.status,
|
|
133
|
+
service: "ai-gateway"
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
async request(method, path, body) {
|
|
137
|
+
const url = `${this.baseUrl}${path}`;
|
|
138
|
+
const headers = {
|
|
139
|
+
"Content-Type": "application/json",
|
|
140
|
+
...this.headersProvider()
|
|
141
|
+
};
|
|
142
|
+
const init = {
|
|
143
|
+
method,
|
|
144
|
+
headers
|
|
145
|
+
};
|
|
146
|
+
if (body !== void 0 && (method === "POST" || method === "PUT" || method === "PATCH")) {
|
|
147
|
+
init.body = JSON.stringify(body);
|
|
148
|
+
}
|
|
149
|
+
const res = await fetch(url, init);
|
|
150
|
+
if (!res.ok) {
|
|
151
|
+
throw new AiHttpError(res.status, `HTTP ${res.status}: ${res.statusText}`);
|
|
152
|
+
}
|
|
153
|
+
if (res.status === 204 || method === "DELETE") {
|
|
154
|
+
return void 0;
|
|
155
|
+
}
|
|
156
|
+
const json = await res.json();
|
|
157
|
+
if (json.code !== void 0 && json.code !== 200) {
|
|
158
|
+
throw new AiHttpError(
|
|
159
|
+
json.code,
|
|
160
|
+
json.message ?? "Unknown API error",
|
|
161
|
+
json.traceId
|
|
162
|
+
);
|
|
163
|
+
}
|
|
164
|
+
return json.data;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
function createInitialState(overrides) {
|
|
168
|
+
return {
|
|
169
|
+
visible: false,
|
|
170
|
+
mode: "floating",
|
|
171
|
+
previousMode: null,
|
|
172
|
+
position: { x: 0, y: 0 },
|
|
173
|
+
size: { width: 420, height: 600 },
|
|
174
|
+
systemCode: "",
|
|
175
|
+
modelCode: "",
|
|
176
|
+
currentConversationId: null,
|
|
177
|
+
conversations: [],
|
|
178
|
+
messagesByConversation: {},
|
|
179
|
+
toolStepsByMessage: {},
|
|
180
|
+
streamStatus: "idle",
|
|
181
|
+
lastSeq: 0,
|
|
182
|
+
lastHeartbeatAt: 0,
|
|
183
|
+
reconnectAttempt: 0,
|
|
184
|
+
themeMode: "system",
|
|
185
|
+
primaryColor: "#1677ff",
|
|
186
|
+
hasError: false,
|
|
187
|
+
lastError: null,
|
|
188
|
+
...overrides
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
function reducer(state, action) {
|
|
192
|
+
switch (action.type) {
|
|
193
|
+
case "OPEN":
|
|
194
|
+
return {
|
|
195
|
+
...state,
|
|
196
|
+
visible: true,
|
|
197
|
+
mode: action.mode ?? state.mode
|
|
198
|
+
};
|
|
199
|
+
case "CLOSE":
|
|
200
|
+
return { ...state, visible: false };
|
|
201
|
+
case "TOGGLE":
|
|
202
|
+
return { ...state, visible: !state.visible };
|
|
203
|
+
case "SWITCH_MODE": {
|
|
204
|
+
return {
|
|
205
|
+
...state,
|
|
206
|
+
previousMode: state.mode,
|
|
207
|
+
mode: action.mode
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
case "SET_POSITION":
|
|
211
|
+
return {
|
|
212
|
+
...state,
|
|
213
|
+
position: { x: action.x, y: action.y }
|
|
214
|
+
};
|
|
215
|
+
case "SET_SIZE":
|
|
216
|
+
return {
|
|
217
|
+
...state,
|
|
218
|
+
size: { width: action.width, height: action.height }
|
|
219
|
+
};
|
|
220
|
+
case "SET_SYSTEM_CODE":
|
|
221
|
+
return { ...state, systemCode: action.systemCode };
|
|
222
|
+
case "SET_MODEL_CODE":
|
|
223
|
+
return { ...state, modelCode: action.modelCode };
|
|
224
|
+
case "SET_CONVERSATION":
|
|
225
|
+
return { ...state, currentConversationId: action.id };
|
|
226
|
+
case "ADD_CONVERSATION": {
|
|
227
|
+
const next = [action.conversation, ...state.conversations];
|
|
228
|
+
return { ...state, conversations: next };
|
|
229
|
+
}
|
|
230
|
+
case "SET_CONVERSATIONS":
|
|
231
|
+
return { ...state, conversations: action.conversations };
|
|
232
|
+
case "APPEND_MESSAGE": {
|
|
233
|
+
const list = state.messagesByConversation[action.conversationId] ?? [];
|
|
234
|
+
return {
|
|
235
|
+
...state,
|
|
236
|
+
messagesByConversation: {
|
|
237
|
+
...state.messagesByConversation,
|
|
238
|
+
[action.conversationId]: [...list, action.message]
|
|
239
|
+
}
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
case "APPEND_DELTA": {
|
|
243
|
+
const list = state.messagesByConversation[action.conversationId];
|
|
244
|
+
if (!list) return state;
|
|
245
|
+
const idx = list.findIndex((m) => m.id === action.messageId);
|
|
246
|
+
if (idx === -1) return state;
|
|
247
|
+
const next = list.slice();
|
|
248
|
+
next[idx] = { ...next[idx], content: next[idx].content + action.delta };
|
|
249
|
+
return {
|
|
250
|
+
...state,
|
|
251
|
+
messagesByConversation: {
|
|
252
|
+
...state.messagesByConversation,
|
|
253
|
+
[action.conversationId]: next
|
|
254
|
+
}
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
case "UPDATE_MESSAGE_STATUS": {
|
|
258
|
+
const list = state.messagesByConversation[action.conversationId];
|
|
259
|
+
if (!list) return state;
|
|
260
|
+
const idx = list.findIndex((m) => m.id === action.messageId);
|
|
261
|
+
if (idx === -1) return state;
|
|
262
|
+
const next = list.slice();
|
|
263
|
+
const msg = next[idx];
|
|
264
|
+
next[idx] = {
|
|
265
|
+
...msg,
|
|
266
|
+
status: action.status,
|
|
267
|
+
finishedAt: action.status === "success" || action.status === "failed" ? (/* @__PURE__ */ new Date()).toISOString() : msg.finishedAt
|
|
268
|
+
};
|
|
269
|
+
return {
|
|
270
|
+
...state,
|
|
271
|
+
messagesByConversation: {
|
|
272
|
+
...state.messagesByConversation,
|
|
273
|
+
[action.conversationId]: next
|
|
274
|
+
}
|
|
275
|
+
};
|
|
276
|
+
}
|
|
277
|
+
case "SET_MESSAGES":
|
|
278
|
+
return {
|
|
279
|
+
...state,
|
|
280
|
+
messagesByConversation: {
|
|
281
|
+
...state.messagesByConversation,
|
|
282
|
+
[action.conversationId]: action.messages
|
|
283
|
+
}
|
|
284
|
+
};
|
|
285
|
+
case "APPEND_TOOL_STEP": {
|
|
286
|
+
const steps = state.toolStepsByMessage[action.messageId] ?? [];
|
|
287
|
+
return {
|
|
288
|
+
...state,
|
|
289
|
+
toolStepsByMessage: {
|
|
290
|
+
...state.toolStepsByMessage,
|
|
291
|
+
[action.messageId]: [...steps, action.step]
|
|
292
|
+
}
|
|
293
|
+
};
|
|
294
|
+
}
|
|
295
|
+
case "UPDATE_TOOL_STEP": {
|
|
296
|
+
const steps = state.toolStepsByMessage[action.messageId];
|
|
297
|
+
if (!steps) return state;
|
|
298
|
+
const idx = steps.findIndex((s) => s.stepId === action.stepId);
|
|
299
|
+
if (idx === -1) return state;
|
|
300
|
+
const next = steps.slice();
|
|
301
|
+
next[idx] = { ...next[idx], ...action.patch };
|
|
302
|
+
return {
|
|
303
|
+
...state,
|
|
304
|
+
toolStepsByMessage: {
|
|
305
|
+
...state.toolStepsByMessage,
|
|
306
|
+
[action.messageId]: next
|
|
307
|
+
}
|
|
308
|
+
};
|
|
309
|
+
}
|
|
310
|
+
case "SET_STREAM_STATUS":
|
|
311
|
+
return { ...state, streamStatus: action.status };
|
|
312
|
+
case "SET_LAST_SEQ":
|
|
313
|
+
return { ...state, lastSeq: action.seq };
|
|
314
|
+
case "SET_HEARTBEAT":
|
|
315
|
+
return { ...state, lastHeartbeatAt: action.ts };
|
|
316
|
+
case "INCREMENT_RECONNECT":
|
|
317
|
+
return { ...state, reconnectAttempt: state.reconnectAttempt + 1 };
|
|
318
|
+
case "RESET_RECONNECT":
|
|
319
|
+
return { ...state, reconnectAttempt: 0 };
|
|
320
|
+
case "SET_THEME":
|
|
321
|
+
return { ...state, themeMode: action.mode };
|
|
322
|
+
case "SET_PRIMARY_COLOR":
|
|
323
|
+
return { ...state, primaryColor: action.color };
|
|
324
|
+
case "SET_ERROR":
|
|
325
|
+
return {
|
|
326
|
+
...state,
|
|
327
|
+
hasError: action.error !== null,
|
|
328
|
+
lastError: action.error
|
|
329
|
+
};
|
|
330
|
+
case "HYDRATE":
|
|
331
|
+
return { ...state, ...action.state };
|
|
332
|
+
default:
|
|
333
|
+
return state;
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
const SERIAL_VERSION = 1;
|
|
337
|
+
function serialize(state) {
|
|
338
|
+
const {
|
|
339
|
+
streamStatus,
|
|
340
|
+
lastSeq,
|
|
341
|
+
lastHeartbeatAt,
|
|
342
|
+
reconnectAttempt,
|
|
343
|
+
hasError,
|
|
344
|
+
lastError,
|
|
345
|
+
...persistable
|
|
346
|
+
} = state;
|
|
347
|
+
return { version: SERIAL_VERSION, state: persistable };
|
|
348
|
+
}
|
|
349
|
+
function deserialize(data) {
|
|
350
|
+
if (!data || typeof data !== "object") return null;
|
|
351
|
+
const parsed = data;
|
|
352
|
+
if (parsed.version !== SERIAL_VERSION) return null;
|
|
353
|
+
return createInitialState(parsed.state);
|
|
354
|
+
}
|
|
355
|
+
function serializeToString(state) {
|
|
356
|
+
return JSON.stringify(serialize(state));
|
|
357
|
+
}
|
|
358
|
+
function deserializeFromString(json) {
|
|
359
|
+
try {
|
|
360
|
+
return deserialize(JSON.parse(json));
|
|
361
|
+
} catch {
|
|
362
|
+
return null;
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
class ToolRegistry {
|
|
366
|
+
constructor() {
|
|
367
|
+
this.tools = /* @__PURE__ */ new Map();
|
|
368
|
+
}
|
|
369
|
+
/** Register a tool with its definition and executor. */
|
|
370
|
+
register(definition, executor) {
|
|
371
|
+
this.tools.set(definition.name, { definition, executor });
|
|
372
|
+
}
|
|
373
|
+
/** Unregister a tool by name. */
|
|
374
|
+
unregister(name) {
|
|
375
|
+
return this.tools.delete(name);
|
|
376
|
+
}
|
|
377
|
+
/** Look up a registered tool. */
|
|
378
|
+
get(name) {
|
|
379
|
+
return this.tools.get(name);
|
|
380
|
+
}
|
|
381
|
+
/** Check whether a tool is registered. */
|
|
382
|
+
has(name) {
|
|
383
|
+
return this.tools.has(name);
|
|
384
|
+
}
|
|
385
|
+
/** List all registered tool names. */
|
|
386
|
+
list() {
|
|
387
|
+
return Array.from(this.tools.keys());
|
|
388
|
+
}
|
|
389
|
+
/** Get all definitions (for sending to LLM). */
|
|
390
|
+
getDefinitions() {
|
|
391
|
+
return Array.from(this.tools.values()).map((t) => t.definition);
|
|
392
|
+
}
|
|
393
|
+
/** Clear all registrations. */
|
|
394
|
+
clear() {
|
|
395
|
+
this.tools.clear();
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
class ToolOrchestrator {
|
|
399
|
+
constructor(options) {
|
|
400
|
+
this.registry = options.registry;
|
|
401
|
+
this.onStepStart = options.onStepStart;
|
|
402
|
+
this.onStepComplete = options.onStepComplete;
|
|
403
|
+
this.onStepError = options.onStepError;
|
|
404
|
+
}
|
|
405
|
+
/**
|
|
406
|
+
* Execute a plan of tool steps.
|
|
407
|
+
*
|
|
408
|
+
* - `serial`: steps run one after another; if one fails, abort the rest.
|
|
409
|
+
* - `parallel`: steps run concurrently; all results collected regardless of individual failures.
|
|
410
|
+
*/
|
|
411
|
+
async execute(plan) {
|
|
412
|
+
if (plan.mode === "serial") {
|
|
413
|
+
return this.executeSerial(plan.steps);
|
|
414
|
+
}
|
|
415
|
+
return this.executeParallel(plan.steps);
|
|
416
|
+
}
|
|
417
|
+
/** Execute a single tool step. */
|
|
418
|
+
async executeSingle(toolName, args, title) {
|
|
419
|
+
var _a, _b, _c, _d;
|
|
420
|
+
const registered = this.registry.get(toolName);
|
|
421
|
+
if (!registered) {
|
|
422
|
+
const step2 = {
|
|
423
|
+
stepId: client.generateId("step_"),
|
|
424
|
+
toolName,
|
|
425
|
+
title: title ?? toolName,
|
|
426
|
+
status: "error",
|
|
427
|
+
args,
|
|
428
|
+
message: `Tool "${toolName}" is not registered`
|
|
429
|
+
};
|
|
430
|
+
(_a = this.onStepError) == null ? void 0 : _a.call(this, step2, new Error(step2.message));
|
|
431
|
+
return step2;
|
|
432
|
+
}
|
|
433
|
+
const step = {
|
|
434
|
+
stepId: client.generateId("step_"),
|
|
435
|
+
toolName,
|
|
436
|
+
title: title ?? registered.definition.description ?? toolName,
|
|
437
|
+
status: "running",
|
|
438
|
+
args
|
|
439
|
+
};
|
|
440
|
+
(_b = this.onStepStart) == null ? void 0 : _b.call(this, step);
|
|
441
|
+
const startTime = Date.now();
|
|
442
|
+
try {
|
|
443
|
+
const result = await registered.executor(args);
|
|
444
|
+
step.status = "success";
|
|
445
|
+
step.result = result;
|
|
446
|
+
step.durationMs = Date.now() - startTime;
|
|
447
|
+
(_c = this.onStepComplete) == null ? void 0 : _c.call(this, step);
|
|
448
|
+
return step;
|
|
449
|
+
} catch (err) {
|
|
450
|
+
step.status = "error";
|
|
451
|
+
step.result = err instanceof Error ? err.message : String(err);
|
|
452
|
+
step.durationMs = Date.now() - startTime;
|
|
453
|
+
(_d = this.onStepError) == null ? void 0 : _d.call(this, step, err instanceof Error ? err : new Error(String(err)));
|
|
454
|
+
return step;
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
async executeSerial(steps) {
|
|
458
|
+
const results = [];
|
|
459
|
+
for (const s of steps) {
|
|
460
|
+
const result = await this.executeSingle(s.toolName, s.args, s.title);
|
|
461
|
+
results.push(result);
|
|
462
|
+
if (result.status === "error") {
|
|
463
|
+
break;
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
return results;
|
|
467
|
+
}
|
|
468
|
+
async executeParallel(steps) {
|
|
469
|
+
return Promise.all(
|
|
470
|
+
steps.map((s) => this.executeSingle(s.toolName, s.args, s.title))
|
|
471
|
+
);
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
const _CitationParser = class _CitationParser {
|
|
475
|
+
/**
|
|
476
|
+
* Extract all citation markers from a text block.
|
|
477
|
+
*
|
|
478
|
+
* @param text — source text containing [1], [2], … markers
|
|
479
|
+
* @returns ordered list of citations with positions
|
|
480
|
+
*/
|
|
481
|
+
parse(text) {
|
|
482
|
+
const citations = [];
|
|
483
|
+
let match;
|
|
484
|
+
_CitationParser.MARKER_RE.lastIndex = 0;
|
|
485
|
+
while ((match = _CitationParser.MARKER_RE.exec(text)) !== null) {
|
|
486
|
+
citations.push({
|
|
487
|
+
marker: match[0],
|
|
488
|
+
index: parseInt(match[1], 10),
|
|
489
|
+
start: match.index,
|
|
490
|
+
end: match.index + match[0].length
|
|
491
|
+
});
|
|
492
|
+
}
|
|
493
|
+
return citations;
|
|
494
|
+
}
|
|
495
|
+
/**
|
|
496
|
+
* Strip citation markers from text, returning clean text and a mapping.
|
|
497
|
+
*
|
|
498
|
+
* @returns `{ text: string, citations: Citation[] }`
|
|
499
|
+
*/
|
|
500
|
+
strip(text) {
|
|
501
|
+
const citations = this.parse(text);
|
|
502
|
+
if (citations.length === 0) {
|
|
503
|
+
return { text, citations: [] };
|
|
504
|
+
}
|
|
505
|
+
let cleaned = "";
|
|
506
|
+
let lastEnd = 0;
|
|
507
|
+
for (const c of citations) {
|
|
508
|
+
cleaned += text.slice(lastEnd, c.start);
|
|
509
|
+
lastEnd = c.end;
|
|
510
|
+
}
|
|
511
|
+
cleaned += text.slice(lastEnd);
|
|
512
|
+
return { text: cleaned.trim(), citations };
|
|
513
|
+
}
|
|
514
|
+
/**
|
|
515
|
+
* Replace citation markers with custom formatter output.
|
|
516
|
+
*
|
|
517
|
+
* @param text — source text
|
|
518
|
+
* @param format — callback receiving citation index, returns replacement string
|
|
519
|
+
*/
|
|
520
|
+
replace(text, format) {
|
|
521
|
+
return text.replace(_CitationParser.MARKER_RE, (_match, num) => format(parseInt(num, 10)));
|
|
522
|
+
}
|
|
523
|
+
};
|
|
524
|
+
_CitationParser.MARKER_RE = /\[(\d+)\]/g;
|
|
525
|
+
let CitationParser = _CitationParser;
|
|
526
|
+
class ChunkMatcher {
|
|
527
|
+
/**
|
|
528
|
+
* Match parsed citations to a list of knowledge chunks.
|
|
529
|
+
*
|
|
530
|
+
* @param citations — output from `CitationParser.parse()`
|
|
531
|
+
* @param chunks — chunks returned by backend (should be 1-based indexed)
|
|
532
|
+
* @returns chunks that were cited, with `citedBy` populated
|
|
533
|
+
*/
|
|
534
|
+
match(citations, chunks) {
|
|
535
|
+
const citedIndices = new Set(citations.map((c) => c.index));
|
|
536
|
+
const indexToCitations = /* @__PURE__ */ new Map();
|
|
537
|
+
for (const c of citations) {
|
|
538
|
+
const arr = indexToCitations.get(c.index) ?? [];
|
|
539
|
+
arr.push(c.index);
|
|
540
|
+
indexToCitations.set(c.index, arr);
|
|
541
|
+
}
|
|
542
|
+
const matched = [];
|
|
543
|
+
for (const chunk of chunks) {
|
|
544
|
+
if (citedIndices.has(chunk.index)) {
|
|
545
|
+
matched.push({
|
|
546
|
+
...chunk,
|
|
547
|
+
citedBy: indexToCitations.get(chunk.index) ?? [chunk.index]
|
|
548
|
+
});
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
matched.sort((a, b) => a.index - b.index);
|
|
552
|
+
return matched;
|
|
553
|
+
}
|
|
554
|
+
/**
|
|
555
|
+
* Build a flat map: citation index → chunk.
|
|
556
|
+
*
|
|
557
|
+
* @returns Map where key is citation number and value is the matching chunk
|
|
558
|
+
*/
|
|
559
|
+
buildIndexMap(chunks) {
|
|
560
|
+
const map = /* @__PURE__ */ new Map();
|
|
561
|
+
for (const chunk of chunks) {
|
|
562
|
+
map.set(chunk.index, chunk);
|
|
563
|
+
}
|
|
564
|
+
return map;
|
|
565
|
+
}
|
|
566
|
+
/**
|
|
567
|
+
* Find chunks that are NOT cited in the text (orphans).
|
|
568
|
+
*/
|
|
569
|
+
findOrphans(citations, chunks) {
|
|
570
|
+
const cited = new Set(citations.map((c) => c.index));
|
|
571
|
+
return chunks.filter((c) => !cited.has(c.index));
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
exports.ErrorCodes = client.ErrorCodes;
|
|
575
|
+
exports.SqlGuard = client.SqlGuard;
|
|
576
|
+
exports.SseClient = client.SseClient;
|
|
577
|
+
exports.clamp = client.clamp;
|
|
578
|
+
exports.createError = client.createError;
|
|
579
|
+
exports.debounce = client.debounce;
|
|
580
|
+
exports.deepClone = client.deepClone;
|
|
581
|
+
exports.delay = client.delay;
|
|
582
|
+
exports.formatDate = client.formatDate;
|
|
583
|
+
exports.formatDuration = client.formatDuration;
|
|
584
|
+
exports.generateId = client.generateId;
|
|
585
|
+
exports.isAborted = client.isAborted;
|
|
586
|
+
exports.isArray = client.isArray;
|
|
587
|
+
exports.isFunction = client.isFunction;
|
|
588
|
+
exports.isNumber = client.isNumber;
|
|
589
|
+
exports.isObject = client.isObject;
|
|
590
|
+
exports.isRetriable = client.isRetriable;
|
|
591
|
+
exports.isString = client.isString;
|
|
592
|
+
exports.throttle = client.throttle;
|
|
593
|
+
exports.AiHttpClient = AiHttpClient;
|
|
594
|
+
exports.AiHttpError = AiHttpError;
|
|
595
|
+
exports.ChunkMatcher = ChunkMatcher;
|
|
596
|
+
exports.CitationParser = CitationParser;
|
|
597
|
+
exports.ToolOrchestrator = ToolOrchestrator;
|
|
598
|
+
exports.ToolRegistry = ToolRegistry;
|
|
599
|
+
exports.createInitialState = createInitialState;
|
|
600
|
+
exports.deserialize = deserialize;
|
|
601
|
+
exports.deserializeFromString = deserializeFromString;
|
|
602
|
+
exports.reducer = reducer;
|
|
603
|
+
exports.serialize = serialize;
|
|
604
|
+
exports.serializeToString = serializeToString;
|
|
605
|
+
//# sourceMappingURL=index.cjs.map
|