@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/README.md +30 -0
- package/dist/{agent-deps.factory-OjrLyAZo.d.cts → agent-deps.factory-CUyVPsa1.d.cts} +10 -1
- package/dist/{agent-deps.factory-OjrLyAZo.d.ts → agent-deps.factory-CUyVPsa1.d.ts} +10 -1
- package/dist/durable/index.cjs +158 -12
- package/dist/durable/index.cjs.map +1 -1
- package/dist/durable/index.d.cts +1 -1
- package/dist/durable/index.d.ts +1 -1
- package/dist/durable/index.js +160 -14
- package/dist/durable/index.js.map +1 -1
- package/dist/index.cjs +139 -11
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +38 -4
- package/dist/index.d.ts +38 -4
- package/dist/index.js +141 -13
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
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-
|
|
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-
|
|
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
|
-
|
|
84
|
-
|
|
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-
|
|
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-
|
|
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
|
-
|
|
84
|
-
|
|
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
|
-
|
|
427
|
-
|
|
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.
|
|
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
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
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,
|