@dudousxd/nestjs-agent-core 0.44.0 → 0.45.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -68,6 +68,7 @@ __export(src_exports, {
68
68
  DEFAULT_MAX_FACT_CHARS: () => DEFAULT_MAX_FACT_CHARS,
69
69
  DEFAULT_MAX_MEMORIES: () => DEFAULT_MAX_MEMORIES,
70
70
  DEFAULT_MAX_SKILLS: () => DEFAULT_MAX_SKILLS,
71
+ DEFAULT_PREVIEW_THROTTLE_MS: () => DEFAULT_PREVIEW_THROTTLE_MS,
71
72
  DEFAULT_REFUSAL_REASON: () => DEFAULT_REFUSAL_REASON,
72
73
  DEFAULT_STRUCTURED_OUTPUT_INSTRUCTION: () => DEFAULT_STRUCTURED_OUTPUT_INSTRUCTION,
73
74
  DEFAULT_TEXT_ACTION_PROPOSAL_REPLIES: () => DEFAULT_TEXT_ACTION_PROPOSAL_REPLIES,
@@ -186,9 +187,12 @@ __export(src_exports, {
186
187
  observeTurnFrames: () => observeTurnFrames,
187
188
  offerMemories: () => offerMemories,
188
189
  offerSkills: () => offerSkills,
190
+ parsePartialJson: () => parsePartialJson,
189
191
  parseTextActionProposalCommand: () => parseTextActionProposalCommand,
190
192
  personaCatalogEntry: () => personaCatalogEntry,
191
193
  prepareActionProposal: () => prepareActionProposal,
194
+ previewToolInputs: () => previewToolInputs,
195
+ previewUiId: () => previewUiId,
192
196
  ptBrActionProposalText: () => ptBrActionProposalText,
193
197
  publishAgentDelegated: () => publishAgentDelegated,
194
198
  publishAgentMemoryResolved: () => publishAgentMemoryResolved,
@@ -209,6 +213,7 @@ __export(src_exports, {
209
213
  quotaWarning: () => quotaWarning,
210
214
  readElicitationInput: () => readElicitationInput,
211
215
  readElicitationQuestions: () => readElicitationQuestions,
216
+ registryInputPreviews: () => registryInputPreviews,
212
217
  releaseGatedFrames: () => releaseGatedFrames,
213
218
  releaseThreadRun: () => releaseThreadRun,
214
219
  rememberInputSchema: () => rememberInputSchema,
@@ -277,6 +282,7 @@ __export(src_exports, {
277
282
  withSkillTool: () => withSkillTool,
278
283
  withToolTimeout: () => withToolTimeout,
279
284
  withTurnFrames: () => withTurnFrames,
285
+ withdrawPreviewEvent: () => withdrawPreviewEvent,
280
286
  wrapToolPreflightDenied: () => wrapToolPreflightDenied,
281
287
  wrapToolStepOutput: () => wrapToolStepOutput,
282
288
  writeMemory: () => writeMemory
@@ -398,7 +404,7 @@ function observeTurnFrames(writer, now = Date.now) {
398
404
  return;
399
405
  }
400
406
  closeBurst();
401
- if (event.kind === "ui") {
407
+ if (event.kind === "ui" && event.partial !== true) {
402
408
  ui.set(event.id, {
403
409
  id: event.id,
404
410
  component: event.component,
@@ -468,6 +474,423 @@ function withTurnFrames(result2, frames) {
468
474
  }
469
475
  __name(withTurnFrames, "withTurnFrames");
470
476
 
477
+ // src/partial-json.ts
478
+ var Cut = class Cut2 extends Error {
479
+ static {
480
+ __name(this, "Cut");
481
+ }
482
+ };
483
+ function parsePartialJson(text) {
484
+ const open = /* @__PURE__ */ new WeakSet();
485
+ const pending = /* @__PURE__ */ new WeakMap();
486
+ let at = 0;
487
+ const skipSpace = /* @__PURE__ */ __name(() => {
488
+ while (at < text.length) {
489
+ const char = text.charCodeAt(at);
490
+ if (char === 32 || char === 9 || char === 10 || char === 13) at += 1;
491
+ else break;
492
+ }
493
+ }, "skipSpace");
494
+ const fail = /* @__PURE__ */ __name(() => {
495
+ throw new SyntaxError(`unexpected character at ${at}`);
496
+ }, "fail");
497
+ const readString = /* @__PURE__ */ __name(() => {
498
+ at += 1;
499
+ let out = "";
500
+ while (at < text.length) {
501
+ const char = text[at];
502
+ if (char === '"') {
503
+ at += 1;
504
+ return {
505
+ value: out,
506
+ cut: false
507
+ };
508
+ }
509
+ if (char === "\\") {
510
+ const next = text[at + 1];
511
+ if (next === void 0) {
512
+ at = text.length;
513
+ return {
514
+ value: out,
515
+ cut: true
516
+ };
517
+ }
518
+ if (next === "u") {
519
+ const hex = text.slice(at + 2, at + 6);
520
+ if (hex.length < 4) {
521
+ at = text.length;
522
+ return {
523
+ value: out,
524
+ cut: true
525
+ };
526
+ }
527
+ if (!/^[0-9a-fA-F]{4}$/.test(hex)) fail();
528
+ out += String.fromCharCode(Number.parseInt(hex, 16));
529
+ at += 6;
530
+ continue;
531
+ }
532
+ const escapes = {
533
+ '"': '"',
534
+ "\\": "\\",
535
+ "/": "/",
536
+ b: "\b",
537
+ f: "\f",
538
+ n: "\n",
539
+ r: "\r",
540
+ t: " "
541
+ };
542
+ const escaped = escapes[next];
543
+ if (escaped === void 0) fail();
544
+ out += escaped;
545
+ at += 2;
546
+ continue;
547
+ }
548
+ out += char;
549
+ at += 1;
550
+ }
551
+ return {
552
+ value: out,
553
+ cut: true
554
+ };
555
+ }, "readString");
556
+ const readValue = /* @__PURE__ */ __name(() => {
557
+ skipSpace();
558
+ if (at >= text.length) throw new Cut();
559
+ const char = text[at];
560
+ if (char === "{") return readObject();
561
+ if (char === "[") return readArray();
562
+ if (char === '"') return readString();
563
+ const rest = text.slice(at);
564
+ const number = /^-?\d*(?:\.\d*)?(?:[eE][+-]?\d*)?/.exec(rest)?.[0] ?? "";
565
+ if (number.length > 0) {
566
+ if (at + number.length >= text.length) throw new Cut();
567
+ if (!/^-?(?:0|[1-9]\d*)(?:\.\d+)?(?:[eE][+-]?\d+)?$/.test(number)) fail();
568
+ at += number.length;
569
+ return {
570
+ value: Number(number),
571
+ cut: false
572
+ };
573
+ }
574
+ for (const [word, value] of [
575
+ [
576
+ "true",
577
+ true
578
+ ],
579
+ [
580
+ "false",
581
+ false
582
+ ],
583
+ [
584
+ "null",
585
+ null
586
+ ]
587
+ ]) {
588
+ if (rest.startsWith(word)) {
589
+ at += word.length;
590
+ return {
591
+ value,
592
+ cut: false
593
+ };
594
+ }
595
+ if (word.startsWith(rest)) throw new Cut();
596
+ }
597
+ return fail();
598
+ }, "readValue");
599
+ const readObject = /* @__PURE__ */ __name(() => {
600
+ const object = {};
601
+ open.add(object);
602
+ at += 1;
603
+ skipSpace();
604
+ if (text[at] === "}") {
605
+ at += 1;
606
+ open.delete(object);
607
+ return {
608
+ value: object,
609
+ cut: false
610
+ };
611
+ }
612
+ for (; ; ) {
613
+ skipSpace();
614
+ if (at >= text.length) return {
615
+ value: object,
616
+ cut: true
617
+ };
618
+ if (text[at] !== '"') fail();
619
+ const key = readString();
620
+ if (key.cut) return {
621
+ value: object,
622
+ cut: true
623
+ };
624
+ skipSpace();
625
+ if (at >= text.length) {
626
+ pending.set(object, key.value);
627
+ return {
628
+ value: object,
629
+ cut: true
630
+ };
631
+ }
632
+ if (text[at] !== ":") fail();
633
+ at += 1;
634
+ let member;
635
+ try {
636
+ member = readValue();
637
+ } catch (error) {
638
+ if (!(error instanceof Cut)) throw error;
639
+ pending.set(object, key.value);
640
+ return {
641
+ value: object,
642
+ cut: true
643
+ };
644
+ }
645
+ object[key.value] = member.value;
646
+ if (member.cut) {
647
+ pending.set(object, key.value);
648
+ return {
649
+ value: object,
650
+ cut: true
651
+ };
652
+ }
653
+ skipSpace();
654
+ if (at >= text.length) return {
655
+ value: object,
656
+ cut: true
657
+ };
658
+ if (text[at] === ",") {
659
+ at += 1;
660
+ continue;
661
+ }
662
+ if (text[at] === "}") {
663
+ at += 1;
664
+ open.delete(object);
665
+ return {
666
+ value: object,
667
+ cut: false
668
+ };
669
+ }
670
+ fail();
671
+ }
672
+ }, "readObject");
673
+ const readArray = /* @__PURE__ */ __name(() => {
674
+ const array = [];
675
+ open.add(array);
676
+ at += 1;
677
+ skipSpace();
678
+ if (text[at] === "]") {
679
+ at += 1;
680
+ open.delete(array);
681
+ return {
682
+ value: array,
683
+ cut: false
684
+ };
685
+ }
686
+ for (; ; ) {
687
+ let item;
688
+ try {
689
+ item = readValue();
690
+ } catch (error) {
691
+ if (!(error instanceof Cut)) throw error;
692
+ pending.set(array, array.length);
693
+ return {
694
+ value: array,
695
+ cut: true
696
+ };
697
+ }
698
+ array.push(item.value);
699
+ if (item.cut) {
700
+ pending.set(array, array.length - 1);
701
+ return {
702
+ value: array,
703
+ cut: true
704
+ };
705
+ }
706
+ skipSpace();
707
+ if (at >= text.length) return {
708
+ value: array,
709
+ cut: true
710
+ };
711
+ if (text[at] === ",") {
712
+ at += 1;
713
+ continue;
714
+ }
715
+ if (text[at] === "]") {
716
+ at += 1;
717
+ open.delete(array);
718
+ return {
719
+ value: array,
720
+ cut: false
721
+ };
722
+ }
723
+ fail();
724
+ }
725
+ }, "readArray");
726
+ let root;
727
+ try {
728
+ root = readValue();
729
+ } catch (error) {
730
+ if (error instanceof Cut) root = {
731
+ value: void 0,
732
+ cut: true
733
+ };
734
+ else return void 0;
735
+ }
736
+ skipSpace();
737
+ return {
738
+ value: root.value,
739
+ complete: !root.cut && at >= text.length,
740
+ isOpen: /* @__PURE__ */ __name((container) => open.has(container), "isOpen"),
741
+ pendingMember: /* @__PURE__ */ __name((container) => pending.get(container), "pendingMember")
742
+ };
743
+ }
744
+ __name(parsePartialJson, "parsePartialJson");
745
+
746
+ // src/tool-input-preview.ts
747
+ var DEFAULT_PREVIEW_THROTTLE_MS = 100;
748
+ function previewUiId(toolCallId) {
749
+ return `${toolCallId}:ui:0`;
750
+ }
751
+ __name(previewUiId, "previewUiId");
752
+ function withdrawPreviewEvent(shown) {
753
+ return {
754
+ kind: "ui",
755
+ id: shown.id,
756
+ component: shown.component,
757
+ props: {},
758
+ toolCallId: shown.toolCallId,
759
+ partial: true
760
+ };
761
+ }
762
+ __name(withdrawPreviewEvent, "withdrawPreviewEvent");
763
+ function previewToolInputs(inner, resolve, now = Date.now) {
764
+ const calls = /* @__PURE__ */ new Map();
765
+ const shown = /* @__PURE__ */ new Map();
766
+ const decoder3 = new TextDecoder();
767
+ let pending = "";
768
+ async function emit2(id, state, input, done) {
769
+ let rendered;
770
+ try {
771
+ const parsed = done && input !== void 0 ? {
772
+ value: input,
773
+ complete: true,
774
+ isOpen: /* @__PURE__ */ __name(() => false, "isOpen"),
775
+ pendingMember: /* @__PURE__ */ __name(() => void 0, "pendingMember")
776
+ } : parsePartialJson(state.text);
777
+ if (parsed === void 0) return;
778
+ rendered = state.preview.render({
779
+ value: parsed.value,
780
+ done: done || parsed.complete,
781
+ isOpen: parsed.isOpen,
782
+ pendingMember: parsed.pendingMember
783
+ });
784
+ } catch {
785
+ rendered = null;
786
+ }
787
+ if (rendered === void 0) return;
788
+ const uiId = previewUiId(id);
789
+ if (rendered === null) {
790
+ state.stopped = true;
791
+ const standing = shown.get(uiId);
792
+ if (standing !== void 0) {
793
+ shown.delete(uiId);
794
+ await inner.write(encodeStreamEvent(withdrawPreviewEvent(standing)));
795
+ }
796
+ return;
797
+ }
798
+ const props = JSON.stringify(rendered.props);
799
+ if (props === state.lastProps && rendered.component === state.component) return;
800
+ state.lastProps = props;
801
+ state.component = rendered.component;
802
+ state.lastAt = now();
803
+ shown.set(uiId, {
804
+ id: uiId,
805
+ component: rendered.component,
806
+ toolCallId: id
807
+ });
808
+ await inner.write(encodeStreamEvent({
809
+ kind: "ui",
810
+ id: uiId,
811
+ component: rendered.component,
812
+ props: JSON.parse(props),
813
+ ...rendered.version !== void 0 ? {
814
+ version: rendered.version
815
+ } : {},
816
+ toolCallId: id,
817
+ partial: true
818
+ }));
819
+ }
820
+ __name(emit2, "emit");
821
+ async function observe(event) {
822
+ if (event.kind === "tool-input-start") {
823
+ if (calls.has(event.id)) return;
824
+ let preview;
825
+ try {
826
+ preview = await resolve(event.name, event.id);
827
+ } catch {
828
+ preview = void 0;
829
+ }
830
+ if (preview !== void 0) {
831
+ calls.set(event.id, {
832
+ preview,
833
+ text: "",
834
+ lastAt: void 0,
835
+ lastProps: void 0,
836
+ component: void 0,
837
+ stopped: false
838
+ });
839
+ }
840
+ return;
841
+ }
842
+ if (event.kind === "tool-input-delta") {
843
+ const state = calls.get(event.id);
844
+ if (state === void 0 || state.stopped) return;
845
+ state.text += event.delta;
846
+ const throttle = state.preview.throttleMs ?? DEFAULT_PREVIEW_THROTTLE_MS;
847
+ if (state.lastAt !== void 0 && now() - state.lastAt < throttle) return;
848
+ await emit2(event.id, state, void 0, false);
849
+ return;
850
+ }
851
+ if (event.kind === "tool-input-available") {
852
+ const state = calls.get(event.id);
853
+ if (state === void 0) return;
854
+ calls.delete(event.id);
855
+ if (state.stopped) return;
856
+ await emit2(event.id, state, event.input, true);
857
+ }
858
+ }
859
+ __name(observe, "observe");
860
+ return {
861
+ writer: {
862
+ async write(chunk) {
863
+ await inner.write(chunk);
864
+ pending += decoder3.decode(chunk, {
865
+ stream: true
866
+ });
867
+ let newline = pending.indexOf("\n");
868
+ while (newline !== -1) {
869
+ const line = pending.slice(0, newline);
870
+ pending = pending.slice(newline + 1);
871
+ const event = line.trim().length > 0 ? decodeStreamEvent(line) : null;
872
+ if (event !== null) await observe(event);
873
+ newline = pending.indexOf("\n");
874
+ }
875
+ },
876
+ end: /* @__PURE__ */ __name(() => inner.end(), "end"),
877
+ fail: /* @__PURE__ */ __name((error) => inner.fail(error), "fail")
878
+ },
879
+ shown: /* @__PURE__ */ __name(() => [
880
+ ...shown.values()
881
+ ], "shown")
882
+ };
883
+ }
884
+ __name(previewToolInputs, "previewToolInputs");
885
+ function registryInputPreviews(registry, offered, scope) {
886
+ const names = new Set(offered.map((tool) => tool.name));
887
+ return async (toolName, toolCallId) => names.has(toolName) ? registry.previewInput(toolName, {
888
+ ...scope,
889
+ toolCallId
890
+ }) : void 0;
891
+ }
892
+ __name(registryInputPreviews, "registryInputPreviews");
893
+
471
894
  // src/tool-ui.ts
472
895
  var TOOL_STEP_UI = "@@nestjs-agent/tool-step-ui";
473
896
  function wrapToolStepOutput(output, ui, text) {
@@ -2997,9 +3420,10 @@ function actionProposalOutcomeFenceValid(row2, command, now) {
2997
3420
  }
2998
3421
  __name(actionProposalOutcomeFenceValid, "actionProposalOutcomeFenceValid");
2999
3422
  function outcomeSummary(outcome) {
3000
- if (outcome.executionStatus === "succeeded") return `Action ${JSON.stringify(outcome.toolName)} completed (proposal ${JSON.stringify(outcome.proposalId)}).${Object.hasOwn(outcome, "result") ? ` Result: ${JSON.stringify(outcome.result)}` : ""}`;
3001
- if (outcome.executionStatus === "failed") return `Action ${JSON.stringify(outcome.toolName)} failed (proposal ${JSON.stringify(outcome.proposalId)}): ${JSON.stringify(outcome.error ?? "Execution failed")}`;
3002
- return `Action ${JSON.stringify(outcome.toolName)} was ${outcome.decision} (proposal ${JSON.stringify(outcome.proposalId)}) and was not executed.${outcome.error ? ` Reason: ${JSON.stringify(outcome.error)}` : ""}`;
3423
+ const tool = JSON.stringify(outcome.toolName);
3424
+ if (outcome.executionStatus === "succeeded") return `Action ${tool} completed.${Object.hasOwn(outcome, "result") ? ` Result: ${JSON.stringify(outcome.result)}` : ""}`;
3425
+ if (outcome.executionStatus === "failed") return `Action ${tool} failed: ${JSON.stringify(outcome.error ?? "Execution failed")}`;
3426
+ return `Action ${tool} was ${outcome.decision} and was not executed.${outcome.error ? ` Reason: ${JSON.stringify(outcome.error)}` : ""}`;
3003
3427
  }
3004
3428
  __name(outcomeSummary, "outcomeSummary");
3005
3429
  function actionProposalOutcomeScope(outcome) {
@@ -3010,8 +3434,15 @@ function actionProposalOutcomeScope(outcome) {
3010
3434
  };
3011
3435
  }
3012
3436
  __name(actionProposalOutcomeScope, "actionProposalOutcomeScope");
3437
+ function storableText(text) {
3438
+ return text.replaceAll(String.fromCharCode(0), "\\u0000").replace(/[\ud800-\udbff](?![\udc00-\udfff])|(?<![\ud800-\udbff])[\udc00-\udfff]/g, (char) => `\\u${char.charCodeAt(0).toString(16)}`);
3439
+ }
3440
+ __name(storableText, "storableText");
3013
3441
  function actionProposalOutcomeText(outcome) {
3014
- return outcomeSummary(outcome) + (outcome.text ? ` UI: ${JSON.stringify(outcome.text)}` : "");
3442
+ const text = outcome.text === void 0 ? void 0 : storableText(outcome.text).trim();
3443
+ return text ? `${text}
3444
+
3445
+ ${outcomeSummary(outcome)}` : outcomeSummary(outcome);
3015
3446
  }
3016
3447
  __name(actionProposalOutcomeText, "actionProposalOutcomeText");
3017
3448
 
@@ -3346,6 +3777,7 @@ function defineComponent(definition) {
3346
3777
  }
3347
3778
  if (definition.version !== void 0 && (!Number.isSafeInteger(definition.version) || definition.version <= 0)) throw new RangeError("genui: component version must be a positive safe integer");
3348
3779
  if (definition.fallbackText !== void 0 && typeof definition.fallbackText !== "function") throw new TypeError("genui: fallbackText must be a function");
3780
+ if (definition.streaming !== void 0 && definition.streaming !== "partial" && definition.streaming !== "complete") throw new TypeError("genui: streaming must be 'partial' or 'complete'");
3349
3781
  return definition;
3350
3782
  }
3351
3783
  __name(defineComponent, "defineComponent");
@@ -4704,6 +5136,19 @@ var ToolRegistry = class {
4704
5136
  unregister(name) {
4705
5137
  return this.entries.delete(name);
4706
5138
  }
5139
+ /**
5140
+ * How a streamed call of `name` is previewed while its input arrives (`ToolHandler.previewInput`),
5141
+ * or `undefined`. A preview that fails to build is no preview: it never fails the turn.
5142
+ */
5143
+ async previewInput(name, scope) {
5144
+ const handler = this.entries.get(name)?.handler;
5145
+ if (handler?.previewInput === void 0) return void 0;
5146
+ try {
5147
+ return await handler.previewInput(scope) ?? void 0;
5148
+ } catch {
5149
+ return void 0;
5150
+ }
5151
+ }
4707
5152
  spec(name) {
4708
5153
  return this.entries.get(name)?.spec;
4709
5154
  }
@@ -4762,6 +5207,9 @@ var ToolRegistry = class {
4762
5207
  * Run a tool. Re-checks that the tool is enabled and that the role allows it (defense-in-depth —
4763
5208
  * a call can reach here from a replayed durable step or an approval granted before the flag
4764
5209
  * moved, neither of which went through `definitionsFor` again) and re-parses the input via Zod.
5210
+ * A tool whose `describe()` answers `available: false` for the call's scope (actor, thread, agent,
5211
+ * `uiCapabilities`) is refused with {@link ToolNotFoundError}, as the unknown tool it was to the
5212
+ * model.
4765
5213
  */
4766
5214
  async invoke(name, input, ctx, policy, options = {}) {
4767
5215
  const { entry, value, ctx: withEmit } = await this.validated(name, input, ctx, policy, options);
@@ -4815,6 +5263,10 @@ var ToolRegistry = class {
4815
5263
  if (options.allowedTools !== void 0 && !options.allowedTools.includes(name)) {
4816
5264
  throw new ToolForbiddenError(name);
4817
5265
  }
5266
+ if (entry.handler.describe !== void 0) {
5267
+ const described = await entry.handler.describe(describeScopeOf(ctx));
5268
+ if (described?.available === false) throw new ToolNotFoundError(name);
5269
+ }
4818
5270
  const validation = await entry.spec.inputSchema["~standard"].validate(input);
4819
5271
  if (validation.issues !== void 0) {
4820
5272
  throw new ToolInputInvalidError(name, validation.issues);
@@ -4830,6 +5282,21 @@ var ToolRegistry = class {
4830
5282
  };
4831
5283
  }
4832
5284
  };
5285
+ function describeScopeOf(ctx) {
5286
+ return {
5287
+ actor: ctx.actor,
5288
+ ...ctx.threadId ? {
5289
+ threadId: ctx.threadId
5290
+ } : {},
5291
+ ...ctx.agentName !== void 0 ? {
5292
+ agentName: ctx.agentName
5293
+ } : {},
5294
+ ...ctx.uiCapabilities !== void 0 ? {
5295
+ uiCapabilities: ctx.uiCapabilities
5296
+ } : {}
5297
+ };
5298
+ }
5299
+ __name(describeScopeOf, "describeScopeOf");
4833
5300
  var DefaultRolesPolicy = class {
4834
5301
  static {
4835
5302
  __name(this, "DefaultRolesPolicy");
@@ -5213,6 +5680,21 @@ var RunCancelledError = class extends Error {
5213
5680
  this.name = "RunCancelledError";
5214
5681
  }
5215
5682
  };
5683
+ async function abortableModelCall(hooks, call) {
5684
+ const signal = hooks.abortSignal;
5685
+ let result2;
5686
+ try {
5687
+ result2 = await call(signal !== void 0 ? {
5688
+ abortSignal: signal
5689
+ } : {});
5690
+ } catch (error) {
5691
+ if (signal?.aborted === true) throw new RunCancelledError();
5692
+ throw error;
5693
+ }
5694
+ if (signal?.aborted === true) throw new RunCancelledError();
5695
+ return result2;
5696
+ }
5697
+ __name(abortableModelCall, "abortableModelCall");
5216
5698
  function agentFailureCode(error) {
5217
5699
  if (error instanceof RunCancelledError) {
5218
5700
  return "cancelled";
@@ -5670,13 +6152,14 @@ async function structureAnswer(schema, deps, input, hooks, messages, step) {
5670
6152
  fail: /* @__PURE__ */ __name(() => {
5671
6153
  }, "fail")
5672
6154
  };
5673
- const turn = await deps.model.runTurn({
6155
+ const turn = await abortableModelCall(hooks, (signal) => deps.model.runTurn({
5674
6156
  system,
5675
6157
  messages,
5676
6158
  tools: [],
5677
6159
  sink: discard,
5678
- outputSchema: schema
5679
- });
6160
+ outputSchema: schema,
6161
+ ...signal
6162
+ }));
5680
6163
  return {
5681
6164
  text: turn.text,
5682
6165
  usage: turn.usage,
@@ -5798,6 +6281,9 @@ function toolContext(deps, input, hooks) {
5798
6281
  ...deps.host !== void 0 ? {
5799
6282
  host: deps.host
5800
6283
  } : {},
6284
+ ...hooks.abortSignal !== void 0 ? {
6285
+ abortSignal: hooks.abortSignal
6286
+ } : {},
5801
6287
  // Replaced per tool call by the call's own collector (see the tool step); this one only serves
5802
6288
  // what runs outside a call — the elicitation wait.
5803
6289
  emitUi: createNoopEmitUi(hooks.runId)
@@ -7165,26 +7651,46 @@ ${block}`;
7165
7651
  writer
7166
7652
  }) : void 0;
7167
7653
  const buffer = gateMode === "whole" ? createFrameBuffer() : void 0;
7168
- const frames = observeTurnFrames(incremental?.writer ?? buffer?.writer ?? writer);
7169
- const result2 = stampToolKinds(withTurnFrames(await traceLlmTurn(hooks.runId, i, () => deps.model.runTurn({
7654
+ const previews = previewToolInputs(incremental?.writer ?? buffer?.writer ?? writer, registryInputPreviews(deps.registry, tools, {
7655
+ actor: input.actor,
7656
+ threadId: input.threadId,
7657
+ ...input.agentName !== void 0 ? {
7658
+ agentName: input.agentName
7659
+ } : {},
7660
+ ...input.uiCapabilities !== void 0 ? {
7661
+ uiCapabilities: input.uiCapabilities
7662
+ } : {}
7663
+ }));
7664
+ const frames = observeTurnFrames(previews.writer);
7665
+ const result2 = stampToolKinds(withTurnFrames(await traceLlmTurn(hooks.runId, i, () => abortableModelCall(hooks, (signal) => deps.model.runTurn({
7170
7666
  system: prompt.system,
7171
7667
  messages: prompt.messages,
7172
7668
  tools,
7173
- sink: frames.writer
7174
- })), frames.summary()), deps);
7669
+ sink: frames.writer,
7670
+ ...signal
7671
+ }))), frames.summary()), deps);
7672
+ const shownPreviews = previews.shown();
7673
+ const previewed = shownPreviews.length > 0 ? {
7674
+ previews: shownPreviews
7675
+ } : {};
7175
7676
  if (incremental !== void 0) {
7176
7677
  await incremental.settled();
7177
7678
  const refusal = incremental.rejection();
7178
7679
  return {
7179
7680
  ...result2,
7681
+ ...previewed,
7180
7682
  releasedText: incremental.released(),
7181
7683
  ...refusal !== void 0 ? {
7182
7684
  gateRejection: refusal
7183
7685
  } : {}
7184
7686
  };
7185
7687
  }
7186
- return buffer === void 0 ? result2 : {
7688
+ return buffer === void 0 ? {
7689
+ ...result2,
7690
+ ...previewed
7691
+ } : {
7187
7692
  ...result2,
7693
+ ...previewed,
7188
7694
  bufferedFrames: buffer.frames()
7189
7695
  };
7190
7696
  });
@@ -7503,6 +8009,12 @@ ${block}`;
7503
8009
  if (toolUi.length > 0) {
7504
8010
  await deps.store.setMessageUi?.(assistant.id, mergeUi(turn.ui, toolUi));
7505
8011
  }
8012
+ for (const preview of turn.previews ?? []) {
8013
+ const pushed = turnCalls.toolUi.get(preview.toolCallId) ?? [];
8014
+ if (!pushed.some((component) => component.id === preview.id)) {
8015
+ await writer.write(encodeStreamEvent(withdrawPreviewEvent(preview)));
8016
+ }
8017
+ }
7506
8018
  for (const result2 of results) {
7507
8019
  await writer.write(encodeStreamEvent(outputFrame(result2)));
7508
8020
  }
@@ -9441,9 +9953,9 @@ var ptBrActionProposalText = {
9441
9953
  ]
9442
9954
  },
9443
9955
  replies: {
9444
- approved: "Proposta aprovada e enfileirada para execu\xE7\xE3o.",
9445
- rejected: "Proposta rejeitada; nenhuma a\xE7\xE3o foi executada.",
9446
- expired: "A proposta expirou; nenhuma a\xE7\xE3o foi executada.",
9956
+ approved: "Confirmado! J\xE1 estou cuidando disso.",
9957
+ rejected: "Tudo bem, cancelado. Nada foi feito.",
9958
+ expired: "Esse pedido expirou; nada foi feito.",
9447
9959
  unchanged: "N\xE3o foi poss\xEDvel alterar esta proposta; atualize a lista para consultar seu estado.",
9448
9960
  ambiguous: /* @__PURE__ */ __name((ids) => `Qual proposta? Responda confirmar #ID ou cancelar #ID: ${ids.join(", ")}`, "ambiguous"),
9449
9961
  tooMany: "H\xE1 v\xE1rias propostas. Confirme ou rejeite usando #ID expl\xEDcito."
@@ -9788,6 +10300,7 @@ __name(createFunctionalTool, "createFunctionalTool");
9788
10300
  DEFAULT_MAX_FACT_CHARS,
9789
10301
  DEFAULT_MAX_MEMORIES,
9790
10302
  DEFAULT_MAX_SKILLS,
10303
+ DEFAULT_PREVIEW_THROTTLE_MS,
9791
10304
  DEFAULT_REFUSAL_REASON,
9792
10305
  DEFAULT_STRUCTURED_OUTPUT_INSTRUCTION,
9793
10306
  DEFAULT_TEXT_ACTION_PROPOSAL_REPLIES,
@@ -9906,9 +10419,12 @@ __name(createFunctionalTool, "createFunctionalTool");
9906
10419
  observeTurnFrames,
9907
10420
  offerMemories,
9908
10421
  offerSkills,
10422
+ parsePartialJson,
9909
10423
  parseTextActionProposalCommand,
9910
10424
  personaCatalogEntry,
9911
10425
  prepareActionProposal,
10426
+ previewToolInputs,
10427
+ previewUiId,
9912
10428
  ptBrActionProposalText,
9913
10429
  publishAgentDelegated,
9914
10430
  publishAgentMemoryResolved,
@@ -9929,6 +10445,7 @@ __name(createFunctionalTool, "createFunctionalTool");
9929
10445
  quotaWarning,
9930
10446
  readElicitationInput,
9931
10447
  readElicitationQuestions,
10448
+ registryInputPreviews,
9932
10449
  releaseGatedFrames,
9933
10450
  releaseThreadRun,
9934
10451
  rememberInputSchema,
@@ -9997,6 +10514,7 @@ __name(createFunctionalTool, "createFunctionalTool");
9997
10514
  withSkillTool,
9998
10515
  withToolTimeout,
9999
10516
  withTurnFrames,
10517
+ withdrawPreviewEvent,
10000
10518
  wrapToolPreflightDenied,
10001
10519
  wrapToolStepOutput,
10002
10520
  writeMemory