@dudousxd/nestjs-agent 1.2.0 → 1.3.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.d.cts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { DynamicModule, OnModuleInit, Type, OnApplicationBootstrap } from '@nestjs/common';
2
- import { b as AgentModuleOptions, c as AgentModuleAsyncOptions, A as AgentDepsFactory, d as AgentSkillsOptions } from './agent-deps.factory-OjrLyAZo.cjs';
3
- export { e as AGENT_TOOL_BRAND, f as AgentAttachmentsOptions, g as AgentDeps, h as AgentMemoryOptions, a as AgentSurface, F as FunctionalTool, i as delegateToolName, p as provideAgentTool, u as utcDay } from './agent-deps.factory-OjrLyAZo.cjs';
2
+ import { b as AgentModuleOptions, c as AgentModuleAsyncOptions, A as AgentDepsFactory, d as AgentSkillsOptions } from './agent-deps.factory-CUyVPsa1.cjs';
3
+ export { e as AGENT_TOOL_BRAND, f as AgentAttachmentsOptions, g as AgentDeps, h as AgentMemoryOptions, a as AgentSurface, F as FunctionalTool, i as delegateToolName, p as provideAgentTool, u as utcDay } from './agent-deps.factory-CUyVPsa1.cjs';
4
4
  import { AgentRunner, AgentStore, QuotaStore, AttachmentStagingStore, Actor, AttachmentRef, PageContext, HumanReply, ThreadSummary, ThreadDetail, UpdateThreadInput, StagedAttachment, QuotaView, AgentApprovalPort, ActorResolver, MessageAttachment, ToolPresentation, AgentHistoryWindow, AgentIntake, SkillContext, ToolRegistry, AgentRegistry, PromptContributor, SkillsConfig, SkillCatalogEntry, ToolCatalogEntry, MemoryConfig, MemoryDigestEntry, SkillProvider, AgentRunInput, TokenStreamSink, SinkWriter, QuotaState } from '@dudousxd/nestjs-agent-core';
5
5
  export * from '@dudousxd/nestjs-agent-core';
6
6
  import { Request } from 'express';
@@ -80,8 +80,19 @@ declare class AgentService {
80
80
  * ownership is derived from.
81
81
  */
82
82
  subscribeAs(actor: Actor, runId: string): Promise<AsyncIterable<Uint8Array>>;
83
- approve(actor: Actor, toolCallId: string): Promise<void>;
84
- reject(actor: Actor, toolCallId: string, reason?: string): Promise<void>;
83
+ /**
84
+ * Approve a parked action call as `actor`. Who may is the call's recorded approver's business
85
+ * (see {@link assertMayDecide}); `remember` approves later calls of the same tool in the same
86
+ * thread, and `via` names the surface the decision came through (`'web'`, `'slack'`, …) — both
87
+ * persisted with the call.
88
+ */
89
+ approve(actor: Actor, toolCallId: string, opts?: {
90
+ remember?: boolean;
91
+ via?: string;
92
+ }): Promise<void>;
93
+ reject(actor: Actor, toolCallId: string, reason?: string, opts?: {
94
+ via?: string;
95
+ }): Promise<void>;
85
96
  /**
86
97
  * Answer a parked question set. An omitted question takes the request's own pre-picked default —
87
98
  * resolved by the LOOP against the request it already holds, so "the user just submitted" and
@@ -193,6 +204,20 @@ declare class AgentService {
193
204
  * adapter can resolve+signal a decision WITHOUT this check — it is authorized upstream instead.
194
205
  */
195
206
  private assertOwnsToolCall;
207
+ /**
208
+ * Authorization seam for approve/reject. The call's recorded approver decides who may settle it:
209
+ * the requester (the default, and every call recorded before approvers existed) is the thread's
210
+ * own actor — the ownership check this always was; any other approver goes through the policy's
211
+ * `canDecide`, which by default asks whether the actor holds that role.
212
+ */
213
+ private assertMayDecide;
214
+ /**
215
+ * Refuse a decision on a request that has already lapsed — recorded `expired`, or past its
216
+ * `expiresAt` with the run's own timer about to fire. Signalling it anyway would race the timeout:
217
+ * a durable runtime buffers a signal nobody is waiting on, and a late approval must not be what a
218
+ * later replay of the run reads back.
219
+ */
220
+ private assertNotExpired;
196
221
  /**
197
222
  * Resolve the run awaiting `toolCallId`. Derived server-side from the tool call alone — the client
198
223
  * never knows or supplies a runId, and that run is the sub-agent's own child run when the pending
@@ -223,10 +248,13 @@ declare class AgentApprovalPortAdapter implements AgentApprovalPort {
223
248
  constructor(agent: AgentService);
224
249
  approve(toolCallId: string, opts?: {
225
250
  executedByRef?: string;
251
+ remember?: boolean;
252
+ decidedVia?: string;
226
253
  }): Promise<void>;
227
254
  reject(toolCallId: string, opts?: {
228
255
  executedByRef?: string;
229
256
  reason?: string;
257
+ decidedVia?: string;
230
258
  }): Promise<void>;
231
259
  }
232
260
 
@@ -754,6 +782,12 @@ declare class InlineAgentRunner implements AgentRunner {
754
782
  * shape it is delivering — the loop asked for one and only ever gets what the caller sent. A
755
783
  * cancel settles the wait too, by rejecting it.
756
784
  */
785
+ /**
786
+ * {@link park} for an approval, bounded by the policy's time to live when it has one: the timer
787
+ * settles the wait as `expired` — the same Decision the durable runner builds from its signal
788
+ * timeout — and a decision that arrives first disarms it.
789
+ */
790
+ private parkApproval;
757
791
  private park;
758
792
  private topLevelHooks;
759
793
  /**
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { DynamicModule, OnModuleInit, Type, OnApplicationBootstrap } from '@nestjs/common';
2
- import { b as AgentModuleOptions, c as AgentModuleAsyncOptions, A as AgentDepsFactory, d as AgentSkillsOptions } from './agent-deps.factory-OjrLyAZo.js';
3
- export { e as AGENT_TOOL_BRAND, f as AgentAttachmentsOptions, g as AgentDeps, h as AgentMemoryOptions, a as AgentSurface, F as FunctionalTool, i as delegateToolName, p as provideAgentTool, u as utcDay } from './agent-deps.factory-OjrLyAZo.js';
2
+ import { b as AgentModuleOptions, c as AgentModuleAsyncOptions, A as AgentDepsFactory, d as AgentSkillsOptions } from './agent-deps.factory-CUyVPsa1.js';
3
+ export { e as AGENT_TOOL_BRAND, f as AgentAttachmentsOptions, g as AgentDeps, h as AgentMemoryOptions, a as AgentSurface, F as FunctionalTool, i as delegateToolName, p as provideAgentTool, u as utcDay } from './agent-deps.factory-CUyVPsa1.js';
4
4
  import { AgentRunner, AgentStore, QuotaStore, AttachmentStagingStore, Actor, AttachmentRef, PageContext, HumanReply, ThreadSummary, ThreadDetail, UpdateThreadInput, StagedAttachment, QuotaView, AgentApprovalPort, ActorResolver, MessageAttachment, ToolPresentation, AgentHistoryWindow, AgentIntake, SkillContext, ToolRegistry, AgentRegistry, PromptContributor, SkillsConfig, SkillCatalogEntry, ToolCatalogEntry, MemoryConfig, MemoryDigestEntry, SkillProvider, AgentRunInput, TokenStreamSink, SinkWriter, QuotaState } from '@dudousxd/nestjs-agent-core';
5
5
  export * from '@dudousxd/nestjs-agent-core';
6
6
  import { Request } from 'express';
@@ -80,8 +80,19 @@ declare class AgentService {
80
80
  * ownership is derived from.
81
81
  */
82
82
  subscribeAs(actor: Actor, runId: string): Promise<AsyncIterable<Uint8Array>>;
83
- approve(actor: Actor, toolCallId: string): Promise<void>;
84
- reject(actor: Actor, toolCallId: string, reason?: string): Promise<void>;
83
+ /**
84
+ * Approve a parked action call as `actor`. Who may is the call's recorded approver's business
85
+ * (see {@link assertMayDecide}); `remember` approves later calls of the same tool in the same
86
+ * thread, and `via` names the surface the decision came through (`'web'`, `'slack'`, …) — both
87
+ * persisted with the call.
88
+ */
89
+ approve(actor: Actor, toolCallId: string, opts?: {
90
+ remember?: boolean;
91
+ via?: string;
92
+ }): Promise<void>;
93
+ reject(actor: Actor, toolCallId: string, reason?: string, opts?: {
94
+ via?: string;
95
+ }): Promise<void>;
85
96
  /**
86
97
  * Answer a parked question set. An omitted question takes the request's own pre-picked default —
87
98
  * resolved by the LOOP against the request it already holds, so "the user just submitted" and
@@ -193,6 +204,20 @@ declare class AgentService {
193
204
  * adapter can resolve+signal a decision WITHOUT this check — it is authorized upstream instead.
194
205
  */
195
206
  private assertOwnsToolCall;
207
+ /**
208
+ * Authorization seam for approve/reject. The call's recorded approver decides who may settle it:
209
+ * the requester (the default, and every call recorded before approvers existed) is the thread's
210
+ * own actor — the ownership check this always was; any other approver goes through the policy's
211
+ * `canDecide`, which by default asks whether the actor holds that role.
212
+ */
213
+ private assertMayDecide;
214
+ /**
215
+ * Refuse a decision on a request that has already lapsed — recorded `expired`, or past its
216
+ * `expiresAt` with the run's own timer about to fire. Signalling it anyway would race the timeout:
217
+ * a durable runtime buffers a signal nobody is waiting on, and a late approval must not be what a
218
+ * later replay of the run reads back.
219
+ */
220
+ private assertNotExpired;
196
221
  /**
197
222
  * Resolve the run awaiting `toolCallId`. Derived server-side from the tool call alone — the client
198
223
  * never knows or supplies a runId, and that run is the sub-agent's own child run when the pending
@@ -223,10 +248,13 @@ declare class AgentApprovalPortAdapter implements AgentApprovalPort {
223
248
  constructor(agent: AgentService);
224
249
  approve(toolCallId: string, opts?: {
225
250
  executedByRef?: string;
251
+ remember?: boolean;
252
+ decidedVia?: string;
226
253
  }): Promise<void>;
227
254
  reject(toolCallId: string, opts?: {
228
255
  executedByRef?: string;
229
256
  reason?: string;
257
+ decidedVia?: string;
230
258
  }): Promise<void>;
231
259
  }
232
260
 
@@ -754,6 +782,12 @@ declare class InlineAgentRunner implements AgentRunner {
754
782
  * shape it is delivering — the loop asked for one and only ever gets what the caller sent. A
755
783
  * cancel settles the wait too, by rejecting it.
756
784
  */
785
+ /**
786
+ * {@link park} for an approval, bounded by the policy's time to live when it has one: the timer
787
+ * settles the wait as `expired` — the same Decision the durable runner builds from its signal
788
+ * timeout — and a decision that arrives first disarms it.
789
+ */
790
+ private parkApproval;
757
791
  private park;
758
792
  private topLevelHooks;
759
793
  /**
package/dist/index.js CHANGED
@@ -122,6 +122,9 @@ var AgentDepsFactory2 = class {
122
122
  store: this.store,
123
123
  sink: this.sink,
124
124
  rolesPolicy: this.rolesPolicy,
125
+ ...this.options.approvalPolicy !== void 0 ? {
126
+ approvalPolicy: this.options.approvalPolicy
127
+ } : {},
125
128
  registry: this.registry,
126
129
  promptContributors: this.promptContributors,
127
130
  systemPrompt: definition?.systemPrompt ?? "You are a helpful assistant.",
@@ -269,8 +272,8 @@ AgentDepsFactory2 = _ts_decorate([
269
272
  ], AgentDepsFactory2);
270
273
 
271
274
  // src/agent.service.ts
272
- import { AGENT_ATTACHMENT_STAGING, AGENT_DEPS_FACTORY, AGENT_QUOTA_STORE as AGENT_QUOTA_STORE2, AGENT_RUNNER, AGENT_STORE as AGENT_STORE2 } from "@dudousxd/nestjs-agent-core";
273
- import { BadRequestException, ForbiddenException, Inject as Inject2, Injectable as Injectable2, NotFoundException, NotImplementedException, Optional as Optional2 } from "@nestjs/common";
275
+ import { AGENT_ATTACHMENT_STAGING, AGENT_DEPS_FACTORY, AGENT_QUOTA_STORE as AGENT_QUOTA_STORE2, AGENT_RUNNER, AGENT_STORE as AGENT_STORE2, REQUESTER_APPROVER, mayDecideApproval } from "@dudousxd/nestjs-agent-core";
276
+ import { BadRequestException, ForbiddenException, GoneException, Inject as Inject2, Injectable as Injectable2, NotFoundException, NotImplementedException, Optional as Optional2 } from "@nestjs/common";
274
277
 
275
278
  // src/agent-deps.ts
276
279
  function utcDay(date = /* @__PURE__ */ new Date()) {
@@ -423,18 +426,35 @@ var AgentService = class {
423
426
  await this.assertOwnsActiveStream(actor, runId);
424
427
  return this.subscribe(runId);
425
428
  }
426
- async approve(actor, toolCallId2) {
427
- await this.assertOwnsToolCall(actor, toolCallId2);
429
+ /**
430
+ * Approve a parked action call as `actor`. Who may is the call's recorded approver's business
431
+ * (see {@link assertMayDecide}); `remember` approves later calls of the same tool in the same
432
+ * thread, and `via` names the surface the decision came through (`'web'`, `'slack'`, …) — both
433
+ * persisted with the call.
434
+ */
435
+ async approve(actor, toolCallId2, opts = {}) {
436
+ await this.assertMayDecide(actor, toolCallId2);
428
437
  return this.signalToolCall(toolCallId2, {
429
- approved: true
438
+ approved: true,
439
+ executedByRef: actor.id,
440
+ ...opts.remember === true ? {
441
+ remember: true
442
+ } : {},
443
+ ...opts.via !== void 0 ? {
444
+ decidedVia: opts.via
445
+ } : {}
430
446
  });
431
447
  }
432
- async reject(actor, toolCallId2, reason) {
433
- await this.assertOwnsToolCall(actor, toolCallId2);
448
+ async reject(actor, toolCallId2, reason, opts = {}) {
449
+ await this.assertMayDecide(actor, toolCallId2);
434
450
  return this.signalToolCall(toolCallId2, {
435
451
  approved: false,
452
+ executedByRef: actor.id,
436
453
  ...reason !== void 0 ? {
437
454
  reason
455
+ } : {},
456
+ ...opts.via !== void 0 ? {
457
+ decidedVia: opts.via
438
458
  } : {}
439
459
  });
440
460
  }
@@ -475,6 +495,7 @@ var AgentService = class {
475
495
  * not the thread's own actor).
476
496
  */
477
497
  async signalToolCall(toolCallId2, reply) {
498
+ await this.assertNotExpired(toolCallId2);
478
499
  const runId = await this.resolveRunForToolCall(toolCallId2);
479
500
  return this.runner.signal(runId, toolCallId2, reply);
480
501
  }
@@ -713,6 +734,47 @@ var AgentService = class {
713
734
  }
714
735
  }
715
736
  /**
737
+ * Authorization seam for approve/reject. The call's recorded approver decides who may settle it:
738
+ * the requester (the default, and every call recorded before approvers existed) is the thread's
739
+ * own actor — the ownership check this always was; any other approver goes through the policy's
740
+ * `canDecide`, which by default asks whether the actor holds that role.
741
+ */
742
+ async assertMayDecide(actor, toolCallId2) {
743
+ const approval = await this.store.toolCallApproval?.(toolCallId2);
744
+ const approver = approval?.approver ?? REQUESTER_APPROVER;
745
+ if (approver === REQUESTER_APPROVER) {
746
+ return this.assertOwnsToolCall(actor, toolCallId2);
747
+ }
748
+ const requesterRef = await this.store.ownerOfToolCall(toolCallId2);
749
+ if (requesterRef === null) {
750
+ throw new NotFoundException(`tool call ${toolCallId2} not found`);
751
+ }
752
+ const allowed = await mayDecideApproval(this.deps.forAgent().approvalPolicy, actor, {
753
+ toolCallId: toolCallId2,
754
+ approver,
755
+ requesterRef
756
+ });
757
+ if (!allowed) {
758
+ throw new ForbiddenException(`this approval is for ${approver}`);
759
+ }
760
+ }
761
+ /**
762
+ * Refuse a decision on a request that has already lapsed — recorded `expired`, or past its
763
+ * `expiresAt` with the run's own timer about to fire. Signalling it anyway would race the timeout:
764
+ * a durable runtime buffers a signal nobody is waiting on, and a late approval must not be what a
765
+ * later replay of the run reads back.
766
+ */
767
+ async assertNotExpired(toolCallId2) {
768
+ const approval = await this.store.toolCallApproval?.(toolCallId2);
769
+ if (approval === null || approval === void 0) {
770
+ return;
771
+ }
772
+ const lapsed = approval.status === "expired" || approval.status === "pending_approval" && approval.expiresAt !== null && Date.parse(approval.expiresAt) <= Date.now();
773
+ if (lapsed) {
774
+ throw new GoneException(`the approval request for tool call ${toolCallId2} has expired`);
775
+ }
776
+ }
777
+ /**
716
778
  * Resolve the run awaiting `toolCallId`. Derived server-side from the tool call alone — the client
717
779
  * never knows or supplies a runId, and that run is the sub-agent's own child run when the pending
718
780
  * call belongs to a delegated agent. The store answers from the CALL'S OWN `runId` where it has
@@ -790,6 +852,12 @@ var AgentApprovalPortAdapter = class {
790
852
  approved: true,
791
853
  ...opts?.executedByRef !== void 0 ? {
792
854
  executedByRef: opts.executedByRef
855
+ } : {},
856
+ ...opts?.remember === true ? {
857
+ remember: true
858
+ } : {},
859
+ ...opts?.decidedVia !== void 0 ? {
860
+ decidedVia: opts.decidedVia
793
861
  } : {}
794
862
  });
795
863
  }
@@ -801,6 +869,9 @@ var AgentApprovalPortAdapter = class {
801
869
  } : {},
802
870
  ...opts?.reason !== void 0 ? {
803
871
  reason: opts.reason
872
+ } : {},
873
+ ...opts?.decidedVia !== void 0 ? {
874
+ decidedVia: opts.decidedVia
804
875
  } : {}
805
876
  });
806
877
  }
@@ -1720,6 +1791,8 @@ var MAX_ANSWERED_QUESTIONS = 100;
1720
1791
  var MAX_VALUES_PER_QUESTION = 100;
1721
1792
  var MAX_ANSWER_VALUE_LENGTH = 4096;
1722
1793
  var MAX_REJECT_REASON_LENGTH = 4096;
1794
+ var MAX_VIA_LENGTH = 64;
1795
+ var DEFAULT_VIA = "web";
1723
1796
  function toolCallId(claimed) {
1724
1797
  if (typeof claimed !== "string" || claimed.length === 0) {
1725
1798
  throw new BadRequestException4("toolCallId must be a non-empty string");
@@ -1740,6 +1813,26 @@ function rejectReason(claimed) {
1740
1813
  return claimed;
1741
1814
  }
1742
1815
  __name(rejectReason, "rejectReason");
1816
+ function remember(claimed) {
1817
+ if (claimed === void 0) {
1818
+ return false;
1819
+ }
1820
+ if (typeof claimed !== "boolean") {
1821
+ throw new BadRequestException4("remember must be a boolean");
1822
+ }
1823
+ return claimed;
1824
+ }
1825
+ __name(remember, "remember");
1826
+ function via(claimed) {
1827
+ if (claimed === void 0) {
1828
+ return DEFAULT_VIA;
1829
+ }
1830
+ if (typeof claimed !== "string" || claimed.length === 0 || claimed.length > MAX_VIA_LENGTH) {
1831
+ throw new BadRequestException4(`via must be a string of 1-${MAX_VIA_LENGTH} characters`);
1832
+ }
1833
+ return claimed;
1834
+ }
1835
+ __name(via, "via");
1743
1836
  function answers(claimed) {
1744
1837
  if (claimed === void 0) {
1745
1838
  return void 0;
@@ -1784,14 +1877,19 @@ var ToolCallController = class {
1784
1877
  }
1785
1878
  async approve(req, body) {
1786
1879
  const actor = await this.actorResolver.resolve(req);
1787
- await this.agent.approve(actor, toolCallId(body.toolCallId));
1880
+ await this.agent.approve(actor, toolCallId(body.toolCallId), {
1881
+ remember: remember(body.remember),
1882
+ via: via(body.via)
1883
+ });
1788
1884
  return {
1789
1885
  ok: true
1790
1886
  };
1791
1887
  }
1792
1888
  async reject(req, body) {
1793
1889
  const actor = await this.actorResolver.resolve(req);
1794
- await this.agent.reject(actor, toolCallId(body.toolCallId), rejectReason(body.reason));
1890
+ await this.agent.reject(actor, toolCallId(body.toolCallId), rejectReason(body.reason), {
1891
+ via: via(body.via)
1892
+ });
1795
1893
  return {
1796
1894
  ok: true
1797
1895
  };
@@ -1857,7 +1955,7 @@ _ts_decorate11([
1857
1955
  _ts_metadata11("design:type", Function),
1858
1956
  _ts_metadata11("design:paramtypes", [
1859
1957
  typeof Request === "undefined" ? Object : Request,
1860
- typeof ApproveBody === "undefined" ? Object : ApproveBody
1958
+ Object
1861
1959
  ]),
1862
1960
  _ts_metadata11("design:returntype", Promise)
1863
1961
  ], ToolCallController.prototype, "skip", null);
@@ -2723,6 +2821,36 @@ var InlineAgentRunner = class _InlineAgentRunner {
2723
2821
  * shape it is delivering — the loop asked for one and only ever gets what the caller sent. A
2724
2822
  * cancel settles the wait too, by rejecting it.
2725
2823
  */
2824
+ /**
2825
+ * {@link park} for an approval, bounded by the policy's time to live when it has one: the timer
2826
+ * settles the wait as `expired` — the same Decision the durable runner builds from its signal
2827
+ * timeout — and a decision that arrives first disarms it.
2828
+ */
2829
+ parkApproval(runId, toolCallId2, timeoutMs) {
2830
+ const waiting = this.park(runId, toolCallId2);
2831
+ if (timeoutMs === void 0) {
2832
+ return waiting;
2833
+ }
2834
+ const key = `${runId}:${toolCallId2}`;
2835
+ let timer;
2836
+ const lapse = new Promise((resolve) => {
2837
+ timer = setTimeout(() => {
2838
+ const entry = this.pending.get(key);
2839
+ if (entry !== void 0) {
2840
+ this.pending.delete(key);
2841
+ resolve({
2842
+ approved: false,
2843
+ expired: true
2844
+ });
2845
+ }
2846
+ }, timeoutMs);
2847
+ timer.unref?.();
2848
+ });
2849
+ return Promise.race([
2850
+ waiting,
2851
+ lapse
2852
+ ]).finally(() => clearTimeout(timer));
2853
+ }
2726
2854
  park(runId, toolCallId2) {
2727
2855
  return new Promise((resolve, reject) => {
2728
2856
  this.pending.set(`${runId}:${toolCallId2}`, {
@@ -2736,7 +2864,7 @@ var InlineAgentRunner = class _InlineAgentRunner {
2736
2864
  return {
2737
2865
  runId,
2738
2866
  openSink: /* @__PURE__ */ __name(() => deps.sink.open(runId), "openSink"),
2739
- awaitApproval: /* @__PURE__ */ __name((call) => this.park(runId, call.id), "awaitApproval"),
2867
+ awaitApproval: /* @__PURE__ */ __name((call, _ctx, opts) => this.parkApproval(runId, call.id, opts?.timeoutMs), "awaitApproval"),
2740
2868
  awaitAnswers: /* @__PURE__ */ __name((request) => this.park(runId, request.id), "awaitAnswers"),
2741
2869
  step: /* @__PURE__ */ __name((_name, fn) => fn(), "step"),
2742
2870
  parallel: settleAll,
@@ -2787,7 +2915,7 @@ var InlineAgentRunner = class _InlineAgentRunner {
2787
2915
  const hooks = {
2788
2916
  runId,
2789
2917
  openSink: /* @__PURE__ */ __name(() => deps.sink.open(runId), "openSink"),
2790
- awaitApproval: /* @__PURE__ */ __name((call) => this.park(runId, call.id), "awaitApproval"),
2918
+ awaitApproval: /* @__PURE__ */ __name((call, _ctx, opts) => this.parkApproval(runId, call.id, opts?.timeoutMs), "awaitApproval"),
2791
2919
  awaitAnswers: /* @__PURE__ */ __name((request) => this.park(runId, request.id), "awaitAnswers"),
2792
2920
  step: /* @__PURE__ */ __name((_name, fn) => fn(), "step"),
2793
2921
  parallel: settleAll,
@@ -2891,7 +3019,7 @@ var InlineAgentRunner = class _InlineAgentRunner {
2891
3019
  runId,
2892
3020
  // Forward into the top-level stream; the top-level run owns end/fail on that shared sink.
2893
3021
  openSink: /* @__PURE__ */ __name(async () => childSinkWriter(await deps.sink.open(sinkRunId)), "openSink"),
2894
- awaitApproval: /* @__PURE__ */ __name((call) => this.park(runId, call.id), "awaitApproval"),
3022
+ awaitApproval: /* @__PURE__ */ __name((call, _ctx, opts) => this.parkApproval(runId, call.id, opts?.timeoutMs), "awaitApproval"),
2895
3023
  awaitAnswers: /* @__PURE__ */ __name((request) => this.park(runId, request.id), "awaitAnswers"),
2896
3024
  step: /* @__PURE__ */ __name((_name, fn) => fn(), "step"),
2897
3025
  parallel: settleAll,