@anvia/studio 0.8.1 → 1.0.0-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/README.md +15 -11
  2. package/dist/index.d.ts +7 -5
  3. package/dist/index.js +387 -383
  4. package/dist/index.js.map +1 -1
  5. package/dist/ui/assets/{ArrowClockwise.es-CSN-gjxO.js → ArrowClockwise.es-yNj_oSyD.js} +2 -2
  6. package/dist/ui/assets/{ArrowClockwise.es-CSN-gjxO.js.map → ArrowClockwise.es-yNj_oSyD.js.map} +1 -1
  7. package/dist/ui/assets/{agents-page-CkNSbqAj.js → agents-page-ucKNS0fS.js} +2 -2
  8. package/dist/ui/assets/agents-page-ucKNS0fS.js.map +1 -0
  9. package/dist/ui/assets/{index-Bh7RLPBw.js → index-DIV9J1_T.js} +4 -4
  10. package/dist/ui/assets/{index-Bh7RLPBw.js.map → index-DIV9J1_T.js.map} +1 -1
  11. package/dist/ui/assets/{knowledge-page-Cot_uYcE.js → knowledge-page-vwFOGhkh.js} +2 -2
  12. package/dist/ui/assets/{knowledge-page-Cot_uYcE.js.map → knowledge-page-vwFOGhkh.js.map} +1 -1
  13. package/dist/ui/assets/{mcps-page-BSO6ork4.js → mcps-page-Bsu_-w7A.js} +2 -2
  14. package/dist/ui/assets/{mcps-page-BSO6ork4.js.map → mcps-page-Bsu_-w7A.js.map} +1 -1
  15. package/dist/ui/assets/{memory-page-CG84G--r.js → memory-page-DJ_nq7Ip.js} +2 -2
  16. package/dist/ui/assets/{memory-page-CG84G--r.js.map → memory-page-DJ_nq7Ip.js.map} +1 -1
  17. package/dist/ui/assets/{pipelines-page-Hbf5ffUH.js → pipelines-page-BsHeSdbO.js} +2 -2
  18. package/dist/ui/assets/{pipelines-page-Hbf5ffUH.js.map → pipelines-page-BsHeSdbO.js.map} +1 -1
  19. package/dist/ui/assets/{renderers-B8gvjR2u.js → renderers-5kT5HxmZ.js} +2 -2
  20. package/dist/ui/assets/{renderers-B8gvjR2u.js.map → renderers-5kT5HxmZ.js.map} +1 -1
  21. package/dist/ui/assets/{sandboxes-page-D910dyFO.js → sandboxes-page-BQuQepXk.js} +2 -2
  22. package/dist/ui/assets/{sandboxes-page-D910dyFO.js.map → sandboxes-page-BQuQepXk.js.map} +1 -1
  23. package/dist/ui/assets/{sessions-page-CSN2vSKZ.js → sessions-page-BLGrHrQT.js} +2 -2
  24. package/dist/ui/assets/{sessions-page-CSN2vSKZ.js.map → sessions-page-BLGrHrQT.js.map} +1 -1
  25. package/dist/ui/assets/{status-page-CgRNt0wi.js → status-page-D-BUKV_r.js} +2 -2
  26. package/dist/ui/assets/{status-page-CgRNt0wi.js.map → status-page-D-BUKV_r.js.map} +1 -1
  27. package/dist/ui/assets/{tool-runner-BZN-PZJU.js → tool-runner-6-N-OOCI.js} +2 -2
  28. package/dist/ui/assets/{tool-runner-BZN-PZJU.js.map → tool-runner-6-N-OOCI.js.map} +1 -1
  29. package/dist/ui/assets/{tools-page-DRv7aklU.js → tools-page-BEQJgFX0.js} +2 -2
  30. package/dist/ui/assets/{tools-page-DRv7aklU.js.map → tools-page-BEQJgFX0.js.map} +1 -1
  31. package/dist/ui/assets/{trace-browser-B07coNNE.js → trace-browser-DdGcJyNX.js} +2 -2
  32. package/dist/ui/assets/{trace-browser-B07coNNE.js.map → trace-browser-DdGcJyNX.js.map} +1 -1
  33. package/dist/ui/assets/{transcript-item-ZNkQEaCw.js → transcript-item-Bbf77TZa.js} +2 -2
  34. package/dist/ui/assets/{transcript-item-ZNkQEaCw.js.map → transcript-item-Bbf77TZa.js.map} +1 -1
  35. package/dist/ui/index.html +1 -1
  36. package/package.json +6 -6
  37. package/dist/ui/assets/agents-page-CkNSbqAj.js.map +0 -1
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  // src/runtime/studio.ts
2
- import { Agent as Agent2 } from "@anvia/core/internal/agent";
2
+ import { Agent, getAgentToolState as getAgentToolState3 } from "@anvia/core/internal/agent";
3
3
  import { Pipeline } from "@anvia/core/pipeline";
4
4
  import { serve } from "@hono/node-server";
5
5
  import { Hono as HonoApp } from "hono";
@@ -200,6 +200,7 @@ var StudioRunTraceObserver = class {
200
200
  const metadata = traceMetadata(this.props.args, result.messages);
201
201
  const trace = {
202
202
  id: this.props.id,
203
+ runId: this.props.args.runId,
203
204
  sessionId,
204
205
  status,
205
206
  trace: this.trace,
@@ -427,6 +428,7 @@ function traceObservation(props) {
427
428
  }
428
429
  function traceMetadata(args, messages) {
429
430
  return compactJsonObject({
431
+ runId: args.runId,
430
432
  agentName: args.agentName,
431
433
  agentDescription: args.agentDescription,
432
434
  maxTurns: args.maxTurns,
@@ -874,70 +876,30 @@ function escapeHtml(value) {
874
876
  return value.replaceAll("&", "&amp;").replaceAll('"', "&quot;").replaceAll("<", "&lt;").replaceAll(">", "&gt;");
875
877
  }
876
878
 
879
+ // src/runtime/agent-context.ts
880
+ import { isContextIndex } from "@anvia/core/agent";
881
+ function staticContextDocuments(agent) {
882
+ return agent.context.filter((input) => !isContextIndex(input));
883
+ }
884
+ function contextIndexes(agent) {
885
+ return agent.context.filter(isContextIndex);
886
+ }
887
+
877
888
  // src/runtime/agent-runs.ts
878
889
  import { Message } from "@anvia/core/completion";
890
+ import { withInternalAgentRunOptions } from "@anvia/core/internal/agent";
879
891
 
880
892
  // src/runtime/agent-utils.ts
881
893
  import {
882
- createHook
883
- } from "@anvia/core/hooks";
884
- import { Agent } from "@anvia/core/internal/agent";
894
+ createResolvedAgent,
895
+ getResolvedAgentOptions
896
+ } from "@anvia/core/internal/agent";
885
897
  function cloneAgent(agent, overrides = {}) {
886
- return new Agent({
887
- id: agent.id,
888
- name: agent.name,
889
- description: agent.description,
890
- model: agent.model,
891
- instructions: agent.instructions,
892
- staticContext: agent.staticContext,
893
- temperature: agent.temperature,
894
- maxTokens: agent.maxTokens,
895
- additionalParams: agent.additionalParams,
896
- toolSet: agent.toolSet,
897
- toolChoice: agent.toolChoice,
898
- defaultMaxTurns: agent.defaultMaxTurns,
899
- hook: agent.hook,
900
- outputSchema: agent.outputSchema,
901
- observers: agent.observers,
902
- approvals: agent.approvals,
903
- dynamicContexts: agent.dynamicContexts,
904
- dynamicTools: agent.dynamicTools,
905
- middlewares: agent.middlewares,
906
- memory: agent.memory,
907
- eventStore: agent.eventStore,
898
+ return createResolvedAgent({
899
+ ...getResolvedAgentOptions(agent),
908
900
  ...overrides
909
901
  });
910
902
  }
911
- function composeHooks(first, second) {
912
- if (first === void 0) {
913
- return second;
914
- }
915
- if (second === void 0) {
916
- return first;
917
- }
918
- return createHook({
919
- async onCompletionCall(args) {
920
- const firstAction = await first.onCompletionCall?.(args);
921
- return firstAction?.type === "terminate" ? firstAction : await second.onCompletionCall?.(args) ?? void 0;
922
- },
923
- async onCompletionResponse(args) {
924
- const firstAction = await first.onCompletionResponse?.(args);
925
- return firstAction?.type === "terminate" ? firstAction : await second.onCompletionResponse?.(args) ?? void 0;
926
- },
927
- async onToolCall(args) {
928
- const firstAction = await first.onToolCall?.(args);
929
- if (firstAction?.type === "skip" || firstAction?.type === "terminate" || firstAction?.type === "approval_request") {
930
- return firstAction;
931
- }
932
- const secondAction = await second.onToolCall?.(args);
933
- return secondAction ?? firstAction ?? void 0;
934
- },
935
- async onToolResult(args) {
936
- const firstAction = await first.onToolResult?.(args);
937
- return firstAction?.type === "terminate" ? firstAction : await second.onToolResult?.(args) ?? void 0;
938
- }
939
- });
940
- }
941
903
 
942
904
  // src/runtime/errors.ts
943
905
  function serializeError(error) {
@@ -1435,6 +1397,7 @@ function traceSummary(trace) {
1435
1397
  startedAt: trace.startedAt,
1436
1398
  observationCount: trace.observations.length
1437
1399
  };
1400
+ if (trace.runId !== void 0) summary.runId = trace.runId;
1438
1401
  if (trace.name !== void 0) summary.name = trace.name;
1439
1402
  if (trace.endedAt !== void 0) summary.endedAt = trace.endedAt;
1440
1403
  if (trace.durationMs !== void 0) summary.durationMs = trace.durationMs;
@@ -3084,7 +3047,7 @@ async function prepareAgentRun(c, props) {
3084
3047
  messages: [promptMessage]
3085
3048
  });
3086
3049
  }
3087
- const request = createRunRequest({
3050
+ const execution = createRunExecution({
3088
3051
  agentId,
3089
3052
  body,
3090
3053
  memoryMetadata,
@@ -3097,7 +3060,8 @@ async function prepareAgentRun(c, props) {
3097
3060
  agent,
3098
3061
  body,
3099
3062
  memoryMetadata,
3100
- request,
3063
+ execution,
3064
+ options: createRunOptions(body, agentId, session),
3101
3065
  runAgent,
3102
3066
  runId,
3103
3067
  runStartedAt,
@@ -3189,23 +3153,30 @@ function runMemoryMetadata(agentId, body, selectedModel, runId) {
3189
3153
  metadata.studioRunId = runId;
3190
3154
  return metadata;
3191
3155
  }
3192
- function createRunRequest(props) {
3193
- const request = props.session !== void 0 ? props.runAgent.memory === void 0 ? props.runAgent.prompt([...props.session.messages, props.promptMessage]) : props.runAgent.session(props.session.id, { metadata: props.memoryMetadata }).prompt(props.body.message) : props.runAgent.prompt(
3194
- props.body.history !== void 0 ? [...props.body.history, props.promptMessage] : props.body.message
3195
- );
3196
- request.withCompletionRetries();
3197
- if (props.body.maxTurns !== void 0) {
3198
- request.maxTurns(props.body.maxTurns);
3199
- }
3200
- if (props.body.toolConcurrency !== void 0) {
3201
- request.withToolConcurrency(props.body.toolConcurrency);
3156
+ function createRunExecution(props) {
3157
+ if (props.session !== void 0 && props.runAgent.memory !== void 0) {
3158
+ const session = props.runAgent.session(props.session.id, { metadata: props.memoryMetadata });
3159
+ return {
3160
+ generate: (options) => session.generate(props.body.message, options),
3161
+ stream: (options) => session.stream(props.body.message, options)
3162
+ };
3202
3163
  }
3203
- if (props.body.trace !== void 0) {
3204
- request.withTrace(traceForRun(props.body.trace, props.agentId, props.session));
3205
- } else if (props.session !== void 0) {
3206
- request.withTrace(traceForRun(void 0, props.agentId, props.session));
3164
+ const input = props.session !== void 0 ? [...props.session.messages, props.promptMessage] : props.body.history !== void 0 ? [...props.body.history, props.promptMessage] : props.body.message;
3165
+ return {
3166
+ generate: (options) => props.runAgent.generate(input, options),
3167
+ stream: (options) => props.runAgent.stream(input, options)
3168
+ };
3169
+ }
3170
+ function createRunOptions(body, agentId, session) {
3171
+ const options = { retries: {} };
3172
+ if (body.maxTurns !== void 0) options.maxTurns = body.maxTurns;
3173
+ if (body.toolConcurrency !== void 0) options.toolConcurrency = body.toolConcurrency;
3174
+ if (body.trace !== void 0) {
3175
+ options.trace = traceForRun(body.trace, agentId, session);
3176
+ } else if (session !== void 0) {
3177
+ options.trace = traceForRun(void 0, agentId, session);
3207
3178
  }
3208
- return request;
3179
+ return options;
3209
3180
  }
3210
3181
  function handleStreamingAgentRun(c, run, props) {
3211
3182
  const runtimeEvents = new AsyncEventQueue();
@@ -3216,7 +3187,6 @@ function handleStreamingAgentRun(c, run, props) {
3216
3187
  };
3217
3188
  if (run.session !== void 0) approvalContext.sessionId = run.session.id;
3218
3189
  if (run.body.metadata !== void 0) approvalContext.metadata = run.body.metadata;
3219
- run.request.approvals(props.approvalRuntime.createApprovals(approvalContext));
3220
3190
  const questionContext = {
3221
3191
  runId: run.runId,
3222
3192
  agentId: run.agentId,
@@ -3224,14 +3194,20 @@ function handleStreamingAgentRun(c, run, props) {
3224
3194
  };
3225
3195
  if (run.session !== void 0) questionContext.sessionId = run.session.id;
3226
3196
  if (run.body.metadata !== void 0) questionContext.metadata = run.body.metadata;
3227
- const effectiveHook = composeHooks(
3228
- run.runAgent.hook,
3229
- props.questionRuntime.createHook(questionContext)
3197
+ const effectiveHook = props.questionRuntime.createHook(questionContext);
3198
+ const streamOptions = withInternalAgentRunOptions(
3199
+ { ...run.options },
3200
+ { hook: effectiveHook, runId: run.runId }
3201
+ );
3202
+ const runStream = mergeRunAndApprovalEvents(
3203
+ resumeStreamingApprovals(
3204
+ run.runAgent,
3205
+ run.execution.stream(streamOptions),
3206
+ props.approvalRuntime,
3207
+ approvalContext
3208
+ ),
3209
+ runtimeEvents
3230
3210
  );
3231
- if (effectiveHook !== void 0) {
3232
- run.request.withHook(effectiveHook);
3233
- }
3234
- const runStream = mergeRunAndApprovalEvents(run.request.stream(), runtimeEvents);
3235
3211
  let stream = runStream;
3236
3212
  let persistedRun;
3237
3213
  if (run.session !== void 0 && run.sessionStore !== void 0) {
@@ -3274,8 +3250,14 @@ function handleStreamingAgentRun(c, run, props) {
3274
3250
  }
3275
3251
  async function handleBufferedAgentRun(c, run, props) {
3276
3252
  try {
3277
- await startBufferedSessionRun(run, props);
3278
- const response = await run.request.send();
3253
+ const runtimeOptions = await startBufferedSessionRun(run, props);
3254
+ let result = await run.execution.generate(runtimeOptions);
3255
+ const approvalContext = createApprovalContext(run);
3256
+ while (result.status === "approval_required") {
3257
+ const decision = await props.approvalRuntime.request(approvalContext, result.approval);
3258
+ result = await run.runAgent.resume(result, decision);
3259
+ }
3260
+ const response = result;
3279
3261
  await completeBufferedSessionRun(run, response);
3280
3262
  return c.json(response);
3281
3263
  } catch (error) {
@@ -3294,19 +3276,33 @@ async function startBufferedSessionRun(run, props) {
3294
3276
  };
3295
3277
  if (run.session !== void 0) questionContext.sessionId = run.session.id;
3296
3278
  if (run.body.metadata !== void 0) questionContext.metadata = run.body.metadata;
3297
- const effectiveHook = composeHooks(
3298
- run.runAgent.hook,
3299
- props.questionRuntime.createHook(questionContext)
3300
- );
3301
- const approvalContext = {
3279
+ const effectiveHook = props.questionRuntime.createHook(questionContext);
3280
+ return withInternalAgentRunOptions({ ...run.options }, { hook: effectiveHook, runId: run.runId });
3281
+ }
3282
+ function createApprovalContext(run, emit) {
3283
+ const context = {
3302
3284
  runId: run.runId,
3303
3285
  agentId: run.agentId
3304
3286
  };
3305
- if (run.session !== void 0) approvalContext.sessionId = run.session.id;
3306
- if (run.body.metadata !== void 0) approvalContext.metadata = run.body.metadata;
3307
- run.request.approvals(props.approvalRuntime.createApprovals(approvalContext));
3308
- if (effectiveHook !== void 0) {
3309
- run.request.withHook(effectiveHook);
3287
+ if (run.session !== void 0) context.sessionId = run.session.id;
3288
+ if (run.body.metadata !== void 0) context.metadata = run.body.metadata;
3289
+ if (emit !== void 0) context.emit = emit;
3290
+ return context;
3291
+ }
3292
+ async function* resumeStreamingApprovals(agent, initialStream, approvalRuntime, context) {
3293
+ let stream = initialStream;
3294
+ while (true) {
3295
+ let pending;
3296
+ for await (const event of stream) {
3297
+ if (event.type === "approval_required") {
3298
+ pending = event;
3299
+ break;
3300
+ }
3301
+ yield event;
3302
+ }
3303
+ if (pending === void 0) return;
3304
+ const decision = await approvalRuntime.request(context, pending.approval);
3305
+ stream = agent.resume(pending, decision);
3310
3306
  }
3311
3307
  }
3312
3308
  async function completeBufferedSessionRun(run, response) {
@@ -3386,6 +3382,9 @@ function usesStoreAsAgentMemory(agent, store) {
3386
3382
  return memoryStore !== void 0 && rawObservedStore(memoryStore) === rawObservedStore(store);
3387
3383
  }
3388
3384
 
3385
+ // src/runtime/approvals.ts
3386
+ import { getAgentApprovalRequestDetails } from "@anvia/core/internal/agent";
3387
+
3389
3388
  // src/runtime/query.ts
3390
3389
  function optionalQueryString(value) {
3391
3390
  const trimmed = value?.trim();
@@ -3491,22 +3490,11 @@ function createApprovalRuntime() {
3491
3490
  const approvals = /* @__PURE__ */ new Map();
3492
3491
  return {
3493
3492
  approvals,
3494
- createApprovals(context) {
3495
- return {
3496
- async handler(request) {
3497
- const approvalRequest = {
3498
- toolName: request.toolName,
3499
- internalCallId: request.internalCallId,
3500
- args: request.rawArgs
3501
- };
3502
- if (request.toolCallId !== void 0) approvalRequest.toolCallId = request.toolCallId;
3503
- if (request.reason !== void 0) approvalRequest.reason = request.reason;
3504
- if (request.rejectMessage !== void 0) {
3505
- approvalRequest.rejectMessage = request.rejectMessage;
3506
- }
3507
- const decision = await requestApproval(approvals, context, approvalRequest);
3508
- return approvalDecision(decision.approved, decision.reason);
3509
- }
3493
+ async request(context, approval) {
3494
+ const decision = await requestApproval(approvals, context, approval);
3495
+ return decision.approved ? { approved: true, ...decision.reason === void 0 ? {} : { reason: decision.reason } } : {
3496
+ approved: false,
3497
+ ...decision.reason === void 0 ? {} : { reason: decision.reason }
3510
3498
  };
3511
3499
  },
3512
3500
  list(options) {
@@ -3567,14 +3555,15 @@ function createApprovalRuntime() {
3567
3555
  };
3568
3556
  }
3569
3557
  async function requestApproval(approvals, context, request) {
3570
- const id = globalThis.crypto.randomUUID();
3558
+ const id = request.id;
3559
+ const details = getAgentApprovalRequestDetails(request);
3571
3560
  const approval = {
3572
3561
  id,
3573
3562
  runId: context.runId,
3574
3563
  agentId: context.agentId,
3575
3564
  toolName: request.toolName,
3576
- internalCallId: request.internalCallId,
3577
- args: request.args,
3565
+ internalCallId: details?.internalCallId ?? request.id,
3566
+ args: details?.rawArgs ?? JSON.stringify(request.input) ?? "null",
3578
3567
  status: "pending",
3579
3568
  requestedAt: (/* @__PURE__ */ new Date()).toISOString(),
3580
3569
  resolve: () => {
@@ -3583,7 +3572,7 @@ async function requestApproval(approvals, context, request) {
3583
3572
  if (context.sessionId !== void 0) approval.sessionId = context.sessionId;
3584
3573
  if (request.toolCallId !== void 0) approval.callId = request.toolCallId;
3585
3574
  if (request.reason !== void 0) approval.reason = request.reason;
3586
- if (request.rejectMessage !== void 0) approval.rejectMessage = request.rejectMessage;
3575
+ if (details?.rejectMessage !== void 0) approval.rejectMessage = details.rejectMessage;
3587
3576
  if (context.emit !== void 0) approval.emit = context.emit;
3588
3577
  const decision = new Promise((resolve2) => {
3589
3578
  approval.resolve = (decision2) => {
@@ -3594,7 +3583,7 @@ async function requestApproval(approvals, context, request) {
3594
3583
  }
3595
3584
  return;
3596
3585
  }
3597
- const reason = decision2.approved ? decision2.reason : decision2.reason ?? request.rejectMessage ?? "Rejected in Anvia Studio.";
3586
+ const reason = decision2.approved ? decision2.reason : decision2.reason ?? details?.rejectMessage ?? "Rejected in Anvia Studio.";
3598
3587
  const resolved = resolveApproval(
3599
3588
  current,
3600
3589
  decision2.approved ? "approved" : "rejected",
@@ -3712,242 +3701,8 @@ function isRecord2(value) {
3712
3701
  return value !== null && typeof value === "object" && !Array.isArray(value);
3713
3702
  }
3714
3703
 
3715
- // src/runtime/tool-metadata.ts
3716
- import { ToolSet } from "@anvia/core/tool";
3717
- var MCP_TOOL_METADATA_KEY = /* @__PURE__ */ Symbol.for("anvia.mcp.tool.metadata");
3718
- function agentToolItems(agent) {
3719
- return [
3720
- ...agent.agent.toolSet.values().map((tool) => ({ tool, source: "static" })),
3721
- ...agent.agent.dynamicTools.flatMap((registration) => {
3722
- const maybeToolSet = registration.index.toolSet;
3723
- if (!(maybeToolSet instanceof ToolSet)) {
3724
- return [];
3725
- }
3726
- return maybeToolSet.values().map((tool) => ({ tool, source: "dynamic" }));
3727
- })
3728
- ];
3729
- }
3730
- function approvalMetadata(tool) {
3731
- const approval = tool.approval;
3732
- if (approval === void 0 || typeof approval !== "object" || approval === null) {
3733
- return { required: false };
3734
- }
3735
- const policy = approval;
3736
- const metadata = { required: true };
3737
- if (typeof policy.reason === "string") metadata.reason = policy.reason;
3738
- if (typeof policy.rejectMessage === "string") metadata.rejectMessage = policy.rejectMessage;
3739
- return metadata;
3740
- }
3741
- function mcpServerName(tool) {
3742
- const metadata = tool[MCP_TOOL_METADATA_KEY];
3743
- if (typeof metadata !== "object" || metadata === null) {
3744
- return void 0;
3745
- }
3746
- const serverName = metadata.serverName;
3747
- return typeof serverName === "string" && serverName.length > 0 ? serverName : void 0;
3748
- }
3749
- function agentHasMcpTools(agent) {
3750
- return agentToolItems(agent).some(({ tool }) => mcpServerName(tool) !== void 0);
3751
- }
3752
-
3753
- // src/runtime/config.ts
3754
- function runnerId(options) {
3755
- return options.id ?? "anvia-studio";
3756
- }
3757
- function agentConfig(agent) {
3758
- const name = agent.name ?? agent.agent.name;
3759
- const description = agent.description ?? agent.agent.description;
3760
- const config = {
3761
- id: agent.id,
3762
- quickPrompts: agent.quickPrompts ?? []
3763
- };
3764
- if (name !== void 0) config.name = name;
3765
- if (description !== void 0) config.description = description;
3766
- if (agent.metadata !== void 0) config.metadata = agent.metadata;
3767
- return config;
3768
- }
3769
- function agentRuntimeSummary(agent) {
3770
- const tools = agentToolItems(agent);
3771
- const name = agent.name ?? agent.agent.name;
3772
- const description = agent.description ?? agent.agent.description;
3773
- const summary = {
3774
- id: agent.id,
3775
- model: toJsonValue2(agent.agent.model),
3776
- toolCount: tools.length,
3777
- staticToolCount: tools.filter((item) => item.source === "static").length,
3778
- dynamicToolCount: tools.filter((item) => item.source === "dynamic").length,
3779
- approvalToolCount: tools.filter((item) => item.tool.approval !== void 0).length,
3780
- mcpToolCount: tools.filter((item) => mcpServerName(item.tool) !== void 0).length,
3781
- staticContextCount: agent.agent.staticContext.length,
3782
- dynamicContextCount: agent.agent.dynamicContexts.length,
3783
- observerCount: agent.agent.observers.length,
3784
- hasMemory: agent.agent.memory !== void 0,
3785
- hasHook: agent.agent.hook !== void 0,
3786
- hasOutputSchema: agent.agent.outputSchema !== void 0
3787
- };
3788
- if (name !== void 0) summary.name = name;
3789
- if (description !== void 0) summary.description = description;
3790
- if (agent.agent.defaultMaxTurns !== void 0) {
3791
- summary.defaultMaxTurns = agent.agent.defaultMaxTurns;
3792
- }
3793
- if (agent.metadata !== void 0) summary.metadata = agent.metadata;
3794
- return summary;
3795
- }
3796
- function pipelineConfig(pipeline) {
3797
- const graph = pipeline.pipeline.graph();
3798
- const stageNodes = graph.nodes.filter((node) => node.kind !== "input" && node.kind !== "output");
3799
- const config = {
3800
- id: pipeline.id,
3801
- stageCount: stageNodes.length,
3802
- edgeCount: graph.edges.length,
3803
- hasParallelStages: graph.nodes.some((node) => node.kind === "parallel"),
3804
- agentCount: graph.nodes.filter((node) => node.kind === "agent").length,
3805
- extractorCount: graph.nodes.filter((node) => node.kind === "extractor").length
3806
- };
3807
- if (pipeline.name !== void 0) config.name = pipeline.name;
3808
- if (pipeline.description !== void 0) config.description = pipeline.description;
3809
- if (pipeline.metadata !== void 0) config.metadata = pipeline.metadata;
3810
- return config;
3811
- }
3812
- function buildConfig(options, agents, pipelines, stores, sandboxCount = 0) {
3813
- const models = options.models === void 0 ? void 0 : studioModelsConfig(createStudioModelRegistry(options.models), agents);
3814
- const config = {
3815
- id: runnerId(options),
3816
- agents: agents.map(agentConfig),
3817
- pipelines: pipelines.map(pipelineConfig),
3818
- evals: options.evals.map(evalConfig),
3819
- chat: {
3820
- quickPrompts: Object.fromEntries(agents.map((agent) => [agent.id, agent.quickPrompts ?? []]))
3821
- },
3822
- capabilities: capabilityConfig(options, agents, pipelines, stores, sandboxCount),
3823
- unsupportedCapabilities: unsupportedCapabilities(stores)
3824
- };
3825
- if (options.name !== void 0) config.name = options.name;
3826
- if (options.description !== void 0) config.description = options.description;
3827
- if (options.version !== void 0) config.version = options.version;
3828
- if (models !== void 0) config.models = models;
3829
- return config;
3830
- }
3831
- function capabilityConfig(_options, agents, pipelines, stores, sandboxCount = 0) {
3832
- const capabilities = {
3833
- agents: { enabled: true },
3834
- observability: { enabled: true },
3835
- status: { enabled: true }
3836
- };
3837
- if (stores.sessions !== void 0) {
3838
- capabilities.sessions = { enabled: true };
3839
- }
3840
- if (stores.sessions !== void 0 || agents.some((agent) => agent.agent.memory !== void 0)) {
3841
- capabilities.memory = { enabled: true };
3842
- }
3843
- if (stores.traces !== void 0) {
3844
- capabilities.traces = { enabled: true };
3845
- }
3846
- if (pipelines.length > 0) {
3847
- capabilities.pipelines = { enabled: true };
3848
- }
3849
- if (_options.evals.length > 0) {
3850
- capabilities.evals = { enabled: true };
3851
- }
3852
- if (agents.some(
3853
- (agent) => agent.agent.toolSet.values().length > 0 || agent.agent.dynamicTools.length > 0
3854
- )) {
3855
- capabilities.tools = { enabled: true };
3856
- }
3857
- if (agents.some(agentHasMcpTools)) {
3858
- capabilities.mcps = { enabled: true };
3859
- }
3860
- if (sandboxCount > 0) {
3861
- capabilities.sandboxes = { enabled: true };
3862
- }
3863
- if (agents.some(
3864
- (agent) => agent.agent.hook !== void 0 || agent.agent.toolSet.values().some((tool) => tool.approval)
3865
- )) {
3866
- capabilities.approvals = { enabled: true };
3867
- }
3868
- if (agents.some(
3869
- (agent) => agent.agent.staticContext.length > 0 || agent.agent.dynamicContexts.length > 0 || agent.agent.dynamicTools.length > 0
3870
- )) {
3871
- capabilities.knowledge = { enabled: true };
3872
- }
3873
- return capabilities;
3874
- }
3875
- function unsupportedCapabilities(stores) {
3876
- const capabilities = [];
3877
- if (stores.sessions === void 0) capabilities.push("sessions");
3878
- if (stores.traces === void 0) capabilities.push("traces");
3879
- return capabilities;
3880
- }
3881
- function toJsonValue2(value) {
3882
- return serializeUnknown(value);
3883
- }
3884
-
3885
- // src/runtime/evals.ts
3886
- import { runEvalSuite } from "@anvia/core/evals";
3887
- function registerEvalRoutes(app, props) {
3888
- app.get(
3889
- "/evals",
3890
- (c) => c.json({
3891
- evals: props.evals.map(evalConfig)
3892
- })
3893
- );
3894
- app.get("/evals/:evalId", (c) => {
3895
- const suite = props.evalMap.get(c.req.param("evalId"));
3896
- if (suite === void 0) {
3897
- return errorResponse(c, 404, "not_found", "Eval suite not found");
3898
- }
3899
- return c.json(evalConfig(suite));
3900
- });
3901
- app.post("/evals/:evalId/runs", async (c) => {
3902
- const suite = props.evalMap.get(c.req.param("evalId"));
3903
- if (suite === void 0) {
3904
- return errorResponse(c, 404, "not_found", "Eval suite not found");
3905
- }
3906
- const body = await parseEvalRunRequest(c);
3907
- if ("error" in body) {
3908
- return body.error;
3909
- }
3910
- const runId = globalThis.crypto.randomUUID();
3911
- const startedAt = Date.now();
3912
- const runOptions = { ...suite };
3913
- if (body.concurrency !== void 0) runOptions.concurrency = body.concurrency;
3914
- const result = await runEvalSuite(runOptions);
3915
- const endedAt = Date.now();
3916
- const jsonResult = toJsonValue(result);
3917
- const response = {
3918
- runId,
3919
- suiteId: suite.id ?? suite.name,
3920
- startedAt: new Date(startedAt).toISOString(),
3921
- endedAt: new Date(endedAt).toISOString(),
3922
- durationMs: endedAt - startedAt,
3923
- result: isJsonObject(jsonResult) ? jsonResult : { value: jsonResult }
3924
- };
3925
- return c.json(response);
3926
- });
3927
- }
3928
- async function parseEvalRunRequest(c) {
3929
- let body = {};
3930
- try {
3931
- body = await c.req.json();
3932
- } catch {
3933
- body = {};
3934
- }
3935
- if (!isObject(body)) {
3936
- return { error: errorResponse(c, 400, "bad_request", "Request body must be an object") };
3937
- }
3938
- const request = {};
3939
- if ("concurrency" in body) {
3940
- if (!isPositiveInteger(body.concurrency)) {
3941
- return {
3942
- error: errorResponse(c, 400, "bad_request", "concurrency must be a positive integer")
3943
- };
3944
- }
3945
- request.concurrency = body.concurrency;
3946
- }
3947
- return request;
3948
- }
3949
-
3950
3704
  // src/runtime/knowledge.ts
3705
+ import { getAgentToolState } from "@anvia/core/internal/agent";
3951
3706
  function registerKnowledgeRoutes(app, props) {
3952
3707
  app.get("/knowledge", async (c) => {
3953
3708
  const limit = parseLimit(c.req.query("limit"));
@@ -3984,12 +3739,17 @@ function registerKnowledgeRoutes(app, props) {
3984
3739
  return c.json(page);
3985
3740
  });
3986
3741
  }
3742
+ function agentHasKnowledge(agent) {
3743
+ const toolIndexes = getAgentToolState(agent.agent).toolIndexes;
3744
+ return agent.agent.context.length > 0 || toolIndexes.length > 0;
3745
+ }
3987
3746
  async function agentKnowledgeConfig(agent) {
3988
3747
  const agentName = agent.name ?? agent.agent.name;
3748
+ const staticContext = staticContextDocuments(agent.agent);
3989
3749
  const config = {
3990
3750
  agentId: agent.id,
3991
3751
  sources: await knowledgeSources(agent),
3992
- staticContext: agent.agent.staticContext.map((document) => {
3752
+ staticContext: staticContext.map((document) => {
3993
3753
  const item = { id: document.id, text: document.text };
3994
3754
  if (document.additionalProps !== void 0) {
3995
3755
  item.additionalProps = jsonObjectFromRecord(document.additionalProps);
@@ -4001,51 +3761,54 @@ async function agentKnowledgeConfig(agent) {
4001
3761
  return config;
4002
3762
  }
4003
3763
  async function knowledgeSources(agent) {
3764
+ const toolIndexes = getAgentToolState(agent.agent).toolIndexes;
3765
+ const staticContext = staticContextDocuments(agent.agent);
3766
+ const indexedContext = contextIndexes(agent.agent);
4004
3767
  const sources = [
4005
3768
  {
4006
3769
  sourceId: staticSourceId(),
4007
3770
  kind: "static_context",
4008
3771
  label: "Static context",
4009
- count: agent.agent.staticContext.length,
3772
+ count: staticContext.length,
4010
3773
  inspectable: true,
4011
- itemCount: agent.agent.staticContext.length
3774
+ itemCount: staticContext.length
4012
3775
  }
4013
3776
  ];
4014
3777
  const dynamicContextSources = await Promise.all(
4015
- agent.agent.dynamicContexts.map(async (registration, index) => {
4016
- const inspect = inspectFn(registration.index);
4017
- const count = await inspectableCount(inspect, registration.options.filter);
3778
+ indexedContext.map(async (contextIndex, index) => {
3779
+ const inspect = inspectFn(contextIndex.index);
3780
+ const count = await inspectableCount(inspect, contextIndex.filter);
4018
3781
  const source = {
4019
3782
  sourceId: dynamicContextSourceId(index),
4020
3783
  kind: "dynamic_context",
4021
3784
  label: `Dynamic context ${index + 1}`,
4022
3785
  count: 1,
4023
3786
  registrationIndex: index,
4024
- topK: registration.options.topK,
3787
+ topK: contextIndex.topK,
4025
3788
  inspectable: inspect !== void 0
4026
3789
  };
4027
- if (registration.options.threshold !== void 0) {
4028
- source.threshold = registration.options.threshold;
3790
+ if (contextIndex.threshold !== void 0) {
3791
+ source.threshold = contextIndex.threshold;
4029
3792
  }
4030
3793
  if (count !== void 0) source.itemCount = count;
4031
3794
  return source;
4032
3795
  })
4033
3796
  );
4034
3797
  const dynamicToolSources = await Promise.all(
4035
- agent.agent.dynamicTools.map(async (registration, index) => {
4036
- const inspect = inspectFn(registration.index);
4037
- const count = await inspectableCount(inspect, registration.options.filter);
3798
+ toolIndexes.map(async (toolIndex, index) => {
3799
+ const inspect = inspectFn(toolIndex);
3800
+ const count = await inspectableCount(inspect, toolIndex.filter);
4038
3801
  const source = {
4039
3802
  sourceId: dynamicToolsSourceId(index),
4040
3803
  kind: "dynamic_tools",
4041
3804
  label: `Dynamic tools ${index + 1}`,
4042
3805
  count: 1,
4043
3806
  registrationIndex: index,
4044
- topK: registration.options.topK,
3807
+ topK: toolIndex.topK,
4045
3808
  inspectable: inspect !== void 0
4046
3809
  };
4047
- if (registration.options.threshold !== void 0) {
4048
- source.threshold = registration.options.threshold;
3810
+ if (toolIndex.threshold !== void 0) {
3811
+ source.threshold = toolIndex.threshold;
4049
3812
  }
4050
3813
  if (count !== void 0) source.itemCount = count;
4051
3814
  return source;
@@ -4066,18 +3829,18 @@ async function knowledgeItemsPage(agent, sourceId, request) {
4066
3829
  }
4067
3830
  const dynamicContextIndex = dynamicSourceIndex(sourceId, "dynamic_context");
4068
3831
  if (dynamicContextIndex !== void 0) {
4069
- const registration = agent.agent.dynamicContexts[dynamicContextIndex];
4070
- if (registration === void 0) {
3832
+ const contextIndex = contextIndexes(agent.agent)[dynamicContextIndex];
3833
+ if (contextIndex === void 0) {
4071
3834
  return void 0;
4072
3835
  }
4073
- const inspect = inspectFn(registration.index);
3836
+ const inspect = inspectFn(contextIndex.index);
4074
3837
  if (inspect === void 0) {
4075
3838
  return nonInspectablePage(agent.id, sourceId, "dynamic_context");
4076
3839
  }
4077
3840
  const page = await inspect({
4078
3841
  limit: request.limit,
4079
3842
  cursor: request.cursor,
4080
- filter: registration.options.filter
3843
+ filter: contextIndex.filter
4081
3844
  });
4082
3845
  const result = {
4083
3846
  agentId: agent.id,
@@ -4092,18 +3855,18 @@ async function knowledgeItemsPage(agent, sourceId, request) {
4092
3855
  }
4093
3856
  const dynamicToolsIndex = dynamicSourceIndex(sourceId, "dynamic_tools");
4094
3857
  if (dynamicToolsIndex !== void 0) {
4095
- const registration = agent.agent.dynamicTools[dynamicToolsIndex];
4096
- if (registration === void 0) {
3858
+ const toolIndex = getAgentToolState(agent.agent).toolIndexes[dynamicToolsIndex];
3859
+ if (toolIndex === void 0) {
4097
3860
  return void 0;
4098
3861
  }
4099
- const inspect = inspectFn(registration.index);
3862
+ const inspect = inspectFn(toolIndex);
4100
3863
  if (inspect === void 0) {
4101
3864
  return nonInspectablePage(agent.id, sourceId, "dynamic_tools");
4102
3865
  }
4103
3866
  const page = await inspect({
4104
3867
  limit: request.limit,
4105
3868
  cursor: request.cursor,
4106
- filter: registration.options.filter
3869
+ filter: toolIndex.filter
4107
3870
  });
4108
3871
  const result = {
4109
3872
  agentId: agent.id,
@@ -4126,8 +3889,9 @@ function inspectFn(index) {
4126
3889
  return (request) => inspect.call(index, request);
4127
3890
  }
4128
3891
  function staticKnowledgeItemsPage(agent, request) {
3892
+ const staticContext = staticContextDocuments(agent.agent);
4129
3893
  const start = Math.max(0, Math.trunc(Number(request.cursor ?? "0")));
4130
- const page = agent.agent.staticContext.slice(start, start + request.limit);
3894
+ const page = staticContext.slice(start, start + request.limit);
4131
3895
  const nextOffset = start + page.length;
4132
3896
  const result = {
4133
3897
  agentId: agent.id,
@@ -4145,9 +3909,9 @@ function staticKnowledgeItemsPage(agent, request) {
4145
3909
  }
4146
3910
  return item;
4147
3911
  }),
4148
- totalCount: agent.agent.staticContext.length
3912
+ totalCount: staticContext.length
4149
3913
  };
4150
- if (nextOffset < agent.agent.staticContext.length) result.nextCursor = String(nextOffset);
3914
+ if (nextOffset < staticContext.length) result.nextCursor = String(nextOffset);
4151
3915
  return result;
4152
3916
  }
4153
3917
  function nonInspectablePage(agentId, sourceId, kind) {
@@ -4336,6 +4100,245 @@ function isRecord3(value) {
4336
4100
  return typeof value === "object" && value !== null && !Array.isArray(value);
4337
4101
  }
4338
4102
 
4103
+ // src/runtime/tool-metadata.ts
4104
+ import { getAgentToolState as getAgentToolState2 } from "@anvia/core/internal/agent";
4105
+ var MCP_TOOL_METADATA_KEY = /* @__PURE__ */ Symbol.for("anvia.mcp.tool.metadata");
4106
+ function agentToolItems(agent) {
4107
+ const state = getAgentToolState2(agent.agent);
4108
+ const items = state.staticTools.map((tool) => ({ tool, source: "static" }));
4109
+ const names = new Set(items.map(({ tool }) => tool.name));
4110
+ for (const index of state.toolIndexes) {
4111
+ for (const tool of index.tools) {
4112
+ if (!names.has(tool.name)) {
4113
+ names.add(tool.name);
4114
+ items.push({ tool, source: "dynamic" });
4115
+ }
4116
+ }
4117
+ }
4118
+ return items;
4119
+ }
4120
+ function approvalMetadata(tool) {
4121
+ const approval = tool.requiresApproval;
4122
+ if (approval === void 0 || approval === false) {
4123
+ return { required: false };
4124
+ }
4125
+ if (typeof approval !== "object" || approval === null) {
4126
+ return { required: true };
4127
+ }
4128
+ const policy = approval;
4129
+ const metadata = { required: true };
4130
+ if (typeof policy.reason === "string") metadata.reason = policy.reason;
4131
+ return metadata;
4132
+ }
4133
+ function toolRequiresApproval(tool) {
4134
+ const approval = tool.requiresApproval;
4135
+ return approval !== void 0 && approval !== false;
4136
+ }
4137
+ function mcpServerName(tool) {
4138
+ const metadata = tool[MCP_TOOL_METADATA_KEY];
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;
4144
+ }
4145
+ function agentHasMcpTools(agent) {
4146
+ return agentToolItems(agent).some(({ tool }) => mcpServerName(tool) !== void 0);
4147
+ }
4148
+
4149
+ // src/runtime/config.ts
4150
+ function runnerId(options) {
4151
+ return options.id ?? "anvia-studio";
4152
+ }
4153
+ function agentConfig(agent) {
4154
+ const name = agent.name ?? agent.agent.name;
4155
+ const description = agent.description ?? agent.agent.description;
4156
+ const config = {
4157
+ id: agent.id,
4158
+ quickPrompts: agent.quickPrompts ?? []
4159
+ };
4160
+ if (name !== void 0) config.name = name;
4161
+ if (description !== void 0) config.description = description;
4162
+ if (agent.metadata !== void 0) config.metadata = agent.metadata;
4163
+ return config;
4164
+ }
4165
+ function agentRuntimeSummary(agent) {
4166
+ const tools = agentToolItems(agent);
4167
+ const staticContext = staticContextDocuments(agent.agent);
4168
+ const indexedContext = contextIndexes(agent.agent);
4169
+ const name = agent.name ?? agent.agent.name;
4170
+ const description = agent.description ?? agent.agent.description;
4171
+ const summary = {
4172
+ id: agent.id,
4173
+ model: toJsonValue2(agent.agent.model),
4174
+ toolCount: tools.length,
4175
+ staticToolCount: tools.filter((item) => item.source === "static").length,
4176
+ dynamicToolCount: tools.filter((item) => item.source === "dynamic").length,
4177
+ approvalToolCount: tools.filter((item) => toolRequiresApproval(item.tool)).length,
4178
+ mcpToolCount: tools.filter((item) => mcpServerName(item.tool) !== void 0).length,
4179
+ staticContextCount: staticContext.length,
4180
+ dynamicContextCount: indexedContext.length,
4181
+ observerCount: agent.agent.observers.length,
4182
+ hasMemory: agent.agent.memory !== void 0,
4183
+ hasLifecycle: agent.agent.lifecycle !== void 0,
4184
+ hasOutputSchema: agent.agent.outputSchema !== void 0
4185
+ };
4186
+ if (name !== void 0) summary.name = name;
4187
+ if (description !== void 0) summary.description = description;
4188
+ if (agent.agent.defaultMaxTurns !== void 0) {
4189
+ summary.defaultMaxTurns = agent.agent.defaultMaxTurns;
4190
+ }
4191
+ if (agent.metadata !== void 0) summary.metadata = agent.metadata;
4192
+ return summary;
4193
+ }
4194
+ function pipelineConfig(pipeline) {
4195
+ const graph = pipeline.pipeline.graph();
4196
+ const stageNodes = graph.nodes.filter((node) => node.kind !== "input" && node.kind !== "output");
4197
+ const config = {
4198
+ id: pipeline.id,
4199
+ stageCount: stageNodes.length,
4200
+ edgeCount: graph.edges.length,
4201
+ hasParallelStages: graph.nodes.some((node) => node.kind === "parallel"),
4202
+ agentCount: graph.nodes.filter((node) => node.kind === "agent").length,
4203
+ extractorCount: graph.nodes.filter((node) => node.kind === "extractor").length
4204
+ };
4205
+ if (pipeline.name !== void 0) config.name = pipeline.name;
4206
+ if (pipeline.description !== void 0) config.description = pipeline.description;
4207
+ if (pipeline.metadata !== void 0) config.metadata = pipeline.metadata;
4208
+ return config;
4209
+ }
4210
+ function buildConfig(options, agents, pipelines, stores, sandboxCount = 0) {
4211
+ const models = options.models === void 0 ? void 0 : studioModelsConfig(createStudioModelRegistry(options.models), agents);
4212
+ const config = {
4213
+ id: runnerId(options),
4214
+ agents: agents.map(agentConfig),
4215
+ pipelines: pipelines.map(pipelineConfig),
4216
+ evals: options.evals.map(evalConfig),
4217
+ chat: {
4218
+ quickPrompts: Object.fromEntries(agents.map((agent) => [agent.id, agent.quickPrompts ?? []]))
4219
+ },
4220
+ capabilities: capabilityConfig(options, agents, pipelines, stores, sandboxCount),
4221
+ unsupportedCapabilities: unsupportedCapabilities(stores)
4222
+ };
4223
+ if (options.name !== void 0) config.name = options.name;
4224
+ if (options.description !== void 0) config.description = options.description;
4225
+ if (options.version !== void 0) config.version = options.version;
4226
+ if (models !== void 0) config.models = models;
4227
+ return config;
4228
+ }
4229
+ function capabilityConfig(_options, agents, pipelines, stores, sandboxCount = 0) {
4230
+ const capabilities = {
4231
+ agents: { enabled: true },
4232
+ observability: { enabled: true },
4233
+ status: { enabled: true }
4234
+ };
4235
+ if (stores.sessions !== void 0) {
4236
+ capabilities.sessions = { enabled: true };
4237
+ }
4238
+ if (stores.sessions !== void 0 || agents.some((agent) => agent.agent.memory !== void 0)) {
4239
+ capabilities.memory = { enabled: true };
4240
+ }
4241
+ if (stores.traces !== void 0) {
4242
+ capabilities.traces = { enabled: true };
4243
+ }
4244
+ if (pipelines.length > 0) {
4245
+ capabilities.pipelines = { enabled: true };
4246
+ }
4247
+ if (_options.evals.length > 0) {
4248
+ capabilities.evals = { enabled: true };
4249
+ }
4250
+ if (agents.some((agent) => agent.agent.tools.length > 0)) {
4251
+ capabilities.tools = { enabled: true };
4252
+ }
4253
+ if (agents.some(agentHasMcpTools)) {
4254
+ capabilities.mcps = { enabled: true };
4255
+ }
4256
+ if (sandboxCount > 0) {
4257
+ capabilities.sandboxes = { enabled: true };
4258
+ }
4259
+ if (agents.some((agent) => agent.agent.tools.some(toolRequiresApproval))) {
4260
+ capabilities.approvals = { enabled: true };
4261
+ }
4262
+ if (agents.some(agentHasKnowledge)) {
4263
+ capabilities.knowledge = { enabled: true };
4264
+ }
4265
+ return capabilities;
4266
+ }
4267
+ function unsupportedCapabilities(stores) {
4268
+ const capabilities = [];
4269
+ if (stores.sessions === void 0) capabilities.push("sessions");
4270
+ if (stores.traces === void 0) capabilities.push("traces");
4271
+ return capabilities;
4272
+ }
4273
+ function toJsonValue2(value) {
4274
+ return serializeUnknown(value);
4275
+ }
4276
+
4277
+ // src/runtime/evals.ts
4278
+ import { runEvalSuite } from "@anvia/core/evals";
4279
+ function registerEvalRoutes(app, props) {
4280
+ app.get(
4281
+ "/evals",
4282
+ (c) => c.json({
4283
+ evals: props.evals.map(evalConfig)
4284
+ })
4285
+ );
4286
+ app.get("/evals/:evalId", (c) => {
4287
+ const suite = props.evalMap.get(c.req.param("evalId"));
4288
+ if (suite === void 0) {
4289
+ return errorResponse(c, 404, "not_found", "Eval suite not found");
4290
+ }
4291
+ return c.json(evalConfig(suite));
4292
+ });
4293
+ app.post("/evals/:evalId/runs", async (c) => {
4294
+ const suite = props.evalMap.get(c.req.param("evalId"));
4295
+ if (suite === void 0) {
4296
+ return errorResponse(c, 404, "not_found", "Eval suite not found");
4297
+ }
4298
+ const body = await parseEvalRunRequest(c);
4299
+ if ("error" in body) {
4300
+ return body.error;
4301
+ }
4302
+ const runId = globalThis.crypto.randomUUID();
4303
+ const startedAt = Date.now();
4304
+ const runOptions = { ...suite };
4305
+ if (body.concurrency !== void 0) runOptions.concurrency = body.concurrency;
4306
+ const result = await runEvalSuite(runOptions);
4307
+ const endedAt = Date.now();
4308
+ const jsonResult = toJsonValue(result);
4309
+ const response = {
4310
+ runId,
4311
+ suiteId: suite.id ?? suite.name,
4312
+ startedAt: new Date(startedAt).toISOString(),
4313
+ endedAt: new Date(endedAt).toISOString(),
4314
+ durationMs: endedAt - startedAt,
4315
+ result: isJsonObject(jsonResult) ? jsonResult : { value: jsonResult }
4316
+ };
4317
+ return c.json(response);
4318
+ });
4319
+ }
4320
+ async function parseEvalRunRequest(c) {
4321
+ let body = {};
4322
+ try {
4323
+ body = await c.req.json();
4324
+ } catch {
4325
+ body = {};
4326
+ }
4327
+ if (!isObject(body)) {
4328
+ return { error: errorResponse(c, 400, "bad_request", "Request body must be an object") };
4329
+ }
4330
+ const request = {};
4331
+ if ("concurrency" in body) {
4332
+ if (!isPositiveInteger(body.concurrency)) {
4333
+ return {
4334
+ error: errorResponse(c, 400, "bad_request", "concurrency must be a positive integer")
4335
+ };
4336
+ }
4337
+ request.concurrency = body.concurrency;
4338
+ }
4339
+ return request;
4340
+ }
4341
+
4339
4342
  // src/runtime/mcps.ts
4340
4343
  function registerMcpRoutes(app, props) {
4341
4344
  app.get("/agents/:agentId/mcps", async (c) => {
@@ -5290,7 +5293,7 @@ function parsePipelineLogAfter(value) {
5290
5293
  }
5291
5294
 
5292
5295
  // src/runtime/questions.ts
5293
- import { createHook as createHook2 } from "@anvia/core/hooks";
5296
+ import { createHook } from "@anvia/core/internal/agent";
5294
5297
  import { parseToolArgs } from "@anvia/core/tool";
5295
5298
  function registerQuestionRoutes(app, questions) {
5296
5299
  app.get("/questions", (c) => {
@@ -5383,7 +5386,7 @@ function createQuestionRuntime() {
5383
5386
  return {
5384
5387
  questions,
5385
5388
  createHook(context) {
5386
- return createHook2({
5389
+ return createHook({
5387
5390
  async onToolCall({ toolName, toolCallId, internalCallId, args, tool: control }) {
5388
5391
  if (toolName !== "ask_question") {
5389
5392
  return control.run();
@@ -6820,7 +6823,7 @@ function waitForShutdown(signal) {
6820
6823
  });
6821
6824
  }
6822
6825
  function studioOptionsFromTargets(targets, options) {
6823
- const agents = targets.filter((target) => target instanceof Agent2);
6826
+ const agents = targets.filter((target) => target instanceof Agent);
6824
6827
  const pipelines = targets.filter(
6825
6828
  // biome-ignore lint/suspicious/noExplicitAny: Studio accepts heterogeneous user pipelines.
6826
6829
  (target) => target instanceof Pipeline
@@ -6873,13 +6876,13 @@ function uniqueAgentId(baseId, ids) {
6873
6876
  }
6874
6877
  function agentMetadata(agent) {
6875
6878
  const metadata = {
6876
- staticContextCount: agent.staticContext.length,
6877
- dynamicContextCount: agent.dynamicContexts.length,
6878
- dynamicToolCount: agent.dynamicTools.length,
6879
+ staticContextCount: staticContextDocuments(agent).length,
6880
+ dynamicContextCount: contextIndexes(agent).length,
6881
+ dynamicToolCount: getAgentToolState3(agent).toolIndexes.length,
6882
+ hasLifecycle: agent.lifecycle !== void 0,
6879
6883
  hasOutputSchema: agent.outputSchema !== void 0,
6880
- hasHook: agent.hook !== void 0,
6881
6884
  observerCount: agent.observers.length,
6882
- approvalToolCount: agent.toolSet.values().filter((tool) => tool.approval !== void 0).length
6885
+ approvalToolCount: agent.tools.filter(toolRequiresApproval).length
6883
6886
  };
6884
6887
  if (agent.defaultMaxTurns !== void 0) metadata.defaultMaxTurns = agent.defaultMaxTurns;
6885
6888
  return metadata;
@@ -8100,6 +8103,7 @@ function toTraceSummary(row) {
8100
8103
  if (error !== void 0) summary.error = error;
8101
8104
  if (usage !== void 0) summary.usage = usage;
8102
8105
  if (metadata !== void 0) summary.metadata = metadata;
8106
+ if (typeof metadata?.runId === "string") summary.runId = metadata.runId;
8103
8107
  return summary;
8104
8108
  }
8105
8109
  function parseJsonArray(value) {