@dudousxd/nestjs-agent-core 0.40.0 → 0.41.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/README.md +7 -0
  2. package/dist/ag-ui/index.cjs +46 -10
  3. package/dist/ag-ui/index.cjs.map +1 -1
  4. package/dist/ag-ui/index.d.cts +9 -3
  5. package/dist/ag-ui/index.d.ts +9 -3
  6. package/dist/ag-ui/index.js +46 -10
  7. package/dist/ag-ui/index.js.map +1 -1
  8. package/dist/{catalog-CrzetM3_.d.cts → catalog-BKS3Yxo6.d.cts} +2 -0
  9. package/dist/{catalog-CrzetM3_.d.ts → catalog-BKS3Yxo6.d.ts} +2 -0
  10. package/dist/genui/builtins.cjs.map +1 -1
  11. package/dist/genui/builtins.d.cts +1 -1
  12. package/dist/genui/builtins.d.ts +1 -1
  13. package/dist/genui/builtins.js.map +1 -1
  14. package/dist/genui/index.cjs +660 -68
  15. package/dist/genui/index.cjs.map +1 -1
  16. package/dist/genui/index.d.cts +5 -5
  17. package/dist/genui/index.d.ts +5 -5
  18. package/dist/genui/index.js +654 -68
  19. package/dist/genui/index.js.map +1 -1
  20. package/dist/guardrails/index.cjs +3 -1
  21. package/dist/guardrails/index.cjs.map +1 -1
  22. package/dist/guardrails/index.d.cts +5 -4
  23. package/dist/guardrails/index.d.ts +5 -4
  24. package/dist/guardrails/index.js +3 -1
  25. package/dist/guardrails/index.js.map +1 -1
  26. package/dist/index.cjs +1161 -421
  27. package/dist/index.cjs.map +1 -1
  28. package/dist/index.d.cts +118 -13
  29. package/dist/index.d.ts +118 -13
  30. package/dist/index.js +1153 -421
  31. package/dist/index.js.map +1 -1
  32. package/dist/{processors-B7nfbU6E.d.cts → processors-BXM-MNga.d.cts} +1 -1
  33. package/dist/{processors-BR3nICcp.d.ts → processors-ByDr5POu.d.ts} +1 -1
  34. package/dist/{stream-events-DAmes2Of.d.ts → stream-events-BGKLD6RX.d.ts} +73 -4
  35. package/dist/{stream-events-M0jc7lSW.d.cts → stream-events-CF-6-Y6L.d.cts} +73 -4
  36. package/package.json +1 -1
package/dist/index.cjs CHANGED
@@ -69,6 +69,8 @@ __export(src_exports, {
69
69
  DEFAULT_MAX_SKILLS: () => DEFAULT_MAX_SKILLS,
70
70
  DEFAULT_REFUSAL_REASON: () => DEFAULT_REFUSAL_REASON,
71
71
  DEFAULT_STRUCTURED_OUTPUT_INSTRUCTION: () => DEFAULT_STRUCTURED_OUTPUT_INSTRUCTION,
72
+ DEFAULT_TEXT_ACTION_PROPOSAL_REPLIES: () => DEFAULT_TEXT_ACTION_PROPOSAL_REPLIES,
73
+ DEFAULT_TEXT_ACTION_PROPOSAL_VOCABULARY: () => DEFAULT_TEXT_ACTION_PROPOSAL_VOCABULARY,
72
74
  DEFAULT_TOOL_TRANSIENT_RETRY_ATTEMPTS: () => DEFAULT_TOOL_TRANSIENT_RETRY_ATTEMPTS,
73
75
  DEFAULT_TOOL_TRANSIENT_RETRY_BACKOFF_MS: () => DEFAULT_TOOL_TRANSIENT_RETRY_BACKOFF_MS,
74
76
  DefaultApprovalPolicy: () => DefaultApprovalPolicy,
@@ -126,12 +128,13 @@ __export(src_exports, {
126
128
  buildSkillsBlock: () => buildSkillsBlock,
127
129
  canActorUseTool: () => canActorUseTool,
128
130
  canonicalActionProposalJson: () => canonicalActionProposalJson,
129
- canonicalJson: () => canonicalJson,
131
+ canonicalJson: () => canonicalJson2,
130
132
  claimActionProposalOutcome: () => claimActionProposalOutcome,
131
133
  closeEmptyRoles: () => closeEmptyRoles,
132
134
  compositeSkillProvider: () => compositeSkillProvider,
133
135
  confirmTokenExpiry: () => confirmTokenExpiry,
134
136
  createFrameBuffer: () => createFrameBuffer,
137
+ createFunctionalTool: () => createFunctionalTool,
135
138
  createIncrementalGate: () => createIncrementalGate,
136
139
  createNegotiatedUiCollector: () => createNegotiatedUiCollector,
137
140
  createNoopEmitUi: () => createNoopEmitUi,
@@ -145,6 +148,7 @@ __export(src_exports, {
145
148
  detachedDelivered: () => detachedDelivered,
146
149
  detachedStarted: () => detachedStarted,
147
150
  detachedUnsettled: () => detachedUnsettled,
151
+ emitToolPresentations: () => emitToolPresentations,
148
152
  encodeStreamEvent: () => encodeStreamEvent,
149
153
  escapeUnsafeToolUiText: () => escapeUnsafeToolUiText,
150
154
  estimateCost: () => estimateCost,
@@ -183,6 +187,7 @@ __export(src_exports, {
183
187
  parseTextActionProposalCommand: () => parseTextActionProposalCommand,
184
188
  personaCatalogEntry: () => personaCatalogEntry,
185
189
  prepareActionProposal: () => prepareActionProposal,
190
+ ptBrActionProposalText: () => ptBrActionProposalText,
186
191
  publishAgentDelegated: () => publishAgentDelegated,
187
192
  publishAgentMemoryResolved: () => publishAgentMemoryResolved,
188
193
  publishAgentMemoryWritten: () => publishAgentMemoryWritten,
@@ -239,6 +244,9 @@ __export(src_exports, {
239
244
  streamFailure: () => streamFailure,
240
245
  summarizeWithModel: () => summarizeWithModel,
241
246
  tenantScope: () => tenantScope,
247
+ textActionProposalReply: () => textActionProposalReply,
248
+ toActionProposalMutationView: () => toActionProposalMutationView,
249
+ toActionProposalView: () => toActionProposalView,
242
250
  toolCallApprovalFromRow: () => toolCallApprovalFromRow,
243
251
  toolCallContext: () => toolCallContext,
244
252
  traceLlmTurn: () => traceLlmTurn,
@@ -800,37 +808,37 @@ async function mayDecideApproval(policy, actor, decision) {
800
808
  return defaultCanDecide(actor, decision);
801
809
  }
802
810
  __name(mayDecideApproval, "mayDecideApproval");
803
- function toolCallApprovalFromRow(row) {
804
- if (row.approver === null || row.approver === void 0) {
811
+ function toolCallApprovalFromRow(row2) {
812
+ if (row2.approver === null || row2.approver === void 0) {
805
813
  return null;
806
814
  }
807
- const status = row.status === "pending_approval" || row.status === "proposed" ? "pending" : row.status === "rejected" ? "rejected" : row.status === "expired" ? "expired" : "approved";
808
- const expiresAt = row.expiresAt instanceof Date ? row.expiresAt.toISOString() : typeof row.expiresAt === "string" ? row.expiresAt : void 0;
815
+ const status = row2.status === "pending_approval" || row2.status === "proposed" ? "pending" : row2.status === "rejected" ? "rejected" : row2.status === "expired" ? "expired" : "approved";
816
+ const expiresAt = row2.expiresAt instanceof Date ? row2.expiresAt.toISOString() : typeof row2.expiresAt === "string" ? row2.expiresAt : void 0;
809
817
  const decided = status === "approved" || status === "rejected";
810
818
  return {
811
- toolCallId: row.toolCallId,
812
- ...row.proposalId != null ? {
813
- proposalId: row.proposalId
819
+ toolCallId: row2.toolCallId,
820
+ ...row2.proposalId != null ? {
821
+ proposalId: row2.proposalId
814
822
  } : {},
815
- approver: row.approver,
816
- ...row.confirmation != null ? {
817
- confirmation: row.confirmation
823
+ approver: row2.approver,
824
+ ...row2.confirmation != null ? {
825
+ confirmation: row2.confirmation
818
826
  } : {},
819
827
  status,
820
828
  ...expiresAt !== void 0 ? {
821
829
  expiresAt
822
830
  } : {},
823
- ...row.remember === true ? {
831
+ ...row2.remember === true ? {
824
832
  remember: true
825
833
  } : {},
826
- ...decided && typeof row.executedByRef === "string" ? {
827
- decidedBy: row.executedByRef
834
+ ...decided && typeof row2.executedByRef === "string" ? {
835
+ decidedBy: row2.executedByRef
828
836
  } : {},
829
- ...decided && typeof row.decidedVia === "string" ? {
830
- decidedVia: row.decidedVia
837
+ ...decided && typeof row2.decidedVia === "string" ? {
838
+ decidedVia: row2.decidedVia
831
839
  } : {},
832
- ...status === "rejected" && typeof row.error === "string" ? {
833
- reason: row.error
840
+ ...status === "rejected" && typeof row2.error === "string" ? {
841
+ reason: row2.error
834
842
  } : {}
835
843
  };
836
844
  }
@@ -847,24 +855,24 @@ function estimateCost(usage, price) {
847
855
  return uncachedInputTokens / 1e6 * price.inputPricePer1m + cacheWriteTokens / 1e6 * (price.cacheWritePricePer1m ?? price.inputPricePer1m) + cacheReadTokens / 1e6 * (price.cacheReadPricePer1m ?? price.inputPricePer1m) + usage.outputTokens / 1e6 * price.outputPricePer1m;
848
856
  }
849
857
  __name(estimateCost, "estimateCost");
850
- function rowCost(row, prices) {
851
- return row.costUsd ?? estimateCost(row, prices.get(row.modelId));
858
+ function rowCost(row2, prices) {
859
+ return row2.costUsd ?? estimateCost(row2, prices.get(row2.modelId));
852
860
  }
853
861
  __name(rowCost, "rowCost");
854
862
  function bucketByModel(rows, prices) {
855
863
  const byModel = /* @__PURE__ */ new Map();
856
- for (const row of rows) {
857
- const bucket = byModel.get(row.modelId) ?? {
864
+ for (const row2 of rows) {
865
+ const bucket = byModel.get(row2.modelId) ?? {
858
866
  requests: 0,
859
867
  inputTokens: 0,
860
868
  outputTokens: 0,
861
869
  costUsd: 0
862
870
  };
863
871
  bucket.requests += 1;
864
- bucket.inputTokens += row.inputTokens;
865
- bucket.outputTokens += row.outputTokens;
866
- bucket.costUsd += rowCost(row, prices);
867
- byModel.set(row.modelId, bucket);
872
+ bucket.inputTokens += row2.inputTokens;
873
+ bucket.outputTokens += row2.outputTokens;
874
+ bucket.costUsd += rowCost(row2, prices);
875
+ byModel.set(row2.modelId, bucket);
868
876
  }
869
877
  const result2 = [];
870
878
  for (const [modelId, bucket] of byModel) {
@@ -882,18 +890,18 @@ function bucketByModel(rows, prices) {
882
890
  __name(bucketByModel, "bucketByModel");
883
891
  function bucketByActor(rows, prices) {
884
892
  const byActor = /* @__PURE__ */ new Map();
885
- for (const row of rows) {
886
- const bucket = byActor.get(row.actorRef) ?? {
893
+ for (const row2 of rows) {
894
+ const bucket = byActor.get(row2.actorRef) ?? {
887
895
  requests: 0,
888
896
  totalTokens: 0,
889
897
  costUsd: 0,
890
898
  threadIds: /* @__PURE__ */ new Set()
891
899
  };
892
900
  bucket.requests += 1;
893
- bucket.totalTokens += row.inputTokens + row.outputTokens;
894
- bucket.costUsd += rowCost(row, prices);
895
- bucket.threadIds.add(row.threadId);
896
- byActor.set(row.actorRef, bucket);
901
+ bucket.totalTokens += row2.inputTokens + row2.outputTokens;
902
+ bucket.costUsd += rowCost(row2, prices);
903
+ bucket.threadIds.add(row2.threadId);
904
+ byActor.set(row2.actorRef, bucket);
897
905
  }
898
906
  const result2 = [];
899
907
  for (const [actorRef, bucket] of byActor) {
@@ -911,16 +919,16 @@ function bucketByActor(rows, prices) {
911
919
  __name(bucketByActor, "bucketByActor");
912
920
  function bucketByThread(rows, prices, threads, options) {
913
921
  const byThread = /* @__PURE__ */ new Map();
914
- for (const row of rows) {
915
- const bucket = byThread.get(row.threadId) ?? {
922
+ for (const row2 of rows) {
923
+ const bucket = byThread.get(row2.threadId) ?? {
916
924
  requests: 0,
917
925
  totalTokens: 0,
918
926
  costUsd: 0
919
927
  };
920
928
  bucket.requests += 1;
921
- bucket.totalTokens += row.inputTokens + row.outputTokens;
922
- bucket.costUsd += rowCost(row, prices);
923
- byThread.set(row.threadId, bucket);
929
+ bucket.totalTokens += row2.inputTokens + row2.outputTokens;
930
+ bucket.costUsd += rowCost(row2, prices);
931
+ byThread.set(row2.threadId, bucket);
924
932
  }
925
933
  const result2 = [];
926
934
  for (const [threadId, bucket] of byThread) {
@@ -949,26 +957,26 @@ function rollupThreadUsage(rows, prices) {
949
957
  totalTokens: 0,
950
958
  costUsd: 0
951
959
  };
952
- for (const row of rows) {
960
+ for (const row2 of rows) {
953
961
  rollup.requests += 1;
954
- rollup.inputTokens += row.inputTokens;
955
- rollup.outputTokens += row.outputTokens;
956
- rollup.totalTokens += row.inputTokens + row.outputTokens;
957
- rollup.costUsd += rowCost(row, prices);
962
+ rollup.inputTokens += row2.inputTokens;
963
+ rollup.outputTokens += row2.outputTokens;
964
+ rollup.totalTokens += row2.inputTokens + row2.outputTokens;
965
+ rollup.costUsd += rowCost(row2, prices);
958
966
  }
959
967
  return rollup;
960
968
  }
961
969
  __name(rollupThreadUsage, "rollupThreadUsage");
962
970
  function bucketUsageTrend(rows, prices) {
963
971
  const byDay = /* @__PURE__ */ new Map();
964
- for (const row of rows) {
965
- const bucket = byDay.get(row.day) ?? {
972
+ for (const row2 of rows) {
973
+ const bucket = byDay.get(row2.day) ?? {
966
974
  totalTokens: 0,
967
975
  costUsd: 0
968
976
  };
969
- bucket.totalTokens += row.inputTokens + row.outputTokens;
970
- bucket.costUsd += rowCost(row, prices);
971
- byDay.set(row.day, bucket);
977
+ bucket.totalTokens += row2.inputTokens + row2.outputTokens;
978
+ bucket.costUsd += rowCost(row2, prices);
979
+ byDay.set(row2.day, bucket);
972
980
  }
973
981
  const result2 = [];
974
982
  for (const [day, bucket] of byDay) {
@@ -1004,7 +1012,7 @@ async function filterToolsByEnabled(entries) {
1004
1012
  entry,
1005
1013
  enabled: await isToolEnabled(entry.spec, entry.handler)
1006
1014
  })));
1007
- return checked.filter((row) => row.enabled).map((row) => row.entry);
1015
+ return checked.filter((row2) => row2.enabled).map((row2) => row2.entry);
1008
1016
  }
1009
1017
  __name(filterToolsByEnabled, "filterToolsByEnabled");
1010
1018
  async function canActorUseTool(actor, handler) {
@@ -1016,7 +1024,7 @@ async function filterToolsByCanUse(entries, actor) {
1016
1024
  entry,
1017
1025
  allowed: await canActorUseTool(actor, entry.handler)
1018
1026
  })));
1019
- return checked.filter((row) => row.allowed).map((row) => row.entry);
1027
+ return checked.filter((row2) => row2.allowed).map((row2) => row2.entry);
1020
1028
  }
1021
1029
  __name(filterToolsByCanUse, "filterToolsByCanUse");
1022
1030
  async function filterToolsByRole(tools, actor, policy) {
@@ -2916,20 +2924,20 @@ function validateActionProposalDiscoveryIndexBatch(command) {
2916
2924
  __name(validateActionProposalDiscoveryIndexBatch, "validateActionProposalDiscoveryIndexBatch");
2917
2925
 
2918
2926
  // src/action-proposal-outcome.ts
2919
- function attachActionProposalOutcome(row, now, ui = [], text) {
2920
- if (row.outcome) return row;
2921
- const execution = row.execution;
2927
+ function attachActionProposalOutcome(row2, now, ui = [], text) {
2928
+ if (row2.outcome) return row2;
2929
+ const execution = row2.execution;
2922
2930
  const outcome = {
2923
- id: `${row.id}:outcome:1`,
2924
- proposalId: row.id,
2931
+ id: `${row2.id}:outcome:1`,
2932
+ proposalId: row2.id,
2925
2933
  outcomeVersion: 1,
2926
- tenantRef: row.tenantRef,
2927
- actorRef: row.actorRef,
2928
- threadId: row.threadId,
2929
- originRunId: row.originRunId,
2930
- originToolCallId: row.originToolCallId,
2931
- toolName: row.toolName,
2932
- decision: row.decision,
2934
+ tenantRef: row2.tenantRef,
2935
+ actorRef: row2.actorRef,
2936
+ threadId: row2.threadId,
2937
+ originRunId: row2.originRunId,
2938
+ originToolCallId: row2.originToolCallId,
2939
+ toolName: row2.toolName,
2940
+ decision: row2.decision,
2933
2941
  ui,
2934
2942
  createdAt: now,
2935
2943
  ...text !== void 0 ? {
@@ -2943,12 +2951,12 @@ function attachActionProposalOutcome(row, now, ui = [], text) {
2943
2951
  } : {},
2944
2952
  ...execution?.error !== void 0 ? {
2945
2953
  error: execution.error
2946
- } : row.decisionAudit?.reason !== void 0 ? {
2947
- error: row.decisionAudit.reason
2954
+ } : row2.decisionAudit?.reason !== void 0 ? {
2955
+ error: row2.decisionAudit.reason
2948
2956
  } : {}
2949
2957
  };
2950
2958
  return snapshotActionProposal({
2951
- ...row,
2959
+ ...row2,
2952
2960
  outcome,
2953
2961
  outcomeDelivery: {
2954
2962
  status: "pending",
@@ -2958,13 +2966,13 @@ function attachActionProposalOutcome(row, now, ui = [], text) {
2958
2966
  });
2959
2967
  }
2960
2968
  __name(attachActionProposalOutcome, "attachActionProposalOutcome");
2961
- function claimActionProposalOutcome(row, command, now, token) {
2969
+ function claimActionProposalOutcome(row2, command, now, token) {
2962
2970
  validateActionProposalWorkerClaim(command, now);
2963
- const delivery = row.outcomeDelivery;
2964
- if (!row.outcome || !delivery || delivery.status !== "pending" || delivery.lease && now < delivery.lease.expiresAt) return null;
2971
+ const delivery = row2.outcomeDelivery;
2972
+ if (!row2.outcome || !delivery || delivery.status !== "pending" || delivery.lease && now < delivery.lease.expiresAt) return null;
2965
2973
  const generation = delivery.generation + 1;
2966
2974
  return snapshotActionProposal({
2967
- ...row,
2975
+ ...row2,
2968
2976
  outcomeDelivery: {
2969
2977
  ...delivery,
2970
2978
  generation,
@@ -2978,11 +2986,11 @@ function claimActionProposalOutcome(row, command, now, token) {
2978
2986
  });
2979
2987
  }
2980
2988
  __name(claimActionProposalOutcome, "claimActionProposalOutcome");
2981
- function actionProposalOutcomeFenceValid(row, command, now) {
2989
+ function actionProposalOutcomeFenceValid(row2, command, now) {
2982
2990
  if (!Number.isSafeInteger(now)) throw new RangeError("Invalid server clock");
2983
2991
  if (typeof command.token !== "string" || !command.token || !Number.isSafeInteger(command.generation) || command.generation < 1 || typeof command.outcomeId !== "string" || !command.outcomeId) throw new TypeError("Invalid outcome fence");
2984
- const delivery = row.outcomeDelivery;
2985
- return row.outcome?.id === command.outcomeId && delivery?.status === "pending" && delivery.generation === command.generation && delivery.lease?.token === command.token && delivery.lease.generation === command.generation && now < delivery.lease.expiresAt;
2992
+ const delivery = row2.outcomeDelivery;
2993
+ return row2.outcome?.id === command.outcomeId && delivery?.status === "pending" && delivery.generation === command.generation && delivery.lease?.token === command.token && delivery.lease.generation === command.generation && now < delivery.lease.expiresAt;
2986
2994
  }
2987
2995
  __name(actionProposalOutcomeFenceValid, "actionProposalOutcomeFenceValid");
2988
2996
  function outcomeSummary(outcome) {
@@ -3157,21 +3165,21 @@ function check(schema, value, path, root, issues, depth) {
3157
3165
  });
3158
3166
  return;
3159
3167
  }
3160
- const s = schema;
3161
- if (typeof s.$ref === "string") {
3162
- const target = resolveRef(root, s.$ref);
3168
+ const s2 = schema;
3169
+ if (typeof s2.$ref === "string") {
3170
+ const target = resolveRef(root, s2.$ref);
3163
3171
  if (target === void 0) {
3164
3172
  issues.push({
3165
3173
  path,
3166
- message: `references unknown schema ${s.$ref}`
3174
+ message: `references unknown schema ${s2.$ref}`
3167
3175
  });
3168
3176
  return;
3169
3177
  }
3170
3178
  check(target, value, path, root, issues, depth + 1);
3171
3179
  }
3172
- if (s.type !== void 0) {
3173
- const types = Array.isArray(s.type) ? s.type : [
3174
- s.type
3180
+ if (s2.type !== void 0) {
3181
+ const types = Array.isArray(s2.type) ? s2.type : [
3182
+ s2.type
3175
3183
  ];
3176
3184
  if (!types.some((type) => matchesType(type, value))) {
3177
3185
  issues.push({
@@ -3181,76 +3189,76 @@ function check(schema, value, path, root, issues, depth) {
3181
3189
  return;
3182
3190
  }
3183
3191
  }
3184
- if (Array.isArray(s.enum) && !s.enum.some((option) => deepEqual(option, value))) {
3192
+ if (Array.isArray(s2.enum) && !s2.enum.some((option) => deepEqual(option, value))) {
3185
3193
  issues.push({
3186
3194
  path,
3187
- message: `must be one of ${s.enum.map((option) => JSON.stringify(option)).join(", ")}`
3195
+ message: `must be one of ${s2.enum.map((option) => JSON.stringify(option)).join(", ")}`
3188
3196
  });
3189
3197
  }
3190
- if ("const" in s && !deepEqual(s.const, value)) {
3198
+ if ("const" in s2 && !deepEqual(s2.const, value)) {
3191
3199
  issues.push({
3192
3200
  path,
3193
- message: `must be ${JSON.stringify(s.const)}`
3201
+ message: `must be ${JSON.stringify(s2.const)}`
3194
3202
  });
3195
3203
  }
3196
3204
  if (typeof value === "string") {
3197
- if (typeof s.minLength === "number" && value.length < s.minLength) {
3205
+ if (typeof s2.minLength === "number" && value.length < s2.minLength) {
3198
3206
  issues.push({
3199
3207
  path,
3200
- message: `must be at least ${s.minLength} characters`
3208
+ message: `must be at least ${s2.minLength} characters`
3201
3209
  });
3202
3210
  }
3203
- if (typeof s.maxLength === "number" && value.length > s.maxLength) {
3211
+ if (typeof s2.maxLength === "number" && value.length > s2.maxLength) {
3204
3212
  issues.push({
3205
3213
  path,
3206
- message: `must be at most ${s.maxLength} characters`
3214
+ message: `must be at most ${s2.maxLength} characters`
3207
3215
  });
3208
3216
  }
3209
- if (typeof s.pattern === "string") {
3217
+ if (typeof s2.pattern === "string") {
3210
3218
  let pattern;
3211
3219
  try {
3212
- pattern = new RegExp(s.pattern, "u");
3220
+ pattern = new RegExp(s2.pattern, "u");
3213
3221
  } catch {
3214
3222
  pattern = void 0;
3215
3223
  }
3216
3224
  if (pattern !== void 0 && !pattern.test(value)) {
3217
3225
  issues.push({
3218
3226
  path,
3219
- message: `must match ${s.pattern}`
3227
+ message: `must match ${s2.pattern}`
3220
3228
  });
3221
3229
  }
3222
3230
  }
3223
3231
  }
3224
3232
  if (typeof value === "number") {
3225
- if (typeof s.minimum === "number" && value < s.minimum) {
3233
+ if (typeof s2.minimum === "number" && value < s2.minimum) {
3226
3234
  issues.push({
3227
3235
  path,
3228
- message: `must be >= ${s.minimum}`
3236
+ message: `must be >= ${s2.minimum}`
3229
3237
  });
3230
3238
  }
3231
- if (typeof s.maximum === "number" && value > s.maximum) {
3239
+ if (typeof s2.maximum === "number" && value > s2.maximum) {
3232
3240
  issues.push({
3233
3241
  path,
3234
- message: `must be <= ${s.maximum}`
3242
+ message: `must be <= ${s2.maximum}`
3235
3243
  });
3236
3244
  }
3237
3245
  }
3238
3246
  if (Array.isArray(value)) {
3239
- if (typeof s.minItems === "number" && value.length < s.minItems) {
3247
+ if (typeof s2.minItems === "number" && value.length < s2.minItems) {
3240
3248
  issues.push({
3241
3249
  path,
3242
- message: `must have at least ${s.minItems} items`
3250
+ message: `must have at least ${s2.minItems} items`
3243
3251
  });
3244
3252
  }
3245
- if (typeof s.maxItems === "number" && value.length > s.maxItems) {
3253
+ if (typeof s2.maxItems === "number" && value.length > s2.maxItems) {
3246
3254
  issues.push({
3247
3255
  path,
3248
- message: `must have at most ${s.maxItems} items`
3256
+ message: `must have at most ${s2.maxItems} items`
3249
3257
  });
3250
3258
  }
3251
- if (s.items !== void 0 && !Array.isArray(s.items)) {
3259
+ if (s2.items !== void 0 && !Array.isArray(s2.items)) {
3252
3260
  value.forEach((item, index) => {
3253
- check(s.items, item, [
3261
+ check(s2.items, item, [
3254
3262
  ...path,
3255
3263
  index
3256
3264
  ], root, issues, depth + 1);
@@ -3259,9 +3267,9 @@ function check(schema, value, path, root, issues, depth) {
3259
3267
  }
3260
3268
  if (matchesType("object", value)) {
3261
3269
  const record2 = value;
3262
- const properties = typeof s.properties === "object" && s.properties !== null ? s.properties : {};
3263
- if (Array.isArray(s.required)) {
3264
- for (const key of s.required) {
3270
+ const properties = typeof s2.properties === "object" && s2.properties !== null ? s2.properties : {};
3271
+ if (Array.isArray(s2.required)) {
3272
+ for (const key of s2.required) {
3265
3273
  if (record2[key] === void 0) {
3266
3274
  issues.push({
3267
3275
  path: [
@@ -3281,7 +3289,7 @@ function check(schema, value, path, root, issues, depth) {
3281
3289
  key
3282
3290
  ], root, issues, depth + 1);
3283
3291
  }
3284
- } else if (s.additionalProperties === false) {
3292
+ } else if (s2.additionalProperties === false) {
3285
3293
  issues.push({
3286
3294
  path: [
3287
3295
  ...path,
@@ -3289,34 +3297,34 @@ function check(schema, value, path, root, issues, depth) {
3289
3297
  ],
3290
3298
  message: "is not a known property"
3291
3299
  });
3292
- } else if (typeof s.additionalProperties === "object" && s.additionalProperties !== null) {
3293
- check(s.additionalProperties, entry, [
3300
+ } else if (typeof s2.additionalProperties === "object" && s2.additionalProperties !== null) {
3301
+ check(s2.additionalProperties, entry, [
3294
3302
  ...path,
3295
3303
  key
3296
3304
  ], root, issues, depth + 1);
3297
3305
  }
3298
3306
  }
3299
3307
  }
3300
- if (Array.isArray(s.allOf)) {
3301
- for (const sub of s.allOf) check(sub, value, path, root, issues, depth + 1);
3308
+ if (Array.isArray(s2.allOf)) {
3309
+ for (const sub of s2.allOf) check(sub, value, path, root, issues, depth + 1);
3302
3310
  }
3303
- if (Array.isArray(s.anyOf) || Array.isArray(s.oneOf)) {
3304
- const options = Array.isArray(s.anyOf) ? s.anyOf : s.oneOf;
3311
+ if (Array.isArray(s2.anyOf) || Array.isArray(s2.oneOf)) {
3312
+ const options = Array.isArray(s2.anyOf) ? s2.anyOf : s2.oneOf;
3305
3313
  const passing = options.filter((sub) => {
3306
3314
  const nested = [];
3307
3315
  check(sub, value, path, root, nested, depth + 1);
3308
3316
  return nested.length === 0;
3309
3317
  }).length;
3310
- if (Array.isArray(s.anyOf) ? passing === 0 : passing !== 1) {
3318
+ if (Array.isArray(s2.anyOf) ? passing === 0 : passing !== 1) {
3311
3319
  issues.push({
3312
3320
  path,
3313
- message: Array.isArray(s.anyOf) ? "does not match any allowed shape" : "must match exactly one allowed shape"
3321
+ message: Array.isArray(s2.anyOf) ? "does not match any allowed shape" : "must match exactly one allowed shape"
3314
3322
  });
3315
3323
  }
3316
3324
  }
3317
- if (s.not !== void 0) {
3325
+ if (s2.not !== void 0) {
3318
3326
  const nested = [];
3319
- check(s.not, value, path, root, nested, depth + 1);
3327
+ check(s2.not, value, path, root, nested, depth + 1);
3320
3328
  if (nested.length === 0) {
3321
3329
  issues.push({
3322
3330
  path,
@@ -3373,7 +3381,7 @@ function buildCatalog(byName, validator) {
3373
3381
  ]
3374
3382
  };
3375
3383
  }
3376
- const result2 = await validateProps(definition.props, props, validator);
3384
+ const result2 = await validateProps(definition.outputProps ?? definition.props, props, validator);
3377
3385
  return result2;
3378
3386
  },
3379
3387
  validateSync(component, props) {
@@ -3389,11 +3397,11 @@ function buildCatalog(byName, validator) {
3389
3397
  ]
3390
3398
  };
3391
3399
  }
3392
- return validatePropsSync(definition.props, props, validator);
3400
+ return validatePropsSync(definition.outputProps ?? definition.props, props, validator);
3393
3401
  },
3394
3402
  jsonSchemaFor(component) {
3395
3403
  const definition = byName.get(component);
3396
- return definition === void 0 ? void 0 : toJsonSchema(definition.props);
3404
+ return definition === void 0 ? void 0 : toJsonSchema(definition.outputProps ?? definition.props);
3397
3405
  },
3398
3406
  extend(more) {
3399
3407
  const next = new Map(byName);
@@ -3409,7 +3417,7 @@ __name(buildCatalog, "buildCatalog");
3409
3417
 
3410
3418
  // src/genui/tree.ts
3411
3419
  var GENUI_TREE_COMPONENT = "genui:tree";
3412
- async function validateTree(catalog, tree, limits = {}) {
3420
+ async function validateTree(catalog, tree, limits = {}, phase = "output") {
3413
3421
  const maxDepth = limits.maxDepth ?? 12;
3414
3422
  const maxNodes = limits.maxNodes ?? 200;
3415
3423
  const issues = [];
@@ -3461,7 +3469,7 @@ async function validateTree(catalog, tree, limits = {}) {
3461
3469
  });
3462
3470
  return void 0;
3463
3471
  }
3464
- const validated = await catalog.validate(element.type, element.props ?? {});
3472
+ const validated = phase === "input" ? await validateProps(definition.props, element.props ?? {}, catalog.validator) : await catalog.validate(element.type, element.props ?? {});
3465
3473
  let props = {};
3466
3474
  if (!validated.ok) {
3467
3475
  for (const issue4 of validated.issues) {
@@ -3821,8 +3829,8 @@ function snapshotActionProposal(value) {
3821
3829
  return JSON.parse(canonicalActionProposalJson(value));
3822
3830
  }
3823
3831
  __name(snapshotActionProposal, "snapshotActionProposal");
3824
- function actionProposalScopeMatches(row, scope) {
3825
- return row.tenantRef === scope.tenantRef && row.actorRef === scope.actorRef && row.threadId === scope.threadId;
3832
+ function actionProposalScopeMatches(row2, scope) {
3833
+ return row2.tenantRef === scope.tenantRef && row2.actorRef === scope.actorRef && row2.threadId === scope.threadId;
3826
3834
  }
3827
3835
  __name(actionProposalScopeMatches, "actionProposalScopeMatches");
3828
3836
  function initialActionProposal(input, now) {
@@ -3838,9 +3846,9 @@ function initialActionProposal(input, now) {
3838
3846
  });
3839
3847
  }
3840
3848
  __name(initialActionProposal, "initialActionProposal");
3841
- function actionProposalCreationMatches(row, input) {
3849
+ function actionProposalCreationMatches(row2, input) {
3842
3850
  validateActionProposalCreation(input);
3843
- const { decision: _decision, decisionAudit: _audit, execution: _execution, createdAt: _created, updatedAt: _updated, supersededBy: _supersededBy, outcome: _outcome, outcomeDelivery: _delivery, ...original } = row;
3851
+ const { decision: _decision, decisionAudit: _audit, execution: _execution, createdAt: _created, updatedAt: _updated, supersededBy: _supersededBy, outcome: _outcome, outcomeDelivery: _delivery, ...original } = row2;
3844
3852
  return canonicalActionProposalJson(original) === canonicalActionProposalJson(input);
3845
3853
  }
3846
3854
  __name(actionProposalCreationMatches, "actionProposalCreationMatches");
@@ -3851,7 +3859,7 @@ function result(status, proposal) {
3851
3859
  };
3852
3860
  }
3853
3861
  __name(result, "result");
3854
- function transitionActionProposalDecision(row, command, now) {
3862
+ function transitionActionProposalDecision(row2, command, now) {
3855
3863
  checkTime(now);
3856
3864
  if (![
3857
3865
  "approved",
@@ -3862,11 +3870,11 @@ function transitionActionProposalDecision(row, command, now) {
3862
3870
  checkString(command.via);
3863
3871
  if (command.reason !== void 0 && typeof command.reason !== "string") throw new TypeError("reason must be a string");
3864
3872
  if (command.remember !== void 0 && typeof command.remember !== "boolean") throw new TypeError("remember must be a boolean");
3865
- if (row.decision !== "pending") {
3866
- return result(row.decision === command.decision ? "unchanged" : row.decision === "expired" ? "expired" : "conflict", row);
3873
+ if (row2.decision !== "pending") {
3874
+ return result(row2.decision === command.decision ? "unchanged" : row2.decision === "expired" ? "expired" : "conflict", row2);
3867
3875
  }
3868
- const next = snapshotActionProposal(row);
3869
- if (row.expiresAt !== null && now >= row.expiresAt) {
3876
+ const next = snapshotActionProposal(row2);
3877
+ if (row2.expiresAt !== null && now >= row2.expiresAt) {
3870
3878
  next.decision = "expired";
3871
3879
  next.decisionAudit = {
3872
3880
  actorRef: "system",
@@ -3876,7 +3884,7 @@ function transitionActionProposalDecision(row, command, now) {
3876
3884
  next.updatedAt = now;
3877
3885
  return result(command.decision === "expired" ? "applied" : "expired", attachActionProposalOutcome(next, now));
3878
3886
  }
3879
- if (command.decision === "expired") return result("conflict", row);
3887
+ if (command.decision === "expired") return result("conflict", row2);
3880
3888
  const { decision, ...audit } = command;
3881
3889
  next.decision = decision;
3882
3890
  next.decisionAudit = {
@@ -3904,13 +3912,13 @@ function checkLeaseMs(leaseMs, now) {
3904
3912
  if (!Number.isSafeInteger(leaseMs) || leaseMs <= 0 || !Number.isSafeInteger(now + leaseMs)) throw new RangeError("leaseMs must be finite and positive");
3905
3913
  }
3906
3914
  __name(checkLeaseMs, "checkLeaseMs");
3907
- function transitionActionProposalClaim(row, command, now, token) {
3915
+ function transitionActionProposalClaim(row2, command, now, token) {
3908
3916
  checkLeaseMs(command.leaseMs, now);
3909
3917
  checkString(command.workerId);
3910
3918
  checkString(token);
3911
- const execution = row.execution;
3912
- if (row.decision !== "approved" || !execution || execution.status !== "queued" && !(execution.status === "executing" && execution.lease && now >= execution.lease.expiresAt)) return result("conflict", row);
3913
- const next = snapshotActionProposal(row);
3919
+ const execution = row2.execution;
3920
+ if (row2.decision !== "approved" || !execution || execution.status !== "queued" && !(execution.status === "executing" && execution.lease && now >= execution.lease.expiresAt)) return result("conflict", row2);
3921
+ const next = snapshotActionProposal(row2);
3914
3922
  const generation = execution.generation + 1;
3915
3923
  next.execution = {
3916
3924
  status: "executing",
@@ -3926,32 +3934,32 @@ function transitionActionProposalClaim(row, command, now, token) {
3926
3934
  return result("applied", next);
3927
3935
  }
3928
3936
  __name(transitionActionProposalClaim, "transitionActionProposalClaim");
3929
- function leaseStatus(row, command, now) {
3937
+ function leaseStatus(row2, command, now) {
3930
3938
  checkTime(now);
3931
3939
  checkString(command.token);
3932
3940
  if (!Number.isSafeInteger(command.generation) || command.generation < 1) throw new RangeError("Invalid lease generation");
3933
- const work = row.execution;
3934
- if (row.decision !== "approved" || work?.status !== "executing" || !work.lease || work.generation !== command.generation || work.lease.generation !== command.generation || work.lease.token !== command.token) return "conflict";
3941
+ const work = row2.execution;
3942
+ if (row2.decision !== "approved" || work?.status !== "executing" || !work.lease || work.generation !== command.generation || work.lease.generation !== command.generation || work.lease.token !== command.token) return "conflict";
3935
3943
  return now >= work.lease.expiresAt ? "expired" : "valid";
3936
3944
  }
3937
3945
  __name(leaseStatus, "leaseStatus");
3938
- function transitionActionProposalLease(row, command, now) {
3946
+ function transitionActionProposalLease(row2, command, now) {
3939
3947
  checkLeaseMs(command.leaseMs, now);
3940
- const status = leaseStatus(row, command, now);
3941
- if (status !== "valid") return result(status, row);
3942
- const next = snapshotActionProposal(row);
3948
+ const status = leaseStatus(row2, command, now);
3949
+ if (status !== "valid") return result(status, row2);
3950
+ const next = snapshotActionProposal(row2);
3943
3951
  if (next.execution?.lease) next.execution.lease.expiresAt = Math.max(next.execution.lease.expiresAt, now + command.leaseMs);
3944
3952
  next.updatedAt = now;
3945
3953
  return result("applied", next);
3946
3954
  }
3947
3955
  __name(transitionActionProposalLease, "transitionActionProposalLease");
3948
- function transitionActionProposalSettlement(row, command, now) {
3956
+ function transitionActionProposalSettlement(row2, command, now) {
3949
3957
  checkTime(now);
3950
3958
  if (command.status !== "succeeded" && command.status !== "failed") throw new TypeError("Unsupported settlement status");
3951
3959
  if (command.status === "succeeded" && command.error !== void 0 || command.status === "failed" && (typeof command.error !== "string" || command.result !== void 0)) throw new TypeError("Ambiguous action proposal settlement");
3952
- const status = leaseStatus(row, command, now);
3953
- if (status !== "valid") return result(status, row);
3954
- const next = snapshotActionProposal(row);
3960
+ const status = leaseStatus(row2, command, now);
3961
+ if (status !== "valid") return result(status, row2);
3962
+ const next = snapshotActionProposal(row2);
3955
3963
  next.execution = command.status === "succeeded" ? {
3956
3964
  status: "succeeded",
3957
3965
  generation: command.generation,
@@ -3971,16 +3979,16 @@ function transitionActionProposalSettlement(row, command, now) {
3971
3979
  return result("applied", attachActionProposalOutcome(next, now, command.ui, command.text));
3972
3980
  }
3973
3981
  __name(transitionActionProposalSettlement, "transitionActionProposalSettlement");
3974
- function transitionActionProposalSupersession(row, replacement, command, now) {
3982
+ function transitionActionProposalSupersession(row2, replacement, command, now) {
3975
3983
  checkTime(now);
3976
3984
  checkString(command.replacementProposalId);
3977
3985
  checkString(command.actorRef);
3978
3986
  checkString(command.via);
3979
- if (replacement.id !== command.replacementProposalId || row.id === replacement.id || !actionProposalScopeMatches(row, replacement) || row.toolName !== replacement.toolName || !row.replacementKey || row.replacementKey !== replacement.replacementKey) return result("conflict", row);
3980
- if (row.decision === "superseded") return result(row.supersededBy === replacement.id ? "unchanged" : "conflict", row);
3981
- if (row.decision !== "pending") return result("conflict", row);
3982
- if (row.expiresAt !== null && now >= row.expiresAt) return {
3983
- ...transitionActionProposalDecision(row, {
3987
+ if (replacement.id !== command.replacementProposalId || row2.id === replacement.id || !actionProposalScopeMatches(row2, replacement) || row2.toolName !== replacement.toolName || !row2.replacementKey || row2.replacementKey !== replacement.replacementKey) return result("conflict", row2);
3988
+ if (row2.decision === "superseded") return result(row2.supersededBy === replacement.id ? "unchanged" : "conflict", row2);
3989
+ if (row2.decision !== "pending") return result("conflict", row2);
3990
+ if (row2.expiresAt !== null && now >= row2.expiresAt) return {
3991
+ ...transitionActionProposalDecision(row2, {
3984
3992
  decision: "expired",
3985
3993
  actorRef: "system",
3986
3994
  via: "expiry"
@@ -3988,7 +3996,7 @@ function transitionActionProposalSupersession(row, replacement, command, now) {
3988
3996
  status: "expired"
3989
3997
  };
3990
3998
  const next = snapshotActionProposal({
3991
- ...row,
3999
+ ...row2,
3992
4000
  decision: "superseded",
3993
4001
  supersededBy: replacement.id,
3994
4002
  decisionAudit: {
@@ -4003,6 +4011,560 @@ function transitionActionProposalSupersession(row, replacement, command, now) {
4003
4011
  }
4004
4012
  __name(transitionActionProposalSupersession, "transitionActionProposalSupersession");
4005
4013
 
4014
+ // src/genui/builtins.ts
4015
+ var str = /* @__PURE__ */ __name((description, extra = {}) => ({
4016
+ type: "string",
4017
+ ...description !== void 0 ? {
4018
+ description
4019
+ } : {},
4020
+ ...extra
4021
+ }), "str");
4022
+ var obj = /* @__PURE__ */ __name((properties, required = []) => ({
4023
+ type: "object",
4024
+ properties,
4025
+ required,
4026
+ additionalProperties: false
4027
+ }), "obj");
4028
+ var arr = /* @__PURE__ */ __name((items, extra = {}) => ({
4029
+ type: "array",
4030
+ items,
4031
+ ...extra
4032
+ }), "arr");
4033
+ var cell = {
4034
+ type: [
4035
+ "string",
4036
+ "number",
4037
+ "boolean",
4038
+ "null"
4039
+ ]
4040
+ };
4041
+ var row = {
4042
+ type: "object",
4043
+ additionalProperties: cell
4044
+ };
4045
+ var s = /* @__PURE__ */ __name((value) => value === null || value === void 0 ? "" : String(value), "s");
4046
+ var heading = /* @__PURE__ */ __name((props) => props.title ? `*${s(props.title)}*
4047
+ ` : "", "heading");
4048
+ function textTable(columns, rows, max = 15) {
4049
+ const shown = rows.slice(0, max);
4050
+ const widths = columns.map((column) => Math.min(28, Math.max(column.label.length, ...shown.map((r) => s(r[column.key]).length))));
4051
+ const format = /* @__PURE__ */ __name((values) => values.map((value, index) => value.slice(0, widths[index]).padEnd(widths[index] ?? 0)).join(" "), "format");
4052
+ const lines = [
4053
+ format(columns.map((column) => column.label)),
4054
+ widths.map((width) => "-".repeat(width)).join(" "),
4055
+ ...shown.map((r) => format(columns.map((column) => s(r[column.key]))))
4056
+ ];
4057
+ if (rows.length > max) lines.push(`\u2026 ${rows.length - max} more rows`);
4058
+ return `\`\`\`
4059
+ ${lines.join("\n")}
4060
+ \`\`\``;
4061
+ }
4062
+ __name(textTable, "textTable");
4063
+ function lineDiff(before, after) {
4064
+ const a = before.split("\n");
4065
+ const b = after.split("\n");
4066
+ if (a.length * b.length > 25e4) {
4067
+ return [
4068
+ ...a.map((text) => ({
4069
+ op: "del",
4070
+ text
4071
+ })),
4072
+ ...b.map((text) => ({
4073
+ op: "add",
4074
+ text
4075
+ }))
4076
+ ];
4077
+ }
4078
+ const dp = Array.from({
4079
+ length: a.length + 1
4080
+ }, () => new Array(b.length + 1).fill(0));
4081
+ const at = /* @__PURE__ */ __name((i2, j2) => dp[i2]?.[j2] ?? 0, "at");
4082
+ for (let i2 = a.length - 1; i2 >= 0; i2--) {
4083
+ for (let j2 = b.length - 1; j2 >= 0; j2--) {
4084
+ dp[i2][j2] = a[i2] === b[j2] ? at(i2 + 1, j2 + 1) + 1 : Math.max(at(i2 + 1, j2), at(i2, j2 + 1));
4085
+ }
4086
+ }
4087
+ const out = [];
4088
+ let i = 0;
4089
+ let j = 0;
4090
+ while (i < a.length && j < b.length) {
4091
+ if (a[i] === b[j]) {
4092
+ out.push({
4093
+ op: "same",
4094
+ text: a[i]
4095
+ });
4096
+ i++;
4097
+ j++;
4098
+ } else if (at(i + 1, j) >= at(i, j + 1)) {
4099
+ out.push({
4100
+ op: "del",
4101
+ text: a[i++]
4102
+ });
4103
+ } else {
4104
+ out.push({
4105
+ op: "add",
4106
+ text: b[j++]
4107
+ });
4108
+ }
4109
+ }
4110
+ while (i < a.length) out.push({
4111
+ op: "del",
4112
+ text: a[i++]
4113
+ });
4114
+ while (j < b.length) out.push({
4115
+ op: "add",
4116
+ text: b[j++]
4117
+ });
4118
+ return out;
4119
+ }
4120
+ __name(lineDiff, "lineDiff");
4121
+ function bar(value, max, width = 20) {
4122
+ const n = max > 0 ? Math.round(Math.abs(value) / max * width) : 0;
4123
+ return "\u2588".repeat(n) || "\u258F";
4124
+ }
4125
+ __name(bar, "bar");
4126
+ var DataTable = defineComponent({
4127
+ name: "DataTable",
4128
+ title: "Data table",
4129
+ description: "Tabular data (records with the same fields) as a sortable table. Prefer it over markdown tables for more than 3 rows.",
4130
+ props: obj({
4131
+ title: str("Short caption"),
4132
+ columns: arr(obj({
4133
+ key: str("Field name in each row"),
4134
+ label: str("Column header"),
4135
+ align: str(void 0, {
4136
+ enum: [
4137
+ "left",
4138
+ "right",
4139
+ "center"
4140
+ ]
4141
+ }),
4142
+ format: str("How to format values", {
4143
+ enum: [
4144
+ "text",
4145
+ "number",
4146
+ "currency",
4147
+ "percent",
4148
+ "date",
4149
+ "link"
4150
+ ]
4151
+ })
4152
+ }, [
4153
+ "key",
4154
+ "label"
4155
+ ]), {
4156
+ minItems: 1,
4157
+ maxItems: 12
4158
+ }),
4159
+ rows: arr(row, {
4160
+ maxItems: 500
4161
+ })
4162
+ }, [
4163
+ "columns",
4164
+ "rows"
4165
+ ]),
4166
+ fallbackText: /* @__PURE__ */ __name((props) => `${heading(props)}${textTable(props.columns ?? [], props.rows ?? [])}`, "fallbackText")
4167
+ });
4168
+ var Chart = defineComponent({
4169
+ name: "Chart",
4170
+ title: "Chart",
4171
+ description: "`bar` to compare categories, `line` for a trend over time. `data` is a list of points; `xKey` names the category/time field and each series names a numeric field.",
4172
+ props: obj({
4173
+ type: str("Chart type", {
4174
+ enum: [
4175
+ "bar",
4176
+ "line"
4177
+ ]
4178
+ }),
4179
+ title: str(),
4180
+ xKey: str("Field of each point used for the x axis"),
4181
+ series: arr(obj({
4182
+ key: str("Numeric field"),
4183
+ label: str()
4184
+ }, [
4185
+ "key"
4186
+ ]), {
4187
+ minItems: 1,
4188
+ maxItems: 6
4189
+ }),
4190
+ data: arr(row, {
4191
+ minItems: 1,
4192
+ maxItems: 200
4193
+ }),
4194
+ unit: str("Unit shown after values, e.g. `KB` or `%`")
4195
+ }, [
4196
+ "type",
4197
+ "xKey",
4198
+ "series",
4199
+ "data"
4200
+ ]),
4201
+ fallbackText: /* @__PURE__ */ __name((props) => {
4202
+ const series = props.series ?? [];
4203
+ const data = props.data ?? [];
4204
+ const first = series[0]?.key ?? "";
4205
+ const max = Math.max(0, ...data.map((point) => Math.abs(Number(point[first]) || 0)));
4206
+ const unit = props.unit ? ` ${s(props.unit)}` : "";
4207
+ const lines = data.slice(0, 20).map((point) => `${s(point[props.xKey]).slice(0, 18).padEnd(18)} ${bar(Number(point[first]) || 0, max)} ${s(point[first])}${unit}`);
4208
+ return `${heading(props)}\`\`\`
4209
+ ${lines.join("\n")}
4210
+ \`\`\``;
4211
+ }, "fallbackText")
4212
+ });
4213
+ var KpiCards = defineComponent({
4214
+ name: "KpiCards",
4215
+ title: "KPI cards",
4216
+ description: "A few key numbers (metrics, totals, counts) as cards.",
4217
+ props: obj({
4218
+ title: str(),
4219
+ items: arr(obj({
4220
+ label: str(),
4221
+ value: {
4222
+ type: [
4223
+ "string",
4224
+ "number"
4225
+ ]
4226
+ },
4227
+ delta: str("Change, e.g. `+12%`"),
4228
+ trend: str(void 0, {
4229
+ enum: [
4230
+ "up",
4231
+ "down",
4232
+ "flat"
4233
+ ]
4234
+ }),
4235
+ hint: str()
4236
+ }, [
4237
+ "label",
4238
+ "value"
4239
+ ]), {
4240
+ minItems: 1,
4241
+ maxItems: 8
4242
+ })
4243
+ }, [
4244
+ "items"
4245
+ ]),
4246
+ fallbackText: /* @__PURE__ */ __name((props) => `${heading(props)}${(props.items ?? []).map((item) => `\u2022 *${s(item.label)}:* ${s(item.value)}${item.delta ? ` (${s(item.delta)})` : ""}`).join("\n")}`, "fallbackText")
4247
+ });
4248
+ var SourceCards = defineComponent({
4249
+ name: "SourceCards",
4250
+ title: "Sources",
4251
+ description: "The documents, pages or links an answer is based on, as cards.",
4252
+ props: obj({
4253
+ title: str(),
4254
+ items: arr(obj({
4255
+ title: str(),
4256
+ url: str(),
4257
+ snippet: str(),
4258
+ source: str("e.g. Wiki, GitHub")
4259
+ }, [
4260
+ "title"
4261
+ ]), {
4262
+ minItems: 1,
4263
+ maxItems: 12
4264
+ })
4265
+ }, [
4266
+ "items"
4267
+ ]),
4268
+ fallbackText: /* @__PURE__ */ __name((props) => `${heading(props)}${(props.items ?? []).map((item) => `\u2022 ${item.url ? `<${s(item.url)}|${s(item.title)}>` : s(item.title)}${item.source ? ` \u2014 ${s(item.source)}` : ""}`).join("\n")}`, "fallbackText")
4269
+ });
4270
+ var Checklist = defineComponent({
4271
+ name: "Checklist",
4272
+ title: "Checklist",
4273
+ description: "Steps or a to-do list with done/not-done state.",
4274
+ props: obj({
4275
+ title: str(),
4276
+ items: arr(obj({
4277
+ label: str(),
4278
+ done: {
4279
+ type: "boolean"
4280
+ },
4281
+ note: str()
4282
+ }, [
4283
+ "label"
4284
+ ]), {
4285
+ minItems: 1,
4286
+ maxItems: 50
4287
+ })
4288
+ }, [
4289
+ "items"
4290
+ ]),
4291
+ fallbackText: /* @__PURE__ */ __name((props) => `${heading(props)}${(props.items ?? []).map((item) => `${item.done ? "\u2611" : "\u2610"} ${s(item.label)}${item.note ? ` \u2014 _${s(item.note)}_` : ""}`).join("\n")}`, "fallbackText")
4292
+ });
4293
+ var Timeline = defineComponent({
4294
+ name: "Timeline",
4295
+ title: "Timeline",
4296
+ description: "Events in chronological order (the history of a project, an incident, a deal).",
4297
+ props: obj({
4298
+ title: str(),
4299
+ events: arr(obj({
4300
+ date: str(),
4301
+ title: str(),
4302
+ description: str()
4303
+ }, [
4304
+ "title"
4305
+ ]), {
4306
+ minItems: 1,
4307
+ maxItems: 50
4308
+ })
4309
+ }, [
4310
+ "events"
4311
+ ]),
4312
+ fallbackText: /* @__PURE__ */ __name((props) => `${heading(props)}${(props.events ?? []).map((event) => `\u2022 ${event.date ? `*${s(event.date)}* ` : ""}${s(event.title)}${event.description ? ` \u2014 ${s(event.description)}` : ""}`).join("\n")}`, "fallbackText")
4313
+ });
4314
+ var CodeBlock = defineComponent({
4315
+ name: "CodeBlock",
4316
+ title: "Code",
4317
+ description: "A code snippet or file excerpt with syntax highlighting.",
4318
+ props: obj({
4319
+ title: str(),
4320
+ language: str(),
4321
+ code: str()
4322
+ }, [
4323
+ "code"
4324
+ ]),
4325
+ fallbackText: /* @__PURE__ */ __name((props) => `${heading(props)}\`\`\`
4326
+ ${s(props.code)}
4327
+ \`\`\``, "fallbackText")
4328
+ });
4329
+ var Diff = defineComponent({
4330
+ name: "Diff",
4331
+ title: "Diff",
4332
+ description: "A before/after change to a text or code file, as a line diff.",
4333
+ props: obj({
4334
+ title: str(),
4335
+ language: str(),
4336
+ before: str(),
4337
+ after: str()
4338
+ }, [
4339
+ "before",
4340
+ "after"
4341
+ ]),
4342
+ fallbackText: /* @__PURE__ */ __name((props) => `${heading(props)}\`\`\`
4343
+ ${lineDiff(s(props.before), s(props.after)).map((line) => `${line.op === "add" ? "+" : line.op === "del" ? "-" : " "} ${line.text}`).join("\n")}
4344
+ \`\`\``, "fallbackText")
4345
+ });
4346
+ var Callout = defineComponent({
4347
+ name: "Callout",
4348
+ title: "Callout",
4349
+ description: "A short note, warning or success message, emphasized.",
4350
+ props: obj({
4351
+ tone: str(void 0, {
4352
+ enum: [
4353
+ "info",
4354
+ "success",
4355
+ "warning",
4356
+ "danger"
4357
+ ]
4358
+ }),
4359
+ title: str(),
4360
+ text: str()
4361
+ }, [
4362
+ "text"
4363
+ ]),
4364
+ fallbackText: /* @__PURE__ */ __name((props) => `${props.tone === "warning" || props.tone === "danger" ? ":warning: " : ":information_source: "}${heading(props)}${s(props.text)}`, "fallbackText")
4365
+ });
4366
+ var Stack = defineComponent({
4367
+ name: "Stack",
4368
+ title: "Stack",
4369
+ description: "Lays its children out vertically (or horizontally with direction=row).",
4370
+ props: obj({
4371
+ direction: str(void 0, {
4372
+ enum: [
4373
+ "column",
4374
+ "row"
4375
+ ]
4376
+ }),
4377
+ gap: {
4378
+ type: "number"
4379
+ }
4380
+ }),
4381
+ children: true,
4382
+ fallbackText: /* @__PURE__ */ __name(() => "", "fallbackText")
4383
+ });
4384
+ var Card = defineComponent({
4385
+ name: "Card",
4386
+ title: "Card",
4387
+ description: "A box with an optional title around its children.",
4388
+ props: obj({
4389
+ title: str(),
4390
+ subtitle: str()
4391
+ }),
4392
+ children: true,
4393
+ fallbackText: /* @__PURE__ */ __name((props) => props.title ? `*${s(props.title)}*${props.subtitle ? ` \u2014 ${s(props.subtitle)}` : ""}` : "", "fallbackText")
4394
+ });
4395
+ var Heading = defineComponent({
4396
+ name: "Heading",
4397
+ title: "Heading",
4398
+ description: "A heading.",
4399
+ props: obj({
4400
+ text: str()
4401
+ }, [
4402
+ "text"
4403
+ ]),
4404
+ fallbackText: /* @__PURE__ */ __name((props) => `*${s(props.text)}*`, "fallbackText")
4405
+ });
4406
+ var Text = defineComponent({
4407
+ name: "Text",
4408
+ title: "Text",
4409
+ description: "A paragraph of plain text (no markdown).",
4410
+ props: obj({
4411
+ text: str(),
4412
+ muted: {
4413
+ type: "boolean"
4414
+ }
4415
+ }, [
4416
+ "text"
4417
+ ]),
4418
+ fallbackText: /* @__PURE__ */ __name((props) => s(props.text), "fallbackText")
4419
+ });
4420
+ var Badge = defineComponent({
4421
+ name: "Badge",
4422
+ title: "Badge",
4423
+ description: "A small label.",
4424
+ props: obj({
4425
+ text: str(),
4426
+ tone: str(void 0, {
4427
+ enum: [
4428
+ "neutral",
4429
+ "brand",
4430
+ "success",
4431
+ "warning",
4432
+ "danger"
4433
+ ]
4434
+ })
4435
+ }, [
4436
+ "text"
4437
+ ]),
4438
+ fallbackText: /* @__PURE__ */ __name((props) => `[${s(props.text)}]`, "fallbackText")
4439
+ });
4440
+ var Link = defineComponent({
4441
+ name: "Link",
4442
+ title: "Link",
4443
+ description: "A link to an http(s) URL.",
4444
+ props: obj({
4445
+ text: str(),
4446
+ url: str(void 0, {
4447
+ pattern: "^https?://"
4448
+ })
4449
+ }, [
4450
+ "text",
4451
+ "url"
4452
+ ]),
4453
+ fallbackText: /* @__PURE__ */ __name((props) => `<${s(props.url)}|${s(props.text || props.url)}>`, "fallbackText")
4454
+ });
4455
+ var Image = defineComponent({
4456
+ name: "Image",
4457
+ title: "Image",
4458
+ description: "An image from an https URL.",
4459
+ props: obj({
4460
+ url: str(void 0, {
4461
+ pattern: "^https://"
4462
+ }),
4463
+ alt: str()
4464
+ }, [
4465
+ "url"
4466
+ ]),
4467
+ fallbackText: /* @__PURE__ */ __name((props) => s(props.url), "fallbackText")
4468
+ });
4469
+
4470
+ // src/genui/registry.ts
4471
+ function snapshotComponentPresentation(value) {
4472
+ const seen = /* @__PURE__ */ new Set();
4473
+ const check2 = /* @__PURE__ */ __name((entry) => {
4474
+ if (entry === null || typeof entry === "string" || typeof entry === "boolean") return;
4475
+ if (typeof entry === "number" && Number.isFinite(entry)) return;
4476
+ if (typeof entry !== "object" || entry === null) throw new TypeError("genui: presentation must contain only JSON values");
4477
+ if (seen.has(entry)) throw new TypeError("genui: presentation must contain acyclic JSON values");
4478
+ if (!Array.isArray(entry) && Object.getPrototypeOf(entry) !== Object.prototype && Object.getPrototypeOf(entry) !== null) throw new TypeError("genui: presentation must contain plain JSON objects");
4479
+ seen.add(entry);
4480
+ for (const item of Object.values(entry)) check2(item);
4481
+ seen.delete(entry);
4482
+ }, "check");
4483
+ check2(value);
4484
+ return JSON.parse(JSON.stringify(value));
4485
+ }
4486
+ __name(snapshotComponentPresentation, "snapshotComponentPresentation");
4487
+ function createComponent(definition, options = {}) {
4488
+ defineComponent(definition);
4489
+ const catalog = defineCatalog([
4490
+ definition
4491
+ ], options);
4492
+ const factory = /* @__PURE__ */ __name(async (props) => {
4493
+ const result2 = await validateProps(definition.props, props, catalog.validator);
4494
+ if (!result2.ok) throw new Error(`genui: invalid ${definition.name} props: ${formatIssues(result2.issues)}`);
4495
+ const normalized = snapshotComponentPresentation(result2.value);
4496
+ if (typeof normalized !== "object" || normalized === null || Array.isArray(normalized)) throw new TypeError("genui: component props must be a JSON object");
4497
+ const portable = await catalog.validate(definition.name, normalized);
4498
+ if (!portable.ok || canonicalJson(snapshotComponentPresentation(portable.value)) !== canonicalJson(normalized)) {
4499
+ throw new Error(`genui: ${definition.name} requires outputProps accepting stable normalized JSON props`);
4500
+ }
4501
+ return {
4502
+ component: definition.name,
4503
+ props: normalized,
4504
+ version: definition.version ?? 1,
4505
+ fallbackText: componentToText(catalog, definition.name, normalized)
4506
+ };
4507
+ }, "factory");
4508
+ return Object.assign(factory, {
4509
+ definition
4510
+ });
4511
+ }
4512
+ __name(createComponent, "createComponent");
4513
+ var table = createComponent(DataTable);
4514
+ var chart = createComponent(Chart);
4515
+ function validatePresentationBatch(presentations) {
4516
+ const batch = Array.isArray(presentations) ? presentations : [
4517
+ presentations
4518
+ ];
4519
+ return batch.map((item) => {
4520
+ const presentation = snapshotComponentPresentation(item);
4521
+ if (typeof presentation !== "object" || presentation === null || typeof presentation.component !== "string" || !/^[A-Za-z][A-Za-z0-9]{0,63}$/.test(presentation.component) || !Number.isSafeInteger(presentation.version) || presentation.version <= 0 || typeof presentation.fallbackText !== "string" || typeof presentation.props !== "object" || presentation.props === null || Array.isArray(presentation.props)) {
4522
+ throw new TypeError("genui: invalid component presentation");
4523
+ }
4524
+ return presentation;
4525
+ });
4526
+ }
4527
+ __name(validatePresentationBatch, "validatePresentationBatch");
4528
+ function canonicalJson(value) {
4529
+ if (Array.isArray(value)) return `[${value.map(canonicalJson).join(",")}]`;
4530
+ if (typeof value === "object" && value !== null) {
4531
+ const record2 = value;
4532
+ return `{${Object.keys(record2).sort().map((key) => `${JSON.stringify(key)}:${canonicalJson(record2[key])}`).join(",")}}`;
4533
+ }
4534
+ return JSON.stringify(value);
4535
+ }
4536
+ __name(canonicalJson, "canonicalJson");
4537
+
4538
+ // src/tool-presentations.ts
4539
+ async function emitToolPresentations(handler, output, ctx, toolName) {
4540
+ if (handler.present === void 0) return;
4541
+ try {
4542
+ const result2 = await handler.present(output, ctx);
4543
+ if (result2 === void 0) return;
4544
+ const batch = validatePresentationBatch(result2);
4545
+ for (const presentation of batch) {
4546
+ await ctx.emitUi(presentation.component, presentation.props, {
4547
+ version: presentation.version,
4548
+ fallbackText: presentation.fallbackText
4549
+ });
4550
+ }
4551
+ } catch (error) {
4552
+ if (ctx.onPresentationError !== void 0) {
4553
+ try {
4554
+ await ctx.onPresentationError(error, {
4555
+ toolName
4556
+ });
4557
+ return;
4558
+ } catch (reportError) {
4559
+ console.warn(`Tool "${toolName}" presentation error reporter failed`, reportError);
4560
+ }
4561
+ } else {
4562
+ console.warn(`Tool "${toolName}" presentation failed after successful execution`, error);
4563
+ }
4564
+ }
4565
+ }
4566
+ __name(emitToolPresentations, "emitToolPresentations");
4567
+
4006
4568
  // src/tool-registry.ts
4007
4569
  var ToolForbiddenError = class extends Error {
4008
4570
  static {
@@ -4085,6 +4647,15 @@ var ToolRegistry = class {
4085
4647
  handler
4086
4648
  });
4087
4649
  }
4650
+ /** Whether a successful preflight shortcut has UI to journal. */
4651
+ hasPresentation(name) {
4652
+ return typeof this.entries.get(name)?.handler.present === "function";
4653
+ }
4654
+ /** Present an already authorized successful domain result without executing its action again. */
4655
+ async presentOutput(name, output, ctx) {
4656
+ const entry = this.entries.get(name);
4657
+ if (entry !== void 0) await emitToolPresentations(entry.handler, output, ctx, name);
4658
+ }
4088
4659
  has(name) {
4089
4660
  return this.entries.has(name);
4090
4661
  }
@@ -4170,8 +4741,9 @@ var ToolRegistry = class {
4170
4741
  }) : void 0;
4171
4742
  if (trusted) assertTrustedInput(name, hookInput, executionInput);
4172
4743
  if (result2?.status === "denied") throw new ToolPreflightDeniedError(name, result2.reason);
4173
- if (result2?.status === "completed") return result2.output;
4174
- return entry.handler.execute(executionInput, withEmit);
4744
+ const output = result2?.status === "completed" ? result2.output : await entry.handler.execute(executionInput, withEmit);
4745
+ await emitToolPresentations(entry.handler, output, withEmit, name);
4746
+ return output;
4175
4747
  }
4176
4748
  /** Authorize and validate without executing. The caller journals this result before approval. */
4177
4749
  async prepare(name, input, ctx, policy, options = {}) {
@@ -4237,6 +4809,7 @@ var DefaultRolesPolicy = class {
4237
4809
  this.emptyRoles = options.emptyRoles ?? "allow";
4238
4810
  }
4239
4811
  can(actor, tool) {
4812
+ if (tool.ability !== void 0 && tool.roles === void 0) return false;
4240
4813
  const allowed = tool.roles ?? this.defaultRoles;
4241
4814
  if (allowed.length === 0) return this.emptyRoles === "allow";
4242
4815
  return (actor.roles ?? []).some((role) => allowed.includes(role));
@@ -4386,7 +4959,8 @@ var AGENT_SPAN_EVENTS = [
4386
4959
  "llm.turn",
4387
4960
  "tool.execution",
4388
4961
  "retrieval",
4389
- "follow-ups"
4962
+ "follow-ups",
4963
+ "structured-output"
4390
4964
  ];
4391
4965
  var AGENT_DIAGNOSTIC_EVENTS = [
4392
4966
  "run.started",
@@ -4424,8 +4998,19 @@ function createNegotiatedUiCollector(toolCallId, scope, resolveCatalog, write) {
4424
4998
  }, "restart"),
4425
4999
  emit: /* @__PURE__ */ __name(async (component, props, options = {}) => {
4426
5000
  if (!resolveCatalog) {
4427
- if (scope.uiCapabilities !== void 0) throw new Error("UI capabilities require an authorized server catalog");
4428
- return collector.emit(component, props, options);
5001
+ const declared = scope.uiCapabilities === void 0 || scope.uiCapabilities.components.some((entry) => entry.name === component && entry.version === (options.version ?? 1));
5002
+ if (declared) return collector.emit(component, props, options);
5003
+ const id2 = options.id ?? `${toolCallId}:ui:${next++}`;
5004
+ if (options.fallbackText !== void 0 && options.fallbackText.length > 0) {
5005
+ texts.set(id2, options.fallbackText);
5006
+ await write?.({
5007
+ kind: "text",
5008
+ text: options.fallbackText
5009
+ });
5010
+ }
5011
+ return {
5012
+ id: id2
5013
+ };
4429
5014
  }
4430
5015
  const capturedProps = snapshotActionProposal(props);
4431
5016
  const capturedOptions = {
@@ -5512,6 +6097,10 @@ async function claimToolCall(turn, call) {
5512
6097
  ...spec?.terminal === true ? {
5513
6098
  terminal: true
5514
6099
  } : {},
6100
+ // Journal this extra checkpoint's opt-in; historical claims without it keep their sequence.
6101
+ ...preflight?.status === "completed" && deps.registry.hasPresentation(call.name) ? {
6102
+ presentCompletedPreflight: true
6103
+ } : {},
5515
6104
  ...approval !== void 0 ? {
5516
6105
  approval
5517
6106
  } : {},
@@ -5542,6 +6131,9 @@ async function claimToolCall(turn, call) {
5542
6131
  ...persisted?.terminal === true ? {
5543
6132
  terminal: true
5544
6133
  } : {},
6134
+ ...persisted?.presentCompletedPreflight === true ? {
6135
+ presentCompletedPreflight: true
6136
+ } : {},
5545
6137
  ...toolType === "action" && persisted?.approval !== void 0 ? {
5546
6138
  approval: persisted.approval
5547
6139
  } : {},
@@ -6068,6 +6660,19 @@ async function runClaimedToolCall(turn, claimed) {
6068
6660
  }
6069
6661
  if (claimed.preflight !== void 0 && claimed.preflight.status !== "ready") {
6070
6662
  const result2 = claimed.preflight;
6663
+ if (result2.status === "completed" && claimed.presentCompletedPreflight === true) {
6664
+ const raw = await hooks.step(`present:${call.id}`, async () => {
6665
+ const ui = createNegotiatedUiCollector(call.id, ctx, deps.resolveUiCatalog, (event) => turn.writer.write(encodeStreamEvent(event)));
6666
+ await deps.registry.presentOutput(call.name, result2.output, {
6667
+ ...toolCallContext(ctx, call.id),
6668
+ emitUi: ui.emit
6669
+ });
6670
+ return wrapToolStepOutput(result2.output, ui.components(), ui.text());
6671
+ });
6672
+ const presented = unwrapToolStepOutput(raw);
6673
+ if (presented.ui.length > 0) turn.toolUi.set(call.id, presented.ui);
6674
+ if (presented.text) turn.toolText.set(call.id, presented.text);
6675
+ }
6071
6676
  if (result2.status === "completed" && claimed.terminal === true) turn.halt.terminal = true;
6072
6677
  const outcome = result2.status === "completed" ? {
6073
6678
  status: "executed",
@@ -6959,14 +7564,14 @@ var InMemoryActionProposalStore = class {
6959
7564
  }
6960
7565
  async createActionProposal(input) {
6961
7566
  validateActionProposalCreation(input);
6962
- const row = this.rows.get(input.id);
6963
- if (row) {
6964
- if (!actionProposalScopeMatches(row, input)) return {
7567
+ const row2 = this.rows.get(input.id);
7568
+ if (row2) {
7569
+ if (!actionProposalScopeMatches(row2, input)) return {
6965
7570
  status: "conflict"
6966
7571
  };
6967
7572
  return {
6968
- status: actionProposalCreationMatches(row, input) ? "unchanged" : "conflict",
6969
- proposal: snapshotActionProposal(row)
7573
+ status: actionProposalCreationMatches(row2, input) ? "unchanged" : "conflict",
7574
+ proposal: snapshotActionProposal(row2)
6970
7575
  };
6971
7576
  }
6972
7577
  const proposal = initialActionProposal(input, this.clock());
@@ -6977,42 +7582,42 @@ var InMemoryActionProposalStore = class {
6977
7582
  };
6978
7583
  }
6979
7584
  async getActionProposal(scope, id) {
6980
- const row = this.rows.get(id);
6981
- return row && actionProposalScopeMatches(row, scope) ? snapshotActionProposal(row) : null;
7585
+ const row2 = this.rows.get(id);
7586
+ return row2 && actionProposalScopeMatches(row2, scope) ? snapshotActionProposal(row2) : null;
6982
7587
  }
6983
7588
  async listActionProposals(scope, query = {}) {
6984
7589
  const limit = validateActionProposalListQuery(query);
6985
7590
  return [
6986
7591
  ...this.rows.values()
6987
- ].filter((row) => actionProposalScopeMatches(row, scope) && (query.decision === void 0 || row.decision === query.decision) && (query.after === void 0 || row.createdAt > query.after.createdAt || row.createdAt === query.after.createdAt && row.id > query.after.id)).sort((a, b) => a.createdAt - b.createdAt || (a.id < b.id ? -1 : a.id > b.id ? 1 : 0)).slice(0, limit).map(snapshotActionProposal);
7592
+ ].filter((row2) => actionProposalScopeMatches(row2, scope) && (query.decision === void 0 || row2.decision === query.decision) && (query.after === void 0 || row2.createdAt > query.after.createdAt || row2.createdAt === query.after.createdAt && row2.id > query.after.id)).sort((a, b) => a.createdAt - b.createdAt || (a.id < b.id ? -1 : a.id > b.id ? 1 : 0)).slice(0, limit).map(snapshotActionProposal);
6988
7593
  }
6989
7594
  mutate(scope, id, transition) {
6990
- const row = this.rows.get(id);
6991
- if (!row || !actionProposalScopeMatches(row, scope)) return {
7595
+ const row2 = this.rows.get(id);
7596
+ if (!row2 || !actionProposalScopeMatches(row2, scope)) return {
6992
7597
  status: "not_found"
6993
7598
  };
6994
- const result2 = transition(row, this.clock());
7599
+ const result2 = transition(row2, this.clock());
6995
7600
  if (result2.proposal) this.rows.set(id, snapshotActionProposal(result2.proposal));
6996
7601
  return result2;
6997
7602
  }
6998
7603
  async decideActionProposal(scope, id, command) {
6999
- return this.mutate(scope, id, (row, now) => transitionActionProposalDecision(row, command, now));
7604
+ return this.mutate(scope, id, (row2, now) => transitionActionProposalDecision(row2, command, now));
7000
7605
  }
7001
7606
  async claimActionProposal(scope, id, command) {
7002
- return this.mutate(scope, id, (row, now) => transitionActionProposalClaim(row, command, now, (0, import_node_crypto2.randomUUID)()));
7607
+ return this.mutate(scope, id, (row2, now) => transitionActionProposalClaim(row2, command, now, (0, import_node_crypto2.randomUUID)()));
7003
7608
  }
7004
7609
  async extendActionProposalLease(scope, id, command) {
7005
- return this.mutate(scope, id, (row, now) => transitionActionProposalLease(row, command, now));
7610
+ return this.mutate(scope, id, (row2, now) => transitionActionProposalLease(row2, command, now));
7006
7611
  }
7007
7612
  async settleActionProposal(scope, id, command) {
7008
- return this.mutate(scope, id, (row, now) => transitionActionProposalSettlement(row, command, now));
7613
+ return this.mutate(scope, id, (row2, now) => transitionActionProposalSettlement(row2, command, now));
7009
7614
  }
7010
7615
  async claimNextActionProposal(command) {
7011
7616
  const now = this.clock();
7012
7617
  validateActionProposalWorkerClaim(command, now);
7013
7618
  const candidates = [
7014
7619
  ...this.rows.values()
7015
- ].filter((row) => row.decision === "approved" && (row.execution?.status === "queued" || row.execution?.status === "executing" && row.execution.lease !== null && now >= row.execution.lease.expiresAt)).sort((a, b) => a.createdAt - b.createdAt || (a.id < b.id ? -1 : a.id > b.id ? 1 : 0)).slice(0, 32);
7620
+ ].filter((row2) => row2.decision === "approved" && (row2.execution?.status === "queued" || row2.execution?.status === "executing" && row2.execution.lease !== null && now >= row2.execution.lease.expiresAt)).sort((a, b) => a.createdAt - b.createdAt || (a.id < b.id ? -1 : a.id > b.id ? 1 : 0)).slice(0, 32);
7016
7621
  for (const candidate of candidates) {
7017
7622
  const claimed = await this.claimActionProposal(candidate, candidate.id, command);
7018
7623
  if (claimed.status === "applied" && claimed.proposal) return claimed.proposal;
@@ -7024,7 +7629,7 @@ var InMemoryActionProposalStore = class {
7024
7629
  validateActionProposalExpiryBatch(command, now);
7025
7630
  const candidates = [
7026
7631
  ...this.rows.values()
7027
- ].filter((row) => row.decision === "pending" && row.expiresAt !== null && now >= row.expiresAt).sort((a, b) => a.createdAt - b.createdAt || (a.id < b.id ? -1 : a.id > b.id ? 1 : 0)).slice(0, command.limit);
7632
+ ].filter((row2) => row2.decision === "pending" && row2.expiresAt !== null && now >= row2.expiresAt).sort((a, b) => a.createdAt - b.createdAt || (a.id < b.id ? -1 : a.id > b.id ? 1 : 0)).slice(0, command.limit);
7028
7633
  let expired = 0;
7029
7634
  for (const candidate of candidates) {
7030
7635
  const result2 = await this.decideActionProposal(candidate, candidate.id, {
@@ -7041,11 +7646,11 @@ var InMemoryActionProposalStore = class {
7041
7646
  validateActionProposalWorkerClaim(command, now);
7042
7647
  const candidates = [
7043
7648
  ...this.rows.values()
7044
- ].filter((row) => row.outcomeDelivery?.status === "pending" && (!row.outcomeDelivery.lease || now >= row.outcomeDelivery.lease.expiresAt)).sort((a, b) => a.createdAt - b.createdAt || (a.id < b.id ? -1 : a.id > b.id ? 1 : 0)).slice(0, 32);
7649
+ ].filter((row2) => row2.outcomeDelivery?.status === "pending" && (!row2.outcomeDelivery.lease || now >= row2.outcomeDelivery.lease.expiresAt)).sort((a, b) => a.createdAt - b.createdAt || (a.id < b.id ? -1 : a.id > b.id ? 1 : 0)).slice(0, 32);
7045
7650
  for (const candidate of candidates) {
7046
- const row = this.rows.get(candidate.id);
7047
- if (!row) continue;
7048
- const next = claimActionProposalOutcome(row, command, this.clock(), (0, import_node_crypto2.randomUUID)());
7651
+ const row2 = this.rows.get(candidate.id);
7652
+ if (!row2) continue;
7653
+ const next = claimActionProposalOutcome(row2, command, this.clock(), (0, import_node_crypto2.randomUUID)());
7049
7654
  if (!next?.outcome || !next.outcomeDelivery?.lease) continue;
7050
7655
  this.rows.set(next.id, next);
7051
7656
  return {
@@ -7065,9 +7670,9 @@ var InMemoryActionProposalStore = class {
7065
7670
  if (existing) return this.createActionProposal(input);
7066
7671
  const proposal = initialActionProposal(input, this.clock());
7067
7672
  const replacements = [];
7068
- if (input.replacementKey) for (const row of this.rows.values()) {
7069
- if (row.decision !== "pending" || !actionProposalScopeMatches(row, input) || row.toolName !== input.toolName || row.replacementKey !== input.replacementKey) continue;
7070
- const result2 = transitionActionProposalSupersession(row, proposal, {
7673
+ if (input.replacementKey) for (const row2 of this.rows.values()) {
7674
+ if (row2.decision !== "pending" || !actionProposalScopeMatches(row2, input) || row2.toolName !== input.toolName || row2.replacementKey !== input.replacementKey) continue;
7675
+ const result2 = transitionActionProposalSupersession(row2, proposal, {
7071
7676
  replacementProposalId: proposal.id,
7072
7677
  actorRef: input.actorRef,
7073
7678
  via: "supersession"
@@ -7075,7 +7680,7 @@ var InMemoryActionProposalStore = class {
7075
7680
  if (result2.proposal) replacements.push(result2.proposal);
7076
7681
  }
7077
7682
  this.rows.set(proposal.id, proposal);
7078
- for (const row of replacements) this.rows.set(row.id, row);
7683
+ for (const row2 of replacements) this.rows.set(row2.id, row2);
7079
7684
  return {
7080
7685
  status: "created",
7081
7686
  proposal: snapshotActionProposal(proposal)
@@ -7086,7 +7691,7 @@ var InMemoryActionProposalStore = class {
7086
7691
  if (!replacement || !actionProposalScopeMatches(replacement, scope)) return {
7087
7692
  status: "not_found"
7088
7693
  };
7089
- return this.mutate(scope, id, (row, now) => transitionActionProposalSupersession(row, replacement, command, now));
7694
+ return this.mutate(scope, id, (row2, now) => transitionActionProposalSupersession(row2, replacement, command, now));
7090
7695
  }
7091
7696
  };
7092
7697
 
@@ -7111,7 +7716,7 @@ var InMemoryAgentStore = class extends InMemoryActionProposalStore {
7111
7716
  throw new Error(`thread ${id} already exists`);
7112
7717
  }
7113
7718
  const ts = this.now();
7114
- const row = {
7719
+ const row2 = {
7115
7720
  id,
7116
7721
  actorRef: input.actor.id,
7117
7722
  tenantRef: input.actor.tenantRef ?? null,
@@ -7124,20 +7729,20 @@ var InMemoryAgentStore = class extends InMemoryActionProposalStore {
7124
7729
  persona: input.persona
7125
7730
  } : {}
7126
7731
  };
7127
- this.threads.set(id, row);
7128
- return this.toSummary(row);
7732
+ this.threads.set(id, row2);
7733
+ return this.toSummary(row2);
7129
7734
  }
7130
7735
  async getThread(threadId) {
7131
- const row = this.threads.get(threadId);
7132
- if (row === void 0) {
7736
+ const row2 = this.threads.get(threadId);
7737
+ if (row2 === void 0) {
7133
7738
  return null;
7134
7739
  }
7135
7740
  return {
7136
- ...this.toSummary(row),
7137
- messages: row.messages.map((message) => this.withApprovals(message)),
7741
+ ...this.toSummary(row2),
7742
+ messages: row2.messages.map((message) => this.withApprovals(message)),
7138
7743
  // The run streaming right now — the one field the read-model reports it under.
7139
- ...row.activeStreamId !== void 0 ? {
7140
- activeRunId: row.activeStreamId
7744
+ ...row2.activeStreamId !== void 0 ? {
7745
+ activeRunId: row2.activeStreamId
7141
7746
  } : {}
7142
7747
  };
7143
7748
  }
@@ -7203,7 +7808,7 @@ var InMemoryAgentStore = class extends InMemoryActionProposalStore {
7203
7808
  async listThreads(actorRef, limit = 50) {
7204
7809
  return [
7205
7810
  ...this.threads.values()
7206
- ].filter((row) => row.actorRef === actorRef && !row.transient).sort((a, b) => b.updatedAt.localeCompare(a.updatedAt)).slice(0, limit).map((row) => this.toSummary(row));
7811
+ ].filter((row2) => row2.actorRef === actorRef && !row2.transient).sort((a, b) => b.updatedAt.localeCompare(a.updatedAt)).slice(0, limit).map((row2) => this.toSummary(row2));
7207
7812
  }
7208
7813
  async softDeleteThread(threadId) {
7209
7814
  this.threads.delete(threadId);
@@ -7219,7 +7824,7 @@ var InMemoryAgentStore = class extends InMemoryActionProposalStore {
7219
7824
  ];
7220
7825
  const id = crypto.randomUUID();
7221
7826
  const ts = this.now();
7222
- const row = {
7827
+ const row2 = {
7223
7828
  id,
7224
7829
  actorRef: source.actorRef,
7225
7830
  tenantRef: source.tenantRef,
@@ -7241,8 +7846,8 @@ var InMemoryAgentStore = class extends InMemoryActionProposalStore {
7241
7846
  persona: source.persona
7242
7847
  } : {}
7243
7848
  };
7244
- this.threads.set(id, row);
7245
- return this.toSummary(row);
7849
+ this.threads.set(id, row2);
7850
+ return this.toSummary(row2);
7246
7851
  }
7247
7852
  async ownerOfThread(threadId) {
7248
7853
  return this.threads.get(threadId)?.actorRef ?? null;
@@ -7262,38 +7867,38 @@ var InMemoryAgentStore = class extends InMemoryActionProposalStore {
7262
7867
  return call.runId ?? this.threads.get(call.threadId)?.activeStreamId ?? null;
7263
7868
  }
7264
7869
  async ownerOfActiveStream(runId) {
7265
- for (const row of this.threads.values()) {
7266
- if (row.activeStreamId === runId) {
7267
- return row.actorRef;
7870
+ for (const row2 of this.threads.values()) {
7871
+ if (row2.activeStreamId === runId) {
7872
+ return row2.actorRef;
7268
7873
  }
7269
7874
  }
7270
7875
  return null;
7271
7876
  }
7272
7877
  async setTitle(threadId, title) {
7273
- const row = this.threads.get(threadId);
7274
- if (row !== void 0) {
7275
- row.title = title;
7276
- row.updatedAt = this.now();
7878
+ const row2 = this.threads.get(threadId);
7879
+ if (row2 !== void 0) {
7880
+ row2.title = title;
7881
+ row2.updatedAt = this.now();
7277
7882
  }
7278
7883
  }
7279
7884
  async updateThread(threadId, patch) {
7280
- const row = this.threads.get(threadId);
7281
- if (row === void 0) {
7885
+ const row2 = this.threads.get(threadId);
7886
+ if (row2 === void 0) {
7282
7887
  return;
7283
7888
  }
7284
7889
  if (patch.title !== void 0) {
7285
- row.title = patch.title;
7890
+ row2.title = patch.title;
7286
7891
  }
7287
7892
  if (patch.defaultAgent !== void 0) {
7288
- row.defaultAgent = patch.defaultAgent;
7893
+ row2.defaultAgent = patch.defaultAgent;
7289
7894
  }
7290
7895
  if (patch.model !== void 0) {
7291
- row.model = patch.model;
7896
+ row2.model = patch.model;
7292
7897
  }
7293
7898
  if (patch.persona !== void 0) {
7294
- row.persona = patch.persona;
7899
+ row2.persona = patch.persona;
7295
7900
  }
7296
- row.updatedAt = this.now();
7901
+ row2.updatedAt = this.now();
7297
7902
  }
7298
7903
  async activeRunForThread(threadId) {
7299
7904
  return this.threads.get(threadId)?.activeStreamId ?? null;
@@ -7341,64 +7946,64 @@ var InMemoryAgentStore = class extends InMemoryActionProposalStore {
7341
7946
  }
7342
7947
  /** Settle a run's outcome. A no-op when the run is unknown (mirrors `setTitle`/`updateThread`). */
7343
7948
  async recordRunEnd(end) {
7344
- const row = this.runs.get(end.runId);
7345
- if (row === void 0) {
7949
+ const row2 = this.runs.get(end.runId);
7950
+ if (row2 === void 0) {
7346
7951
  return;
7347
7952
  }
7348
- row.status = end.status;
7349
- row.settledAt = this.now();
7953
+ row2.status = end.status;
7954
+ row2.settledAt = this.now();
7350
7955
  if (end.durationMs !== void 0) {
7351
- row.durationMs = end.durationMs;
7956
+ row2.durationMs = end.durationMs;
7352
7957
  }
7353
7958
  if (end.errorCode !== void 0) {
7354
- row.errorCode = end.errorCode;
7959
+ row2.errorCode = end.errorCode;
7355
7960
  }
7356
7961
  if (end.errorMessage !== void 0) {
7357
- row.errorMessage = end.errorMessage;
7962
+ row2.errorMessage = end.errorMessage;
7358
7963
  }
7359
7964
  }
7360
7965
  /** Bump the run's llm-step retry counter. */
7361
7966
  async bumpRunRetries(runId) {
7362
- const row = this.runs.get(runId);
7363
- if (row !== void 0) {
7364
- row.retries += 1;
7967
+ const row2 = this.runs.get(runId);
7968
+ if (row2 !== void 0) {
7969
+ row2.retries += 1;
7365
7970
  }
7366
7971
  }
7367
7972
  async promoteThread(threadId) {
7368
- const row = this.threads.get(threadId);
7369
- if (row?.transient) {
7370
- row.transient = false;
7371
- row.updatedAt = this.now();
7973
+ const row2 = this.threads.get(threadId);
7974
+ if (row2?.transient) {
7975
+ row2.transient = false;
7976
+ row2.updatedAt = this.now();
7372
7977
  }
7373
7978
  }
7374
7979
  async setActiveStream(threadId, runId) {
7375
- const row = this.threads.get(threadId);
7376
- if (row !== void 0) {
7980
+ const row2 = this.threads.get(threadId);
7981
+ if (row2 !== void 0) {
7377
7982
  if (runId === null) {
7378
- delete row.activeStreamId;
7983
+ delete row2.activeStreamId;
7379
7984
  } else {
7380
- row.activeStreamId = runId;
7985
+ row2.activeStreamId = runId;
7381
7986
  }
7382
7987
  }
7383
7988
  }
7384
7989
  async claimActiveStream(threadId, runId, options = {}) {
7385
- const row = this.threads.get(threadId);
7386
- if (row === void 0) {
7990
+ const row2 = this.threads.get(threadId);
7991
+ if (row2 === void 0) {
7387
7992
  return false;
7388
7993
  }
7389
- const holder = row.activeStreamId;
7994
+ const holder = row2.activeStreamId;
7390
7995
  if (holder !== void 0 && holder !== runId && holder !== options.replacing) {
7391
7996
  return false;
7392
7997
  }
7393
- row.activeStreamId = runId;
7998
+ row2.activeStreamId = runId;
7394
7999
  return true;
7395
8000
  }
7396
8001
  async releaseActiveStream(threadId, runId) {
7397
- const row = this.threads.get(threadId);
7398
- if (row?.activeStreamId !== runId) {
8002
+ const row2 = this.threads.get(threadId);
8003
+ if (row2?.activeStreamId !== runId) {
7399
8004
  return false;
7400
8005
  }
7401
- delete row.activeStreamId;
8006
+ delete row2.activeStreamId;
7402
8007
  return true;
7403
8008
  }
7404
8009
  async enqueueMessage(input) {
@@ -7531,38 +8136,38 @@ var InMemoryAgentStore = class extends InMemoryActionProposalStore {
7531
8136
  return void 0;
7532
8137
  }
7533
8138
  async getThreadActionProposalScope(threadId) {
7534
- const row = this.threads.get(threadId);
7535
- return row ? {
8139
+ const row2 = this.threads.get(threadId);
8140
+ return row2 ? {
7536
8141
  threadId,
7537
- actorRef: row.actorRef,
7538
- tenantRef: row.tenantRef
8142
+ actorRef: row2.actorRef,
8143
+ tenantRef: row2.tenantRef
7539
8144
  } : null;
7540
8145
  }
7541
8146
  async admitActionProposalOutcome(command) {
7542
- const row = [
8147
+ const row2 = [
7543
8148
  ...this.rows.values()
7544
- ].find((row2) => row2.outcome?.id === command.outcomeId);
7545
- if (!row?.outcome || !row.outcomeDelivery) return {
8149
+ ].find((row3) => row3.outcome?.id === command.outcomeId);
8150
+ if (!row2?.outcome || !row2.outcomeDelivery) return {
7546
8151
  status: "not_found"
7547
8152
  };
7548
- if (row.outcomeDelivery.status === "admitted") return {
8153
+ if (row2.outcomeDelivery.status === "admitted") return {
7549
8154
  status: "unchanged",
7550
- ...row.outcomeDelivery.messageId !== void 0 ? {
7551
- messageId: row.outcomeDelivery.messageId
8155
+ ...row2.outcomeDelivery.messageId !== void 0 ? {
8156
+ messageId: row2.outcomeDelivery.messageId
7552
8157
  } : {}
7553
8158
  };
7554
- if (row.outcomeDelivery.status === "discarded") return {
8159
+ if (row2.outcomeDelivery.status === "discarded") return {
7555
8160
  status: "discarded"
7556
8161
  };
7557
- if (!actionProposalOutcomeFenceValid(row, command, this.clock())) return {
8162
+ if (!actionProposalOutcomeFenceValid(row2, command, this.clock())) return {
7558
8163
  status: "conflict"
7559
8164
  };
7560
- const thread = this.threads.get(row.threadId);
8165
+ const thread = this.threads.get(row2.threadId);
7561
8166
  if (!thread) {
7562
- this.rows.set(row.id, snapshotActionProposal({
7563
- ...row,
8167
+ this.rows.set(row2.id, snapshotActionProposal({
8168
+ ...row2,
7564
8169
  outcomeDelivery: {
7565
- ...row.outcomeDelivery,
8170
+ ...row2.outcomeDelivery,
7566
8171
  status: "discarded",
7567
8172
  lease: null
7568
8173
  }
@@ -7571,7 +8176,7 @@ var InMemoryAgentStore = class extends InMemoryActionProposalStore {
7571
8176
  status: "discarded"
7572
8177
  };
7573
8178
  }
7574
- if (thread.actorRef !== row.actorRef || thread.tenantRef !== row.tenantRef) return {
8179
+ if (thread.actorRef !== row2.actorRef || thread.tenantRef !== row2.tenantRef) return {
7575
8180
  status: "conflict"
7576
8181
  };
7577
8182
  if (thread.activeStreamId) return {
@@ -7580,15 +8185,15 @@ var InMemoryAgentStore = class extends InMemoryActionProposalStore {
7580
8185
  const message = {
7581
8186
  id: crypto.randomUUID(),
7582
8187
  role: "assistant",
7583
- content: actionProposalOutcomeText(row.outcome),
8188
+ content: actionProposalOutcomeText(row2.outcome),
7584
8189
  createdAt: this.now(),
7585
- actionProposalOutcome: snapshotActionProposal(row.outcome),
7586
- ui: snapshotActionProposal(row.outcome.ui)
8190
+ actionProposalOutcome: snapshotActionProposal(row2.outcome),
8191
+ ui: snapshotActionProposal(row2.outcome.ui)
7587
8192
  };
7588
8193
  const next = snapshotActionProposal({
7589
- ...row,
8194
+ ...row2,
7590
8195
  outcomeDelivery: {
7591
- ...row.outcomeDelivery,
8196
+ ...row2.outcomeDelivery,
7592
8197
  status: "admitted",
7593
8198
  lease: null,
7594
8199
  messageId: message.id
@@ -7596,15 +8201,15 @@ var InMemoryAgentStore = class extends InMemoryActionProposalStore {
7596
8201
  });
7597
8202
  thread.messages.push(message);
7598
8203
  thread.updatedAt = message.createdAt;
7599
- this.rows.set(row.id, next);
8204
+ this.rows.set(row2.id, next);
7600
8205
  return {
7601
8206
  status: "applied",
7602
8207
  messageId: message.id
7603
8208
  };
7604
8209
  }
7605
8210
  async appendMessage(input) {
7606
- const row = this.threads.get(input.threadId);
7607
- if (row === void 0) {
8211
+ const row2 = this.threads.get(input.threadId);
8212
+ if (row2 === void 0) {
7608
8213
  throw new Error(`thread ${input.threadId} not found`);
7609
8214
  }
7610
8215
  const message = {
@@ -7649,13 +8254,13 @@ var InMemoryAgentStore = class extends InMemoryActionProposalStore {
7649
8254
  actionProposalOutcome: input.actionProposalOutcome
7650
8255
  } : {}
7651
8256
  };
7652
- row.messages.push(message);
7653
- row.updatedAt = message.createdAt;
8257
+ row2.messages.push(message);
8258
+ row2.updatedAt = message.createdAt;
7654
8259
  return message;
7655
8260
  }
7656
8261
  async setMessageToolResults(messageId, results) {
7657
- for (const row of this.threads.values()) {
7658
- const message = row.messages.find((candidate) => candidate.id === messageId);
8262
+ for (const row2 of this.threads.values()) {
8263
+ const message = row2.messages.find((candidate) => candidate.id === messageId);
7659
8264
  if (message !== void 0) {
7660
8265
  message.toolResults = results;
7661
8266
  return;
@@ -7663,12 +8268,12 @@ var InMemoryAgentStore = class extends InMemoryActionProposalStore {
7663
8268
  }
7664
8269
  }
7665
8270
  async setMessageUi(messageId, ui) {
7666
- for (const row of this.threads.values()) {
7667
- const index = row.messages.findIndex((candidate) => candidate.id === messageId);
7668
- const message = row.messages[index];
8271
+ for (const row2 of this.threads.values()) {
8272
+ const index = row2.messages.findIndex((candidate) => candidate.id === messageId);
8273
+ const message = row2.messages[index];
7669
8274
  if (message !== void 0) {
7670
8275
  const { ui: _previous, ...rest } = message;
7671
- row.messages[index] = ui.length > 0 ? {
8276
+ row2.messages[index] = ui.length > 0 ? {
7672
8277
  ...rest,
7673
8278
  ui
7674
8279
  } : rest;
@@ -7680,12 +8285,12 @@ var InMemoryAgentStore = class extends InMemoryActionProposalStore {
7680
8285
  return this.threadIdForMessage(messageId) ?? null;
7681
8286
  }
7682
8287
  async setMessageFeedback(messageId, feedback) {
7683
- for (const row of this.threads.values()) {
7684
- const index = row.messages.findIndex((candidate) => candidate.id === messageId);
7685
- const message = row.messages[index];
8288
+ for (const row2 of this.threads.values()) {
8289
+ const index = row2.messages.findIndex((candidate) => candidate.id === messageId);
8290
+ const message = row2.messages[index];
7686
8291
  if (message !== void 0) {
7687
8292
  const { feedback: _previous, ...rest } = message;
7688
- row.messages[index] = feedback !== null ? {
8293
+ row2.messages[index] = feedback !== null ? {
7689
8294
  ...rest,
7690
8295
  feedback
7691
8296
  } : rest;
@@ -7694,13 +8299,13 @@ var InMemoryAgentStore = class extends InMemoryActionProposalStore {
7694
8299
  }
7695
8300
  }
7696
8301
  async truncateFrom(threadId, messageId) {
7697
- const row = this.threads.get(threadId);
7698
- if (row === void 0) {
8302
+ const row2 = this.threads.get(threadId);
8303
+ if (row2 === void 0) {
7699
8304
  return;
7700
8305
  }
7701
- const cutoff = row.messages.findIndex((message) => message.id === messageId);
8306
+ const cutoff = row2.messages.findIndex((message) => message.id === messageId);
7702
8307
  if (cutoff >= 0) {
7703
- row.messages = row.messages.slice(0, cutoff);
8308
+ row2.messages = row2.messages.slice(0, cutoff);
7704
8309
  }
7705
8310
  }
7706
8311
  /**
@@ -7765,16 +8370,16 @@ var InMemoryAgentStore = class extends InMemoryActionProposalStore {
7765
8370
  async toolCallOutcomes(toolCallIds) {
7766
8371
  const outcomes = [];
7767
8372
  for (const id of toolCallIds) {
7768
- const row = this.toolCalls.get(id);
7769
- if (row !== void 0) {
8373
+ const row2 = this.toolCalls.get(id);
8374
+ if (row2 !== void 0) {
7770
8375
  outcomes.push({
7771
8376
  id,
7772
- status: row.status,
7773
- ...row.output !== void 0 ? {
7774
- output: row.output
8377
+ status: row2.status,
8378
+ ...row2.output !== void 0 ? {
8379
+ output: row2.output
7775
8380
  } : {},
7776
- ...row.error !== void 0 ? {
7777
- error: row.error
8381
+ ...row2.error !== void 0 ? {
8382
+ error: row2.error
7778
8383
  } : {}
7779
8384
  });
7780
8385
  }
@@ -7783,38 +8388,38 @@ var InMemoryAgentStore = class extends InMemoryActionProposalStore {
7783
8388
  }
7784
8389
  async failUnsettledToolCalls(runId, error) {
7785
8390
  let settled = 0;
7786
- for (const row of this.toolCalls.values()) {
7787
- if (row.runId === runId && row.status === "pending_approval") {
7788
- row.status = "failed";
7789
- row.error = error;
8391
+ for (const row2 of this.toolCalls.values()) {
8392
+ if (row2.runId === runId && row2.status === "pending_approval") {
8393
+ row2.status = "failed";
8394
+ row2.error = error;
7790
8395
  settled += 1;
7791
8396
  }
7792
8397
  }
7793
8398
  return settled;
7794
8399
  }
7795
8400
  async updateToolCall(input) {
7796
- const row = this.toolCalls.get(input.toolCallId);
7797
- if (row === void 0) {
8401
+ const row2 = this.toolCalls.get(input.toolCallId);
8402
+ if (row2 === void 0) {
7798
8403
  return;
7799
8404
  }
7800
- row.status = input.status;
8405
+ row2.status = input.status;
7801
8406
  if (input.output !== void 0) {
7802
- row.output = input.output;
8407
+ row2.output = input.output;
7803
8408
  }
7804
8409
  if (input.error !== void 0) {
7805
- row.error = input.error;
8410
+ row2.error = input.error;
7806
8411
  }
7807
8412
  if (input.executionMs !== void 0) {
7808
- row.executionMs = input.executionMs;
8413
+ row2.executionMs = input.executionMs;
7809
8414
  }
7810
8415
  if (input.executedByRef !== void 0) {
7811
- row.executedByRef = input.executedByRef;
8416
+ row2.executedByRef = input.executedByRef;
7812
8417
  }
7813
8418
  if (input.remember !== void 0) {
7814
- row.remember = input.remember;
8419
+ row2.remember = input.remember;
7815
8420
  }
7816
8421
  if (input.decidedVia !== void 0) {
7817
- row.decidedVia = input.decidedVia;
8422
+ row2.decidedVia = input.decidedVia;
7818
8423
  }
7819
8424
  }
7820
8425
  async recordUsage(input) {
@@ -7842,9 +8447,9 @@ var InMemoryAgentStore = class extends InMemoryActionProposalStore {
7842
8447
  return this.usageBetween(actorRef, day, day);
7843
8448
  }
7844
8449
  async usageBetween(actorRef, fromDay, toDay) {
7845
- const rows = this.usage.filter((row) => row.actorRef === actorRef && row.day >= fromDay && row.day <= toDay);
7846
- const usedTokens = rows.reduce((sum, row) => sum + row.inputTokens + row.outputTokens, 0);
7847
- const costUsd = rows.reduce((sum, row) => sum + (row.costUsd ?? 0), 0);
8450
+ const rows = this.usage.filter((row2) => row2.actorRef === actorRef && row2.day >= fromDay && row2.day <= toDay);
8451
+ const usedTokens = rows.reduce((sum, row2) => sum + row2.inputTokens + row2.outputTokens, 0);
8452
+ const costUsd = rows.reduce((sum, row2) => sum + (row2.costUsd ?? 0), 0);
7848
8453
  return {
7849
8454
  usedTokens,
7850
8455
  costUsd
@@ -7852,30 +8457,30 @@ var InMemoryAgentStore = class extends InMemoryActionProposalStore {
7852
8457
  }
7853
8458
  /** Test helper: read the recorded usage rows (modelId + token totals). */
7854
8459
  usageRows() {
7855
- return this.usage.map((row) => ({
7856
- actorRef: row.actorRef,
7857
- tokens: row.inputTokens + row.outputTokens,
7858
- modelId: row.modelId
8460
+ return this.usage.map((row2) => ({
8461
+ actorRef: row2.actorRef,
8462
+ tokens: row2.inputTokens + row2.outputTokens,
8463
+ modelId: row2.modelId
7859
8464
  }));
7860
8465
  }
7861
8466
  /** Governance read-model feed: recorded usage rows with the input/output split + thread/day. */
7862
8467
  governanceUsage() {
7863
- return this.usage.map((row) => ({
7864
- actorRef: row.actorRef,
7865
- threadId: row.threadId,
7866
- modelId: row.modelId,
7867
- inputTokens: row.inputTokens,
7868
- outputTokens: row.outputTokens,
7869
- day: row.day,
7870
- createdAt: row.createdAt,
7871
- ...row.cacheWriteTokens !== void 0 ? {
7872
- cacheWriteTokens: row.cacheWriteTokens
8468
+ return this.usage.map((row2) => ({
8469
+ actorRef: row2.actorRef,
8470
+ threadId: row2.threadId,
8471
+ modelId: row2.modelId,
8472
+ inputTokens: row2.inputTokens,
8473
+ outputTokens: row2.outputTokens,
8474
+ day: row2.day,
8475
+ createdAt: row2.createdAt,
8476
+ ...row2.cacheWriteTokens !== void 0 ? {
8477
+ cacheWriteTokens: row2.cacheWriteTokens
7873
8478
  } : {},
7874
- ...row.cacheReadTokens !== void 0 ? {
7875
- cacheReadTokens: row.cacheReadTokens
8479
+ ...row2.cacheReadTokens !== void 0 ? {
8480
+ cacheReadTokens: row2.cacheReadTokens
7876
8481
  } : {},
7877
- ...row.costUsd !== void 0 ? {
7878
- costUsd: row.costUsd
8482
+ ...row2.costUsd !== void 0 ? {
8483
+ costUsd: row2.costUsd
7879
8484
  } : {}
7880
8485
  }));
7881
8486
  }
@@ -7883,22 +8488,22 @@ var InMemoryAgentStore = class extends InMemoryActionProposalStore {
7883
8488
  governanceToolCalls() {
7884
8489
  return [
7885
8490
  ...this.toolCalls.values()
7886
- ].map((row) => ({
7887
- toolCallId: row.toolCallId,
7888
- toolName: row.toolName,
7889
- toolType: row.toolType,
7890
- status: row.status,
7891
- threadId: row.threadId,
7892
- messageId: row.messageId,
7893
- createdAt: row.createdAt,
7894
- ...row.executionMs !== void 0 ? {
7895
- executionMs: row.executionMs
8491
+ ].map((row2) => ({
8492
+ toolCallId: row2.toolCallId,
8493
+ toolName: row2.toolName,
8494
+ toolType: row2.toolType,
8495
+ status: row2.status,
8496
+ threadId: row2.threadId,
8497
+ messageId: row2.messageId,
8498
+ createdAt: row2.createdAt,
8499
+ ...row2.executionMs !== void 0 ? {
8500
+ executionMs: row2.executionMs
7896
8501
  } : {},
7897
- ...row.error !== void 0 ? {
7898
- error: row.error
8502
+ ...row2.error !== void 0 ? {
8503
+ error: row2.error
7899
8504
  } : {},
7900
- ...row.runId !== void 0 ? {
7901
- runId: row.runId
8505
+ ...row2.runId !== void 0 ? {
8506
+ runId: row2.runId
7902
8507
  } : {}
7903
8508
  }));
7904
8509
  }
@@ -7958,51 +8563,51 @@ var InMemoryAgentStore = class extends InMemoryActionProposalStore {
7958
8563
  governanceThreads() {
7959
8564
  return [
7960
8565
  ...this.threads.values()
7961
- ].map((row) => ({
7962
- threadId: row.id,
7963
- title: row.title,
7964
- actorRef: row.actorRef,
7965
- messageCount: row.messages.length,
7966
- updatedAt: row.updatedAt
8566
+ ].map((row2) => ({
8567
+ threadId: row2.id,
8568
+ title: row2.title,
8569
+ actorRef: row2.actorRef,
8570
+ messageCount: row2.messages.length,
8571
+ updatedAt: row2.updatedAt
7967
8572
  }));
7968
8573
  }
7969
8574
  /** Governance read-model feed: recorded run outcomes (the reliability surfaces). */
7970
8575
  governanceRuns() {
7971
8576
  return [
7972
8577
  ...this.runs.values()
7973
- ].map((row) => ({
7974
- runId: row.runId,
7975
- threadId: row.threadId,
7976
- actorRef: row.actorRef,
7977
- status: row.status,
7978
- retries: row.retries,
7979
- startedAt: row.startedAt,
7980
- ...row.agentName !== void 0 ? {
7981
- agentName: row.agentName
8578
+ ].map((row2) => ({
8579
+ runId: row2.runId,
8580
+ threadId: row2.threadId,
8581
+ actorRef: row2.actorRef,
8582
+ status: row2.status,
8583
+ retries: row2.retries,
8584
+ startedAt: row2.startedAt,
8585
+ ...row2.agentName !== void 0 ? {
8586
+ agentName: row2.agentName
7982
8587
  } : {},
7983
- ...row.parentRunId !== void 0 ? {
7984
- parentRunId: row.parentRunId
8588
+ ...row2.parentRunId !== void 0 ? {
8589
+ parentRunId: row2.parentRunId
7985
8590
  } : {},
7986
- ...row.durationMs !== void 0 ? {
7987
- durationMs: row.durationMs
8591
+ ...row2.durationMs !== void 0 ? {
8592
+ durationMs: row2.durationMs
7988
8593
  } : {},
7989
- ...row.errorCode !== void 0 ? {
7990
- errorCode: row.errorCode
8594
+ ...row2.errorCode !== void 0 ? {
8595
+ errorCode: row2.errorCode
7991
8596
  } : {},
7992
- ...row.errorMessage !== void 0 ? {
7993
- errorMessage: row.errorMessage
8597
+ ...row2.errorMessage !== void 0 ? {
8598
+ errorMessage: row2.errorMessage
7994
8599
  } : {},
7995
- ...row.settledAt !== void 0 ? {
7996
- settledAt: row.settledAt
8600
+ ...row2.settledAt !== void 0 ? {
8601
+ settledAt: row2.settledAt
7997
8602
  } : {},
7998
- ...row.promptHash !== void 0 ? {
7999
- promptHash: row.promptHash
8603
+ ...row2.promptHash !== void 0 ? {
8604
+ promptHash: row2.promptHash
8000
8605
  } : {}
8001
8606
  }));
8002
8607
  }
8003
8608
  threadIdForMessage(messageId) {
8004
- for (const [threadId, row] of this.threads) {
8005
- if (row.messages.some((message) => message.id === messageId)) {
8609
+ for (const [threadId, row2] of this.threads) {
8610
+ if (row2.messages.some((message) => message.id === messageId)) {
8006
8611
  return threadId;
8007
8612
  }
8008
8613
  }
@@ -8012,54 +8617,54 @@ var InMemoryAgentStore = class extends InMemoryActionProposalStore {
8012
8617
  toolCallRows() {
8013
8618
  return [
8014
8619
  ...this.toolCalls.values()
8015
- ].map((row) => ({
8016
- toolCallId: row.toolCallId,
8017
- toolName: row.toolName,
8018
- toolType: row.toolType,
8019
- status: row.status,
8020
- input: row.input,
8021
- ...row.output !== void 0 ? {
8022
- output: row.output
8620
+ ].map((row2) => ({
8621
+ toolCallId: row2.toolCallId,
8622
+ toolName: row2.toolName,
8623
+ toolType: row2.toolType,
8624
+ status: row2.status,
8625
+ input: row2.input,
8626
+ ...row2.output !== void 0 ? {
8627
+ output: row2.output
8023
8628
  } : {},
8024
- ...row.error !== void 0 ? {
8025
- error: row.error
8629
+ ...row2.error !== void 0 ? {
8630
+ error: row2.error
8026
8631
  } : {},
8027
- ...row.runId !== void 0 ? {
8028
- runId: row.runId
8632
+ ...row2.runId !== void 0 ? {
8633
+ runId: row2.runId
8029
8634
  } : {},
8030
- ...row.executedByRef !== void 0 ? {
8031
- executedByRef: row.executedByRef
8635
+ ...row2.executedByRef !== void 0 ? {
8636
+ executedByRef: row2.executedByRef
8032
8637
  } : {},
8033
- ...row.approver !== void 0 ? {
8034
- approver: row.approver
8638
+ ...row2.approver !== void 0 ? {
8639
+ approver: row2.approver
8035
8640
  } : {},
8036
- ...row.expiresAt !== void 0 ? {
8037
- expiresAt: row.expiresAt
8641
+ ...row2.expiresAt !== void 0 ? {
8642
+ expiresAt: row2.expiresAt
8038
8643
  } : {},
8039
- ...row.remember !== void 0 ? {
8040
- remember: row.remember
8644
+ ...row2.remember !== void 0 ? {
8645
+ remember: row2.remember
8041
8646
  } : {},
8042
- ...row.decidedVia !== void 0 ? {
8043
- decidedVia: row.decidedVia
8647
+ ...row2.decidedVia !== void 0 ? {
8648
+ decidedVia: row2.decidedVia
8044
8649
  } : {}
8045
8650
  }));
8046
8651
  }
8047
- toSummary(row) {
8048
- const last = row.messages[row.messages.length - 1];
8652
+ toSummary(row2) {
8653
+ const last = row2.messages[row2.messages.length - 1];
8049
8654
  return {
8050
- id: row.id,
8051
- title: row.title,
8052
- transient: row.transient,
8053
- createdAt: row.createdAt,
8054
- updatedAt: row.updatedAt,
8655
+ id: row2.id,
8656
+ title: row2.title,
8657
+ transient: row2.transient,
8658
+ createdAt: row2.createdAt,
8659
+ updatedAt: row2.updatedAt,
8055
8660
  ...last !== void 0 ? {
8056
8661
  lastMessagePreview: last.content.slice(0, 120)
8057
8662
  } : {},
8058
- defaultAgent: row.defaultAgent ?? null,
8059
- ...row.model != null ? {
8060
- model: row.model
8663
+ defaultAgent: row2.defaultAgent ?? null,
8664
+ ...row2.model != null ? {
8665
+ model: row2.model
8061
8666
  } : {},
8062
- persona: row.persona ?? null
8667
+ persona: row2.persona ?? null
8063
8668
  };
8064
8669
  }
8065
8670
  };
@@ -8067,22 +8672,22 @@ var InMemoryAgentStore = class extends InMemoryActionProposalStore {
8067
8672
  // src/confirm-token.ts
8068
8673
  var import_node_crypto3 = require("crypto");
8069
8674
  var DEFAULT_CONFIRM_TTL_MS = 15 * 60 * 1e3;
8070
- function canonicalJson(value) {
8675
+ function canonicalJson2(value) {
8071
8676
  if (value === void 0) return "null";
8072
8677
  if (value === null || typeof value !== "object") return JSON.stringify(value) ?? "null";
8073
- if (Array.isArray(value)) return `[${value.map(canonicalJson).join(",")}]`;
8678
+ if (Array.isArray(value)) return `[${value.map(canonicalJson2).join(",")}]`;
8074
8679
  if (typeof value.toJSON === "function") {
8075
- return canonicalJson(value.toJSON());
8680
+ return canonicalJson2(value.toJSON());
8076
8681
  }
8077
8682
  const entries = Object.entries(value).filter(([, entry]) => entry !== void 0).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0);
8078
- return `{${entries.map(([key, entry]) => `${JSON.stringify(key)}:${canonicalJson(entry)}`).join(",")}}`;
8683
+ return `{${entries.map(([key, entry]) => `${JSON.stringify(key)}:${canonicalJson2(entry)}`).join(",")}}`;
8079
8684
  }
8080
- __name(canonicalJson, "canonicalJson");
8685
+ __name(canonicalJson2, "canonicalJson");
8081
8686
  function signature(subject, expiresAt, secret) {
8082
8687
  if (secret === "") {
8083
8688
  throw new Error("confirm token: the secret is empty");
8084
8689
  }
8085
- return (0, import_node_crypto3.createHmac)("sha256", secret).update(canonicalJson([
8690
+ return (0, import_node_crypto3.createHmac)("sha256", secret).update(canonicalJson2([
8086
8691
  "agent-confirm",
8087
8692
  subject.tool,
8088
8693
  subject.actorId,
@@ -8410,8 +9015,8 @@ var SqlTokenStreamSink = class {
8410
9015
  autoPurge;
8411
9016
  writes = /* @__PURE__ */ new Map();
8412
9017
  lastAutoPurge = 0;
8413
- constructor(table, options = {}) {
8414
- this.table = table;
9018
+ constructor(table2, options = {}) {
9019
+ this.table = table2;
8415
9020
  this.pollIntervalMs = Math.max(1, options.pollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS);
8416
9021
  this.idlePollIntervalMs = Math.max(this.pollIntervalMs, options.idlePollIntervalMs ?? DEFAULT_IDLE_POLL_INTERVAL_MS);
8417
9022
  this.flushMs = Math.max(0, options.flushMs ?? DEFAULT_FLUSH_MS);
@@ -8553,15 +9158,15 @@ var SqlTokenStreamSink = class {
8553
9158
  let quietSince = Date.now();
8554
9159
  while (true) {
8555
9160
  const rows = await this.table.read(runId, cursor, READ_PAGE);
8556
- for (const row of rows) {
8557
- cursor = row.seq;
8558
- if (row.frame === null) {
8559
- if (row.error !== null) {
8560
- throw new AgentStreamError(JSON.parse(row.error));
9161
+ for (const row2 of rows) {
9162
+ cursor = row2.seq;
9163
+ if (row2.frame === null) {
9164
+ if (row2.error !== null) {
9165
+ throw new AgentStreamError(JSON.parse(row2.error));
8561
9166
  }
8562
9167
  return;
8563
9168
  }
8564
- yield encoder2.encode(row.frame);
9169
+ yield encoder2.encode(row2.frame);
8565
9170
  }
8566
9171
  if (rows.length > 0) {
8567
9172
  quietSince = Date.now();
@@ -8613,8 +9218,8 @@ var SqlTokenStreamSink = class {
8613
9218
  };
8614
9219
 
8615
9220
  // src/action-proposal-text.ts
8616
- function resolveTextActionProposalDecision(text, proposals) {
8617
- const command = parseTextActionProposalCommand(text);
9221
+ function resolveTextActionProposalDecision(text, proposals, vocabulary) {
9222
+ const command = parseTextActionProposalCommand(text, vocabulary);
8618
9223
  if (command.status === "unmatched") return command;
8619
9224
  const { decision, remember } = command;
8620
9225
  const pending = proposals.filter((proposal) => proposal.decision === "pending");
@@ -8649,40 +9254,136 @@ function resolveTextActionProposalDecision(text, proposals) {
8649
9254
  };
8650
9255
  }
8651
9256
  __name(resolveTextActionProposalDecision, "resolveTextActionProposalDecision");
8652
- function parseTextActionProposalCommand(text) {
9257
+ var DEFAULT_TEXT_ACTION_PROPOSAL_VOCABULARY = {
9258
+ approve: [
9259
+ "yes",
9260
+ "confirm",
9261
+ "approve",
9262
+ "approved",
9263
+ "ok"
9264
+ ],
9265
+ reject: [
9266
+ "no",
9267
+ "cancel",
9268
+ "reject",
9269
+ "deny"
9270
+ ],
9271
+ remember: [
9272
+ "always in this conversation"
9273
+ ]
9274
+ };
9275
+ var DEFAULT_TEXT_ACTION_PROPOSAL_REPLIES = {
9276
+ approved: "Proposal approved and queued to run.",
9277
+ rejected: "Proposal rejected; nothing was run.",
9278
+ expired: "The proposal expired; nothing was run.",
9279
+ unchanged: "This proposal could not be changed; refresh the list to see where it stands.",
9280
+ ambiguous: /* @__PURE__ */ __name((ids) => `Which proposal? Reply confirm #ID or cancel #ID: ${ids.join(", ")}`, "ambiguous"),
9281
+ tooMany: "There are several proposals. Confirm or reject one with an explicit #ID."
9282
+ };
9283
+ function textActionProposalReply(result2, decision, replies = DEFAULT_TEXT_ACTION_PROPOSAL_REPLIES) {
9284
+ return result2.status === "expired" || result2.proposal?.decision === "expired" ? replies.expired : result2.status === "applied" || result2.status === "unchanged" ? decision === "approved" ? replies.approved : replies.rejected : replies.unchanged;
9285
+ }
9286
+ __name(textActionProposalReply, "textActionProposalReply");
9287
+ var escapeRegExp = /* @__PURE__ */ __name((word) => word.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), "escapeRegExp");
9288
+ var alternatives = /* @__PURE__ */ __name((words) => words.map((word) => word.trim()).filter((word) => word.length > 0).map((word) => escapeRegExp(word).replace(/\s+/g, "\\s+")).join("|"), "alternatives");
9289
+ var fold = /* @__PURE__ */ __name((word) => word.trim().toLowerCase(), "fold");
9290
+ function parseTextActionProposalCommand(text, vocabulary = DEFAULT_TEXT_ACTION_PROPOSAL_VOCABULARY) {
8653
9291
  if (/[\r\n]/u.test(text)) return {
8654
9292
  status: "unmatched"
8655
9293
  };
8656
- const normalized = text.trim();
8657
- const match = /^(sim|confirmo|confirmar|aprovar|aprovo|cancelar|rejeitar|rejeito|não|nao)(?: (sempre nesta conversa))?(?: #([^\s]+?))?[.!]?$/iu.exec(normalized);
9294
+ const verbs = alternatives([
9295
+ ...vocabulary.approve,
9296
+ ...vocabulary.reject
9297
+ ]);
9298
+ if (verbs.length === 0) return {
9299
+ status: "unmatched"
9300
+ };
9301
+ const remember = alternatives(vocabulary.remember);
9302
+ const match = new RegExp(`^(${verbs})${remember.length > 0 ? `(?: (${remember}))?` : "()"}(?: #([^\\s]+?))?[.!]?$`, "iu").exec(text.trim());
8658
9303
  if (!match) return {
8659
9304
  status: "unmatched"
8660
9305
  };
8661
- const verb = match[1]?.toLocaleLowerCase("pt-BR");
9306
+ const verb = match[1] === void 0 ? void 0 : fold(match[1]);
8662
9307
  if (verb === void 0) return {
8663
9308
  status: "unmatched"
8664
9309
  };
8665
- const decision = [
8666
- "cancelar",
8667
- "rejeitar",
8668
- "rejeito",
8669
- "n\xE3o",
8670
- "nao"
8671
- ].includes(verb) ? "rejected" : "approved";
8672
- const remember = match[2] !== void 0;
8673
- if (remember && decision !== "approved") return {
9310
+ const decision = vocabulary.reject.some((word) => fold(word) === verb) ? "rejected" : "approved";
9311
+ const remembers = match[2] !== void 0 && match[2] !== "";
9312
+ if (remembers && decision !== "approved") return {
8674
9313
  status: "unmatched"
8675
9314
  };
8676
9315
  return {
8677
9316
  status: "command",
8678
9317
  decision,
8679
- remember,
9318
+ remember: remembers,
8680
9319
  ...match[3] !== void 0 ? {
8681
9320
  proposalId: match[3]
8682
9321
  } : {}
8683
9322
  };
8684
9323
  }
8685
9324
  __name(parseTextActionProposalCommand, "parseTextActionProposalCommand");
9325
+ var ptBrActionProposalText = {
9326
+ vocabulary: {
9327
+ approve: [
9328
+ "sim",
9329
+ "confirmo",
9330
+ "confirmar",
9331
+ "aprovar",
9332
+ "aprovo",
9333
+ "pode",
9334
+ ...DEFAULT_TEXT_ACTION_PROPOSAL_VOCABULARY.approve
9335
+ ],
9336
+ reject: [
9337
+ "n\xE3o",
9338
+ "nao",
9339
+ "cancelar",
9340
+ "cancela",
9341
+ "rejeitar",
9342
+ "rejeito",
9343
+ ...DEFAULT_TEXT_ACTION_PROPOSAL_VOCABULARY.reject
9344
+ ],
9345
+ remember: [
9346
+ "sempre nesta conversa",
9347
+ ...DEFAULT_TEXT_ACTION_PROPOSAL_VOCABULARY.remember
9348
+ ]
9349
+ },
9350
+ replies: {
9351
+ approved: "Proposta aprovada e enfileirada para execu\xE7\xE3o.",
9352
+ rejected: "Proposta rejeitada; nenhuma a\xE7\xE3o foi executada.",
9353
+ expired: "A proposta expirou; nenhuma a\xE7\xE3o foi executada.",
9354
+ unchanged: "N\xE3o foi poss\xEDvel alterar esta proposta; atualize a lista para consultar seu estado.",
9355
+ ambiguous: /* @__PURE__ */ __name((ids) => `Qual proposta? Responda confirmar #ID ou cancelar #ID: ${ids.join(", ")}`, "ambiguous"),
9356
+ tooMany: "H\xE1 v\xE1rias propostas. Confirme ou rejeite usando #ID expl\xEDcito."
9357
+ }
9358
+ };
9359
+
9360
+ // src/action-proposal-view.ts
9361
+ function toActionProposalView(proposal) {
9362
+ const { execution, outcomeDelivery, idempotencyKey: _idempotencyKey, preparationInput: _preparationInput, executionContext: _executionContext, ...rest } = proposal;
9363
+ return {
9364
+ ...rest,
9365
+ execution: execution === null ? null : withoutLease(execution),
9366
+ ...outcomeDelivery !== void 0 ? {
9367
+ outcomeDelivery: withoutLease(outcomeDelivery)
9368
+ } : {}
9369
+ };
9370
+ }
9371
+ __name(toActionProposalView, "toActionProposalView");
9372
+ function toActionProposalMutationView(result2) {
9373
+ const { proposal, ...rest } = result2;
9374
+ return {
9375
+ ...rest,
9376
+ ...proposal !== void 0 ? {
9377
+ proposal: toActionProposalView(proposal)
9378
+ } : {}
9379
+ };
9380
+ }
9381
+ __name(toActionProposalMutationView, "toActionProposalMutationView");
9382
+ function withoutLease(value) {
9383
+ const { lease: _lease, ...rest } = value;
9384
+ return rest;
9385
+ }
9386
+ __name(withoutLease, "withoutLease");
8686
9387
 
8687
9388
  // src/action-proposal-executor.ts
8688
9389
  var ActionProposalExecutor = class {
@@ -8914,6 +9615,37 @@ function assertIndependentActionCapabilities(store, resolver) {
8914
9615
  if (required.some((method) => typeof candidate[method] !== "function")) throw new Error("Independent action mode requires proposal, worker, outcome and admission capabilities on the conversation store");
8915
9616
  }
8916
9617
  __name(assertIndependentActionCapabilities, "assertIndependentActionCapabilities");
9618
+
9619
+ // src/functional-tool.ts
9620
+ function createFunctionalTool(definition) {
9621
+ const { input, execute, present, preflight, isEnabled, canUse, describe, kind, ...metadata } = definition;
9622
+ return {
9623
+ spec: {
9624
+ ...metadata,
9625
+ kind: kind ?? "read",
9626
+ inputSchema: input
9627
+ },
9628
+ handler: {
9629
+ execute: execute.bind(definition),
9630
+ ...present === void 0 ? {} : {
9631
+ present: present.bind(definition)
9632
+ },
9633
+ ...preflight === void 0 ? {} : {
9634
+ preflight: preflight.bind(definition)
9635
+ },
9636
+ ...isEnabled === void 0 ? {} : {
9637
+ isEnabled: isEnabled.bind(definition)
9638
+ },
9639
+ ...canUse === void 0 ? {} : {
9640
+ canUse: canUse.bind(definition)
9641
+ },
9642
+ ...describe === void 0 ? {} : {
9643
+ describe: describe.bind(definition)
9644
+ }
9645
+ }
9646
+ };
9647
+ }
9648
+ __name(createFunctionalTool, "createFunctionalTool");
8917
9649
  // Annotate the CommonJS export names for ESM import in node:
8918
9650
  0 && (module.exports = {
8919
9651
  AGENT_ACTOR_DIRECTORY,
@@ -8964,6 +9696,8 @@ __name(assertIndependentActionCapabilities, "assertIndependentActionCapabilities
8964
9696
  DEFAULT_MAX_SKILLS,
8965
9697
  DEFAULT_REFUSAL_REASON,
8966
9698
  DEFAULT_STRUCTURED_OUTPUT_INSTRUCTION,
9699
+ DEFAULT_TEXT_ACTION_PROPOSAL_REPLIES,
9700
+ DEFAULT_TEXT_ACTION_PROPOSAL_VOCABULARY,
8967
9701
  DEFAULT_TOOL_TRANSIENT_RETRY_ATTEMPTS,
8968
9702
  DEFAULT_TOOL_TRANSIENT_RETRY_BACKOFF_MS,
8969
9703
  DefaultApprovalPolicy,
@@ -9027,6 +9761,7 @@ __name(assertIndependentActionCapabilities, "assertIndependentActionCapabilities
9027
9761
  compositeSkillProvider,
9028
9762
  confirmTokenExpiry,
9029
9763
  createFrameBuffer,
9764
+ createFunctionalTool,
9030
9765
  createIncrementalGate,
9031
9766
  createNegotiatedUiCollector,
9032
9767
  createNoopEmitUi,
@@ -9040,6 +9775,7 @@ __name(assertIndependentActionCapabilities, "assertIndependentActionCapabilities
9040
9775
  detachedDelivered,
9041
9776
  detachedStarted,
9042
9777
  detachedUnsettled,
9778
+ emitToolPresentations,
9043
9779
  encodeStreamEvent,
9044
9780
  escapeUnsafeToolUiText,
9045
9781
  estimateCost,
@@ -9078,6 +9814,7 @@ __name(assertIndependentActionCapabilities, "assertIndependentActionCapabilities
9078
9814
  parseTextActionProposalCommand,
9079
9815
  personaCatalogEntry,
9080
9816
  prepareActionProposal,
9817
+ ptBrActionProposalText,
9081
9818
  publishAgentDelegated,
9082
9819
  publishAgentMemoryResolved,
9083
9820
  publishAgentMemoryWritten,
@@ -9134,6 +9871,9 @@ __name(assertIndependentActionCapabilities, "assertIndependentActionCapabilities
9134
9871
  streamFailure,
9135
9872
  summarizeWithModel,
9136
9873
  tenantScope,
9874
+ textActionProposalReply,
9875
+ toActionProposalMutationView,
9876
+ toActionProposalView,
9137
9877
  toolCallApprovalFromRow,
9138
9878
  toolCallContext,
9139
9879
  traceLlmTurn,