@anvia/studio 1.0.0-rc.1 → 1.0.0-rc.2
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 +18 -10
- package/dist/index.d.ts +30 -55
- package/dist/index.js +610 -338
- package/dist/index.js.map +1 -1
- package/dist/ui/assets/{ArrowClockwise.es-yNj_oSyD.js → ArrowClockwise.es-DMJj7Hv0.js} +2 -2
- package/dist/ui/assets/{ArrowClockwise.es-yNj_oSyD.js.map → ArrowClockwise.es-DMJj7Hv0.js.map} +1 -1
- package/dist/ui/assets/{agents-page-ucKNS0fS.js → agents-page-CbQpO3Tg.js} +2 -2
- package/dist/ui/assets/{agents-page-ucKNS0fS.js.map → agents-page-CbQpO3Tg.js.map} +1 -1
- package/dist/ui/assets/{badge-RJJoRC4P.js → badge-BIWy1K8W.js} +1 -1
- package/dist/ui/assets/{badge-RJJoRC4P.js.map → badge-BIWy1K8W.js.map} +1 -1
- package/dist/ui/assets/index-DizotQot.js +119 -0
- package/dist/ui/assets/index-DizotQot.js.map +1 -0
- package/dist/ui/assets/{input-BOUv3rgO.js → input-BTHDDFpv.js} +1 -1
- package/dist/ui/assets/{input-BOUv3rgO.js.map → input-BTHDDFpv.js.map} +1 -1
- package/dist/ui/assets/{knowledge-page-vwFOGhkh.js → knowledge-page-C8zg8uTL.js} +2 -2
- package/dist/ui/assets/{knowledge-page-vwFOGhkh.js.map → knowledge-page-C8zg8uTL.js.map} +1 -1
- package/dist/ui/assets/{mcps-page-Bsu_-w7A.js → mcps-page-gNYeqSPB.js} +2 -2
- package/dist/ui/assets/{mcps-page-Bsu_-w7A.js.map → mcps-page-gNYeqSPB.js.map} +1 -1
- package/dist/ui/assets/{memory-page-DJ_nq7Ip.js → memory-page-BLrfOqyU.js} +4 -4
- package/dist/ui/assets/memory-page-BLrfOqyU.js.map +1 -0
- package/dist/ui/assets/pipelines-page-hTEhFZGg.js +8 -0
- package/dist/ui/assets/pipelines-page-hTEhFZGg.js.map +1 -0
- package/dist/ui/assets/{renderers-5kT5HxmZ.js → renderers-DC_-TD_X.js} +3 -3
- package/dist/ui/assets/{renderers-5kT5HxmZ.js.map → renderers-DC_-TD_X.js.map} +1 -1
- package/dist/ui/assets/{sandboxes-page-BQuQepXk.js → sandboxes-page-DtPnuza7.js} +2 -2
- package/dist/ui/assets/{sandboxes-page-BQuQepXk.js.map → sandboxes-page-DtPnuza7.js.map} +1 -1
- package/dist/ui/assets/{sessions-page-BLGrHrQT.js → sessions-page-DBzoP7MV.js} +2 -2
- package/dist/ui/assets/{sessions-page-BLGrHrQT.js.map → sessions-page-DBzoP7MV.js.map} +1 -1
- package/dist/ui/assets/{status-page-D-BUKV_r.js → status-page-Bf1lq444.js} +2 -2
- package/dist/ui/assets/{status-page-D-BUKV_r.js.map → status-page-Bf1lq444.js.map} +1 -1
- package/dist/ui/assets/tool-runner-BbUlfPEO.js +2 -0
- package/dist/ui/assets/{tool-runner-6-N-OOCI.js.map → tool-runner-BbUlfPEO.js.map} +1 -1
- package/dist/ui/assets/{tools-page-BEQJgFX0.js → tools-page-BgUz-79v.js} +2 -2
- package/dist/ui/assets/{tools-page-BEQJgFX0.js.map → tools-page-BgUz-79v.js.map} +1 -1
- package/dist/ui/assets/trace-browser-qfYPcdR2.js +10 -0
- package/dist/ui/assets/trace-browser-qfYPcdR2.js.map +1 -0
- package/dist/ui/assets/{transcript-item-Bbf77TZa.js → transcript-item-HFuuqmKM.js} +3 -3
- package/dist/ui/assets/{transcript-item-Bbf77TZa.js.map → transcript-item-HFuuqmKM.js.map} +1 -1
- package/dist/ui/index.html +1 -2
- package/package.json +12 -11
- package/dist/ui/assets/chunk-ADH7NNCS-DM6fsnDI.js +0 -2
- package/dist/ui/assets/chunk-ADH7NNCS-DM6fsnDI.js.map +0 -1
- package/dist/ui/assets/index-DIV9J1_T.js +0 -56
- package/dist/ui/assets/index-DIV9J1_T.js.map +0 -1
- package/dist/ui/assets/memory-page-DJ_nq7Ip.js.map +0 -1
- package/dist/ui/assets/pipelines-page-BsHeSdbO.js +0 -8
- package/dist/ui/assets/pipelines-page-BsHeSdbO.js.map +0 -1
- package/dist/ui/assets/tool-runner-6-N-OOCI.js +0 -2
- package/dist/ui/assets/trace-browser-DdGcJyNX.js +0 -10
- package/dist/ui/assets/trace-browser-DdGcJyNX.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -178,7 +178,12 @@ var StudioRunTraceObserver = class {
|
|
|
178
178
|
async end(args) {
|
|
179
179
|
await this.save("success", {
|
|
180
180
|
endedAt: /* @__PURE__ */ new Date(),
|
|
181
|
-
output: args.output,
|
|
181
|
+
output: args.status === "completed" ? traceOutput(args.output) : args.text,
|
|
182
|
+
result: {
|
|
183
|
+
status: args.status,
|
|
184
|
+
text: args.text,
|
|
185
|
+
...args.status === "completed" ? { output: toJsonValue(args.output) } : { stage: args.stage }
|
|
186
|
+
},
|
|
182
187
|
usage: args.usage,
|
|
183
188
|
messages: toJsonValue(args.messages)
|
|
184
189
|
});
|
|
@@ -198,12 +203,13 @@ var StudioRunTraceObserver = class {
|
|
|
198
203
|
return;
|
|
199
204
|
}
|
|
200
205
|
const metadata = traceMetadata(this.props.args, result.messages);
|
|
206
|
+
if (result.result !== void 0) metadata.result = result.result;
|
|
201
207
|
const trace = {
|
|
202
208
|
id: this.props.id,
|
|
203
209
|
runId: this.props.args.runId,
|
|
204
210
|
sessionId,
|
|
205
211
|
status,
|
|
206
|
-
trace: this.trace,
|
|
212
|
+
trace: { observer: "studio", ...this.trace },
|
|
207
213
|
startedAt: this.startedAt.toISOString(),
|
|
208
214
|
endedAt: result.endedAt.toISOString(),
|
|
209
215
|
durationMs: durationMs(this.startedAt, result.endedAt),
|
|
@@ -282,15 +288,14 @@ var ChildAgentToolTraceAccumulator = class {
|
|
|
282
288
|
}
|
|
283
289
|
if (child.type === "tool_call" && isRecord(child.toolCall)) {
|
|
284
290
|
const toolCall = child.toolCall;
|
|
285
|
-
const
|
|
286
|
-
const
|
|
287
|
-
const callId = typeof toolCall.callId === "string" ? toolCall.callId : typeof toolCall.id === "string" ? toolCall.id : void 0;
|
|
291
|
+
const toolName = typeof toolCall.toolName === "string" ? toolCall.toolName : "tool";
|
|
292
|
+
const callId = typeof toolCall.toolCallId === "string" ? toolCall.toolCallId : typeof toolCall.callId === "string" ? toolCall.callId : void 0;
|
|
288
293
|
const start = {
|
|
289
294
|
startedAt: /* @__PURE__ */ new Date(),
|
|
290
295
|
agentId,
|
|
291
296
|
childTurn,
|
|
292
297
|
toolName,
|
|
293
|
-
input: toJsonValue(
|
|
298
|
+
input: toJsonValue("input" in toolCall ? toolCall.input : {}),
|
|
294
299
|
completed: false
|
|
295
300
|
};
|
|
296
301
|
if (agentName !== void 0) start.agentName = agentName;
|
|
@@ -443,14 +448,12 @@ function generationMetadata(args, endArgs) {
|
|
|
443
448
|
const request = args.request;
|
|
444
449
|
const response = endArgs?.response;
|
|
445
450
|
const rawResponse = isRecord(response?.rawResponse) ? response.rawResponse : void 0;
|
|
446
|
-
const
|
|
451
|
+
const modelId = args.modelInfo?.modelId ?? stringValue(rawResponse?.model) ?? "unknown";
|
|
447
452
|
const providerResponse = providerResponseSummary(rawResponse);
|
|
448
453
|
const usage = response?.usage;
|
|
449
454
|
return compactJsonObject({
|
|
450
455
|
provider: args.modelInfo?.provider,
|
|
451
|
-
|
|
452
|
-
requestedModel: request.model,
|
|
453
|
-
defaultModel: args.modelInfo?.defaultModel,
|
|
456
|
+
modelId,
|
|
454
457
|
messageId: response?.messageId,
|
|
455
458
|
usage,
|
|
456
459
|
toolCount: request.tools.length,
|
|
@@ -460,15 +463,13 @@ function generationMetadata(args, endArgs) {
|
|
|
460
463
|
temperature: request.temperature,
|
|
461
464
|
maxTokens: request.maxTokens,
|
|
462
465
|
toolChoice: request.toolChoice,
|
|
463
|
-
|
|
466
|
+
providerOptionKeys: isRecord(request.providerOptions) ? Object.keys(request.providerOptions).sort() : void 0,
|
|
464
467
|
hasOutputSchema: request.outputSchema !== void 0,
|
|
465
468
|
firstDeltaMs: endArgs?.firstDeltaMs,
|
|
466
469
|
providerResponse,
|
|
467
470
|
modelInfo: compactJsonObject({
|
|
468
471
|
provider: args.modelInfo?.provider,
|
|
469
|
-
|
|
470
|
-
requestedModel: request.model,
|
|
471
|
-
defaultModel: args.modelInfo?.defaultModel,
|
|
472
|
+
modelId,
|
|
472
473
|
capabilities: args.modelInfo?.capabilities
|
|
473
474
|
}),
|
|
474
475
|
modelCall: compactJsonObject({
|
|
@@ -494,7 +495,6 @@ function generationMetadata(args, endArgs) {
|
|
|
494
495
|
}
|
|
495
496
|
function completionRequestSummary(request) {
|
|
496
497
|
return compactJsonObject({
|
|
497
|
-
model: request.model,
|
|
498
498
|
instructions: request.instructions === void 0 ? void 0 : { present: true },
|
|
499
499
|
messageCount: request.chatHistory.length,
|
|
500
500
|
documentCount: request.documents.length,
|
|
@@ -504,7 +504,7 @@ function completionRequestSummary(request) {
|
|
|
504
504
|
temperature: request.temperature,
|
|
505
505
|
maxTokens: request.maxTokens,
|
|
506
506
|
toolChoice: request.toolChoice,
|
|
507
|
-
|
|
507
|
+
providerOptionKeys: isRecord(request.providerOptions) ? Object.keys(request.providerOptions).sort() : void 0,
|
|
508
508
|
hasOutputSchema: request.outputSchema !== void 0
|
|
509
509
|
});
|
|
510
510
|
}
|
|
@@ -541,7 +541,6 @@ function toolMetadata(args, skipped, result) {
|
|
|
541
541
|
argumentBytes: byteLength(args.args),
|
|
542
542
|
resultBytes: result === void 0 ? void 0 : byteLength(result),
|
|
543
543
|
hasCallSignature: args.toolCall.signature !== void 0,
|
|
544
|
-
hasAdditionalParams: args.toolCall.additionalParams !== void 0,
|
|
545
544
|
toolDescription: args.toolDefinition?.description,
|
|
546
545
|
parameterKeys: Object.keys(properties).sort(),
|
|
547
546
|
requiredParameterKeys: required,
|
|
@@ -559,8 +558,7 @@ function toolMetadata(args, skipped, result) {
|
|
|
559
558
|
mcpServerName: args.toolMetadata?.mcpServerName,
|
|
560
559
|
argumentBytes: byteLength(args.args),
|
|
561
560
|
resultBytes: result === void 0 ? void 0 : byteLength(result),
|
|
562
|
-
hasCallSignature: args.toolCall.signature !== void 0
|
|
563
|
-
hasAdditionalParams: args.toolCall.additionalParams !== void 0
|
|
561
|
+
hasCallSignature: args.toolCall.signature !== void 0
|
|
564
562
|
})
|
|
565
563
|
});
|
|
566
564
|
}
|
|
@@ -577,6 +575,16 @@ function parseOrString(value) {
|
|
|
577
575
|
return value;
|
|
578
576
|
}
|
|
579
577
|
}
|
|
578
|
+
function traceOutput(value) {
|
|
579
|
+
if (typeof value === "string") {
|
|
580
|
+
return value;
|
|
581
|
+
}
|
|
582
|
+
try {
|
|
583
|
+
return JSON.stringify(toJsonValue(value));
|
|
584
|
+
} catch {
|
|
585
|
+
return String(value);
|
|
586
|
+
}
|
|
587
|
+
}
|
|
580
588
|
function isRecord(value) {
|
|
581
589
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
582
590
|
}
|
|
@@ -877,17 +885,18 @@ function escapeHtml(value) {
|
|
|
877
885
|
}
|
|
878
886
|
|
|
879
887
|
// src/runtime/agent-context.ts
|
|
880
|
-
import {
|
|
888
|
+
import { isVectorContext } from "@anvia/core/agent";
|
|
881
889
|
function staticContextDocuments(agent) {
|
|
882
|
-
return agent.context.filter((input) => !
|
|
890
|
+
return agent.context.filter((input) => !isVectorContext(input));
|
|
883
891
|
}
|
|
884
|
-
function
|
|
885
|
-
return agent.context.filter(
|
|
892
|
+
function vectorContexts(agent) {
|
|
893
|
+
return agent.context.filter(isVectorContext);
|
|
886
894
|
}
|
|
887
895
|
|
|
888
896
|
// src/runtime/agent-runs.ts
|
|
889
|
-
import {
|
|
890
|
-
|
|
897
|
+
import {
|
|
898
|
+
withInternalAgentRunOptions
|
|
899
|
+
} from "@anvia/core/internal/agent";
|
|
891
900
|
|
|
892
901
|
// src/runtime/agent-utils.ts
|
|
893
902
|
import {
|
|
@@ -914,7 +923,8 @@ function serializeError(error) {
|
|
|
914
923
|
|
|
915
924
|
// src/runtime/type-guards.ts
|
|
916
925
|
import {
|
|
917
|
-
isJsonValue as isCoreJsonValue
|
|
926
|
+
isJsonValue as isCoreJsonValue,
|
|
927
|
+
isMessage
|
|
918
928
|
} from "@anvia/core/completion";
|
|
919
929
|
function isObject(value) {
|
|
920
930
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -925,26 +935,16 @@ function isJsonObject(value) {
|
|
|
925
935
|
function isJsonValue(value) {
|
|
926
936
|
return isCoreJsonValue(value);
|
|
927
937
|
}
|
|
928
|
-
function isMessageInput(value) {
|
|
929
|
-
return typeof value === "string" || isMessage(value);
|
|
930
|
-
}
|
|
931
|
-
function isMessage(value) {
|
|
932
|
-
if (!isObject(value) || typeof value.role !== "string") {
|
|
933
|
-
return false;
|
|
934
|
-
}
|
|
935
|
-
if (value.role === "system") {
|
|
936
|
-
return typeof value.content === "string";
|
|
937
|
-
}
|
|
938
|
-
if (value.role === "user" || value.role === "assistant" || value.role === "tool") {
|
|
939
|
-
return Array.isArray(value.content);
|
|
940
|
-
}
|
|
941
|
-
return false;
|
|
942
|
-
}
|
|
943
938
|
function isAgentTraceOptions(value) {
|
|
944
939
|
if (!isObject(value)) {
|
|
945
940
|
return false;
|
|
946
941
|
}
|
|
947
|
-
|
|
942
|
+
if (!Object.keys(value).every(
|
|
943
|
+
(key) => ["name", "userId", "sessionId", "metadata", "tags", "version", "traceId"].includes(key)
|
|
944
|
+
)) {
|
|
945
|
+
return false;
|
|
946
|
+
}
|
|
947
|
+
return optionalString(value.name) && optionalString(value.userId) && optionalString(value.sessionId) && optionalString(value.version) && optionalString(value.traceId) && optionalStringArray(value.tags) && (value.metadata === void 0 || isJsonObject(value.metadata));
|
|
948
948
|
}
|
|
949
949
|
function isNonNegativeInteger(value) {
|
|
950
950
|
return Number.isInteger(value) && typeof value === "number" && value >= 0;
|
|
@@ -955,15 +955,9 @@ function isPositiveInteger(value) {
|
|
|
955
955
|
function optionalString(value) {
|
|
956
956
|
return value === void 0 || typeof value === "string";
|
|
957
957
|
}
|
|
958
|
-
function optionalBoolean(value) {
|
|
959
|
-
return value === void 0 || typeof value === "boolean";
|
|
960
|
-
}
|
|
961
958
|
function optionalStringArray(value) {
|
|
962
959
|
return value === void 0 || Array.isArray(value) && value.every((item) => typeof item === "string");
|
|
963
960
|
}
|
|
964
|
-
function optionalObject(value) {
|
|
965
|
-
return value === void 0 || isObject(value);
|
|
966
|
-
}
|
|
967
961
|
|
|
968
962
|
// src/runtime/http.ts
|
|
969
963
|
function errorResponse(c, status, code, message, details) {
|
|
@@ -1013,8 +1007,8 @@ function createStudioModelRegistry(config) {
|
|
|
1013
1007
|
id,
|
|
1014
1008
|
staticModels
|
|
1015
1009
|
};
|
|
1016
|
-
if (provider.
|
|
1017
|
-
runtimeProvider.
|
|
1010
|
+
if (provider.defaultModelId !== void 0) {
|
|
1011
|
+
runtimeProvider.defaultModelId = normalizeModelId(provider.defaultModelId);
|
|
1018
1012
|
}
|
|
1019
1013
|
providers.set(id, runtimeProvider);
|
|
1020
1014
|
}
|
|
@@ -1023,8 +1017,10 @@ function createStudioModelRegistry(config) {
|
|
|
1023
1017
|
agentPolicies: normalizeAgentPolicies(config.agents ?? {}),
|
|
1024
1018
|
modelCache: /* @__PURE__ */ new Map()
|
|
1025
1019
|
};
|
|
1026
|
-
if (config.
|
|
1027
|
-
Object.assign(registry, {
|
|
1020
|
+
if (config.defaultModelRef !== void 0) {
|
|
1021
|
+
Object.assign(registry, {
|
|
1022
|
+
defaultModelRef: normalizeModelRef(config.defaultModelRef)
|
|
1023
|
+
});
|
|
1028
1024
|
}
|
|
1029
1025
|
return registry;
|
|
1030
1026
|
}
|
|
@@ -1041,7 +1037,7 @@ function studioModelsConfig(registry, agents) {
|
|
|
1041
1037
|
models
|
|
1042
1038
|
};
|
|
1043
1039
|
if (provider.name !== void 0) config2.name = provider.name;
|
|
1044
|
-
if (provider.
|
|
1040
|
+
if (provider.defaultModelId !== void 0) config2.defaultModelId = provider.defaultModelId;
|
|
1045
1041
|
if (provider.metadata !== void 0) config2.metadata = provider.metadata;
|
|
1046
1042
|
return config2;
|
|
1047
1043
|
});
|
|
@@ -1053,7 +1049,7 @@ function studioModelsConfig(registry, agents) {
|
|
|
1053
1049
|
providers,
|
|
1054
1050
|
agents: agentsConfig
|
|
1055
1051
|
};
|
|
1056
|
-
if (registry.
|
|
1052
|
+
if (registry.defaultModelRef !== void 0) config.defaultModelRef = registry.defaultModelRef;
|
|
1057
1053
|
return config;
|
|
1058
1054
|
}
|
|
1059
1055
|
function registerModelRoutes(app, props) {
|
|
@@ -1067,8 +1063,8 @@ function registerModelRoutes(app, props) {
|
|
|
1067
1063
|
const response = {
|
|
1068
1064
|
providers
|
|
1069
1065
|
};
|
|
1070
|
-
if (props.registry.
|
|
1071
|
-
response.
|
|
1066
|
+
if (props.registry.defaultModelRef !== void 0) {
|
|
1067
|
+
response.defaultModelRef = props.registry.defaultModelRef;
|
|
1072
1068
|
}
|
|
1073
1069
|
return c.json(response);
|
|
1074
1070
|
});
|
|
@@ -1101,7 +1097,7 @@ function resolveStudioModel(registry, input) {
|
|
|
1101
1097
|
if (registry === void 0) {
|
|
1102
1098
|
return { warnings: [] };
|
|
1103
1099
|
}
|
|
1104
|
-
const selectedRef = normalizeOptionalModelRef(input.request.model) ?? sessionModelRef(input.sessionMetadata) ?? registry.agentPolicies.get(input.agent.id)?.
|
|
1100
|
+
const selectedRef = normalizeOptionalModelRef(input.request.model) ?? sessionModelRef(input.sessionMetadata) ?? registry.agentPolicies.get(input.agent.id)?.defaultModelRef ?? registry.defaultModelRef;
|
|
1105
1101
|
if (selectedRef === void 0) {
|
|
1106
1102
|
return { warnings: [] };
|
|
1107
1103
|
}
|
|
@@ -1113,7 +1109,7 @@ function resolveStudioModel(registry, input) {
|
|
|
1113
1109
|
}
|
|
1114
1110
|
let model = registry.modelCache.get(selectedRef);
|
|
1115
1111
|
if (model === void 0) {
|
|
1116
|
-
model = provider.createCompletionModel(modelId);
|
|
1112
|
+
model = provider.createCompletionModel({ modelId });
|
|
1117
1113
|
registry.modelCache.set(selectedRef, model);
|
|
1118
1114
|
}
|
|
1119
1115
|
const metadata = provider.staticModels.get(modelId);
|
|
@@ -1131,12 +1127,7 @@ function normalizeOptionalModelRef(ref) {
|
|
|
1131
1127
|
return ref === void 0 ? void 0 : normalizeModelRef(ref);
|
|
1132
1128
|
}
|
|
1133
1129
|
function normalizeModelRef(ref) {
|
|
1134
|
-
|
|
1135
|
-
const trimmed = ref.trim();
|
|
1136
|
-
const parsed = parseModelRef(trimmed);
|
|
1137
|
-
return `${parsed.providerId}:${parsed.modelId}`;
|
|
1138
|
-
}
|
|
1139
|
-
return `${normalizeProviderId(ref.provider)}:${normalizeModelId(ref.model)}`;
|
|
1130
|
+
return `${normalizeProviderId(ref.providerId)}:${normalizeModelId(ref.modelId)}`;
|
|
1140
1131
|
}
|
|
1141
1132
|
function parseModelRef(ref) {
|
|
1142
1133
|
const index = ref.indexOf(":");
|
|
@@ -1179,12 +1170,12 @@ async function agentModelsCatalog(registry, agent) {
|
|
|
1179
1170
|
return [];
|
|
1180
1171
|
}
|
|
1181
1172
|
});
|
|
1182
|
-
const
|
|
1173
|
+
const defaultModelRef = policy?.defaultModelRef ?? registry.defaultModelRef;
|
|
1183
1174
|
const summary = {
|
|
1184
1175
|
agentId: agent.id,
|
|
1185
1176
|
models: [...models, ...exactPolicyModels]
|
|
1186
1177
|
};
|
|
1187
|
-
if (
|
|
1178
|
+
if (defaultModelRef !== void 0) summary.defaultModelRef = defaultModelRef;
|
|
1188
1179
|
if (warnings.length > 0) summary.warnings = warnings;
|
|
1189
1180
|
return summary;
|
|
1190
1181
|
}
|
|
@@ -1222,7 +1213,7 @@ async function providerCatalog(provider) {
|
|
|
1222
1213
|
models: [...models.values()].sort((left, right) => left.ref.localeCompare(right.ref))
|
|
1223
1214
|
};
|
|
1224
1215
|
if (provider.name !== void 0) catalog.name = provider.name;
|
|
1225
|
-
if (provider.
|
|
1216
|
+
if (provider.defaultModelId !== void 0) catalog.defaultModelId = provider.defaultModelId;
|
|
1226
1217
|
if (provider.metadata !== void 0) catalog.metadata = provider.metadata;
|
|
1227
1218
|
if (warning !== void 0) catalog.warning = warning;
|
|
1228
1219
|
return catalog;
|
|
@@ -1256,19 +1247,33 @@ function normalizeAgentPolicies(policies) {
|
|
|
1256
1247
|
return new Map(
|
|
1257
1248
|
Object.entries(policies).map(([agentId, policy]) => {
|
|
1258
1249
|
const normalized = {};
|
|
1259
|
-
if (policy.
|
|
1250
|
+
if (policy.defaultModelRef !== void 0) {
|
|
1251
|
+
normalized.defaultModelRef = normalizeModelRef(policy.defaultModelRef);
|
|
1252
|
+
}
|
|
1260
1253
|
if (policy.allowed !== void 0) {
|
|
1261
|
-
normalized.allowed = policy.allowed.map(
|
|
1262
|
-
(
|
|
1263
|
-
|
|
1254
|
+
normalized.allowed = policy.allowed.map((entry) => {
|
|
1255
|
+
if (typeof entry === "string") {
|
|
1256
|
+
return normalizeWildcardModelRef(entry);
|
|
1257
|
+
}
|
|
1258
|
+
return normalizeModelRef(entry);
|
|
1259
|
+
});
|
|
1264
1260
|
}
|
|
1265
1261
|
return [agentId.trim(), normalized];
|
|
1266
1262
|
})
|
|
1267
1263
|
);
|
|
1268
1264
|
}
|
|
1265
|
+
function normalizeWildcardModelRef(ref) {
|
|
1266
|
+
const normalized = ref.trim();
|
|
1267
|
+
if (!normalized.endsWith(":*")) {
|
|
1268
|
+
throw new ModelSelectionError(`Invalid wildcard model reference: ${ref}`);
|
|
1269
|
+
}
|
|
1270
|
+
return `${normalizeProviderId(normalized.slice(0, -2))}:*`;
|
|
1271
|
+
}
|
|
1269
1272
|
function publicPolicy(policy) {
|
|
1270
1273
|
const config = {};
|
|
1271
|
-
if (policy.
|
|
1274
|
+
if (policy.defaultModelRef !== void 0) {
|
|
1275
|
+
config.defaultModelRef = policy.defaultModelRef;
|
|
1276
|
+
}
|
|
1272
1277
|
if (policy.allowed !== void 0) config.allowed = policy.allowed;
|
|
1273
1278
|
return config;
|
|
1274
1279
|
}
|
|
@@ -1299,15 +1304,13 @@ function modelWarnings(ref, model, request) {
|
|
|
1299
1304
|
function requestModalities(request) {
|
|
1300
1305
|
const modalities = /* @__PURE__ */ new Set(["text"]);
|
|
1301
1306
|
for (const message of requestMessages(request)) {
|
|
1302
|
-
if (typeof message === "string") {
|
|
1303
|
-
continue;
|
|
1304
|
-
}
|
|
1305
1307
|
if (message.role === "user" || message.role === "assistant") {
|
|
1308
|
+
if (typeof message.content === "string") continue;
|
|
1306
1309
|
for (const content of message.content) {
|
|
1307
1310
|
if (content.type === "image") {
|
|
1308
1311
|
modalities.add("image");
|
|
1309
1312
|
}
|
|
1310
|
-
if (content.type === "
|
|
1313
|
+
if (content.type === "file") {
|
|
1311
1314
|
modalities.add("document");
|
|
1312
1315
|
}
|
|
1313
1316
|
}
|
|
@@ -1316,7 +1319,7 @@ function requestModalities(request) {
|
|
|
1316
1319
|
return modalities;
|
|
1317
1320
|
}
|
|
1318
1321
|
function requestMessages(request) {
|
|
1319
|
-
return
|
|
1322
|
+
return request.messages;
|
|
1320
1323
|
}
|
|
1321
1324
|
function normalizeProviderId(id) {
|
|
1322
1325
|
const trimmed = id.trim();
|
|
@@ -1334,7 +1337,7 @@ function normalizeModelId(id) {
|
|
|
1334
1337
|
}
|
|
1335
1338
|
|
|
1336
1339
|
// src/runtime/streams.ts
|
|
1337
|
-
import {
|
|
1340
|
+
import { createClientStreamResponse, createEventStreamResponse } from "@anvia/server";
|
|
1338
1341
|
var studioJsonlHeaders = {
|
|
1339
1342
|
"cache-control": "no-cache, no-transform",
|
|
1340
1343
|
connection: "keep-alive",
|
|
@@ -1343,7 +1346,15 @@ var studioJsonlHeaders = {
|
|
|
1343
1346
|
"x-accel-buffering": "no"
|
|
1344
1347
|
};
|
|
1345
1348
|
function streamStudioJsonl(events) {
|
|
1346
|
-
return
|
|
1349
|
+
return createEventStreamResponse({
|
|
1350
|
+
events: withStudioStreamErrors(events),
|
|
1351
|
+
format: "jsonl",
|
|
1352
|
+
headers: studioJsonlHeaders
|
|
1353
|
+
});
|
|
1354
|
+
}
|
|
1355
|
+
function streamStudioClient(options) {
|
|
1356
|
+
return createClientStreamResponse({
|
|
1357
|
+
events: options.events,
|
|
1347
1358
|
format: "jsonl",
|
|
1348
1359
|
headers: studioJsonlHeaders
|
|
1349
1360
|
});
|
|
@@ -1362,8 +1373,9 @@ function withStudioStreamErrors(events) {
|
|
|
1362
1373
|
const next = await iterator.next();
|
|
1363
1374
|
if (next.done === true) {
|
|
1364
1375
|
done = true;
|
|
1376
|
+
return next;
|
|
1365
1377
|
}
|
|
1366
|
-
return next;
|
|
1378
|
+
return { done: false, value: serializeStreamError(next.value) };
|
|
1367
1379
|
} catch (error) {
|
|
1368
1380
|
done = true;
|
|
1369
1381
|
return {
|
|
@@ -1381,6 +1393,12 @@ function withStudioStreamErrors(events) {
|
|
|
1381
1393
|
}
|
|
1382
1394
|
};
|
|
1383
1395
|
}
|
|
1396
|
+
function serializeStreamError(event) {
|
|
1397
|
+
if (typeof event !== "object" || event === null || !("type" in event) || event.type !== "error" || !("error" in event)) {
|
|
1398
|
+
return event;
|
|
1399
|
+
}
|
|
1400
|
+
return { ...event, error: serializeError(event.error) };
|
|
1401
|
+
}
|
|
1384
1402
|
function studioStreamError(error) {
|
|
1385
1403
|
return {
|
|
1386
1404
|
type: "error",
|
|
@@ -1589,6 +1607,15 @@ function isEventType(value) {
|
|
|
1589
1607
|
return value === "session_log" || value === "pipeline_log" || value === "trace";
|
|
1590
1608
|
}
|
|
1591
1609
|
|
|
1610
|
+
// src/runtime/runs.ts
|
|
1611
|
+
import {
|
|
1612
|
+
customAgentEventsToClientStream
|
|
1613
|
+
} from "@anvia/client";
|
|
1614
|
+
import {
|
|
1615
|
+
isJsonValue as isJsonValue2,
|
|
1616
|
+
parseMessages
|
|
1617
|
+
} from "@anvia/core/completion";
|
|
1618
|
+
|
|
1592
1619
|
// src/runtime/transcript.ts
|
|
1593
1620
|
function renumberTranscript(entries) {
|
|
1594
1621
|
return entries.map((entry, entryId) => ({ ...entry, entryId }));
|
|
@@ -1602,7 +1629,8 @@ function transcriptFromMessages(messages) {
|
|
|
1602
1629
|
if (message.role === "user") {
|
|
1603
1630
|
const attachments = attachmentsFromMessage(message);
|
|
1604
1631
|
let textEntryAdded = false;
|
|
1605
|
-
|
|
1632
|
+
const contents2 = typeof message.content === "string" ? [{ type: "text", text: message.content }] : message.content;
|
|
1633
|
+
for (const content of contents2) {
|
|
1606
1634
|
if (content.type === "text") {
|
|
1607
1635
|
const entry = {
|
|
1608
1636
|
entryId: transcript.length,
|
|
@@ -1631,17 +1659,16 @@ function transcriptFromMessages(messages) {
|
|
|
1631
1659
|
transcript.push({
|
|
1632
1660
|
entryId: transcript.length,
|
|
1633
1661
|
kind: "tool",
|
|
1634
|
-
toolName:
|
|
1635
|
-
callId: content.callId ?? content.
|
|
1636
|
-
result: content.
|
|
1637
|
-
|
|
1638
|
-
).join("\n"),
|
|
1639
|
-
structuredResult: content.content
|
|
1662
|
+
toolName: content.toolName,
|
|
1663
|
+
callId: content.callId ?? content.toolCallId,
|
|
1664
|
+
result: toolResultText(content.output),
|
|
1665
|
+
...content.output.type === "content" ? { structuredResult: content.output.value } : {}
|
|
1640
1666
|
});
|
|
1641
1667
|
}
|
|
1642
1668
|
continue;
|
|
1643
1669
|
}
|
|
1644
|
-
|
|
1670
|
+
const contents = typeof message.content === "string" ? [{ type: "text", text: message.content }] : message.content;
|
|
1671
|
+
for (const content of contents) {
|
|
1645
1672
|
if (content.type === "text") {
|
|
1646
1673
|
appendAssistantTranscriptText(transcript, content.text);
|
|
1647
1674
|
} else if (content.type === "reasoning") {
|
|
@@ -1652,13 +1679,13 @@ function transcriptFromMessages(messages) {
|
|
|
1652
1679
|
};
|
|
1653
1680
|
if (content.id !== void 0) entry.reasoningId = content.id;
|
|
1654
1681
|
transcript.push(entry);
|
|
1655
|
-
} else if (content.type === "
|
|
1682
|
+
} else if (content.type === "tool-call") {
|
|
1656
1683
|
transcript.push({
|
|
1657
1684
|
entryId: transcript.length,
|
|
1658
1685
|
kind: "tool",
|
|
1659
|
-
toolName: content.
|
|
1660
|
-
callId: content.callId ?? content.
|
|
1661
|
-
args: formatJson(content.
|
|
1686
|
+
toolName: content.toolName,
|
|
1687
|
+
callId: content.callId ?? content.toolCallId,
|
|
1688
|
+
args: formatJson(content.input)
|
|
1662
1689
|
});
|
|
1663
1690
|
}
|
|
1664
1691
|
}
|
|
@@ -1669,28 +1696,37 @@ function attachmentsFromMessage(message) {
|
|
|
1669
1696
|
if (message.role !== "user" && message.role !== "assistant") {
|
|
1670
1697
|
return [];
|
|
1671
1698
|
}
|
|
1699
|
+
if (typeof message.content === "string") return [];
|
|
1672
1700
|
return message.content.flatMap((content) => {
|
|
1673
1701
|
if (content.type === "image") {
|
|
1674
1702
|
const attachment = { kind: "image" };
|
|
1675
|
-
if (content.
|
|
1676
|
-
attachment.data = content.
|
|
1677
|
-
attachment.mediaType = content.
|
|
1703
|
+
if (content.image.type === "data") {
|
|
1704
|
+
attachment.data = content.image.data;
|
|
1705
|
+
if (content.mediaType !== void 0) attachment.mediaType = content.mediaType;
|
|
1678
1706
|
} else {
|
|
1679
|
-
attachment.url = content.
|
|
1707
|
+
attachment.url = content.image.url;
|
|
1680
1708
|
}
|
|
1681
1709
|
return [attachment];
|
|
1682
1710
|
}
|
|
1683
|
-
if (content.type === "
|
|
1711
|
+
if (content.type === "file") {
|
|
1684
1712
|
const attachment = { kind: "document" };
|
|
1685
|
-
if (content.
|
|
1686
|
-
|
|
1687
|
-
if (content.
|
|
1688
|
-
if (content.
|
|
1713
|
+
if (content.filename !== void 0) attachment.name = content.filename;
|
|
1714
|
+
attachment.mediaType = content.mediaType;
|
|
1715
|
+
if (content.data.type === "data") attachment.data = content.data.data;
|
|
1716
|
+
if (content.data.type === "url") attachment.url = content.data.url;
|
|
1689
1717
|
return [attachment];
|
|
1690
1718
|
}
|
|
1691
1719
|
return [];
|
|
1692
1720
|
});
|
|
1693
1721
|
}
|
|
1722
|
+
function toolResultText(output) {
|
|
1723
|
+
if (output.type === "text" || output.type === "error-text") return output.value;
|
|
1724
|
+
if (output.type === "json" || output.type === "error-json") return formatJson(output.value);
|
|
1725
|
+
if (output.type === "execution-denied") return output.reason ?? "Execution denied";
|
|
1726
|
+
return output.value.map(
|
|
1727
|
+
(part) => part.type === "text" ? part.text : `[file:${part.mediaType}${part.filename === void 0 ? "" : `:${part.filename}`}]`
|
|
1728
|
+
).join("\n");
|
|
1729
|
+
}
|
|
1694
1730
|
function appendAssistantTranscriptText(transcript, text) {
|
|
1695
1731
|
const last = transcript.at(-1);
|
|
1696
1732
|
if (last?.kind === "message" && last.role === "assistant") {
|
|
@@ -1778,8 +1814,97 @@ async function* mergeRunAndApprovalEvents(runEvents, approvalEvents) {
|
|
|
1778
1814
|
approvalEvents.close();
|
|
1779
1815
|
}
|
|
1780
1816
|
}
|
|
1781
|
-
function streamAgentRunEvents(_c, events, options
|
|
1782
|
-
return
|
|
1817
|
+
function streamAgentRunEvents(_c, events, options) {
|
|
1818
|
+
return streamStudioClient({
|
|
1819
|
+
events: customAgentEventsToClientStream({
|
|
1820
|
+
events: withAgentRunCancellation(events, options.onCancel),
|
|
1821
|
+
runId: options.runId,
|
|
1822
|
+
mapCustomEvent: studioEventToClientEvent
|
|
1823
|
+
})
|
|
1824
|
+
});
|
|
1825
|
+
}
|
|
1826
|
+
function studioEventToClientEvent(event, context) {
|
|
1827
|
+
if (event.type === "tool_approval_request" || event.type === "tool_approval_result") {
|
|
1828
|
+
return {
|
|
1829
|
+
type: "tool_approval",
|
|
1830
|
+
runId: context.runId,
|
|
1831
|
+
...context.turn === void 0 ? {} : { turn: context.turn },
|
|
1832
|
+
...context.scope === void 0 ? {} : { scope: context.scope },
|
|
1833
|
+
approval: {
|
|
1834
|
+
id: event.approval.id,
|
|
1835
|
+
runId: event.approval.runId,
|
|
1836
|
+
agentId: event.approval.agentId,
|
|
1837
|
+
...event.approval.sessionId === void 0 ? {} : { sessionId: event.approval.sessionId },
|
|
1838
|
+
toolName: event.approval.toolName,
|
|
1839
|
+
...event.approval.callId === void 0 ? {} : { callId: event.approval.callId },
|
|
1840
|
+
internalCallId: event.approval.internalCallId,
|
|
1841
|
+
input: parseJsonOrString(event.approval.args),
|
|
1842
|
+
status: event.approval.status,
|
|
1843
|
+
requestedAt: event.approval.requestedAt,
|
|
1844
|
+
...event.approval.resolvedAt === void 0 ? {} : { resolvedAt: event.approval.resolvedAt },
|
|
1845
|
+
...event.approval.reason === void 0 ? {} : { reason: event.approval.reason }
|
|
1846
|
+
}
|
|
1847
|
+
};
|
|
1848
|
+
}
|
|
1849
|
+
if (event.type === "tool_question_request" || event.type === "tool_question_result") {
|
|
1850
|
+
return {
|
|
1851
|
+
type: "tool_question",
|
|
1852
|
+
runId: context.runId,
|
|
1853
|
+
...context.turn === void 0 ? {} : { turn: context.turn },
|
|
1854
|
+
...context.scope === void 0 ? {} : { scope: context.scope },
|
|
1855
|
+
question: {
|
|
1856
|
+
id: event.question.id,
|
|
1857
|
+
runId: event.question.runId,
|
|
1858
|
+
agentId: event.question.agentId,
|
|
1859
|
+
...event.question.sessionId === void 0 ? {} : { sessionId: event.question.sessionId },
|
|
1860
|
+
toolName: event.question.toolName,
|
|
1861
|
+
...event.question.callId === void 0 ? {} : { callId: event.question.callId },
|
|
1862
|
+
internalCallId: event.question.internalCallId,
|
|
1863
|
+
input: parseJsonOrString(event.question.args),
|
|
1864
|
+
questions: event.question.questions,
|
|
1865
|
+
status: event.question.status,
|
|
1866
|
+
requestedAt: event.question.requestedAt,
|
|
1867
|
+
...event.question.answeredAt === void 0 ? {} : { answeredAt: event.question.answeredAt },
|
|
1868
|
+
...event.question.cancelledAt === void 0 ? {} : { cancelledAt: event.question.cancelledAt },
|
|
1869
|
+
...event.question.answers === void 0 ? {} : { answers: event.question.answers }
|
|
1870
|
+
}
|
|
1871
|
+
};
|
|
1872
|
+
}
|
|
1873
|
+
if (event.type === "session_log" && isJsonValue2(event.log)) {
|
|
1874
|
+
return {
|
|
1875
|
+
type: "data",
|
|
1876
|
+
runId: context.runId,
|
|
1877
|
+
name: "studio.session_log",
|
|
1878
|
+
data: event.log,
|
|
1879
|
+
transient: true
|
|
1880
|
+
};
|
|
1881
|
+
}
|
|
1882
|
+
if (event.type === "pipeline_log" && isJsonValue2(event.log)) {
|
|
1883
|
+
return {
|
|
1884
|
+
type: "data",
|
|
1885
|
+
runId: context.runId,
|
|
1886
|
+
name: "studio.pipeline_log",
|
|
1887
|
+
data: event.log,
|
|
1888
|
+
transient: true
|
|
1889
|
+
};
|
|
1890
|
+
}
|
|
1891
|
+
if (event.type === "pipeline_final" && isJsonValue2(event.output)) {
|
|
1892
|
+
return {
|
|
1893
|
+
type: "data",
|
|
1894
|
+
runId: context.runId,
|
|
1895
|
+
name: "studio.pipeline_final",
|
|
1896
|
+
data: event.output
|
|
1897
|
+
};
|
|
1898
|
+
}
|
|
1899
|
+
return void 0;
|
|
1900
|
+
}
|
|
1901
|
+
function parseJsonOrString(value) {
|
|
1902
|
+
try {
|
|
1903
|
+
const parsed = JSON.parse(value);
|
|
1904
|
+
return isJsonValue2(parsed) ? parsed : value;
|
|
1905
|
+
} catch {
|
|
1906
|
+
return value;
|
|
1907
|
+
}
|
|
1783
1908
|
}
|
|
1784
1909
|
function withAgentRunCancellation(events, onCancel) {
|
|
1785
1910
|
const iterator = events[Symbol.asyncIterator]();
|
|
@@ -1899,10 +2024,10 @@ function createPersistedStreamingSessionTranscript(props) {
|
|
|
1899
2024
|
};
|
|
1900
2025
|
if (event.type === "error") saveInput.error = serializeError(event.error);
|
|
1901
2026
|
await saveTranscript(saveInput);
|
|
1902
|
-
const generatedMessages = event.type === "final" ? event.messages.slice(1) : [];
|
|
2027
|
+
const generatedMessages = event.type === "final" ? event.result.messages.slice(1) : [];
|
|
1903
2028
|
if (props.persistGeneratedMessages === true && generatedMessages.length > 0) {
|
|
1904
2029
|
await props.store.append({
|
|
1905
|
-
|
|
2030
|
+
scope: { sessionId: props.session.id },
|
|
1906
2031
|
runId: props.runId,
|
|
1907
2032
|
turn: 1,
|
|
1908
2033
|
messages: generatedMessages
|
|
@@ -2004,9 +2129,9 @@ function acceptTranscriptStreamEvent(transcript, event) {
|
|
|
2004
2129
|
transcript.push({
|
|
2005
2130
|
entryId: transcript.length,
|
|
2006
2131
|
kind: "tool",
|
|
2007
|
-
toolName: event.toolCall.
|
|
2008
|
-
callId: event.toolCall.callId ?? event.toolCall.
|
|
2009
|
-
args: formatJson(event.toolCall.
|
|
2132
|
+
toolName: event.toolCall.toolName,
|
|
2133
|
+
callId: event.toolCall.callId ?? event.toolCall.toolCallId,
|
|
2134
|
+
args: formatJson(event.toolCall.input)
|
|
2010
2135
|
});
|
|
2011
2136
|
}
|
|
2012
2137
|
if (event.type === "tool_result") {
|
|
@@ -2114,8 +2239,8 @@ function acceptTranscriptStreamEvent(transcript, event) {
|
|
|
2114
2239
|
matched.question = question;
|
|
2115
2240
|
}
|
|
2116
2241
|
}
|
|
2117
|
-
if (event.type === "final" && event.trace?.traceId !== void 0) {
|
|
2118
|
-
assignTranscriptTraceId(transcript, event.trace.traceId);
|
|
2242
|
+
if (event.type === "final" && event.result.trace?.traceId !== void 0) {
|
|
2243
|
+
assignTranscriptTraceId(transcript, event.result.trace.traceId);
|
|
2119
2244
|
}
|
|
2120
2245
|
if (event.type === "error") {
|
|
2121
2246
|
appendTranscriptAssistantError(transcript, errorText(event.error));
|
|
@@ -2187,9 +2312,9 @@ function childAgentTranscriptEvent(event) {
|
|
|
2187
2312
|
const entry = {
|
|
2188
2313
|
kind: "tool",
|
|
2189
2314
|
agentId: event.agentId,
|
|
2190
|
-
toolName: child.toolCall.
|
|
2191
|
-
callId: child.toolCall.callId ?? child.toolCall.
|
|
2192
|
-
args: formatJson(child.toolCall.
|
|
2315
|
+
toolName: child.toolCall.toolName,
|
|
2316
|
+
callId: child.toolCall.callId ?? child.toolCall.toolCallId,
|
|
2317
|
+
args: formatJson(child.toolCall.input)
|
|
2193
2318
|
};
|
|
2194
2319
|
if (event.agentName !== void 0) entry.agentName = event.agentName;
|
|
2195
2320
|
return entry;
|
|
@@ -2326,17 +2451,18 @@ function extractMessageText(message) {
|
|
|
2326
2451
|
if (message.role === "system") {
|
|
2327
2452
|
return message.content;
|
|
2328
2453
|
}
|
|
2454
|
+
if (typeof message.content === "string") {
|
|
2455
|
+
return message.content;
|
|
2456
|
+
}
|
|
2329
2457
|
return message.content.flatMap((item) => {
|
|
2330
2458
|
if (item.type === "text" || item.type === "reasoning") {
|
|
2331
2459
|
return [item.text];
|
|
2332
2460
|
}
|
|
2333
|
-
if (item.type === "
|
|
2334
|
-
return [`${item.
|
|
2461
|
+
if (item.type === "tool-call") {
|
|
2462
|
+
return [`${item.toolName}(${formatJson(item.input)})`];
|
|
2335
2463
|
}
|
|
2336
|
-
if (item.type === "
|
|
2337
|
-
return item.
|
|
2338
|
-
(result) => "text" in result ? result.text : `[image:${result.mediaType ?? "image/png"}]`
|
|
2339
|
-
);
|
|
2464
|
+
if (item.type === "tool-result") {
|
|
2465
|
+
return [toolResultOutputText(item.output)];
|
|
2340
2466
|
}
|
|
2341
2467
|
return [];
|
|
2342
2468
|
}).join("\n");
|
|
@@ -2345,23 +2471,26 @@ function optionalTranscriptAttachments(message) {
|
|
|
2345
2471
|
if (typeof message === "string" || message.role !== "user") {
|
|
2346
2472
|
return {};
|
|
2347
2473
|
}
|
|
2474
|
+
if (typeof message.content === "string") {
|
|
2475
|
+
return {};
|
|
2476
|
+
}
|
|
2348
2477
|
const attachments = message.content.flatMap((content) => {
|
|
2349
2478
|
if (content.type === "image") {
|
|
2350
2479
|
const attachment = { kind: "image" };
|
|
2351
|
-
if (content.
|
|
2352
|
-
attachment.data = content.
|
|
2353
|
-
attachment.mediaType = content.
|
|
2480
|
+
if (content.image.type === "data") {
|
|
2481
|
+
attachment.data = content.image.data;
|
|
2482
|
+
if (content.mediaType !== void 0) attachment.mediaType = content.mediaType;
|
|
2354
2483
|
} else {
|
|
2355
|
-
attachment.url = content.
|
|
2484
|
+
attachment.url = content.image.url;
|
|
2356
2485
|
}
|
|
2357
2486
|
return [attachment];
|
|
2358
2487
|
}
|
|
2359
|
-
if (content.type === "
|
|
2488
|
+
if (content.type === "file") {
|
|
2360
2489
|
const attachment = { kind: "document" };
|
|
2361
|
-
if (content.
|
|
2362
|
-
|
|
2363
|
-
if (content.
|
|
2364
|
-
if (content.
|
|
2490
|
+
if (content.filename !== void 0) attachment.name = content.filename;
|
|
2491
|
+
attachment.mediaType = content.mediaType;
|
|
2492
|
+
if (content.data.type === "data") attachment.data = content.data.data;
|
|
2493
|
+
if (content.data.type === "url") attachment.url = content.data.url;
|
|
2365
2494
|
return [attachment];
|
|
2366
2495
|
}
|
|
2367
2496
|
return [];
|
|
@@ -2378,32 +2507,27 @@ async function parseRunRequest(c) {
|
|
|
2378
2507
|
if (!isObject(body)) {
|
|
2379
2508
|
return { error: errorResponse(c, 400, "bad_request", "Request body must be an object") };
|
|
2380
2509
|
}
|
|
2381
|
-
|
|
2382
|
-
if ("error" in request) {
|
|
2383
|
-
return request;
|
|
2384
|
-
}
|
|
2385
|
-
return parseRunRequestOptions(c, body, request);
|
|
2386
|
-
}
|
|
2387
|
-
function parseLegacyRunRequestBody(c, body) {
|
|
2388
|
-
if (!isMessageInput(body.message)) {
|
|
2510
|
+
if ("message" in body || "history" in body) {
|
|
2389
2511
|
return {
|
|
2390
|
-
error: errorResponse(
|
|
2512
|
+
error: errorResponse(
|
|
2513
|
+
c,
|
|
2514
|
+
400,
|
|
2515
|
+
"bad_request",
|
|
2516
|
+
"Legacy message/history requests are not supported; use messages"
|
|
2517
|
+
)
|
|
2391
2518
|
};
|
|
2392
2519
|
}
|
|
2393
|
-
const request =
|
|
2394
|
-
|
|
2395
|
-
|
|
2396
|
-
if ("history" in body) {
|
|
2397
|
-
if (!Array.isArray(body.history) || !body.history.every(isMessage)) {
|
|
2398
|
-
return { error: errorResponse(c, 400, "bad_request", "history must be a Message array") };
|
|
2399
|
-
}
|
|
2400
|
-
request.history = body.history;
|
|
2520
|
+
const request = parseRunRequestBody(c, body);
|
|
2521
|
+
if ("error" in request) {
|
|
2522
|
+
return request;
|
|
2401
2523
|
}
|
|
2402
|
-
return request;
|
|
2524
|
+
return parseRunRequestOptions(c, body, request);
|
|
2403
2525
|
}
|
|
2404
|
-
function
|
|
2405
|
-
|
|
2406
|
-
|
|
2526
|
+
function parseRunRequestBody(c, body) {
|
|
2527
|
+
let messages;
|
|
2528
|
+
try {
|
|
2529
|
+
messages = parseMessages(body.messages);
|
|
2530
|
+
} catch {
|
|
2407
2531
|
return {
|
|
2408
2532
|
error: errorResponse(c, 400, "bad_request", "messages must be a non-empty Message array")
|
|
2409
2533
|
};
|
|
@@ -2419,19 +2543,21 @@ function parseUiRunRequestBody(c, body) {
|
|
|
2419
2543
|
error: errorResponse(c, 400, "bad_request", "messages must be a non-empty Message array")
|
|
2420
2544
|
};
|
|
2421
2545
|
}
|
|
2422
|
-
|
|
2423
|
-
|
|
2424
|
-
|
|
2425
|
-
|
|
2546
|
+
if (message.role !== "user") {
|
|
2547
|
+
return {
|
|
2548
|
+
error: errorResponse(c, 400, "bad_request", "The final message must be user-authored")
|
|
2549
|
+
};
|
|
2550
|
+
}
|
|
2551
|
+
return { messages };
|
|
2426
2552
|
}
|
|
2427
2553
|
function parseRunRequestOptions(c, body, request) {
|
|
2428
2554
|
if ("sessionId" in body) {
|
|
2429
2555
|
if (typeof body.sessionId !== "string" || body.sessionId.trim().length === 0) {
|
|
2430
2556
|
return { error: errorResponse(c, 400, "bad_request", "sessionId must be a string") };
|
|
2431
2557
|
}
|
|
2432
|
-
if (request.
|
|
2558
|
+
if (request.messages.length !== 1 || request.messages[0]?.role !== "user") {
|
|
2433
2559
|
return {
|
|
2434
|
-
error: errorResponse(c, 400, "bad_request", "sessionId
|
|
2560
|
+
error: errorResponse(c, 400, "bad_request", "sessionId requires exactly one user message")
|
|
2435
2561
|
};
|
|
2436
2562
|
}
|
|
2437
2563
|
request.sessionId = body.sessionId;
|
|
@@ -2459,12 +2585,10 @@ function parseRunRequestOptions(c, body, request) {
|
|
|
2459
2585
|
request.toolConcurrency = body.toolConcurrency;
|
|
2460
2586
|
}
|
|
2461
2587
|
if ("model" in body) {
|
|
2462
|
-
if (typeof body.model === "string") {
|
|
2463
|
-
request.model = body.model;
|
|
2464
|
-
} else if (isObject(body.model) && typeof body.model.provider === "string" && typeof body.model.model === "string") {
|
|
2588
|
+
if (isObject(body.model) && typeof body.model.providerId === "string" && typeof body.model.modelId === "string") {
|
|
2465
2589
|
request.model = {
|
|
2466
|
-
|
|
2467
|
-
|
|
2590
|
+
providerId: body.model.providerId,
|
|
2591
|
+
modelId: body.model.modelId
|
|
2468
2592
|
};
|
|
2469
2593
|
} else {
|
|
2470
2594
|
return {
|
|
@@ -2472,7 +2596,7 @@ function parseRunRequestOptions(c, body, request) {
|
|
|
2472
2596
|
c,
|
|
2473
2597
|
400,
|
|
2474
2598
|
"bad_request",
|
|
2475
|
-
"model must be a
|
|
2599
|
+
"model must be a { providerId, modelId } object"
|
|
2476
2600
|
)
|
|
2477
2601
|
};
|
|
2478
2602
|
}
|
|
@@ -2493,6 +2617,14 @@ function parseRunRequestOptions(c, body, request) {
|
|
|
2493
2617
|
}
|
|
2494
2618
|
return request;
|
|
2495
2619
|
}
|
|
2620
|
+
function toolResultOutputText(output) {
|
|
2621
|
+
if (output.type === "text" || output.type === "error-text") return output.value;
|
|
2622
|
+
if (output.type === "json" || output.type === "error-json") return formatJson(output.value);
|
|
2623
|
+
if (output.type === "execution-denied") return output.reason ?? "Execution denied";
|
|
2624
|
+
return output.value.map(
|
|
2625
|
+
(part) => part.type === "text" ? part.text : `[file:${part.mediaType}${part.filename === void 0 ? "" : `:${part.filename}`}]`
|
|
2626
|
+
).join("\n");
|
|
2627
|
+
}
|
|
2496
2628
|
|
|
2497
2629
|
// src/runtime/session-logs.ts
|
|
2498
2630
|
async function appendSessionLog(store, input) {
|
|
@@ -2627,6 +2759,25 @@ function memorySavedLog(props) {
|
|
|
2627
2759
|
metadata
|
|
2628
2760
|
};
|
|
2629
2761
|
}
|
|
2762
|
+
function memoryCompactedLog(props) {
|
|
2763
|
+
const metadata = {
|
|
2764
|
+
originalMessageCount: props.originalMessageCount,
|
|
2765
|
+
compactedMessageCount: props.compactedMessageCount,
|
|
2766
|
+
retainedMessageCount: props.retainedMessageCount,
|
|
2767
|
+
attempts: props.attempts
|
|
2768
|
+
};
|
|
2769
|
+
const usage = usageSummary(props.usage);
|
|
2770
|
+
if (usage !== void 0) metadata.usage = usage;
|
|
2771
|
+
return {
|
|
2772
|
+
sessionId: props.sessionId,
|
|
2773
|
+
runId: props.runId,
|
|
2774
|
+
level: "info",
|
|
2775
|
+
category: "memory",
|
|
2776
|
+
event: "memory.compacted",
|
|
2777
|
+
message: "Session memory compacted",
|
|
2778
|
+
metadata
|
|
2779
|
+
};
|
|
2780
|
+
}
|
|
2630
2781
|
function runFailedLog(sessionId, runId, error, startedAt) {
|
|
2631
2782
|
return {
|
|
2632
2783
|
sessionId,
|
|
@@ -2643,6 +2794,9 @@ function runFailedLog(sessionId, runId, error, startedAt) {
|
|
|
2643
2794
|
}
|
|
2644
2795
|
function logsFromStreamEvent(props) {
|
|
2645
2796
|
const { event, sessionId, runId } = props;
|
|
2797
|
+
if (event.type === "memory_compaction") {
|
|
2798
|
+
return [memoryCompactedLog({ sessionId, runId, ...event })];
|
|
2799
|
+
}
|
|
2646
2800
|
if (event.type === "turn_start") {
|
|
2647
2801
|
return [
|
|
2648
2802
|
{
|
|
@@ -2668,12 +2822,12 @@ function logsFromStreamEvent(props) {
|
|
|
2668
2822
|
level: "info",
|
|
2669
2823
|
category: "tool",
|
|
2670
2824
|
event: "tool.called",
|
|
2671
|
-
message: `Tool ${event.toolCall.
|
|
2825
|
+
message: `Tool ${event.toolCall.toolName} called`,
|
|
2672
2826
|
metadata: {
|
|
2673
2827
|
turn: event.turn,
|
|
2674
|
-
toolName: event.toolCall.
|
|
2675
|
-
callId: event.toolCall.callId ?? event.toolCall.
|
|
2676
|
-
argumentBytes: byteLength2(formatUnknown(event.toolCall.
|
|
2828
|
+
toolName: event.toolCall.toolName,
|
|
2829
|
+
callId: event.toolCall.callId ?? event.toolCall.toolCallId,
|
|
2830
|
+
argumentBytes: byteLength2(formatUnknown(event.toolCall.input))
|
|
2677
2831
|
}
|
|
2678
2832
|
}
|
|
2679
2833
|
];
|
|
@@ -2722,16 +2876,17 @@ function logsFromStreamEvent(props) {
|
|
|
2722
2876
|
];
|
|
2723
2877
|
}
|
|
2724
2878
|
if (event.type === "final") {
|
|
2879
|
+
const result = event.result;
|
|
2725
2880
|
return [
|
|
2726
2881
|
runCompletedLog({
|
|
2727
2882
|
sessionId,
|
|
2728
2883
|
runId,
|
|
2729
2884
|
durationMs: Date.now() - props.startedAt,
|
|
2730
|
-
usage:
|
|
2731
|
-
output:
|
|
2732
|
-
messageCount:
|
|
2885
|
+
usage: result.usage,
|
|
2886
|
+
output: result.text,
|
|
2887
|
+
messageCount: result.messages.length
|
|
2733
2888
|
}),
|
|
2734
|
-
memorySavedLog({ sessionId, runId, messageCount:
|
|
2889
|
+
memorySavedLog({ sessionId, runId, messageCount: result.messages.length })
|
|
2735
2890
|
];
|
|
2736
2891
|
}
|
|
2737
2892
|
if (event.type === "error") {
|
|
@@ -2843,16 +2998,16 @@ function childAgentLog(event, sessionId, runId) {
|
|
|
2843
2998
|
level: "debug",
|
|
2844
2999
|
category: "tool",
|
|
2845
3000
|
event: "child_tool.called",
|
|
2846
|
-
message: `Child agent ${event.agentName ?? event.agentId} called ${child.toolCall.
|
|
3001
|
+
message: `Child agent ${event.agentName ?? event.agentId} called ${child.toolCall.toolName}`,
|
|
2847
3002
|
metadata: {
|
|
2848
3003
|
parentToolName: event.toolName,
|
|
2849
3004
|
agentId: event.agentId,
|
|
2850
3005
|
hasAgentName: event.agentName !== void 0,
|
|
2851
3006
|
turn: event.turn,
|
|
2852
3007
|
childTurn: child.turn,
|
|
2853
|
-
toolName: child.toolCall.
|
|
2854
|
-
callId: child.toolCall.callId ?? child.toolCall.
|
|
2855
|
-
argumentBytes: byteLength2(formatUnknown(child.toolCall.
|
|
3008
|
+
toolName: child.toolCall.toolName,
|
|
3009
|
+
callId: child.toolCall.callId ?? child.toolCall.toolCallId,
|
|
3010
|
+
argumentBytes: byteLength2(formatUnknown(child.toolCall.input))
|
|
2856
3011
|
}
|
|
2857
3012
|
}
|
|
2858
3013
|
];
|
|
@@ -2903,14 +3058,16 @@ function childAgentLog(event, sessionId, runId) {
|
|
|
2903
3058
|
];
|
|
2904
3059
|
}
|
|
2905
3060
|
if (child.type === "final") {
|
|
3061
|
+
const result = child.result;
|
|
2906
3062
|
const metadata = {
|
|
2907
3063
|
parentToolName: event.toolName,
|
|
2908
3064
|
agentId: event.agentId,
|
|
2909
3065
|
hasAgentName: event.agentName !== void 0,
|
|
2910
|
-
outputBytes: byteLength2(
|
|
2911
|
-
messageCount:
|
|
3066
|
+
outputBytes: byteLength2(result.text),
|
|
3067
|
+
messageCount: result.messages.length,
|
|
3068
|
+
status: result.status
|
|
2912
3069
|
};
|
|
2913
|
-
const usage = usageSummary(
|
|
3070
|
+
const usage = usageSummary(result.usage);
|
|
2914
3071
|
if (usage !== void 0) metadata.usage = usage;
|
|
2915
3072
|
return [
|
|
2916
3073
|
{
|
|
@@ -3036,12 +3193,12 @@ async function prepareAgentRun(c, props) {
|
|
|
3036
3193
|
store: props.stores.sessions
|
|
3037
3194
|
});
|
|
3038
3195
|
const memoryMetadata = runMemoryMetadata(agentId, body, selectedModel, runId);
|
|
3039
|
-
const promptMessage =
|
|
3196
|
+
const promptMessage = body.messages.at(-1);
|
|
3040
3197
|
const sessionStore = props.stores.sessions;
|
|
3041
3198
|
const shouldPersistSessionMessages = session !== void 0 && sessionStore !== void 0 && !usesStoreAsAgentMemory(runAgent, sessionStore);
|
|
3042
3199
|
if (shouldPersistSessionMessages) {
|
|
3043
3200
|
await sessionStore.append({
|
|
3044
|
-
|
|
3201
|
+
scope: { sessionId: session.id, metadata: memoryMetadata },
|
|
3045
3202
|
runId,
|
|
3046
3203
|
turn: 1,
|
|
3047
3204
|
messages: [promptMessage]
|
|
@@ -3061,7 +3218,9 @@ async function prepareAgentRun(c, props) {
|
|
|
3061
3218
|
body,
|
|
3062
3219
|
memoryMetadata,
|
|
3063
3220
|
execution,
|
|
3064
|
-
|
|
3221
|
+
failureMessages: void 0,
|
|
3222
|
+
memoryCompactionLogged: false,
|
|
3223
|
+
options: createRunOptions(body, agentId, session, c.req.raw.signal),
|
|
3065
3224
|
runAgent,
|
|
3066
3225
|
runId,
|
|
3067
3226
|
runStartedAt,
|
|
@@ -3106,7 +3265,7 @@ async function recordRunReceived(props) {
|
|
|
3106
3265
|
sessionId: props.session.id,
|
|
3107
3266
|
runId: props.runId,
|
|
3108
3267
|
agentId: props.agentId,
|
|
3109
|
-
message: props.body.
|
|
3268
|
+
message: props.body.messages.at(-1),
|
|
3110
3269
|
stream: props.body.stream === true,
|
|
3111
3270
|
hasTrace: props.body.trace !== void 0
|
|
3112
3271
|
};
|
|
@@ -3154,21 +3313,29 @@ function runMemoryMetadata(agentId, body, selectedModel, runId) {
|
|
|
3154
3313
|
return metadata;
|
|
3155
3314
|
}
|
|
3156
3315
|
function createRunExecution(props) {
|
|
3157
|
-
|
|
3158
|
-
|
|
3316
|
+
const session = props.session;
|
|
3317
|
+
if (session !== void 0 && props.runAgent.memory !== void 0) {
|
|
3159
3318
|
return {
|
|
3160
|
-
generate: (options) =>
|
|
3161
|
-
|
|
3319
|
+
generate: (options) => props.runAgent.generate({
|
|
3320
|
+
prompt: props.promptMessage,
|
|
3321
|
+
session: { sessionId: session.id, metadata: props.memoryMetadata },
|
|
3322
|
+
...options
|
|
3323
|
+
}),
|
|
3324
|
+
stream: (options) => props.runAgent.stream({
|
|
3325
|
+
prompt: props.promptMessage,
|
|
3326
|
+
session: { sessionId: session.id, metadata: props.memoryMetadata },
|
|
3327
|
+
...options
|
|
3328
|
+
})
|
|
3162
3329
|
};
|
|
3163
3330
|
}
|
|
3164
|
-
const
|
|
3331
|
+
const transcript = session !== void 0 ? [...session.messages, props.promptMessage] : props.body.messages;
|
|
3165
3332
|
return {
|
|
3166
|
-
generate: (options) => props.runAgent.generate(
|
|
3167
|
-
stream: (options) => props.runAgent.stream(
|
|
3333
|
+
generate: (options) => props.runAgent.generate({ messages: transcript, ...options }),
|
|
3334
|
+
stream: (options) => props.runAgent.stream({ messages: transcript, ...options })
|
|
3168
3335
|
};
|
|
3169
3336
|
}
|
|
3170
|
-
function createRunOptions(body, agentId, session) {
|
|
3171
|
-
const options = {
|
|
3337
|
+
function createRunOptions(body, agentId, session, abortSignal) {
|
|
3338
|
+
const options = { abortSignal };
|
|
3172
3339
|
if (body.maxTurns !== void 0) options.maxTurns = body.maxTurns;
|
|
3173
3340
|
if (body.toolConcurrency !== void 0) options.toolConcurrency = body.toolConcurrency;
|
|
3174
3341
|
if (body.trace !== void 0) {
|
|
@@ -3221,7 +3388,7 @@ function handleStreamingAgentRun(c, run, props) {
|
|
|
3221
3388
|
}),
|
|
3222
3389
|
store: run.sessionStore,
|
|
3223
3390
|
session: run.session,
|
|
3224
|
-
message: run.body.
|
|
3391
|
+
message: run.body.messages.at(-1),
|
|
3225
3392
|
runId: run.runId,
|
|
3226
3393
|
startedAt: run.runStartedAt,
|
|
3227
3394
|
persistGeneratedMessages: run.shouldPersistSessionMessages
|
|
@@ -3229,6 +3396,7 @@ function handleStreamingAgentRun(c, run, props) {
|
|
|
3229
3396
|
stream = persistedRun.events;
|
|
3230
3397
|
}
|
|
3231
3398
|
return streamAgentRunEvents(c, stream, {
|
|
3399
|
+
runId: run.runId,
|
|
3232
3400
|
onCancel: async () => {
|
|
3233
3401
|
props.approvalRuntime.cancelRun(run.runId);
|
|
3234
3402
|
props.questionRuntime.cancelRun(run.runId);
|
|
@@ -3277,7 +3445,29 @@ async function startBufferedSessionRun(run, props) {
|
|
|
3277
3445
|
if (run.session !== void 0) questionContext.sessionId = run.session.id;
|
|
3278
3446
|
if (run.body.metadata !== void 0) questionContext.metadata = run.body.metadata;
|
|
3279
3447
|
const effectiveHook = props.questionRuntime.createHook(questionContext);
|
|
3280
|
-
|
|
3448
|
+
const internalOptions = {
|
|
3449
|
+
hook: effectiveHook,
|
|
3450
|
+
onFailure: ({ messages }) => {
|
|
3451
|
+
run.failureMessages = structuredClone(messages);
|
|
3452
|
+
},
|
|
3453
|
+
runId: run.runId
|
|
3454
|
+
};
|
|
3455
|
+
if (run.session !== void 0 && run.sessionStore !== void 0) {
|
|
3456
|
+
const sessionId = run.session.id;
|
|
3457
|
+
const sessionStore = run.sessionStore;
|
|
3458
|
+
internalOptions.onMemoryCompaction = async (compaction) => {
|
|
3459
|
+
await appendSessionLog(
|
|
3460
|
+
sessionStore,
|
|
3461
|
+
memoryCompactedLog({
|
|
3462
|
+
sessionId,
|
|
3463
|
+
runId: run.runId,
|
|
3464
|
+
...compaction
|
|
3465
|
+
})
|
|
3466
|
+
);
|
|
3467
|
+
run.memoryCompactionLogged = true;
|
|
3468
|
+
};
|
|
3469
|
+
}
|
|
3470
|
+
return withInternalAgentRunOptions({ ...run.options }, internalOptions);
|
|
3281
3471
|
}
|
|
3282
3472
|
function createApprovalContext(run, emit) {
|
|
3283
3473
|
const context = {
|
|
@@ -3313,7 +3503,7 @@ async function completeBufferedSessionRun(run, response) {
|
|
|
3313
3503
|
const generatedMessages = response.messages.slice(1);
|
|
3314
3504
|
if (generatedMessages.length > 0) {
|
|
3315
3505
|
await run.sessionStore.append({
|
|
3316
|
-
|
|
3506
|
+
scope: { sessionId: run.session.id, metadata: run.memoryMetadata },
|
|
3317
3507
|
runId: run.runId,
|
|
3318
3508
|
turn: 1,
|
|
3319
3509
|
messages: generatedMessages
|
|
@@ -3326,10 +3516,21 @@ async function completeBufferedSessionRun(run, response) {
|
|
|
3326
3516
|
await run.sessionStore.saveSessionRunTranscript({
|
|
3327
3517
|
id: run.session.id,
|
|
3328
3518
|
runId: run.runId,
|
|
3329
|
-
...optionalTitle(run.body.
|
|
3519
|
+
...optionalTitle(run.body.messages.at(-1)),
|
|
3330
3520
|
transcript,
|
|
3331
3521
|
status: "success"
|
|
3332
3522
|
});
|
|
3523
|
+
if (response.memoryCompaction !== void 0 && !run.memoryCompactionLogged) {
|
|
3524
|
+
await appendSessionLog(
|
|
3525
|
+
run.sessionStore,
|
|
3526
|
+
memoryCompactedLog({
|
|
3527
|
+
sessionId: run.session.id,
|
|
3528
|
+
runId: run.runId,
|
|
3529
|
+
...response.memoryCompaction
|
|
3530
|
+
})
|
|
3531
|
+
);
|
|
3532
|
+
run.memoryCompactionLogged = true;
|
|
3533
|
+
}
|
|
3333
3534
|
await appendSessionLog(
|
|
3334
3535
|
run.sessionStore,
|
|
3335
3536
|
runCompletedLog({
|
|
@@ -3337,7 +3538,7 @@ async function completeBufferedSessionRun(run, response) {
|
|
|
3337
3538
|
runId: run.runId,
|
|
3338
3539
|
durationMs: durationMs2,
|
|
3339
3540
|
usage: response.usage,
|
|
3340
|
-
output: response.
|
|
3541
|
+
output: response.text,
|
|
3341
3542
|
messageCount: response.messages.length
|
|
3342
3543
|
})
|
|
3343
3544
|
);
|
|
@@ -3354,17 +3555,14 @@ async function failBufferedSessionRun(run, error) {
|
|
|
3354
3555
|
if (run.session === void 0 || run.sessionStore === void 0) {
|
|
3355
3556
|
return;
|
|
3356
3557
|
}
|
|
3357
|
-
const messages = await run.sessionStore.load({
|
|
3358
|
-
sessionId: run.session.id,
|
|
3359
|
-
metadata: run.memoryMetadata
|
|
3360
|
-
});
|
|
3361
3558
|
const durationMs2 = Date.now() - run.runStartedAt;
|
|
3362
|
-
const
|
|
3559
|
+
const messages = run.failureMessages ?? [run.body.messages.at(-1)];
|
|
3560
|
+
const transcript = transcriptFromMessages([...messages]);
|
|
3363
3561
|
assignTranscriptRunDuration(transcript, durationMs2);
|
|
3364
3562
|
await run.sessionStore.saveSessionRunTranscript({
|
|
3365
3563
|
id: run.session.id,
|
|
3366
3564
|
runId: run.runId,
|
|
3367
|
-
...optionalTitle(run.body.
|
|
3565
|
+
...optionalTitle(run.body.messages.at(-1)),
|
|
3368
3566
|
transcript,
|
|
3369
3567
|
status: "error",
|
|
3370
3568
|
error: serializeError(error)
|
|
@@ -3374,9 +3572,6 @@ async function failBufferedSessionRun(run, error) {
|
|
|
3374
3572
|
runFailedLog(run.session.id, run.runId, error, run.runStartedAt)
|
|
3375
3573
|
);
|
|
3376
3574
|
}
|
|
3377
|
-
function normalizePromptMessage(message) {
|
|
3378
|
-
return typeof message === "string" ? Message.user(message) : message;
|
|
3379
|
-
}
|
|
3380
3575
|
function usesStoreAsAgentMemory(agent, store) {
|
|
3381
3576
|
const memoryStore = agent.memory?.store;
|
|
3382
3577
|
return memoryStore !== void 0 && rawObservedStore(memoryStore) === rawObservedStore(store);
|
|
@@ -3763,7 +3958,7 @@ async function agentKnowledgeConfig(agent) {
|
|
|
3763
3958
|
async function knowledgeSources(agent) {
|
|
3764
3959
|
const toolIndexes = getAgentToolState(agent.agent).toolIndexes;
|
|
3765
3960
|
const staticContext = staticContextDocuments(agent.agent);
|
|
3766
|
-
const indexedContext =
|
|
3961
|
+
const indexedContext = vectorContexts(agent.agent);
|
|
3767
3962
|
const sources = [
|
|
3768
3963
|
{
|
|
3769
3964
|
sourceId: staticSourceId(),
|
|
@@ -3775,20 +3970,20 @@ async function knowledgeSources(agent) {
|
|
|
3775
3970
|
}
|
|
3776
3971
|
];
|
|
3777
3972
|
const dynamicContextSources = await Promise.all(
|
|
3778
|
-
indexedContext.map(async (
|
|
3779
|
-
const inspect = inspectFn(
|
|
3780
|
-
const count = await inspectableCount(inspect,
|
|
3973
|
+
indexedContext.map(async (vectorContext, index) => {
|
|
3974
|
+
const inspect = inspectFn(vectorContext.store);
|
|
3975
|
+
const count = await inspectableCount(inspect, vectorContext.filter);
|
|
3781
3976
|
const source = {
|
|
3782
3977
|
sourceId: dynamicContextSourceId(index),
|
|
3783
3978
|
kind: "dynamic_context",
|
|
3784
3979
|
label: `Dynamic context ${index + 1}`,
|
|
3785
3980
|
count: 1,
|
|
3786
3981
|
registrationIndex: index,
|
|
3787
|
-
topK:
|
|
3982
|
+
topK: vectorContext.topK,
|
|
3788
3983
|
inspectable: inspect !== void 0
|
|
3789
3984
|
};
|
|
3790
|
-
if (
|
|
3791
|
-
source.
|
|
3985
|
+
if (vectorContext.minScore !== void 0) {
|
|
3986
|
+
source.minScore = vectorContext.minScore;
|
|
3792
3987
|
}
|
|
3793
3988
|
if (count !== void 0) source.itemCount = count;
|
|
3794
3989
|
return source;
|
|
@@ -3807,8 +4002,8 @@ async function knowledgeSources(agent) {
|
|
|
3807
4002
|
topK: toolIndex.topK,
|
|
3808
4003
|
inspectable: inspect !== void 0
|
|
3809
4004
|
};
|
|
3810
|
-
if (toolIndex.
|
|
3811
|
-
source.
|
|
4005
|
+
if (toolIndex.minScore !== void 0) {
|
|
4006
|
+
source.minScore = toolIndex.minScore;
|
|
3812
4007
|
}
|
|
3813
4008
|
if (count !== void 0) source.itemCount = count;
|
|
3814
4009
|
return source;
|
|
@@ -3827,20 +4022,20 @@ async function knowledgeItemsPage(agent, sourceId, request) {
|
|
|
3827
4022
|
if (sourceId === staticSourceId()) {
|
|
3828
4023
|
return staticKnowledgeItemsPage(agent, request);
|
|
3829
4024
|
}
|
|
3830
|
-
const
|
|
3831
|
-
if (
|
|
3832
|
-
const
|
|
3833
|
-
if (
|
|
4025
|
+
const vectorContextIndex = dynamicSourceIndex(sourceId, "dynamic_context");
|
|
4026
|
+
if (vectorContextIndex !== void 0) {
|
|
4027
|
+
const vectorContext = vectorContexts(agent.agent)[vectorContextIndex];
|
|
4028
|
+
if (vectorContext === void 0) {
|
|
3834
4029
|
return void 0;
|
|
3835
4030
|
}
|
|
3836
|
-
const inspect = inspectFn(
|
|
4031
|
+
const inspect = inspectFn(vectorContext.store);
|
|
3837
4032
|
if (inspect === void 0) {
|
|
3838
4033
|
return nonInspectablePage(agent.id, sourceId, "dynamic_context");
|
|
3839
4034
|
}
|
|
3840
4035
|
const page = await inspect({
|
|
3841
4036
|
limit: request.limit,
|
|
3842
4037
|
cursor: request.cursor,
|
|
3843
|
-
filter:
|
|
4038
|
+
filter: vectorContext.filter
|
|
3844
4039
|
});
|
|
3845
4040
|
const result = {
|
|
3846
4041
|
agentId: agent.id,
|
|
@@ -3881,12 +4076,12 @@ async function knowledgeItemsPage(agent, sourceId, request) {
|
|
|
3881
4076
|
}
|
|
3882
4077
|
return void 0;
|
|
3883
4078
|
}
|
|
3884
|
-
function inspectFn(
|
|
3885
|
-
if (!isRecord3(
|
|
4079
|
+
function inspectFn(store) {
|
|
4080
|
+
if (!isRecord3(store) || typeof store.inspect !== "function") {
|
|
3886
4081
|
return void 0;
|
|
3887
4082
|
}
|
|
3888
|
-
const inspect =
|
|
3889
|
-
return (request) => inspect.call(
|
|
4083
|
+
const inspect = store.inspect;
|
|
4084
|
+
return (request) => inspect.call(store, request);
|
|
3890
4085
|
}
|
|
3891
4086
|
function staticKnowledgeItemsPage(agent, request) {
|
|
3892
4087
|
const staticContext = staticContextDocuments(agent.agent);
|
|
@@ -4102,7 +4297,7 @@ function isRecord3(value) {
|
|
|
4102
4297
|
|
|
4103
4298
|
// src/runtime/tool-metadata.ts
|
|
4104
4299
|
import { getAgentToolState as getAgentToolState2 } from "@anvia/core/internal/agent";
|
|
4105
|
-
|
|
4300
|
+
import { isMcpTool } from "@anvia/core/mcp";
|
|
4106
4301
|
function agentToolItems(agent) {
|
|
4107
4302
|
const state = getAgentToolState2(agent.agent);
|
|
4108
4303
|
const items = state.staticTools.map((tool) => ({ tool, source: "static" }));
|
|
@@ -4135,15 +4330,10 @@ function toolRequiresApproval(tool) {
|
|
|
4135
4330
|
return approval !== void 0 && approval !== false;
|
|
4136
4331
|
}
|
|
4137
4332
|
function mcpServerName(tool) {
|
|
4138
|
-
|
|
4139
|
-
if (typeof metadata !== "object" || metadata === null) {
|
|
4140
|
-
return void 0;
|
|
4141
|
-
}
|
|
4142
|
-
const serverName = metadata.serverName;
|
|
4143
|
-
return typeof serverName === "string" && serverName.length > 0 ? serverName : void 0;
|
|
4333
|
+
return isMcpTool(tool) ? tool.mcp.serverName : void 0;
|
|
4144
4334
|
}
|
|
4145
|
-
function
|
|
4146
|
-
return
|
|
4335
|
+
function agentHasMcpServers(agent) {
|
|
4336
|
+
return agent.agent.mcpServers.length > 0;
|
|
4147
4337
|
}
|
|
4148
4338
|
|
|
4149
4339
|
// src/runtime/config.ts
|
|
@@ -4165,7 +4355,7 @@ function agentConfig(agent) {
|
|
|
4165
4355
|
function agentRuntimeSummary(agent) {
|
|
4166
4356
|
const tools = agentToolItems(agent);
|
|
4167
4357
|
const staticContext = staticContextDocuments(agent.agent);
|
|
4168
|
-
const indexedContext =
|
|
4358
|
+
const indexedContext = vectorContexts(agent.agent);
|
|
4169
4359
|
const name = agent.name ?? agent.agent.name;
|
|
4170
4360
|
const description = agent.description ?? agent.agent.description;
|
|
4171
4361
|
const summary = {
|
|
@@ -4178,7 +4368,7 @@ function agentRuntimeSummary(agent) {
|
|
|
4178
4368
|
mcpToolCount: tools.filter((item) => mcpServerName(item.tool) !== void 0).length,
|
|
4179
4369
|
staticContextCount: staticContext.length,
|
|
4180
4370
|
dynamicContextCount: indexedContext.length,
|
|
4181
|
-
observerCount: agent.agent.observers.length,
|
|
4371
|
+
observerCount: Object.keys(agent.agent.observability?.observers ?? {}).length,
|
|
4182
4372
|
hasMemory: agent.agent.memory !== void 0,
|
|
4183
4373
|
hasLifecycle: agent.agent.lifecycle !== void 0,
|
|
4184
4374
|
hasOutputSchema: agent.agent.outputSchema !== void 0
|
|
@@ -4250,7 +4440,7 @@ function capabilityConfig(_options, agents, pipelines, stores, sandboxCount = 0)
|
|
|
4250
4440
|
if (agents.some((agent) => agent.agent.tools.length > 0)) {
|
|
4251
4441
|
capabilities.tools = { enabled: true };
|
|
4252
4442
|
}
|
|
4253
|
-
if (agents.some(
|
|
4443
|
+
if (agents.some(agentHasMcpServers)) {
|
|
4254
4444
|
capabilities.mcps = { enabled: true };
|
|
4255
4445
|
}
|
|
4256
4446
|
if (sandboxCount > 0) {
|
|
@@ -4354,43 +4544,29 @@ function registerMcpRoutes(app, props) {
|
|
|
4354
4544
|
});
|
|
4355
4545
|
}
|
|
4356
4546
|
async function agentMcpMetadata(agent) {
|
|
4357
|
-
|
|
4358
|
-
|
|
4359
|
-
|
|
4360
|
-
|
|
4361
|
-
|
|
4362
|
-
|
|
4363
|
-
|
|
4364
|
-
|
|
4365
|
-
|
|
4366
|
-
|
|
4367
|
-
|
|
4368
|
-
|
|
4369
|
-
|
|
4370
|
-
|
|
4371
|
-
|
|
4372
|
-
|
|
4373
|
-
|
|
4374
|
-
|
|
4375
|
-
|
|
4376
|
-
|
|
4377
|
-
|
|
4378
|
-
|
|
4379
|
-
|
|
4380
|
-
return [...servers.entries()].map(([name, tools]) => {
|
|
4381
|
-
const sortedTools = tools.sort((left, right) => {
|
|
4382
|
-
if (left.source !== right.source) {
|
|
4383
|
-
return left.source === "static" ? -1 : 1;
|
|
4384
|
-
}
|
|
4385
|
-
return left.name.localeCompare(right.name);
|
|
4386
|
-
});
|
|
4387
|
-
return {
|
|
4388
|
-
agentId: agent.id,
|
|
4389
|
-
name,
|
|
4390
|
-
toolCount: sortedTools.length,
|
|
4391
|
-
tools: sortedTools
|
|
4392
|
-
};
|
|
4393
|
-
}).sort((left, right) => left.name.localeCompare(right.name));
|
|
4547
|
+
return Promise.all(
|
|
4548
|
+
agent.agent.mcpServers.map(async (server) => {
|
|
4549
|
+
const tools = await Promise.all(
|
|
4550
|
+
server.tools.map(async (tool) => {
|
|
4551
|
+
const definition = await tool.definition("");
|
|
4552
|
+
return {
|
|
4553
|
+
name: definition.name,
|
|
4554
|
+
description: definition.description,
|
|
4555
|
+
parameters: definition.parameters,
|
|
4556
|
+
source: "static",
|
|
4557
|
+
approval: approvalMetadata(tool)
|
|
4558
|
+
};
|
|
4559
|
+
})
|
|
4560
|
+
);
|
|
4561
|
+
const sortedTools = tools.sort((left, right) => left.name.localeCompare(right.name));
|
|
4562
|
+
return {
|
|
4563
|
+
agentId: agent.id,
|
|
4564
|
+
name: server.name,
|
|
4565
|
+
toolCount: sortedTools.length,
|
|
4566
|
+
tools: sortedTools
|
|
4567
|
+
};
|
|
4568
|
+
})
|
|
4569
|
+
).then((servers) => servers.sort((left, right) => left.name.localeCompare(right.name)));
|
|
4394
4570
|
}
|
|
4395
4571
|
|
|
4396
4572
|
// src/runtime/memory.ts
|
|
@@ -4612,7 +4788,7 @@ function agentMemorySource(ref, label, agentId, storeKindValue, inspector) {
|
|
|
4612
4788
|
).slice(0, options.limit);
|
|
4613
4789
|
},
|
|
4614
4790
|
async getConversation(conversationRef) {
|
|
4615
|
-
const conversation = await inspector.getConversation(conversationRef);
|
|
4791
|
+
const conversation = await inspector.getConversation({ ref: conversationRef });
|
|
4616
4792
|
return conversation === void 0 ? void 0 : inspectorConversationDetail(conversation, summary.agentIds);
|
|
4617
4793
|
}
|
|
4618
4794
|
};
|
|
@@ -4835,12 +5011,12 @@ function pipelineRunFailedLog(pipelineId, runId, error, startedAt) {
|
|
|
4835
5011
|
}
|
|
4836
5012
|
};
|
|
4837
5013
|
}
|
|
4838
|
-
function pipelineStageLog(
|
|
5014
|
+
function pipelineStageLog(event, studioPipelineId = event.pipelineId) {
|
|
4839
5015
|
const category = stageCategory(event.node);
|
|
4840
5016
|
if (event.type === "stage_started") {
|
|
4841
5017
|
return {
|
|
4842
|
-
pipelineId,
|
|
4843
|
-
runId,
|
|
5018
|
+
pipelineId: studioPipelineId,
|
|
5019
|
+
runId: event.runId,
|
|
4844
5020
|
level: "debug",
|
|
4845
5021
|
category,
|
|
4846
5022
|
event: `${event.node.kind}.started`,
|
|
@@ -4850,8 +5026,8 @@ function pipelineStageLog(pipelineId, runId, event) {
|
|
|
4850
5026
|
}
|
|
4851
5027
|
if (event.type === "stage_completed") {
|
|
4852
5028
|
return {
|
|
4853
|
-
pipelineId,
|
|
4854
|
-
runId,
|
|
5029
|
+
pipelineId: studioPipelineId,
|
|
5030
|
+
runId: event.runId,
|
|
4855
5031
|
level: "debug",
|
|
4856
5032
|
category,
|
|
4857
5033
|
event: `${event.node.kind}.completed`,
|
|
@@ -4863,8 +5039,8 @@ function pipelineStageLog(pipelineId, runId, event) {
|
|
|
4863
5039
|
};
|
|
4864
5040
|
}
|
|
4865
5041
|
return {
|
|
4866
|
-
pipelineId,
|
|
4867
|
-
runId,
|
|
5042
|
+
pipelineId: studioPipelineId,
|
|
5043
|
+
runId: event.runId,
|
|
4868
5044
|
level: "error",
|
|
4869
5045
|
category,
|
|
4870
5046
|
event: `${event.node.kind}.failed`,
|
|
@@ -4891,6 +5067,7 @@ function stageCategory(node) {
|
|
|
4891
5067
|
function nodeMetadata(node) {
|
|
4892
5068
|
const metadata = {
|
|
4893
5069
|
nodeId: node.id,
|
|
5070
|
+
nodePath: [...node.path],
|
|
4894
5071
|
kind: node.kind,
|
|
4895
5072
|
label: node.label
|
|
4896
5073
|
};
|
|
@@ -5052,17 +5229,24 @@ async function executePipelineRun(c, props, pipeline, body) {
|
|
|
5052
5229
|
if (body.metadata !== void 0) streamOptions.metadata = body.metadata;
|
|
5053
5230
|
if (props.logStore !== void 0) streamOptions.logStore = props.logStore;
|
|
5054
5231
|
if (props.runStore !== void 0) streamOptions.runStore = props.runStore;
|
|
5232
|
+
streamOptions.abortSignal = c.req.raw.signal;
|
|
5055
5233
|
return streamPipelineRun(c, streamOptions);
|
|
5056
5234
|
}
|
|
5057
5235
|
try {
|
|
5058
5236
|
await appendPipelineLog(props.logStore, pipelineRunStartedLog(pipeline, runId));
|
|
5059
|
-
const
|
|
5237
|
+
const result = await pipeline.pipeline.run({
|
|
5238
|
+
input: body.input,
|
|
5239
|
+
runId,
|
|
5240
|
+
metadata: body.metadata,
|
|
5241
|
+
abortSignal: c.req.raw.signal,
|
|
5060
5242
|
observer: {
|
|
5061
5243
|
async onEvent(event) {
|
|
5062
|
-
await appendPipelineLog(props.logStore, pipelineStageLog(pipeline.id
|
|
5244
|
+
await appendPipelineLog(props.logStore, pipelineStageLog(event, pipeline.id));
|
|
5063
5245
|
}
|
|
5064
|
-
}
|
|
5246
|
+
},
|
|
5247
|
+
failOnObserverError: true
|
|
5065
5248
|
});
|
|
5249
|
+
const output = result.output;
|
|
5066
5250
|
const jsonOutput = toJsonValue(output);
|
|
5067
5251
|
const endedAt = Date.now();
|
|
5068
5252
|
const successRecord = {
|
|
@@ -5127,19 +5311,24 @@ function streamPipelineRun(_c, props) {
|
|
|
5127
5311
|
async function* pipelineRunEvents(props) {
|
|
5128
5312
|
yield* emitPipelineLog(props.logStore, pipelineRunStartedLog(props.pipeline, props.runId));
|
|
5129
5313
|
const events = new AsyncEventQueue();
|
|
5130
|
-
const run = props.pipeline.pipeline.run(
|
|
5314
|
+
const run = props.pipeline.pipeline.run({
|
|
5315
|
+
input: props.input,
|
|
5316
|
+
runId: props.runId,
|
|
5317
|
+
metadata: props.metadata,
|
|
5318
|
+
abortSignal: props.abortSignal,
|
|
5131
5319
|
observer: {
|
|
5132
5320
|
async onEvent(event) {
|
|
5133
5321
|
const log = await appendPipelineLog(
|
|
5134
5322
|
props.logStore,
|
|
5135
|
-
pipelineStageLog(props.pipeline.id
|
|
5323
|
+
pipelineStageLog(event, props.pipeline.id)
|
|
5136
5324
|
);
|
|
5137
5325
|
if (log !== void 0) {
|
|
5138
5326
|
events.push({ type: "pipeline_log", log });
|
|
5139
5327
|
}
|
|
5140
5328
|
}
|
|
5141
|
-
}
|
|
5142
|
-
|
|
5329
|
+
},
|
|
5330
|
+
failOnObserverError: true
|
|
5331
|
+
}).then(async ({ output }) => {
|
|
5143
5332
|
const jsonOutput = toJsonValue(output);
|
|
5144
5333
|
const endedAt = Date.now();
|
|
5145
5334
|
const successRecord = {
|
|
@@ -6143,6 +6332,16 @@ function createInMemoryStudioStore() {
|
|
|
6143
6332
|
}
|
|
6144
6333
|
var InMemoryStudioStore = class {
|
|
6145
6334
|
kind = "memory";
|
|
6335
|
+
compaction = {
|
|
6336
|
+
snapshot: ({ scope }) => {
|
|
6337
|
+
const messages = this.sessions.get(scope.sessionId)?.messages ?? [];
|
|
6338
|
+
return Promise.resolve({
|
|
6339
|
+
revision: memoryRevision(messages),
|
|
6340
|
+
messages: cloneMessages(messages)
|
|
6341
|
+
});
|
|
6342
|
+
},
|
|
6343
|
+
replacePrefix: (options) => this.replaceCompactionPrefix(options)
|
|
6344
|
+
};
|
|
6146
6345
|
sessions = /* @__PURE__ */ new Map();
|
|
6147
6346
|
traces = /* @__PURE__ */ new Map();
|
|
6148
6347
|
pipelineLogs = /* @__PURE__ */ new Map();
|
|
@@ -6184,20 +6383,20 @@ var InMemoryStudioStore = class {
|
|
|
6184
6383
|
session.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
6185
6384
|
return materializeSession(session);
|
|
6186
6385
|
}
|
|
6187
|
-
load(
|
|
6188
|
-
return Promise.resolve(this.sessions.get(
|
|
6386
|
+
load({ scope }) {
|
|
6387
|
+
return Promise.resolve(cloneMessages(this.sessions.get(scope.sessionId)?.messages ?? []));
|
|
6189
6388
|
}
|
|
6190
6389
|
append(input) {
|
|
6191
|
-
const session = this.sessions.get(input.
|
|
6390
|
+
const session = this.sessions.get(input.scope.sessionId);
|
|
6192
6391
|
if (session !== void 0) {
|
|
6193
|
-
session.messages.push(...input.messages);
|
|
6392
|
+
session.messages.push(...cloneMessages(input.messages));
|
|
6194
6393
|
session.messageCount = session.messages.length;
|
|
6195
6394
|
session.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
6196
6395
|
}
|
|
6197
6396
|
return Promise.resolve();
|
|
6198
6397
|
}
|
|
6199
|
-
clear(
|
|
6200
|
-
const session = this.sessions.get(
|
|
6398
|
+
clear({ scope }) {
|
|
6399
|
+
const session = this.sessions.get(scope.sessionId);
|
|
6201
6400
|
if (session !== void 0) {
|
|
6202
6401
|
session.messages = [];
|
|
6203
6402
|
session.runs = [];
|
|
@@ -6208,13 +6407,26 @@ var InMemoryStudioStore = class {
|
|
|
6208
6407
|
}
|
|
6209
6408
|
async recordError(input) {
|
|
6210
6409
|
await this.saveSessionRunTranscript({
|
|
6211
|
-
id: input.
|
|
6212
|
-
runId: studioRunId(input.
|
|
6410
|
+
id: input.scope.sessionId,
|
|
6411
|
+
runId: studioRunId(input.scope) ?? input.runId,
|
|
6213
6412
|
transcript: transcriptFromMessages(input.messages),
|
|
6214
6413
|
status: "error",
|
|
6215
6414
|
error: serializeJsonError(input.error)
|
|
6216
6415
|
});
|
|
6217
6416
|
}
|
|
6417
|
+
replaceCompactionPrefix(input) {
|
|
6418
|
+
if (!Number.isSafeInteger(input.messageCount) || input.messageCount < 1) {
|
|
6419
|
+
throw new RangeError("messageCount must be a positive integer.");
|
|
6420
|
+
}
|
|
6421
|
+
const session = this.sessions.get(input.scope.sessionId);
|
|
6422
|
+
if (session === void 0 || memoryRevision(session.messages) !== input.revision || input.messageCount > session.messages.length) {
|
|
6423
|
+
return Promise.resolve({ status: "conflict" });
|
|
6424
|
+
}
|
|
6425
|
+
session.messages.splice(0, input.messageCount, structuredClone(input.replacement));
|
|
6426
|
+
session.messageCount = session.messages.length;
|
|
6427
|
+
session.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
6428
|
+
return Promise.resolve({ status: "committed" });
|
|
6429
|
+
}
|
|
6218
6430
|
saveSessionRunTranscript(input) {
|
|
6219
6431
|
const session = this.sessions.get(input.id);
|
|
6220
6432
|
if (session === void 0) {
|
|
@@ -6340,18 +6552,24 @@ function sessionSummary(session) {
|
|
|
6340
6552
|
function materializeSession(session) {
|
|
6341
6553
|
return {
|
|
6342
6554
|
...sessionSummary(session),
|
|
6343
|
-
messages:
|
|
6555
|
+
messages: cloneMessages(session.messages),
|
|
6344
6556
|
transcript: renumberTranscript(session.runs.flatMap((run) => run.transcript))
|
|
6345
6557
|
};
|
|
6346
6558
|
}
|
|
6559
|
+
function cloneMessages(messages) {
|
|
6560
|
+
return structuredClone([...messages]);
|
|
6561
|
+
}
|
|
6347
6562
|
function traceAgentId(trace) {
|
|
6348
6563
|
const nestedMetadata = trace.metadata?.metadata;
|
|
6349
6564
|
return isJsonObject(nestedMetadata) && typeof nestedMetadata.agentId === "string" ? nestedMetadata.agentId : void 0;
|
|
6350
6565
|
}
|
|
6351
|
-
function studioRunId(
|
|
6352
|
-
const value =
|
|
6566
|
+
function studioRunId(scope) {
|
|
6567
|
+
const value = scope.metadata?.studioRunId;
|
|
6353
6568
|
return typeof value === "string" && value.length > 0 ? value : void 0;
|
|
6354
6569
|
}
|
|
6570
|
+
function memoryRevision(messages) {
|
|
6571
|
+
return JSON.stringify(messages);
|
|
6572
|
+
}
|
|
6355
6573
|
function serializeJsonError(error) {
|
|
6356
6574
|
if (error instanceof Error) {
|
|
6357
6575
|
return {
|
|
@@ -6877,11 +7095,11 @@ function uniqueAgentId(baseId, ids) {
|
|
|
6877
7095
|
function agentMetadata(agent) {
|
|
6878
7096
|
const metadata = {
|
|
6879
7097
|
staticContextCount: staticContextDocuments(agent).length,
|
|
6880
|
-
dynamicContextCount:
|
|
7098
|
+
dynamicContextCount: vectorContexts(agent).length,
|
|
6881
7099
|
dynamicToolCount: getAgentToolState3(agent).toolIndexes.length,
|
|
6882
7100
|
hasLifecycle: agent.lifecycle !== void 0,
|
|
6883
7101
|
hasOutputSchema: agent.outputSchema !== void 0,
|
|
6884
|
-
observerCount: agent.observers.length,
|
|
7102
|
+
observerCount: Object.keys(agent.observability?.observers ?? {}).length,
|
|
6885
7103
|
approvalToolCount: agent.tools.filter(toolRequiresApproval).length
|
|
6886
7104
|
};
|
|
6887
7105
|
if (agent.defaultMaxTurns !== void 0) metadata.defaultMaxTurns = agent.defaultMaxTurns;
|
|
@@ -7012,30 +7230,37 @@ function createStudioApp(options) {
|
|
|
7012
7230
|
return studio;
|
|
7013
7231
|
}
|
|
7014
7232
|
function withStudioTraceObserver(studioAgent, traceStore) {
|
|
7015
|
-
if (traceStore === void 0
|
|
7016
|
-
|
|
7233
|
+
if (traceStore === void 0) return studioAgent;
|
|
7234
|
+
const existing = studioAgent.agent.observability;
|
|
7235
|
+
const studioObserver = existing?.observers.studio;
|
|
7236
|
+
if (studioObserver !== void 0 && !(studioObserver instanceof StudioTraceObserver)) {
|
|
7237
|
+
throw new TypeError('Studio reserves the observer name "studio" for local trace persistence.');
|
|
7238
|
+
}
|
|
7239
|
+
for (const [name, observer] of Object.entries(existing?.observers ?? {})) {
|
|
7240
|
+
if (observer instanceof StudioTraceObserver && name !== "studio") {
|
|
7241
|
+
throw new TypeError('StudioTraceObserver must be registered with the name "studio".');
|
|
7242
|
+
}
|
|
7017
7243
|
}
|
|
7018
7244
|
return {
|
|
7019
7245
|
...studioAgent,
|
|
7020
7246
|
agent: cloneAgent(studioAgent.agent, {
|
|
7021
|
-
|
|
7022
|
-
|
|
7023
|
-
|
|
7024
|
-
|
|
7247
|
+
observability: {
|
|
7248
|
+
observers: {
|
|
7249
|
+
...existing?.observers ?? {},
|
|
7250
|
+
studio: studioObserver ?? new StudioTraceObserver({ store: traceStore })
|
|
7251
|
+
},
|
|
7252
|
+
primaryTrace: "studio",
|
|
7253
|
+
errorPolicy: existing?.errorPolicy ?? "ignore"
|
|
7254
|
+
}
|
|
7025
7255
|
})
|
|
7026
7256
|
};
|
|
7027
7257
|
}
|
|
7028
|
-
function hasStudioTraceObserver(agent) {
|
|
7029
|
-
return agent.observers.some(
|
|
7030
|
-
(registration) => registration.observer instanceof StudioTraceObserver
|
|
7031
|
-
);
|
|
7032
|
-
}
|
|
7033
7258
|
|
|
7034
7259
|
// src/storage/sqlite-store.ts
|
|
7035
7260
|
import { mkdirSync } from "fs";
|
|
7036
7261
|
import { createRequire } from "module";
|
|
7037
7262
|
import { dirname, resolve } from "path";
|
|
7038
|
-
import { isJsonValue as
|
|
7263
|
+
import { isJsonValue as isJsonValue3 } from "@anvia/core/completion";
|
|
7039
7264
|
var DatabaseSync;
|
|
7040
7265
|
function createSqliteSessionStore(options = {}) {
|
|
7041
7266
|
return new SqliteSessionStore(options.path ?? ":memory:");
|
|
@@ -7046,6 +7271,13 @@ var SqliteSessionStore = class {
|
|
|
7046
7271
|
}
|
|
7047
7272
|
path;
|
|
7048
7273
|
kind = "sqlite";
|
|
7274
|
+
compaction = {
|
|
7275
|
+
snapshot: ({ scope }) => {
|
|
7276
|
+
const messages = this.listSessionMessages(scope.sessionId);
|
|
7277
|
+
return Promise.resolve({ revision: memoryRevision2(messages), messages });
|
|
7278
|
+
},
|
|
7279
|
+
replacePrefix: (options) => this.replaceCompactionPrefix(options)
|
|
7280
|
+
};
|
|
7049
7281
|
db;
|
|
7050
7282
|
listSessions(options) {
|
|
7051
7283
|
const db = this.database();
|
|
@@ -7117,8 +7349,8 @@ var SqliteSessionStore = class {
|
|
|
7117
7349
|
}
|
|
7118
7350
|
return this.getSession(id);
|
|
7119
7351
|
}
|
|
7120
|
-
load(
|
|
7121
|
-
const session = this.getSession(
|
|
7352
|
+
load({ scope }) {
|
|
7353
|
+
const session = this.getSession(scope.sessionId);
|
|
7122
7354
|
return Promise.resolve(session?.messages ?? []);
|
|
7123
7355
|
}
|
|
7124
7356
|
append(input) {
|
|
@@ -7129,20 +7361,20 @@ var SqliteSessionStore = class {
|
|
|
7129
7361
|
`SELECT id, agent_id, title, metadata_json, created_at, updated_at
|
|
7130
7362
|
FROM anvia_studio_sessions
|
|
7131
7363
|
WHERE id = $id`
|
|
7132
|
-
).get({ $id: input.
|
|
7364
|
+
).get({ $id: input.scope.sessionId });
|
|
7133
7365
|
if (row === void 0) {
|
|
7134
7366
|
db.exec("ROLLBACK");
|
|
7135
7367
|
return Promise.resolve();
|
|
7136
7368
|
}
|
|
7137
7369
|
const updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
7138
|
-
const nextIndex = this.nextMessageIndex(input.
|
|
7139
|
-
this.insertMessages(input.
|
|
7370
|
+
const nextIndex = this.nextMessageIndex(input.scope.sessionId);
|
|
7371
|
+
this.insertMessages(input.scope.sessionId, input.messages, nextIndex, updatedAt);
|
|
7140
7372
|
db.prepare(
|
|
7141
7373
|
`UPDATE anvia_studio_sessions
|
|
7142
7374
|
SET updated_at = $updatedAt
|
|
7143
7375
|
WHERE id = $id`
|
|
7144
7376
|
).run({
|
|
7145
|
-
$id: input.
|
|
7377
|
+
$id: input.scope.sessionId,
|
|
7146
7378
|
$updatedAt: updatedAt
|
|
7147
7379
|
});
|
|
7148
7380
|
db.exec("COMMIT");
|
|
@@ -7154,7 +7386,7 @@ var SqliteSessionStore = class {
|
|
|
7154
7386
|
throw error;
|
|
7155
7387
|
}
|
|
7156
7388
|
}
|
|
7157
|
-
clear(
|
|
7389
|
+
clear({ scope }) {
|
|
7158
7390
|
const db = this.database();
|
|
7159
7391
|
const updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
7160
7392
|
try {
|
|
@@ -7164,14 +7396,14 @@ var SqliteSessionStore = class {
|
|
|
7164
7396
|
SET updated_at = $updatedAt
|
|
7165
7397
|
WHERE id = $id`
|
|
7166
7398
|
).run({
|
|
7167
|
-
$id:
|
|
7399
|
+
$id: scope.sessionId,
|
|
7168
7400
|
$updatedAt: updatedAt
|
|
7169
7401
|
});
|
|
7170
7402
|
db.prepare("DELETE FROM anvia_studio_session_messages WHERE session_id = $id").run({
|
|
7171
|
-
$id:
|
|
7403
|
+
$id: scope.sessionId
|
|
7172
7404
|
});
|
|
7173
7405
|
db.prepare("DELETE FROM anvia_studio_session_runs WHERE session_id = $id").run({
|
|
7174
|
-
$id:
|
|
7406
|
+
$id: scope.sessionId
|
|
7175
7407
|
});
|
|
7176
7408
|
db.exec("COMMIT");
|
|
7177
7409
|
return Promise.resolve();
|
|
@@ -7183,17 +7415,51 @@ var SqliteSessionStore = class {
|
|
|
7183
7415
|
}
|
|
7184
7416
|
}
|
|
7185
7417
|
async recordError(input) {
|
|
7186
|
-
const runId = studioRunId2(input.
|
|
7187
|
-
const existing = this.getSessionRun(input.
|
|
7418
|
+
const runId = studioRunId2(input.scope) ?? input.runId;
|
|
7419
|
+
const existing = this.getSessionRun(input.scope.sessionId, runId);
|
|
7188
7420
|
const transcript = existing === void 0 || parseJsonArray(existing.transcript_json).length === 0 ? transcriptFromMessages(input.messages) : parseJsonArray(existing.transcript_json);
|
|
7189
7421
|
await this.saveSessionRunTranscript({
|
|
7190
|
-
id: input.
|
|
7422
|
+
id: input.scope.sessionId,
|
|
7191
7423
|
runId,
|
|
7192
7424
|
transcript,
|
|
7193
7425
|
status: "error",
|
|
7194
7426
|
error: serializeJsonError2(input.error)
|
|
7195
7427
|
});
|
|
7196
7428
|
}
|
|
7429
|
+
replaceCompactionPrefix(input) {
|
|
7430
|
+
if (!Number.isSafeInteger(input.messageCount) || input.messageCount < 1) {
|
|
7431
|
+
throw new RangeError("messageCount must be a positive integer.");
|
|
7432
|
+
}
|
|
7433
|
+
const db = this.database();
|
|
7434
|
+
try {
|
|
7435
|
+
db.exec("BEGIN IMMEDIATE");
|
|
7436
|
+
const messages = this.listSessionMessages(input.scope.sessionId);
|
|
7437
|
+
if (memoryRevision2(messages) !== input.revision || input.messageCount > messages.length || this.getSessionRow(input.scope.sessionId) === void 0) {
|
|
7438
|
+
db.exec("ROLLBACK");
|
|
7439
|
+
return Promise.resolve({ status: "conflict" });
|
|
7440
|
+
}
|
|
7441
|
+
db.prepare("DELETE FROM anvia_studio_session_messages WHERE session_id = $id").run({
|
|
7442
|
+
$id: input.scope.sessionId
|
|
7443
|
+
});
|
|
7444
|
+
const updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
7445
|
+
this.insertMessages(
|
|
7446
|
+
input.scope.sessionId,
|
|
7447
|
+
[input.replacement, ...messages.slice(input.messageCount)],
|
|
7448
|
+
0,
|
|
7449
|
+
updatedAt
|
|
7450
|
+
);
|
|
7451
|
+
db.prepare(
|
|
7452
|
+
`UPDATE anvia_studio_sessions
|
|
7453
|
+
SET updated_at = $updatedAt
|
|
7454
|
+
WHERE id = $id`
|
|
7455
|
+
).run({ $id: input.scope.sessionId, $updatedAt: updatedAt });
|
|
7456
|
+
db.exec("COMMIT");
|
|
7457
|
+
return Promise.resolve({ status: "committed" });
|
|
7458
|
+
} catch (error) {
|
|
7459
|
+
if (db.isTransaction) db.exec("ROLLBACK");
|
|
7460
|
+
throw error;
|
|
7461
|
+
}
|
|
7462
|
+
}
|
|
7197
7463
|
saveSessionRunTranscript(input) {
|
|
7198
7464
|
const db = this.database();
|
|
7199
7465
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -7889,7 +8155,7 @@ var SqliteSessionStore = class {
|
|
|
7889
8155
|
);
|
|
7890
8156
|
messages.forEach((message, messageOffset) => {
|
|
7891
8157
|
const messageIndex = startIndex + messageOffset;
|
|
7892
|
-
if (message.metadata !== void 0 && !
|
|
8158
|
+
if (message.metadata !== void 0 && !isJsonValue3(message.metadata)) {
|
|
7893
8159
|
throw new TypeError("Studio message metadata must be a strict JSON value.");
|
|
7894
8160
|
}
|
|
7895
8161
|
insertMessage.run({
|
|
@@ -7990,6 +8256,9 @@ function messageParts(message) {
|
|
|
7990
8256
|
if (message.role === "system") {
|
|
7991
8257
|
return [{ type: "text", value: { type: "text", text: message.content } }];
|
|
7992
8258
|
}
|
|
8259
|
+
if (typeof message.content === "string") {
|
|
8260
|
+
return [{ type: "text", value: { type: "text", text: message.content } }];
|
|
8261
|
+
}
|
|
7993
8262
|
return message.content.map((content) => ({
|
|
7994
8263
|
type: content.type,
|
|
7995
8264
|
value: content
|
|
@@ -7998,40 +8267,40 @@ function messageParts(message) {
|
|
|
7998
8267
|
function messageFromRows(row, partRows) {
|
|
7999
8268
|
const parts = partRows.map((partRow) => JSON.parse(partRow.part_json));
|
|
8000
8269
|
const metadata = parseJsonValue(row.metadata_json);
|
|
8001
|
-
if (metadata !== void 0 && !
|
|
8002
|
-
throw new TypeError("Stored Studio message metadata is not a strict JSON
|
|
8270
|
+
if (metadata !== void 0 && (!isJsonValue3(metadata) || typeof metadata !== "object" || metadata === null || Array.isArray(metadata))) {
|
|
8271
|
+
throw new TypeError("Stored Studio message metadata is not a strict JSON object.");
|
|
8003
8272
|
}
|
|
8004
8273
|
if (row.role === "system") {
|
|
8005
8274
|
const message = {
|
|
8006
8275
|
role: "system",
|
|
8007
|
-
content: systemContentFromParts(parts)
|
|
8276
|
+
content: systemContentFromParts(parts),
|
|
8277
|
+
...metadata === void 0 ? {} : { metadata }
|
|
8008
8278
|
};
|
|
8009
|
-
if (metadata !== void 0) message.metadata = metadata;
|
|
8010
8279
|
return message;
|
|
8011
8280
|
}
|
|
8012
8281
|
if (row.role === "user") {
|
|
8013
8282
|
const message = {
|
|
8014
8283
|
role: "user",
|
|
8015
|
-
content: parts
|
|
8284
|
+
content: parts,
|
|
8285
|
+
...metadata === void 0 ? {} : { metadata }
|
|
8016
8286
|
};
|
|
8017
|
-
if (metadata !== void 0) message.metadata = metadata;
|
|
8018
8287
|
return message;
|
|
8019
8288
|
}
|
|
8020
8289
|
if (row.role === "assistant") {
|
|
8021
8290
|
const message = {
|
|
8022
8291
|
role: "assistant",
|
|
8023
|
-
content: parts
|
|
8292
|
+
content: parts,
|
|
8293
|
+
...row.message_id === null ? {} : { id: row.message_id },
|
|
8294
|
+
...metadata === void 0 ? {} : { metadata }
|
|
8024
8295
|
};
|
|
8025
|
-
if (row.message_id !== null) message.id = row.message_id;
|
|
8026
|
-
if (metadata !== void 0) message.metadata = metadata;
|
|
8027
8296
|
return message;
|
|
8028
8297
|
}
|
|
8029
8298
|
if (row.role === "tool") {
|
|
8030
8299
|
const message = {
|
|
8031
8300
|
role: "tool",
|
|
8032
|
-
content: parts
|
|
8301
|
+
content: parts,
|
|
8302
|
+
...metadata === void 0 ? {} : { metadata }
|
|
8033
8303
|
};
|
|
8034
|
-
if (metadata !== void 0) message.metadata = metadata;
|
|
8035
8304
|
return message;
|
|
8036
8305
|
}
|
|
8037
8306
|
throw new Error(`Unsupported stored message role: ${row.role}`);
|
|
@@ -8116,10 +8385,13 @@ function parseJsonValue(value) {
|
|
|
8116
8385
|
}
|
|
8117
8386
|
return JSON.parse(value);
|
|
8118
8387
|
}
|
|
8119
|
-
function studioRunId2(
|
|
8120
|
-
const value =
|
|
8388
|
+
function studioRunId2(scope) {
|
|
8389
|
+
const value = scope.metadata?.studioRunId;
|
|
8121
8390
|
return typeof value === "string" && value.length > 0 ? value : void 0;
|
|
8122
8391
|
}
|
|
8392
|
+
function memoryRevision2(messages) {
|
|
8393
|
+
return JSON.stringify(messages);
|
|
8394
|
+
}
|
|
8123
8395
|
function serializeJsonError2(error) {
|
|
8124
8396
|
if (error instanceof Error) {
|
|
8125
8397
|
return {
|