@kognitivedev/vercel-ai-provider 0.2.21 → 0.2.26
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/CHANGELOG.md +58 -0
- package/README.md +29 -4
- package/dist/__tests__/cognitive-layer-extra.test.js +151 -0
- package/dist/__tests__/wrap-stream-logging.test.js +131 -9
- package/dist/index.d.ts +55 -5
- package/dist/index.js +643 -137
- package/package.json +6 -4
- package/src/__tests__/cognitive-layer-extra.test.ts +158 -1
- package/src/__tests__/wrap-stream-logging.test.ts +152 -10
- package/src/index.ts +746 -145
package/dist/index.js
CHANGED
|
@@ -1,4 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __asyncValues = (this && this.__asyncValues) || function (o) {
|
|
3
|
+
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
|
|
4
|
+
var m = o[Symbol.asyncIterator], i;
|
|
5
|
+
return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
|
|
6
|
+
function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
|
|
7
|
+
function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
|
|
8
|
+
};
|
|
2
9
|
var __rest = (this && this.__rest) || function (s, e) {
|
|
3
10
|
var t = {};
|
|
4
11
|
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
@@ -12,9 +19,13 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
12
19
|
};
|
|
13
20
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
21
|
exports.renderTemplate = void 0;
|
|
22
|
+
exports.toMessageEventStream = toMessageEventStream;
|
|
23
|
+
exports.toGeneratedMessageEventStream = toGeneratedMessageEventStream;
|
|
15
24
|
exports.createCognitiveLayer = createCognitiveLayer;
|
|
16
25
|
const ai_1 = require("ai");
|
|
17
|
-
const
|
|
26
|
+
const memory_1 = require("@kognitivedev/memory");
|
|
27
|
+
const tools_1 = require("@kognitivedev/tools");
|
|
28
|
+
const shared_1 = require("@kognitivedev/shared");
|
|
18
29
|
const prompthub_1 = require("@kognitivedev/prompthub");
|
|
19
30
|
var template_1 = require("./template");
|
|
20
31
|
Object.defineProperty(exports, "renderTemplate", { enumerable: true, get: function () { return template_1.renderTemplate; } });
|
|
@@ -72,30 +83,6 @@ function createLogger(logLevel) {
|
|
|
72
83
|
},
|
|
73
84
|
};
|
|
74
85
|
}
|
|
75
|
-
function getContentText(content) {
|
|
76
|
-
if (typeof content === "string") {
|
|
77
|
-
if (content.includes("data:image/") && content.includes("base64,"))
|
|
78
|
-
return "[Image]";
|
|
79
|
-
return content;
|
|
80
|
-
}
|
|
81
|
-
if (!Array.isArray(content))
|
|
82
|
-
return "";
|
|
83
|
-
return content.map((part) => {
|
|
84
|
-
if (!part || typeof part !== "object")
|
|
85
|
-
return "";
|
|
86
|
-
if (typeof part.text === "string")
|
|
87
|
-
return part.text;
|
|
88
|
-
if (part.type === "tool-call" && typeof part.toolName === "string")
|
|
89
|
-
return `Called ${part.toolName}`;
|
|
90
|
-
if (part.type === "tool-result")
|
|
91
|
-
return "Received tool result";
|
|
92
|
-
if (part.type === "image" || part.type === "image_url")
|
|
93
|
-
return "[Image]";
|
|
94
|
-
if (part.type === "file")
|
|
95
|
-
return "[File]";
|
|
96
|
-
return "";
|
|
97
|
-
}).filter(Boolean).join(" ");
|
|
98
|
-
}
|
|
99
86
|
/**
|
|
100
87
|
* Unwraps V2/V3 ToolResultOutput discriminated union to a displayable value.
|
|
101
88
|
* Stream ToolResult uses plain `result` (passthrough), while prompt ToolResultPart
|
|
@@ -123,14 +110,6 @@ function extractOutputValue(raw) {
|
|
|
123
110
|
return raw;
|
|
124
111
|
}
|
|
125
112
|
}
|
|
126
|
-
function buildTracePreviews(messages) {
|
|
127
|
-
const request = [...messages].reverse().find((message) => (message === null || message === void 0 ? void 0 : message.role) === "user");
|
|
128
|
-
const response = [...messages].reverse().find((message) => (message === null || message === void 0 ? void 0 : message.role) === "assistant");
|
|
129
|
-
return {
|
|
130
|
-
requestPreview: request ? getContentText(request.content).slice(0, 220) : "No request captured",
|
|
131
|
-
responsePreview: response ? getContentText(response.content).slice(0, 240) : "No response captured",
|
|
132
|
-
};
|
|
133
|
-
}
|
|
134
113
|
function buildTraceSpansFromMessages(messages) {
|
|
135
114
|
var _a, _b;
|
|
136
115
|
const resultMap = new Map();
|
|
@@ -191,6 +170,143 @@ const MEMORY_TAG_REGEX = /<MemoryContext>/i;
|
|
|
191
170
|
const SESSION_KEY = Symbol.for("cl:session");
|
|
192
171
|
// Session key → prompt metadata (populated by cl.streamText/cl.generateText, read by middleware)
|
|
193
172
|
const sessionPromptMetadata = new Map();
|
|
173
|
+
function toAISDKTopicMemoryTool(userId, baseUrl, apiKey) {
|
|
174
|
+
const tool = (0, tools_1.createTopicMemoryTool)({ apiKey, baseUrl });
|
|
175
|
+
return {
|
|
176
|
+
description: tool.description,
|
|
177
|
+
inputSchema: tool.inputSchema,
|
|
178
|
+
execute: async (input) => {
|
|
179
|
+
const result = await tool.execute(input, {
|
|
180
|
+
abortSignal: new AbortController().signal,
|
|
181
|
+
resourceId: { userId },
|
|
182
|
+
metadata: undefined,
|
|
183
|
+
emit: () => { },
|
|
184
|
+
});
|
|
185
|
+
return tool.toModelOutput ? tool.toModelOutput(result) : result;
|
|
186
|
+
},
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
function withAutoInjectedTools(params, session, baseUrl, apiKey, options) {
|
|
190
|
+
var _a;
|
|
191
|
+
if (!(options === null || options === void 0 ? void 0 : options.autoTopicMemoryTool) || !isValidId(session === null || session === void 0 ? void 0 : session.userId)) {
|
|
192
|
+
return params;
|
|
193
|
+
}
|
|
194
|
+
const existingTools = params.tools;
|
|
195
|
+
if (existingTools && (typeof existingTools !== "object" || Array.isArray(existingTools))) {
|
|
196
|
+
return params;
|
|
197
|
+
}
|
|
198
|
+
const toolSet = Object.assign({}, ((_a = existingTools) !== null && _a !== void 0 ? _a : {}));
|
|
199
|
+
if (tools_1.TOPIC_MEMORY_TOOL_ID in toolSet) {
|
|
200
|
+
return params;
|
|
201
|
+
}
|
|
202
|
+
toolSet[tools_1.TOPIC_MEMORY_TOOL_ID] = toAISDKTopicMemoryTool(session.userId, baseUrl, apiKey);
|
|
203
|
+
return Object.assign(Object.assign({}, params), { tools: toolSet });
|
|
204
|
+
}
|
|
205
|
+
function toMessageEventStream(result) {
|
|
206
|
+
return new ReadableStream({
|
|
207
|
+
async start(controller) {
|
|
208
|
+
var _a, e_1, _b, _c;
|
|
209
|
+
try {
|
|
210
|
+
try {
|
|
211
|
+
for (var _d = true, _e = __asyncValues(result.fullStream), _f; _f = await _e.next(), _a = _f.done, !_a; _d = true) {
|
|
212
|
+
_c = _f.value;
|
|
213
|
+
_d = false;
|
|
214
|
+
const chunk = _c;
|
|
215
|
+
if (chunk.type === "text-delta" && chunk.delta) {
|
|
216
|
+
controller.enqueue({
|
|
217
|
+
event: "messages",
|
|
218
|
+
data: { token: chunk.delta },
|
|
219
|
+
});
|
|
220
|
+
continue;
|
|
221
|
+
}
|
|
222
|
+
if (chunk.type === "tool-call") {
|
|
223
|
+
controller.enqueue({
|
|
224
|
+
event: "messages",
|
|
225
|
+
data: {
|
|
226
|
+
type: "tool-call",
|
|
227
|
+
id: chunk.toolCallId,
|
|
228
|
+
name: chunk.toolName,
|
|
229
|
+
input: chunk.input,
|
|
230
|
+
},
|
|
231
|
+
});
|
|
232
|
+
continue;
|
|
233
|
+
}
|
|
234
|
+
if (chunk.type === "tool-result") {
|
|
235
|
+
controller.enqueue({
|
|
236
|
+
event: "messages",
|
|
237
|
+
data: {
|
|
238
|
+
type: "tool-result",
|
|
239
|
+
id: chunk.toolCallId,
|
|
240
|
+
name: chunk.toolName,
|
|
241
|
+
result: chunk.result,
|
|
242
|
+
},
|
|
243
|
+
});
|
|
244
|
+
continue;
|
|
245
|
+
}
|
|
246
|
+
if (chunk.type === "error") {
|
|
247
|
+
controller.enqueue({
|
|
248
|
+
event: "debug",
|
|
249
|
+
data: {
|
|
250
|
+
type: "error",
|
|
251
|
+
message: chunk.error instanceof Error ? chunk.error.message : String(chunk.error),
|
|
252
|
+
},
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
258
|
+
finally {
|
|
259
|
+
try {
|
|
260
|
+
if (!_d && !_a && (_b = _e.return)) await _b.call(_e);
|
|
261
|
+
}
|
|
262
|
+
finally { if (e_1) throw e_1.error; }
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
finally {
|
|
266
|
+
controller.close();
|
|
267
|
+
}
|
|
268
|
+
},
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
function toGeneratedMessageEventStream(result) {
|
|
272
|
+
return new ReadableStream({
|
|
273
|
+
start(controller) {
|
|
274
|
+
var _a, _b, _c, _d, _e, _f;
|
|
275
|
+
const steps = ((_a = result.steps) === null || _a === void 0 ? void 0 : _a.length)
|
|
276
|
+
? result.steps
|
|
277
|
+
: [{
|
|
278
|
+
toolCalls: result.toolCalls,
|
|
279
|
+
toolResults: result.toolResults,
|
|
280
|
+
}];
|
|
281
|
+
for (const step of steps) {
|
|
282
|
+
for (const toolCall of (_b = step.toolCalls) !== null && _b !== void 0 ? _b : []) {
|
|
283
|
+
controller.enqueue({
|
|
284
|
+
event: "messages",
|
|
285
|
+
data: {
|
|
286
|
+
type: "tool-call",
|
|
287
|
+
id: toolCall.toolCallId,
|
|
288
|
+
name: (_c = toolCall.toolName) !== null && _c !== void 0 ? _c : "tool",
|
|
289
|
+
input: toolCall.input,
|
|
290
|
+
},
|
|
291
|
+
});
|
|
292
|
+
}
|
|
293
|
+
for (const toolResult of (_d = step.toolResults) !== null && _d !== void 0 ? _d : []) {
|
|
294
|
+
controller.enqueue({
|
|
295
|
+
event: "messages",
|
|
296
|
+
data: Object.assign({ type: "tool-result", id: toolResult.toolCallId, name: (_e = toolResult.toolName) !== null && _e !== void 0 ? _e : "tool", result: (_f = toolResult.output) !== null && _f !== void 0 ? _f : toolResult.result }, (toolResult.isError ? { isError: true } : {})),
|
|
297
|
+
});
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
if (result.text) {
|
|
301
|
+
controller.enqueue({
|
|
302
|
+
event: "messages",
|
|
303
|
+
data: { token: result.text },
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
controller.close();
|
|
307
|
+
},
|
|
308
|
+
});
|
|
309
|
+
}
|
|
194
310
|
/**
|
|
195
311
|
* Check if any system message already contains a <MemoryContext> block.
|
|
196
312
|
*/
|
|
@@ -215,6 +331,11 @@ function createCognitiveLayer(config) {
|
|
|
215
331
|
// Default to 'info' log level
|
|
216
332
|
const logLevel = clConfig.logLevel || 'info';
|
|
217
333
|
const logger = createLogger(logLevel);
|
|
334
|
+
const memoryClient = new memory_1.MemoryClient({
|
|
335
|
+
apiKey: clConfig.apiKey,
|
|
336
|
+
baseUrl,
|
|
337
|
+
logger: logger,
|
|
338
|
+
});
|
|
218
339
|
const authHeaders = {
|
|
219
340
|
"Content-Type": "application/json",
|
|
220
341
|
"Authorization": `Bearer ${clConfig.apiKey}`,
|
|
@@ -224,6 +345,17 @@ function createCognitiveLayer(config) {
|
|
|
224
345
|
apiKey: clConfig.apiKey,
|
|
225
346
|
logger,
|
|
226
347
|
});
|
|
348
|
+
const sessionTurnIndexes = new Map();
|
|
349
|
+
const reserveTurnIndex = (agentName, userId, sessionId, requestedRunScope) => {
|
|
350
|
+
var _a;
|
|
351
|
+
if (!isValidId(userId) || !isValidId(sessionId) || !(0, shared_1.isSessionScopedExecution)(requestedRunScope, sessionId ? "session" : "invocation")) {
|
|
352
|
+
return undefined;
|
|
353
|
+
}
|
|
354
|
+
const key = `${agentName}:${getSessionKey(userId, sessionId)}`;
|
|
355
|
+
const nextIndex = (_a = sessionTurnIndexes.get(key)) !== null && _a !== void 0 ? _a : 0;
|
|
356
|
+
sessionTurnIndexes.set(key, nextIndex + 1);
|
|
357
|
+
return nextIndex;
|
|
358
|
+
};
|
|
227
359
|
const resolvePrompt = async (slug, userIdOrOptions) => {
|
|
228
360
|
var _a;
|
|
229
361
|
const userId = typeof userIdOrOptions === "string"
|
|
@@ -263,23 +395,73 @@ function createCognitiveLayer(config) {
|
|
|
263
395
|
};
|
|
264
396
|
const logConversation = async (payload) => {
|
|
265
397
|
try {
|
|
266
|
-
await fetch(`${baseUrl}/api/cognitive/log`, {
|
|
398
|
+
const response = await fetch(`${baseUrl}/api/cognitive/log`, {
|
|
267
399
|
method: "POST",
|
|
268
400
|
headers: authHeaders,
|
|
269
401
|
body: JSON.stringify(Object.assign(Object.assign({}, payload), { type: "conversation", timestamp: new Date().toISOString() })),
|
|
270
402
|
});
|
|
403
|
+
if (!response.ok) {
|
|
404
|
+
logger.warn("Log failed", { status: response.status });
|
|
405
|
+
return null;
|
|
406
|
+
}
|
|
407
|
+
const data = await response.json().catch(() => null);
|
|
408
|
+
return {
|
|
409
|
+
generatedTitle: typeof (data === null || data === void 0 ? void 0 : data.generatedTitle) === "string" ? data.generatedTitle : null,
|
|
410
|
+
};
|
|
271
411
|
}
|
|
272
412
|
catch (e) {
|
|
273
413
|
logger.error("Log failed", e);
|
|
414
|
+
return null;
|
|
274
415
|
}
|
|
275
416
|
};
|
|
276
|
-
const
|
|
277
|
-
|
|
278
|
-
fetch(`${baseUrl}/api/cognitive/
|
|
417
|
+
const postAgentRun = async (payload) => {
|
|
418
|
+
try {
|
|
419
|
+
const response = await fetch(`${baseUrl}/api/cognitive/agent-run`, {
|
|
279
420
|
method: "POST",
|
|
280
421
|
headers: authHeaders,
|
|
281
|
-
body: JSON.stringify(
|
|
282
|
-
})
|
|
422
|
+
body: JSON.stringify(payload),
|
|
423
|
+
});
|
|
424
|
+
if (!response.ok) {
|
|
425
|
+
logger.warn("Agent run request failed", { status: response.status });
|
|
426
|
+
return null;
|
|
427
|
+
}
|
|
428
|
+
return await response.json().catch(() => null);
|
|
429
|
+
}
|
|
430
|
+
catch (e) {
|
|
431
|
+
logger.error("Agent run request failed", e);
|
|
432
|
+
return null;
|
|
433
|
+
}
|
|
434
|
+
};
|
|
435
|
+
const postTraceEvents = async (payload) => {
|
|
436
|
+
try {
|
|
437
|
+
const response = await fetch(`${baseUrl}/api/cognitive/trace-events`, {
|
|
438
|
+
method: "POST",
|
|
439
|
+
headers: authHeaders,
|
|
440
|
+
body: JSON.stringify(payload),
|
|
441
|
+
});
|
|
442
|
+
if (!response.ok) {
|
|
443
|
+
logger.warn("Trace events request failed", { status: response.status });
|
|
444
|
+
return null;
|
|
445
|
+
}
|
|
446
|
+
return await response.json().catch(() => null);
|
|
447
|
+
}
|
|
448
|
+
catch (e) {
|
|
449
|
+
logger.error("Trace events request failed", e);
|
|
450
|
+
return null;
|
|
451
|
+
}
|
|
452
|
+
};
|
|
453
|
+
const appendLiveTraceEvents = async (payload) => {
|
|
454
|
+
await postTraceEvents({
|
|
455
|
+
traceDbId: payload.traceDbId,
|
|
456
|
+
traceId: payload.traceId,
|
|
457
|
+
sessionDbId: payload.sessionDbId,
|
|
458
|
+
events: payload.events,
|
|
459
|
+
});
|
|
460
|
+
};
|
|
461
|
+
const triggerProcessing = (userId, sessionId) => {
|
|
462
|
+
const run = () => {
|
|
463
|
+
memoryClient.triggerProcessing(userId, sessionId)
|
|
464
|
+
.catch((e) => logger.error("Process trigger failed", e));
|
|
283
465
|
};
|
|
284
466
|
if (processDelay > 0) {
|
|
285
467
|
setTimeout(run, processDelay);
|
|
@@ -304,6 +486,30 @@ function createCognitiveLayer(config) {
|
|
|
304
486
|
const updated = [{ role: "system", content: memoryPrompt }, ...incomingMessages];
|
|
305
487
|
return { nextParams, messages: updated, mode: "prepend-system" };
|
|
306
488
|
};
|
|
489
|
+
const getKognitiveProviderConfig = (params) => {
|
|
490
|
+
var _a, _b;
|
|
491
|
+
const providerOptionsKognitive = (_a = params === null || params === void 0 ? void 0 : params.providerOptions) === null || _a === void 0 ? void 0 : _a.kognitive;
|
|
492
|
+
if (providerOptionsKognitive && typeof providerOptionsKognitive === "object") {
|
|
493
|
+
return providerOptionsKognitive;
|
|
494
|
+
}
|
|
495
|
+
const providerMetadataKognitive = (_b = params === null || params === void 0 ? void 0 : params.providerMetadata) === null || _b === void 0 ? void 0 : _b.kognitive;
|
|
496
|
+
if (providerMetadataKognitive && typeof providerMetadataKognitive === "object") {
|
|
497
|
+
return providerMetadataKognitive;
|
|
498
|
+
}
|
|
499
|
+
return undefined;
|
|
500
|
+
};
|
|
501
|
+
const resolveRequestedRunScope = (params) => {
|
|
502
|
+
const direct = typeof (params === null || params === void 0 ? void 0 : params.runScope) === "string" ? params.runScope : undefined;
|
|
503
|
+
const kognitiveConfig = getKognitiveProviderConfig(params);
|
|
504
|
+
const providerMetadataScope = typeof (kognitiveConfig === null || kognitiveConfig === void 0 ? void 0 : kognitiveConfig.runScope) === "string"
|
|
505
|
+
? kognitiveConfig.runScope
|
|
506
|
+
: undefined;
|
|
507
|
+
return direct !== null && direct !== void 0 ? direct : providerMetadataScope;
|
|
508
|
+
};
|
|
509
|
+
const resolveAutomaticTitleConfig = (params) => {
|
|
510
|
+
var _a;
|
|
511
|
+
return (0, shared_1.normalizeAutomaticThreadTitleConfig)((_a = getKognitiveProviderConfig(params)) === null || _a === void 0 ? void 0 : _a.automaticTitle);
|
|
512
|
+
};
|
|
307
513
|
const buildMiddleware = (userId, projectId, sessionId, modelId) => ({
|
|
308
514
|
specificationVersion: 'v3',
|
|
309
515
|
async transformParams({ params }) {
|
|
@@ -323,67 +529,36 @@ function createCognitiveLayer(config) {
|
|
|
323
529
|
// 3) Fetch snapshot only if not cached
|
|
324
530
|
if (systemPromptToAdd === undefined) {
|
|
325
531
|
try {
|
|
326
|
-
const url = `${baseUrl}/api/cognitive/snapshot?userId=${userId}`;
|
|
327
532
|
logger.debug("Fetching snapshot from backend", {
|
|
328
533
|
userId,
|
|
329
534
|
sessionId,
|
|
330
|
-
url
|
|
535
|
+
url: `${baseUrl}/api/cognitive/snapshot?userId=${userId}`,
|
|
331
536
|
baseUrl,
|
|
332
537
|
apiKeyHint: maskSecret(clConfig.apiKey),
|
|
333
538
|
});
|
|
334
|
-
const
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
539
|
+
const snapshot = await memoryClient.getSnapshot(userId);
|
|
540
|
+
const systemBlock = (snapshot === null || snapshot === void 0 ? void 0 : snapshot.systemBlock) || "";
|
|
541
|
+
const userContextBlock = (snapshot === null || snapshot === void 0 ? void 0 : snapshot.userContextBlock) || "";
|
|
542
|
+
const topicIndexBlock = (snapshot === null || snapshot === void 0 ? void 0 : snapshot.topicIndexBlock) || "";
|
|
543
|
+
const topicContextBlock = (snapshot === null || snapshot === void 0 ? void 0 : snapshot.topicContextBlock) || "";
|
|
544
|
+
systemPromptToAdd = snapshot ? memoryClient.buildMemoryBlock(snapshot) : "";
|
|
545
|
+
sessionSnapshots.set(sessionKey, systemPromptToAdd);
|
|
546
|
+
logger.info("Snapshot fetched and cached", {
|
|
338
547
|
userId,
|
|
339
548
|
sessionId,
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
549
|
+
sessionKey,
|
|
550
|
+
systemLen: systemBlock.length,
|
|
551
|
+
userLen: userContextBlock.length,
|
|
552
|
+
topicIndexLen: topicIndexBlock.length,
|
|
553
|
+
topicContextLen: topicContextBlock.length,
|
|
554
|
+
});
|
|
555
|
+
logger.debug("Full snapshot data", {
|
|
556
|
+
systemBlock,
|
|
557
|
+
userContextBlock,
|
|
558
|
+
topicIndexBlock,
|
|
559
|
+
topicContextBlock,
|
|
560
|
+
rawData: snapshot,
|
|
343
561
|
});
|
|
344
|
-
if (res.ok) {
|
|
345
|
-
const data = await res.json();
|
|
346
|
-
const systemBlock = data.systemBlock || "";
|
|
347
|
-
const userContextBlock = data.userContextBlock || "";
|
|
348
|
-
systemPromptToAdd =
|
|
349
|
-
systemBlock !== "" || userContextBlock !== ""
|
|
350
|
-
? `
|
|
351
|
-
<MemoryContext>
|
|
352
|
-
Use the following memory to stay consistent. Prefer UserContext facts for answers; AgentHeuristics guide style, safety, and priorities.
|
|
353
|
-
${systemBlock || "None"}
|
|
354
|
-
${userContextBlock || "None"}
|
|
355
|
-
</MemoryContext>
|
|
356
|
-
`.trim()
|
|
357
|
-
: "";
|
|
358
|
-
// Cache the snapshot for this session
|
|
359
|
-
sessionSnapshots.set(sessionKey, systemPromptToAdd);
|
|
360
|
-
logger.info("Snapshot fetched and cached", {
|
|
361
|
-
userId,
|
|
362
|
-
sessionId,
|
|
363
|
-
sessionKey,
|
|
364
|
-
systemLen: systemBlock.length,
|
|
365
|
-
userLen: userContextBlock.length,
|
|
366
|
-
});
|
|
367
|
-
// At debug level, log the full snapshot data
|
|
368
|
-
logger.debug("Full snapshot data", {
|
|
369
|
-
systemBlock,
|
|
370
|
-
userContextBlock,
|
|
371
|
-
rawData: data,
|
|
372
|
-
});
|
|
373
|
-
}
|
|
374
|
-
else {
|
|
375
|
-
const body = await res.text();
|
|
376
|
-
logger.warn("Snapshot fetch failed", { status: res.status });
|
|
377
|
-
logger.debug("Snapshot response body preview", {
|
|
378
|
-
userId,
|
|
379
|
-
projectId,
|
|
380
|
-
sessionId,
|
|
381
|
-
status: res.status,
|
|
382
|
-
bodyPreview: previewText(body),
|
|
383
|
-
});
|
|
384
|
-
systemPromptToAdd = "";
|
|
385
|
-
sessionSnapshots.set(sessionKey, systemPromptToAdd);
|
|
386
|
-
}
|
|
387
562
|
}
|
|
388
563
|
catch (e) {
|
|
389
564
|
logger.warn("Failed to fetch snapshot", e);
|
|
@@ -408,20 +583,96 @@ ${userContextBlock || "None"}
|
|
|
408
583
|
async wrapGenerate({ doGenerate, params }) {
|
|
409
584
|
var _a, _b, _c;
|
|
410
585
|
const startedAt = new Date();
|
|
586
|
+
const requestedRunScope = resolveRequestedRunScope(params);
|
|
587
|
+
const remoteAgentName = (_a = clConfig.appId) !== null && _a !== void 0 ? _a : modelId;
|
|
588
|
+
const turnIndex = reserveTurnIndex(remoteAgentName, userId, sessionId, requestedRunScope);
|
|
589
|
+
const remoteExecution = (0, shared_1.createRemoteExecutionContext)({
|
|
590
|
+
agentName: remoteAgentName,
|
|
591
|
+
sessionId,
|
|
592
|
+
requestedRunScope,
|
|
593
|
+
runId: (_b = getKognitiveProviderConfig(params)) === null || _b === void 0 ? void 0 : _b.agentRunId,
|
|
594
|
+
turnIndex,
|
|
595
|
+
});
|
|
596
|
+
const traceId = remoteExecution.traceId;
|
|
597
|
+
let liveTraceDbId;
|
|
598
|
+
if (isValidId(userId) && isValidId(sessionId)) {
|
|
599
|
+
const messagesInput = params.prompt || params.messages || [];
|
|
600
|
+
const { requestPreview } = (0, shared_1.buildRemoteTracePreviews)(messagesInput);
|
|
601
|
+
await postAgentRun((0, shared_1.buildRemoteRunPayload)({
|
|
602
|
+
execution: remoteExecution,
|
|
603
|
+
userId,
|
|
604
|
+
sessionId,
|
|
605
|
+
modelId,
|
|
606
|
+
status: "running",
|
|
607
|
+
inputPreview: requestPreview,
|
|
608
|
+
startedAt: startedAt.toISOString(),
|
|
609
|
+
metadata: {
|
|
610
|
+
appId: clConfig.appId,
|
|
611
|
+
},
|
|
612
|
+
sessionMetadata: {
|
|
613
|
+
kind: "chat",
|
|
614
|
+
agentName: remoteExecution.agentName,
|
|
615
|
+
},
|
|
616
|
+
}));
|
|
617
|
+
}
|
|
618
|
+
if (isValidId(userId) && isValidId(sessionId) && isValidId(projectId)) {
|
|
619
|
+
const messagesInput = params.prompt || params.messages || [];
|
|
620
|
+
const { requestPreview } = (0, shared_1.buildRemoteTracePreviews)(messagesInput);
|
|
621
|
+
const traceResponse = await postTraceEvents((0, shared_1.buildRemoteTraceStartPayload)({
|
|
622
|
+
execution: remoteExecution,
|
|
623
|
+
userId,
|
|
624
|
+
projectId,
|
|
625
|
+
sessionId,
|
|
626
|
+
requestPreview,
|
|
627
|
+
modelId,
|
|
628
|
+
metadata: {
|
|
629
|
+
appId: clConfig.appId,
|
|
630
|
+
},
|
|
631
|
+
startedAt: startedAt.toISOString(),
|
|
632
|
+
}));
|
|
633
|
+
liveTraceDbId = typeof (traceResponse === null || traceResponse === void 0 ? void 0 : traceResponse.traceDbId) === "string" ? traceResponse.traceDbId : undefined;
|
|
634
|
+
}
|
|
411
635
|
let result;
|
|
412
636
|
try {
|
|
413
637
|
result = await doGenerate();
|
|
414
638
|
}
|
|
415
639
|
catch (err) {
|
|
640
|
+
const errorMessage = err instanceof Error ? err.message : String(err);
|
|
641
|
+
if (liveTraceDbId) {
|
|
642
|
+
await postTraceEvents((0, shared_1.buildRemoteTraceFinishPayload)({
|
|
643
|
+
execution: remoteExecution,
|
|
644
|
+
traceDbId: liveTraceDbId,
|
|
645
|
+
state: "error",
|
|
646
|
+
responsePreview: errorMessage.slice(0, 240),
|
|
647
|
+
durationMs: Date.now() - startedAt.getTime(),
|
|
648
|
+
errorMessage,
|
|
649
|
+
}));
|
|
650
|
+
}
|
|
651
|
+
if (isValidId(userId) && isValidId(sessionId)) {
|
|
652
|
+
await postAgentRun((0, shared_1.buildRemoteRunPayload)({
|
|
653
|
+
execution: remoteExecution,
|
|
654
|
+
userId,
|
|
655
|
+
sessionId,
|
|
656
|
+
modelId,
|
|
657
|
+
status: "failed",
|
|
658
|
+
errorMessage,
|
|
659
|
+
durationMs: Date.now() - startedAt.getTime(),
|
|
660
|
+
startedAt: startedAt.toISOString(),
|
|
661
|
+
completedAt: new Date().toISOString(),
|
|
662
|
+
metadata: {
|
|
663
|
+
appId: clConfig.appId,
|
|
664
|
+
},
|
|
665
|
+
}));
|
|
666
|
+
}
|
|
416
667
|
logger.error("doGenerate failed", err);
|
|
417
|
-
logger.error("doGenerate params.prompt", JSON.stringify((
|
|
668
|
+
logger.error("doGenerate params.prompt", JSON.stringify((_c = params.prompt) === null || _c === void 0 ? void 0 : _c.map((m) => ({ role: m.role, contentType: typeof m.content, contentLength: Array.isArray(m.content) ? m.content.length : undefined })), null, 2));
|
|
418
669
|
throw err;
|
|
419
670
|
}
|
|
420
671
|
if (isValidId(userId) && isValidId(sessionId)) {
|
|
421
672
|
const endedAt = new Date();
|
|
422
673
|
const sessionKey = getSessionKey(userId, sessionId);
|
|
423
674
|
const promptMeta = sessionPromptMetadata.get(sessionKey);
|
|
424
|
-
const
|
|
675
|
+
const automaticTitle = resolveAutomaticTitleConfig(params);
|
|
425
676
|
const messagesInput = params.prompt || params.messages || [];
|
|
426
677
|
// Build assistant message from result.content (V2/V3 GenerateResult)
|
|
427
678
|
const resultContent = Array.isArray(result === null || result === void 0 ? void 0 : result.content) ? result.content : [];
|
|
@@ -451,10 +702,31 @@ ${userContextBlock || "None"}
|
|
|
451
702
|
? [{ role: "assistant", content: assistantParts }]
|
|
452
703
|
: [];
|
|
453
704
|
const finalMessages = [...messagesInput, ...assistantMessage];
|
|
454
|
-
const { requestPreview, responsePreview } =
|
|
705
|
+
const { requestPreview, responsePreview } = (0, shared_1.buildRemoteTracePreviews)(finalMessages);
|
|
455
706
|
const spans = buildTraceSpansFromMessages(finalMessages);
|
|
456
707
|
const toolDefs = extractToolDefinitions(params);
|
|
457
|
-
|
|
708
|
+
const usage = (0, shared_1.normalizeRemoteUsage)(result.usage);
|
|
709
|
+
await postAgentRun((0, shared_1.buildRemoteRunPayload)({
|
|
710
|
+
execution: remoteExecution,
|
|
711
|
+
userId,
|
|
712
|
+
sessionId,
|
|
713
|
+
modelId,
|
|
714
|
+
status: "completed",
|
|
715
|
+
inputPreview: requestPreview,
|
|
716
|
+
outputPreview: responsePreview,
|
|
717
|
+
inputTokens: usage.inputTokens,
|
|
718
|
+
outputTokens: usage.outputTokens,
|
|
719
|
+
cachedInputTokens: usage.cachedInputTokens,
|
|
720
|
+
durationMs: endedAt.getTime() - startedAt.getTime(),
|
|
721
|
+
startedAt: startedAt.toISOString(),
|
|
722
|
+
completedAt: endedAt.toISOString(),
|
|
723
|
+
metadata: Object.assign(Object.assign(Object.assign({ appId: clConfig.appId }, ((promptMeta === null || promptMeta === void 0 ? void 0 : promptMeta.tag) && { promptTag: promptMeta.tag })), ((promptMeta === null || promptMeta === void 0 ? void 0 : promptMeta.abTestId) && { abTestId: promptMeta.abTestId })), ((promptMeta === null || promptMeta === void 0 ? void 0 : promptMeta.variant) && { variant: promptMeta.variant })),
|
|
724
|
+
sessionMetadata: {
|
|
725
|
+
kind: "chat",
|
|
726
|
+
agentName: remoteExecution.agentName,
|
|
727
|
+
},
|
|
728
|
+
}));
|
|
729
|
+
const logResult = await logConversation((0, shared_1.buildRemoteLogPayload)(Object.assign(Object.assign(Object.assign({ execution: remoteExecution, userId,
|
|
458
730
|
sessionId, messages: finalMessages, modelId, usage: result.usage }, (promptMeta && {
|
|
459
731
|
promptSlug: promptMeta.promptSlug,
|
|
460
732
|
promptVersion: promptMeta.promptVersion,
|
|
@@ -462,21 +734,107 @@ ${userContextBlock || "None"}
|
|
|
462
734
|
tag: promptMeta.tag,
|
|
463
735
|
abTestId: promptMeta.abTestId,
|
|
464
736
|
variant: promptMeta.variant,
|
|
465
|
-
})), (toolDefs && { tools: toolDefs })),
|
|
466
|
-
responsePreview, state: "completed", startedAt: startedAt.toISOString(), endedAt: endedAt.toISOString(), durationMs: endedAt.getTime() - startedAt.getTime(), metadata: Object.assign(Object.assign(Object.assign({ appId: clConfig.appId }, ((promptMeta === null || promptMeta === void 0 ? void 0 : promptMeta.tag) && { promptTag: promptMeta.tag })), ((promptMeta === null || promptMeta === void 0 ? void 0 : promptMeta.abTestId) && { abTestId: promptMeta.abTestId })), ((promptMeta === null || promptMeta === void 0 ? void 0 : promptMeta.variant) && { variant: promptMeta.variant })), spans
|
|
737
|
+
})), (toolDefs && { tools: toolDefs })), { requestPreview,
|
|
738
|
+
responsePreview, state: "completed", startedAt: startedAt.toISOString(), endedAt: endedAt.toISOString(), durationMs: endedAt.getTime() - startedAt.getTime(), metadata: Object.assign(Object.assign(Object.assign({ appId: clConfig.appId }, ((promptMeta === null || promptMeta === void 0 ? void 0 : promptMeta.tag) && { promptTag: promptMeta.tag })), ((promptMeta === null || promptMeta === void 0 ? void 0 : promptMeta.abTestId) && { abTestId: promptMeta.abTestId })), ((promptMeta === null || promptMeta === void 0 ? void 0 : promptMeta.variant) && { variant: promptMeta.variant })), spans,
|
|
739
|
+
automaticTitle })));
|
|
740
|
+
if (logResult) {
|
|
741
|
+
triggerProcessing(userId, sessionId);
|
|
742
|
+
}
|
|
743
|
+
await postTraceEvents((0, shared_1.buildRemoteTraceFinishPayload)({
|
|
744
|
+
execution: remoteExecution,
|
|
745
|
+
traceDbId: liveTraceDbId,
|
|
746
|
+
state: "completed",
|
|
747
|
+
responsePreview,
|
|
748
|
+
durationMs: endedAt.getTime() - startedAt.getTime(),
|
|
749
|
+
usage: result.usage,
|
|
750
|
+
}));
|
|
467
751
|
}
|
|
468
752
|
return result;
|
|
469
753
|
},
|
|
470
754
|
async wrapStream({ doStream, params }) {
|
|
471
755
|
var _a, _b, _c;
|
|
472
756
|
const startedAt = new Date();
|
|
473
|
-
const
|
|
757
|
+
const requestedRunScope = resolveRequestedRunScope(params);
|
|
758
|
+
const remoteAgentName = (_a = clConfig.appId) !== null && _a !== void 0 ? _a : modelId;
|
|
759
|
+
const turnIndex = reserveTurnIndex(remoteAgentName, userId, sessionId, requestedRunScope);
|
|
760
|
+
const remoteExecution = (0, shared_1.createRemoteExecutionContext)({
|
|
761
|
+
agentName: remoteAgentName,
|
|
762
|
+
sessionId,
|
|
763
|
+
requestedRunScope,
|
|
764
|
+
runId: (_b = getKognitiveProviderConfig(params)) === null || _b === void 0 ? void 0 : _b.agentRunId,
|
|
765
|
+
turnIndex,
|
|
766
|
+
});
|
|
767
|
+
const traceId = remoteExecution.traceId;
|
|
768
|
+
let liveTraceDbId;
|
|
769
|
+
if (isValidId(userId) && isValidId(sessionId)) {
|
|
770
|
+
const messagesInput = params.prompt || params.messages || [];
|
|
771
|
+
const { requestPreview } = (0, shared_1.buildRemoteTracePreviews)(messagesInput);
|
|
772
|
+
await postAgentRun((0, shared_1.buildRemoteRunPayload)({
|
|
773
|
+
execution: remoteExecution,
|
|
774
|
+
userId,
|
|
775
|
+
sessionId,
|
|
776
|
+
modelId,
|
|
777
|
+
status: "running",
|
|
778
|
+
inputPreview: requestPreview,
|
|
779
|
+
startedAt: startedAt.toISOString(),
|
|
780
|
+
metadata: {
|
|
781
|
+
appId: clConfig.appId,
|
|
782
|
+
},
|
|
783
|
+
sessionMetadata: {
|
|
784
|
+
kind: "chat",
|
|
785
|
+
agentName: remoteExecution.agentName,
|
|
786
|
+
},
|
|
787
|
+
}));
|
|
788
|
+
}
|
|
789
|
+
if (isValidId(userId) && isValidId(sessionId) && isValidId(projectId)) {
|
|
790
|
+
const messagesInput = params.prompt || params.messages || [];
|
|
791
|
+
const { requestPreview } = (0, shared_1.buildRemoteTracePreviews)(messagesInput);
|
|
792
|
+
const traceResponse = await postTraceEvents((0, shared_1.buildRemoteTraceStartPayload)({
|
|
793
|
+
execution: remoteExecution,
|
|
794
|
+
userId,
|
|
795
|
+
projectId,
|
|
796
|
+
sessionId,
|
|
797
|
+
requestPreview,
|
|
798
|
+
modelId,
|
|
799
|
+
metadata: {
|
|
800
|
+
appId: clConfig.appId,
|
|
801
|
+
},
|
|
802
|
+
startedAt: startedAt.toISOString(),
|
|
803
|
+
}));
|
|
804
|
+
liveTraceDbId = typeof (traceResponse === null || traceResponse === void 0 ? void 0 : traceResponse.traceDbId) === "string" ? traceResponse.traceDbId : undefined;
|
|
805
|
+
}
|
|
474
806
|
let result;
|
|
475
807
|
try {
|
|
476
808
|
logger.debug("Starting doStream with params", JSON.stringify(params, null, 2));
|
|
477
809
|
result = await doStream();
|
|
478
810
|
}
|
|
479
811
|
catch (err) {
|
|
812
|
+
if (liveTraceDbId) {
|
|
813
|
+
await postTraceEvents((0, shared_1.buildRemoteTraceFinishPayload)({
|
|
814
|
+
execution: remoteExecution,
|
|
815
|
+
traceDbId: liveTraceDbId,
|
|
816
|
+
state: "error",
|
|
817
|
+
responsePreview: err instanceof Error ? err.message.slice(0, 240) : "Stream failed",
|
|
818
|
+
durationMs: Date.now() - startedAt.getTime(),
|
|
819
|
+
errorMessage: err instanceof Error ? err.message : String(err),
|
|
820
|
+
}));
|
|
821
|
+
}
|
|
822
|
+
if (isValidId(userId) && isValidId(sessionId)) {
|
|
823
|
+
await postAgentRun((0, shared_1.buildRemoteRunPayload)({
|
|
824
|
+
execution: remoteExecution,
|
|
825
|
+
userId,
|
|
826
|
+
sessionId,
|
|
827
|
+
modelId,
|
|
828
|
+
status: "failed",
|
|
829
|
+
errorMessage: err instanceof Error ? err.message : String(err),
|
|
830
|
+
durationMs: Date.now() - startedAt.getTime(),
|
|
831
|
+
startedAt: startedAt.toISOString(),
|
|
832
|
+
completedAt: new Date().toISOString(),
|
|
833
|
+
metadata: {
|
|
834
|
+
appId: clConfig.appId,
|
|
835
|
+
},
|
|
836
|
+
}));
|
|
837
|
+
}
|
|
480
838
|
console.log(err.cause);
|
|
481
839
|
console.log(err.stack);
|
|
482
840
|
logger.error("doStream failed", err);
|
|
@@ -485,7 +843,7 @@ ${userContextBlock || "None"}
|
|
|
485
843
|
if (isValidId(userId) && isValidId(sessionId)) {
|
|
486
844
|
const sessionKey = getSessionKey(userId, sessionId);
|
|
487
845
|
const promptMeta = sessionPromptMetadata.get(sessionKey);
|
|
488
|
-
const
|
|
846
|
+
const automaticTitle = resolveAutomaticTitleConfig(params);
|
|
489
847
|
const messagesInput = params.prompt || params.messages || [];
|
|
490
848
|
const resultMessages = (_c = result === null || result === void 0 ? void 0 : result.response) === null || _c === void 0 ? void 0 : _c.messages;
|
|
491
849
|
const finalMessages = Array.isArray(resultMessages) && resultMessages.length > 0
|
|
@@ -493,7 +851,10 @@ ${userContextBlock || "None"}
|
|
|
493
851
|
: messagesInput;
|
|
494
852
|
let streamUsage;
|
|
495
853
|
let accumulatedText = '';
|
|
854
|
+
let pendingProgressDelta = '';
|
|
855
|
+
let lastProgressAt = Date.now();
|
|
496
856
|
const toolCallInputs = new Map();
|
|
857
|
+
const startedToolCalls = new Set();
|
|
497
858
|
const completedToolCalls = [];
|
|
498
859
|
const completedToolResults = [];
|
|
499
860
|
const originalStream = result.stream;
|
|
@@ -501,6 +862,23 @@ ${userContextBlock || "None"}
|
|
|
501
862
|
transform(chunk, controller) {
|
|
502
863
|
if (chunk.type === 'text-delta') {
|
|
503
864
|
accumulatedText += chunk.delta;
|
|
865
|
+
pendingProgressDelta += chunk.delta;
|
|
866
|
+
if (liveTraceDbId && pendingProgressDelta && (pendingProgressDelta.length >= 80 || Date.now() - lastProgressAt >= 250)) {
|
|
867
|
+
void appendLiveTraceEvents({
|
|
868
|
+
traceDbId: liveTraceDbId,
|
|
869
|
+
traceId,
|
|
870
|
+
events: [{
|
|
871
|
+
eventType: "assistant.progress",
|
|
872
|
+
status: "active",
|
|
873
|
+
payload: {
|
|
874
|
+
text: pendingProgressDelta,
|
|
875
|
+
preview: previewText(accumulatedText),
|
|
876
|
+
},
|
|
877
|
+
}],
|
|
878
|
+
});
|
|
879
|
+
pendingProgressDelta = '';
|
|
880
|
+
lastProgressAt = Date.now();
|
|
881
|
+
}
|
|
504
882
|
}
|
|
505
883
|
if (chunk.type === 'finish' && chunk.usage) {
|
|
506
884
|
streamUsage = chunk.usage;
|
|
@@ -508,6 +886,23 @@ ${userContextBlock || "None"}
|
|
|
508
886
|
// Capture tool-call stream chunks (V2/V3 shared types)
|
|
509
887
|
if (chunk.type === 'tool-input-start') {
|
|
510
888
|
toolCallInputs.set(chunk.id, { toolName: chunk.toolName, chunks: [] });
|
|
889
|
+
if (liveTraceDbId && !startedToolCalls.has(chunk.id)) {
|
|
890
|
+
startedToolCalls.add(chunk.id);
|
|
891
|
+
void appendLiveTraceEvents({
|
|
892
|
+
traceDbId: liveTraceDbId,
|
|
893
|
+
traceId,
|
|
894
|
+
events: [{
|
|
895
|
+
eventType: "tool.started",
|
|
896
|
+
spanKey: chunk.id,
|
|
897
|
+
status: "active",
|
|
898
|
+
payload: {
|
|
899
|
+
toolCallId: chunk.id,
|
|
900
|
+
toolName: chunk.toolName,
|
|
901
|
+
inputPreview: "",
|
|
902
|
+
},
|
|
903
|
+
}],
|
|
904
|
+
});
|
|
905
|
+
}
|
|
511
906
|
}
|
|
512
907
|
if (chunk.type === 'tool-input-delta') {
|
|
513
908
|
const entry = toolCallInputs.get(chunk.id);
|
|
@@ -521,6 +916,29 @@ ${userContextBlock || "None"}
|
|
|
521
916
|
toolName: chunk.toolName,
|
|
522
917
|
input: chunk.input,
|
|
523
918
|
});
|
|
919
|
+
if (!toolCallInputs.has(chunk.toolCallId)) {
|
|
920
|
+
toolCallInputs.set(chunk.toolCallId, {
|
|
921
|
+
toolName: chunk.toolName,
|
|
922
|
+
chunks: typeof chunk.input === "string" ? [chunk.input] : [],
|
|
923
|
+
});
|
|
924
|
+
}
|
|
925
|
+
if (liveTraceDbId && !startedToolCalls.has(chunk.toolCallId)) {
|
|
926
|
+
startedToolCalls.add(chunk.toolCallId);
|
|
927
|
+
void appendLiveTraceEvents({
|
|
928
|
+
traceDbId: liveTraceDbId,
|
|
929
|
+
traceId,
|
|
930
|
+
events: [{
|
|
931
|
+
eventType: "tool.started",
|
|
932
|
+
spanKey: chunk.toolCallId,
|
|
933
|
+
status: "active",
|
|
934
|
+
payload: {
|
|
935
|
+
toolCallId: chunk.toolCallId,
|
|
936
|
+
toolName: chunk.toolName,
|
|
937
|
+
inputPreview: typeof chunk.input === "string" ? previewText(chunk.input) : "",
|
|
938
|
+
},
|
|
939
|
+
}],
|
|
940
|
+
});
|
|
941
|
+
}
|
|
524
942
|
}
|
|
525
943
|
if (chunk.type === 'tool-result') {
|
|
526
944
|
completedToolResults.push({
|
|
@@ -529,11 +947,41 @@ ${userContextBlock || "None"}
|
|
|
529
947
|
toolName: chunk.toolName,
|
|
530
948
|
result: chunk.result,
|
|
531
949
|
});
|
|
950
|
+
if (liveTraceDbId) {
|
|
951
|
+
void appendLiveTraceEvents({
|
|
952
|
+
traceDbId: liveTraceDbId,
|
|
953
|
+
traceId,
|
|
954
|
+
events: [{
|
|
955
|
+
eventType: "tool.completed",
|
|
956
|
+
spanKey: chunk.toolCallId,
|
|
957
|
+
status: "completed",
|
|
958
|
+
payload: {
|
|
959
|
+
toolCallId: chunk.toolCallId,
|
|
960
|
+
toolName: chunk.toolName,
|
|
961
|
+
outputPreview: previewText(JSON.stringify(chunk.result)),
|
|
962
|
+
},
|
|
963
|
+
}],
|
|
964
|
+
});
|
|
965
|
+
}
|
|
532
966
|
}
|
|
533
967
|
controller.enqueue(chunk);
|
|
534
968
|
},
|
|
535
969
|
async flush() {
|
|
536
970
|
const endedAt = new Date();
|
|
971
|
+
if (liveTraceDbId && pendingProgressDelta) {
|
|
972
|
+
await appendLiveTraceEvents({
|
|
973
|
+
traceDbId: liveTraceDbId,
|
|
974
|
+
traceId,
|
|
975
|
+
events: [{
|
|
976
|
+
eventType: "assistant.progress",
|
|
977
|
+
status: "active",
|
|
978
|
+
payload: {
|
|
979
|
+
text: pendingProgressDelta,
|
|
980
|
+
preview: previewText(accumulatedText),
|
|
981
|
+
},
|
|
982
|
+
}],
|
|
983
|
+
});
|
|
984
|
+
}
|
|
537
985
|
// Finalize any tool calls from incremental input chunks
|
|
538
986
|
for (const [id, entry] of toolCallInputs) {
|
|
539
987
|
// Only add if not already captured via a tool-call chunk
|
|
@@ -557,12 +1005,31 @@ ${userContextBlock || "None"}
|
|
|
557
1005
|
if (completedToolResults.length > 0) {
|
|
558
1006
|
allMessages.push({ role: "tool", content: completedToolResults });
|
|
559
1007
|
}
|
|
560
|
-
const { requestPreview, responsePreview } =
|
|
1008
|
+
const { requestPreview, responsePreview } = (0, shared_1.buildRemoteTracePreviews)(allMessages);
|
|
561
1009
|
const spans = buildTraceSpansFromMessages(allMessages);
|
|
562
1010
|
const toolDefs = extractToolDefinitions(params);
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
1011
|
+
const usage = (0, shared_1.normalizeRemoteUsage)(streamUsage);
|
|
1012
|
+
await postAgentRun((0, shared_1.buildRemoteRunPayload)({
|
|
1013
|
+
execution: remoteExecution,
|
|
1014
|
+
userId,
|
|
1015
|
+
sessionId,
|
|
1016
|
+
modelId,
|
|
1017
|
+
status: "completed",
|
|
1018
|
+
inputPreview: requestPreview,
|
|
1019
|
+
outputPreview: responsePreview,
|
|
1020
|
+
inputTokens: usage.inputTokens,
|
|
1021
|
+
outputTokens: usage.outputTokens,
|
|
1022
|
+
cachedInputTokens: usage.cachedInputTokens,
|
|
1023
|
+
durationMs: endedAt.getTime() - startedAt.getTime(),
|
|
1024
|
+
startedAt: startedAt.toISOString(),
|
|
1025
|
+
completedAt: endedAt.toISOString(),
|
|
1026
|
+
metadata: Object.assign(Object.assign(Object.assign({ appId: clConfig.appId }, ((promptMeta === null || promptMeta === void 0 ? void 0 : promptMeta.tag) && { promptTag: promptMeta.tag })), ((promptMeta === null || promptMeta === void 0 ? void 0 : promptMeta.abTestId) && { abTestId: promptMeta.abTestId })), ((promptMeta === null || promptMeta === void 0 ? void 0 : promptMeta.variant) && { variant: promptMeta.variant })),
|
|
1027
|
+
sessionMetadata: {
|
|
1028
|
+
kind: "chat",
|
|
1029
|
+
agentName: remoteExecution.agentName,
|
|
1030
|
+
},
|
|
1031
|
+
}));
|
|
1032
|
+
const logResult = await logConversation((0, shared_1.buildRemoteLogPayload)(Object.assign(Object.assign(Object.assign({ execution: remoteExecution, userId,
|
|
566
1033
|
sessionId, messages: allMessages, modelId, usage: streamUsage }, (promptMeta && {
|
|
567
1034
|
promptSlug: promptMeta.promptSlug,
|
|
568
1035
|
promptVersion: promptMeta.promptVersion,
|
|
@@ -570,10 +1037,30 @@ ${userContextBlock || "None"}
|
|
|
570
1037
|
tag: promptMeta.tag,
|
|
571
1038
|
abTestId: promptMeta.abTestId,
|
|
572
1039
|
variant: promptMeta.variant,
|
|
573
|
-
})), (toolDefs && { tools: toolDefs })),
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
1040
|
+
})), (toolDefs && { tools: toolDefs })), { requestPreview,
|
|
1041
|
+
responsePreview, state: "completed", startedAt: startedAt.toISOString(), endedAt: endedAt.toISOString(), durationMs: endedAt.getTime() - startedAt.getTime(), metadata: Object.assign(Object.assign(Object.assign({ appId: clConfig.appId }, ((promptMeta === null || promptMeta === void 0 ? void 0 : promptMeta.tag) && { promptTag: promptMeta.tag })), ((promptMeta === null || promptMeta === void 0 ? void 0 : promptMeta.abTestId) && { abTestId: promptMeta.abTestId })), ((promptMeta === null || promptMeta === void 0 ? void 0 : promptMeta.variant) && { variant: promptMeta.variant })), spans,
|
|
1042
|
+
automaticTitle })));
|
|
1043
|
+
if (logResult) {
|
|
1044
|
+
triggerProcessing(userId, sessionId);
|
|
1045
|
+
}
|
|
1046
|
+
if (logResult === null || logResult === void 0 ? void 0 : logResult.generatedTitle) {
|
|
1047
|
+
const currentProviderMetadata = result.providerMetadata && typeof result.providerMetadata === "object"
|
|
1048
|
+
? result.providerMetadata
|
|
1049
|
+
: {};
|
|
1050
|
+
const currentKognitiveMetadata = currentProviderMetadata.kognitive
|
|
1051
|
+
&& typeof currentProviderMetadata.kognitive === "object"
|
|
1052
|
+
? currentProviderMetadata.kognitive
|
|
1053
|
+
: {};
|
|
1054
|
+
result.providerMetadata = Object.assign(Object.assign({}, currentProviderMetadata), { kognitive: Object.assign(Object.assign({}, currentKognitiveMetadata), { generatedTitle: logResult.generatedTitle }) });
|
|
1055
|
+
}
|
|
1056
|
+
await postTraceEvents((0, shared_1.buildRemoteTraceFinishPayload)({
|
|
1057
|
+
execution: remoteExecution,
|
|
1058
|
+
traceDbId: liveTraceDbId,
|
|
1059
|
+
state: "completed",
|
|
1060
|
+
responsePreview,
|
|
1061
|
+
durationMs: endedAt.getTime() - startedAt.getTime(),
|
|
1062
|
+
usage: streamUsage,
|
|
1063
|
+
}));
|
|
577
1064
|
}
|
|
578
1065
|
});
|
|
579
1066
|
result.stream = originalStream.pipeThrough(transformStream);
|
|
@@ -632,23 +1119,29 @@ ${userContextBlock || "None"}
|
|
|
632
1119
|
return wrappedModel;
|
|
633
1120
|
};
|
|
634
1121
|
const clStreamText = async (options) => {
|
|
635
|
-
const { prompt: promptConfig } = options, rest = __rest(options, ["prompt"]);
|
|
1122
|
+
const { prompt: promptConfig, kognitive } = options, rest = __rest(options, ["prompt", "kognitive"]);
|
|
636
1123
|
const session = options.model[SESSION_KEY];
|
|
637
1124
|
// Resolve and interpolate prompt (graceful fallback on failure)
|
|
638
1125
|
let resolved = null;
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
1126
|
+
if (promptConfig === null || promptConfig === void 0 ? void 0 : promptConfig.slug) {
|
|
1127
|
+
try {
|
|
1128
|
+
resolved = await resolvePrompt(promptConfig.slug, {
|
|
1129
|
+
userId: session === null || session === void 0 ? void 0 : session.userId,
|
|
1130
|
+
tag: promptConfig.tag,
|
|
1131
|
+
});
|
|
1132
|
+
}
|
|
1133
|
+
catch (err) {
|
|
1134
|
+
if ((0, shared_1.isModerationError)(err)) {
|
|
1135
|
+
throw err;
|
|
1136
|
+
}
|
|
1137
|
+
logger.warn(`Failed to resolve prompt "${promptConfig.slug}", streaming without system prompt.`, err);
|
|
1138
|
+
}
|
|
647
1139
|
}
|
|
648
|
-
let system;
|
|
1140
|
+
let system = typeof rest.system === "string" ? rest.system : undefined;
|
|
649
1141
|
if (resolved) {
|
|
650
|
-
|
|
651
|
-
|
|
1142
|
+
const resolvedPromptConfig = promptConfig;
|
|
1143
|
+
system = resolvedPromptConfig.variables
|
|
1144
|
+
? (0, template_2.renderTemplate)(resolved.content, resolvedPromptConfig.variables)
|
|
652
1145
|
: resolved.content;
|
|
653
1146
|
// Store prompt metadata for the session (read by middleware during logging)
|
|
654
1147
|
if (session === null || session === void 0 ? void 0 : session.sessionId) {
|
|
@@ -663,37 +1156,44 @@ ${userContextBlock || "None"}
|
|
|
663
1156
|
});
|
|
664
1157
|
}
|
|
665
1158
|
logger.info("cl.streamText called", {
|
|
666
|
-
slug:
|
|
1159
|
+
slug: resolvedPromptConfig.slug,
|
|
667
1160
|
version: resolved.version,
|
|
668
1161
|
systemLength: system.length,
|
|
669
1162
|
});
|
|
670
1163
|
}
|
|
671
|
-
else {
|
|
1164
|
+
else if (promptConfig === null || promptConfig === void 0 ? void 0 : promptConfig.slug) {
|
|
672
1165
|
logger.info("cl.streamText called without resolved prompt", {
|
|
673
1166
|
slug: promptConfig.slug,
|
|
674
1167
|
});
|
|
675
1168
|
}
|
|
676
1169
|
const model = resolveModel(options.model, resolved === null || resolved === void 0 ? void 0 : resolved.gatewaySlug);
|
|
677
|
-
|
|
1170
|
+
const nextParams = withAutoInjectedTools(Object.assign(Object.assign(Object.assign({}, rest), { model }), (system && { system })), session, baseUrl, clConfig.apiKey, kognitive);
|
|
1171
|
+
return (0, ai_1.streamText)(nextParams);
|
|
678
1172
|
};
|
|
679
1173
|
const clGenerateText = async (options) => {
|
|
680
|
-
const { prompt: promptConfig } = options, rest = __rest(options, ["prompt"]);
|
|
1174
|
+
const { prompt: promptConfig, kognitive } = options, rest = __rest(options, ["prompt", "kognitive"]);
|
|
681
1175
|
const session = options.model[SESSION_KEY];
|
|
682
1176
|
// Resolve and interpolate prompt (graceful fallback on failure)
|
|
683
1177
|
let resolved = null;
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
1178
|
+
if (promptConfig === null || promptConfig === void 0 ? void 0 : promptConfig.slug) {
|
|
1179
|
+
try {
|
|
1180
|
+
resolved = await resolvePrompt(promptConfig.slug, {
|
|
1181
|
+
userId: session === null || session === void 0 ? void 0 : session.userId,
|
|
1182
|
+
tag: promptConfig.tag,
|
|
1183
|
+
});
|
|
1184
|
+
}
|
|
1185
|
+
catch (err) {
|
|
1186
|
+
if ((0, shared_1.isModerationError)(err)) {
|
|
1187
|
+
throw err;
|
|
1188
|
+
}
|
|
1189
|
+
logger.warn(`Failed to resolve prompt "${promptConfig.slug}", generating without system prompt.`, err);
|
|
1190
|
+
}
|
|
692
1191
|
}
|
|
693
|
-
let system;
|
|
1192
|
+
let system = typeof rest.system === "string" ? rest.system : undefined;
|
|
694
1193
|
if (resolved) {
|
|
695
|
-
|
|
696
|
-
|
|
1194
|
+
const resolvedPromptConfig = promptConfig;
|
|
1195
|
+
system = resolvedPromptConfig.variables
|
|
1196
|
+
? (0, template_2.renderTemplate)(resolved.content, resolvedPromptConfig.variables)
|
|
697
1197
|
: resolved.content;
|
|
698
1198
|
// Store prompt metadata for the session (read by middleware during logging)
|
|
699
1199
|
if (session === null || session === void 0 ? void 0 : session.sessionId) {
|
|
@@ -708,18 +1208,19 @@ ${userContextBlock || "None"}
|
|
|
708
1208
|
});
|
|
709
1209
|
}
|
|
710
1210
|
logger.info("cl.generateText called", {
|
|
711
|
-
slug:
|
|
1211
|
+
slug: resolvedPromptConfig.slug,
|
|
712
1212
|
version: resolved.version,
|
|
713
1213
|
systemLength: system.length,
|
|
714
1214
|
});
|
|
715
1215
|
}
|
|
716
|
-
else {
|
|
1216
|
+
else if (promptConfig === null || promptConfig === void 0 ? void 0 : promptConfig.slug) {
|
|
717
1217
|
logger.info("cl.generateText called without resolved prompt", {
|
|
718
1218
|
slug: promptConfig.slug,
|
|
719
1219
|
});
|
|
720
1220
|
}
|
|
721
1221
|
const model = resolveModel(options.model, resolved === null || resolved === void 0 ? void 0 : resolved.gatewaySlug);
|
|
722
|
-
|
|
1222
|
+
const nextParams = withAutoInjectedTools(Object.assign(Object.assign(Object.assign({}, rest), { model }), (system && { system })), session, baseUrl, clConfig.apiKey, kognitive);
|
|
1223
|
+
return (0, ai_1.generateText)(nextParams);
|
|
723
1224
|
};
|
|
724
1225
|
// Return the model wrapper function with streamText/generateText attached
|
|
725
1226
|
return Object.assign(clWrapper, {
|
|
@@ -732,10 +1233,15 @@ ${userContextBlock || "None"}
|
|
|
732
1233
|
if (sessionKey) {
|
|
733
1234
|
sessionSnapshots.delete(sessionKey);
|
|
734
1235
|
sessionPromptMetadata.delete(sessionKey);
|
|
1236
|
+
for (const key of sessionTurnIndexes.keys()) {
|
|
1237
|
+
if (key.endsWith(`:${sessionKey}`))
|
|
1238
|
+
sessionTurnIndexes.delete(key);
|
|
1239
|
+
}
|
|
735
1240
|
}
|
|
736
1241
|
else {
|
|
737
1242
|
sessionSnapshots.clear();
|
|
738
1243
|
sessionPromptMetadata.clear();
|
|
1244
|
+
sessionTurnIndexes.clear();
|
|
739
1245
|
}
|
|
740
1246
|
},
|
|
741
1247
|
});
|