@dudousxd/nestjs-agent 1.36.1 → 1.37.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 +2 -2
- package/dist/a2ui/index.cjs +11 -1
- package/dist/a2ui/index.cjs.map +1 -1
- package/dist/a2ui/index.d.cts +2 -2
- package/dist/a2ui/index.d.ts +2 -2
- package/dist/a2ui/index.js +11 -1
- package/dist/a2ui/index.js.map +1 -1
- package/dist/{chat-queue.service-CzXsKVb1.d.ts → chat-queue.service-YjiKVTKE.d.ts} +2 -2
- package/dist/{chat-queue.service-CF2fcJDx.d.cts → chat-queue.service-fopUN313.d.cts} +2 -2
- package/dist/durable/index.cjs +250 -50
- package/dist/durable/index.cjs.map +1 -1
- package/dist/durable/index.d.cts +6 -18
- package/dist/durable/index.d.ts +6 -18
- package/dist/durable/index.js +250 -50
- package/dist/durable/index.js.map +1 -1
- package/dist/{index-NF93YDF4.d.cts → index-4caNqEQ-.d.cts} +29 -6
- package/dist/{index-DpS9P7so.d.ts → index-yC_Ra3CE.d.ts} +29 -6
- package/dist/index.cjs +244 -47
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +19 -7
- package/dist/index.d.ts +19 -7
- package/dist/index.js +244 -47
- package/dist/index.js.map +1 -1
- package/dist/sink-redis/index.cjs +164 -18
- package/dist/sink-redis/index.cjs.map +1 -1
- package/dist/sink-redis/index.d.cts +36 -7
- package/dist/sink-redis/index.d.ts +36 -7
- package/dist/sink-redis/index.js +165 -19
- package/dist/sink-redis/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.d.cts
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { DynamicModule, Type, OnApplicationBootstrap, OnModuleInit, ConflictException, OnModuleDestroy } from '@nestjs/common';
|
|
2
|
-
import { b as AgentModuleOptions, c as AgentModuleAsyncOptions, d as AgentProtocolAdapter, A as AgentDepsFactory, e as AgentSkillsOptions, C as ChatQueueService } from './chat-queue.service-
|
|
3
|
-
export { f as AGENT_TOOL_BRAND, g as AgentAttachmentsOptions, h as AgentDeps, i as AgentEngine, j as AgentMemoryOptions, a as AgentSurface, F as FunctionalTool, L as LedgerQuotaProvider, Q as QueuePlan, k as QueueSettleOutcome, l as QueuedTurn, m as QueuedTurnStarter, n as QuotaLimits, o as QuotaWindowLimits, p as defineTool, q as delegateToolName, r as provideAgentTool, s as provideAgentTools, u as utcDay } from './chat-queue.service-
|
|
2
|
+
import { b as AgentModuleOptions, c as AgentModuleAsyncOptions, d as AgentProtocolAdapter, A as AgentDepsFactory, e as AgentSkillsOptions, C as ChatQueueService } from './chat-queue.service-fopUN313.cjs';
|
|
3
|
+
export { f as AGENT_TOOL_BRAND, g as AgentAttachmentsOptions, h as AgentDeps, i as AgentEngine, j as AgentMemoryOptions, a as AgentSurface, F as FunctionalTool, L as LedgerQuotaProvider, Q as QueuePlan, k as QueueSettleOutcome, l as QueuedTurn, m as QueuedTurnStarter, n as QuotaLimits, o as QuotaWindowLimits, p as defineTool, q as delegateToolName, r as provideAgentTool, s as provideAgentTools, u as utcDay } from './chat-queue.service-fopUN313.cjs';
|
|
4
4
|
import * as _dudousxd_nestjs_agent_core from '@dudousxd/nestjs-agent-core';
|
|
5
|
-
import { ActorResolver, AttachmentStagingStore, AgentApprovalPort, Actor, AgentStore, StagedAttachment, MessageAttachment, ModelCatalog, AgentClientConfig, ToolSpec, ToolPresentation, AgentHistoryWindow, AgentIntake, Persona, SkillContext, ToolRegistry, AgentRegistry, PromptContributor, SkillsConfig, SkillCatalogEntry, MessageFeedbackValue, MessageFeedback, ModelCatalogView, ToolCatalogEntry, MemoryConfig, MemoryDigestEntry, SkillProvider, AgentRunner, AgentRunInput, AgentRunStartOptions, HumanReply, ChatQueueState, TokenStreamSink, SinkWriter, ActionProposalOutcome, ActionProposal } from '@dudousxd/nestjs-agent-core';
|
|
5
|
+
import { ActorResolver, AttachmentStagingStore, AgentApprovalPort, Actor, AgentStore, StagedAttachment, MessageAttachment, ModelCatalog, AgentClientConfig, ToolSpec, ToolPresentation, AgentHistoryWindow, AgentIntake, Persona, SkillContext, ToolRegistry, AgentRegistry, PromptContributor, SkillsConfig, SkillCatalogEntry, MessageFeedbackValue, MessageFeedback, ModelCatalogView, ToolCatalogEntry, MemoryConfig, MemoryDigestEntry, SkillProvider, AgentRunner, AgentRunInput, AgentRunStartOptions, HumanReply, ChatQueueState, TokenStreamSink, SinkWriter, SubscribeOptions, ActionProposalOutcome, ActionProposal } from '@dudousxd/nestjs-agent-core';
|
|
6
6
|
export * from '@dudousxd/nestjs-agent-core';
|
|
7
7
|
export { FunctionalToolDefinition } from '@dudousxd/nestjs-agent-core';
|
|
8
8
|
import { A2uiOptions } from '@dudousxd/nestjs-agent-core/a2ui';
|
|
9
9
|
import { Request, Response } from 'express';
|
|
10
|
-
import { A as AgentService, a as ActionProposalService } from './index-
|
|
11
|
-
export { b as A2uiAdapterOptions, c as A2uiRunHandler, d as AttachmentLimits, C as ChatParams, e as ChatSendMode, f as ChatSendResult, D as DEFAULT_ALLOWED_ATTACHMENT_CONTENT_TYPES, g as DEFAULT_MAX_ATTACHMENT_BYTES, M as MAX_ATTACHMENTS_PER_MESSAGE, N as NO_USER_MESSAGE_CODE, Q as QueuedSend, T as ThreadDefaultAgentReader, h as ThreadModelReader, i as a2uiAdapter, j as attachmentLimits } from './index-
|
|
10
|
+
import { A as AgentService, a as ActionProposalService } from './index-4caNqEQ-.cjs';
|
|
11
|
+
export { b as A2uiAdapterOptions, c as A2uiRunHandler, d as AttachmentLimits, C as ChatParams, e as ChatSendMode, f as ChatSendResult, D as DEFAULT_ALLOWED_ATTACHMENT_CONTENT_TYPES, g as DEFAULT_MAX_ATTACHMENT_BYTES, F as ForkThreadParams, M as MAX_ATTACHMENTS_PER_MESSAGE, N as NO_USER_MESSAGE_CODE, Q as QueuedSend, T as ThreadDefaultAgentReader, h as ThreadModelReader, i as a2uiAdapter, j as attachmentLimits } from './index-4caNqEQ-.cjs';
|
|
12
12
|
import { AgentGenui } from './genui/index.cjs';
|
|
13
13
|
import { StandardSchemaV1 } from '@standard-schema/spec';
|
|
14
14
|
import { DiscoveryService, MetadataScanner } from '@nestjs/core';
|
|
@@ -870,7 +870,8 @@ declare const AGENT_SERVICE: unique symbol;
|
|
|
870
870
|
|
|
871
871
|
/**
|
|
872
872
|
* The default `TokenStreamSink`: buffers chunks per run in-process so a reconnecting subscriber
|
|
873
|
-
* replays everything so far, then follows live.
|
|
873
|
+
* replays everything so far, then follows live. A run's buffer is dropped {@link ENDED_GRACE_MS}
|
|
874
|
+
* after it ends, or {@link LIVE_TTL_MS} after its last write if it never does.
|
|
874
875
|
*
|
|
875
876
|
* Single-replica only. Because the buffer lives in one process's memory, a resume/reconnect that
|
|
876
877
|
* lands on a different replica than the one running the turn finds an empty buffer — the stream
|
|
@@ -879,10 +880,21 @@ declare const AGENT_SERVICE: unique symbol;
|
|
|
879
880
|
*/
|
|
880
881
|
declare class InProcessTokenStreamSink implements TokenStreamSink {
|
|
881
882
|
private readonly runs;
|
|
883
|
+
/** Subscribers of a run nothing has opened yet, woken by its `open()`. */
|
|
884
|
+
private readonly waiting;
|
|
882
885
|
private buffer;
|
|
886
|
+
private expireAfter;
|
|
887
|
+
/** Forget the run, and let anyone still following it finish as if it had ended. */
|
|
888
|
+
private drop;
|
|
883
889
|
private wake;
|
|
890
|
+
private finish;
|
|
891
|
+
/**
|
|
892
|
+
* The run's writer. Each call finds the run's buffer afresh, so a run that went quiet past the
|
|
893
|
+
* live TTL (parked on a person) and then writes again starts a new buffer its next subscriber
|
|
894
|
+
* follows, rather than writing into one nothing reads.
|
|
895
|
+
*/
|
|
884
896
|
open(runId: string): SinkWriter;
|
|
885
|
-
subscribe(runId: string): AsyncIterable<Uint8Array>;
|
|
897
|
+
subscribe(runId: string, options?: SubscribeOptions): AsyncIterable<Uint8Array>;
|
|
886
898
|
close(runId: string): void;
|
|
887
899
|
}
|
|
888
900
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { DynamicModule, Type, OnApplicationBootstrap, OnModuleInit, ConflictException, OnModuleDestroy } from '@nestjs/common';
|
|
2
|
-
import { b as AgentModuleOptions, c as AgentModuleAsyncOptions, d as AgentProtocolAdapter, A as AgentDepsFactory, e as AgentSkillsOptions, C as ChatQueueService } from './chat-queue.service-
|
|
3
|
-
export { f as AGENT_TOOL_BRAND, g as AgentAttachmentsOptions, h as AgentDeps, i as AgentEngine, j as AgentMemoryOptions, a as AgentSurface, F as FunctionalTool, L as LedgerQuotaProvider, Q as QueuePlan, k as QueueSettleOutcome, l as QueuedTurn, m as QueuedTurnStarter, n as QuotaLimits, o as QuotaWindowLimits, p as defineTool, q as delegateToolName, r as provideAgentTool, s as provideAgentTools, u as utcDay } from './chat-queue.service-
|
|
2
|
+
import { b as AgentModuleOptions, c as AgentModuleAsyncOptions, d as AgentProtocolAdapter, A as AgentDepsFactory, e as AgentSkillsOptions, C as ChatQueueService } from './chat-queue.service-YjiKVTKE.js';
|
|
3
|
+
export { f as AGENT_TOOL_BRAND, g as AgentAttachmentsOptions, h as AgentDeps, i as AgentEngine, j as AgentMemoryOptions, a as AgentSurface, F as FunctionalTool, L as LedgerQuotaProvider, Q as QueuePlan, k as QueueSettleOutcome, l as QueuedTurn, m as QueuedTurnStarter, n as QuotaLimits, o as QuotaWindowLimits, p as defineTool, q as delegateToolName, r as provideAgentTool, s as provideAgentTools, u as utcDay } from './chat-queue.service-YjiKVTKE.js';
|
|
4
4
|
import * as _dudousxd_nestjs_agent_core from '@dudousxd/nestjs-agent-core';
|
|
5
|
-
import { ActorResolver, AttachmentStagingStore, AgentApprovalPort, Actor, AgentStore, StagedAttachment, MessageAttachment, ModelCatalog, AgentClientConfig, ToolSpec, ToolPresentation, AgentHistoryWindow, AgentIntake, Persona, SkillContext, ToolRegistry, AgentRegistry, PromptContributor, SkillsConfig, SkillCatalogEntry, MessageFeedbackValue, MessageFeedback, ModelCatalogView, ToolCatalogEntry, MemoryConfig, MemoryDigestEntry, SkillProvider, AgentRunner, AgentRunInput, AgentRunStartOptions, HumanReply, ChatQueueState, TokenStreamSink, SinkWriter, ActionProposalOutcome, ActionProposal } from '@dudousxd/nestjs-agent-core';
|
|
5
|
+
import { ActorResolver, AttachmentStagingStore, AgentApprovalPort, Actor, AgentStore, StagedAttachment, MessageAttachment, ModelCatalog, AgentClientConfig, ToolSpec, ToolPresentation, AgentHistoryWindow, AgentIntake, Persona, SkillContext, ToolRegistry, AgentRegistry, PromptContributor, SkillsConfig, SkillCatalogEntry, MessageFeedbackValue, MessageFeedback, ModelCatalogView, ToolCatalogEntry, MemoryConfig, MemoryDigestEntry, SkillProvider, AgentRunner, AgentRunInput, AgentRunStartOptions, HumanReply, ChatQueueState, TokenStreamSink, SinkWriter, SubscribeOptions, ActionProposalOutcome, ActionProposal } from '@dudousxd/nestjs-agent-core';
|
|
6
6
|
export * from '@dudousxd/nestjs-agent-core';
|
|
7
7
|
export { FunctionalToolDefinition } from '@dudousxd/nestjs-agent-core';
|
|
8
8
|
import { A2uiOptions } from '@dudousxd/nestjs-agent-core/a2ui';
|
|
9
9
|
import { Request, Response } from 'express';
|
|
10
|
-
import { A as AgentService, a as ActionProposalService } from './index-
|
|
11
|
-
export { b as A2uiAdapterOptions, c as A2uiRunHandler, d as AttachmentLimits, C as ChatParams, e as ChatSendMode, f as ChatSendResult, D as DEFAULT_ALLOWED_ATTACHMENT_CONTENT_TYPES, g as DEFAULT_MAX_ATTACHMENT_BYTES, M as MAX_ATTACHMENTS_PER_MESSAGE, N as NO_USER_MESSAGE_CODE, Q as QueuedSend, T as ThreadDefaultAgentReader, h as ThreadModelReader, i as a2uiAdapter, j as attachmentLimits } from './index-
|
|
10
|
+
import { A as AgentService, a as ActionProposalService } from './index-yC_Ra3CE.js';
|
|
11
|
+
export { b as A2uiAdapterOptions, c as A2uiRunHandler, d as AttachmentLimits, C as ChatParams, e as ChatSendMode, f as ChatSendResult, D as DEFAULT_ALLOWED_ATTACHMENT_CONTENT_TYPES, g as DEFAULT_MAX_ATTACHMENT_BYTES, F as ForkThreadParams, M as MAX_ATTACHMENTS_PER_MESSAGE, N as NO_USER_MESSAGE_CODE, Q as QueuedSend, T as ThreadDefaultAgentReader, h as ThreadModelReader, i as a2uiAdapter, j as attachmentLimits } from './index-yC_Ra3CE.js';
|
|
12
12
|
import { AgentGenui } from './genui/index.js';
|
|
13
13
|
import { StandardSchemaV1 } from '@standard-schema/spec';
|
|
14
14
|
import { DiscoveryService, MetadataScanner } from '@nestjs/core';
|
|
@@ -870,7 +870,8 @@ declare const AGENT_SERVICE: unique symbol;
|
|
|
870
870
|
|
|
871
871
|
/**
|
|
872
872
|
* The default `TokenStreamSink`: buffers chunks per run in-process so a reconnecting subscriber
|
|
873
|
-
* replays everything so far, then follows live.
|
|
873
|
+
* replays everything so far, then follows live. A run's buffer is dropped {@link ENDED_GRACE_MS}
|
|
874
|
+
* after it ends, or {@link LIVE_TTL_MS} after its last write if it never does.
|
|
874
875
|
*
|
|
875
876
|
* Single-replica only. Because the buffer lives in one process's memory, a resume/reconnect that
|
|
876
877
|
* lands on a different replica than the one running the turn finds an empty buffer — the stream
|
|
@@ -879,10 +880,21 @@ declare const AGENT_SERVICE: unique symbol;
|
|
|
879
880
|
*/
|
|
880
881
|
declare class InProcessTokenStreamSink implements TokenStreamSink {
|
|
881
882
|
private readonly runs;
|
|
883
|
+
/** Subscribers of a run nothing has opened yet, woken by its `open()`. */
|
|
884
|
+
private readonly waiting;
|
|
882
885
|
private buffer;
|
|
886
|
+
private expireAfter;
|
|
887
|
+
/** Forget the run, and let anyone still following it finish as if it had ended. */
|
|
888
|
+
private drop;
|
|
883
889
|
private wake;
|
|
890
|
+
private finish;
|
|
891
|
+
/**
|
|
892
|
+
* The run's writer. Each call finds the run's buffer afresh, so a run that went quiet past the
|
|
893
|
+
* live TTL (parked on a person) and then writes again starts a new buffer its next subscriber
|
|
894
|
+
* follows, rather than writing into one nothing reads.
|
|
895
|
+
*/
|
|
884
896
|
open(runId: string): SinkWriter;
|
|
885
|
-
subscribe(runId: string): AsyncIterable<Uint8Array>;
|
|
897
|
+
subscribe(runId: string, options?: SubscribeOptions): AsyncIterable<Uint8Array>;
|
|
886
898
|
close(runId: string): void;
|
|
887
899
|
}
|
|
888
900
|
|
package/dist/index.js
CHANGED
|
@@ -1584,6 +1584,26 @@ var RunNotActiveException = class extends ConflictException {
|
|
|
1584
1584
|
}
|
|
1585
1585
|
};
|
|
1586
1586
|
|
|
1587
|
+
// src/thread-reads.ts
|
|
1588
|
+
function threadReads(store, threadId, separately) {
|
|
1589
|
+
const projecting = store;
|
|
1590
|
+
if (typeof projecting.threadSettings !== "function") {
|
|
1591
|
+
return separately;
|
|
1592
|
+
}
|
|
1593
|
+
let settings;
|
|
1594
|
+
const read = /* @__PURE__ */ __name(() => {
|
|
1595
|
+
settings ??= projecting.threadSettings?.(threadId) ?? Promise.resolve(null);
|
|
1596
|
+
return settings;
|
|
1597
|
+
}, "read");
|
|
1598
|
+
return {
|
|
1599
|
+
owner: /* @__PURE__ */ __name(async () => (await read())?.actorRef ?? null, "owner"),
|
|
1600
|
+
defaultAgent: /* @__PURE__ */ __name(async () => (await read())?.defaultAgent ?? null, "defaultAgent"),
|
|
1601
|
+
persona: /* @__PURE__ */ __name(async () => (await read())?.persona ?? null, "persona"),
|
|
1602
|
+
model: /* @__PURE__ */ __name(async () => (await read())?.model ?? null, "model")
|
|
1603
|
+
};
|
|
1604
|
+
}
|
|
1605
|
+
__name(threadReads, "threadReads");
|
|
1606
|
+
|
|
1587
1607
|
// src/agent.service.ts
|
|
1588
1608
|
function _ts_decorate5(decorators, target, key, desc) {
|
|
1589
1609
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
@@ -1847,7 +1867,7 @@ var AgentService2 = class {
|
|
|
1847
1867
|
* else the thread's pinned one, else none. An agent the catalog locks to one model runs on it
|
|
1848
1868
|
* whatever was sent or pinned, and a send naming another model is refused.
|
|
1849
1869
|
*/
|
|
1850
|
-
async resolveModel(actor, agent, requested, threadId) {
|
|
1870
|
+
async resolveModel(actor, agent, requested, threadId, reads) {
|
|
1851
1871
|
const locked = this.models !== void 0 ? (await this.models.list({
|
|
1852
1872
|
actor,
|
|
1853
1873
|
agent
|
|
@@ -1858,7 +1878,7 @@ var AgentService2 = class {
|
|
|
1858
1878
|
}
|
|
1859
1879
|
return locked.model;
|
|
1860
1880
|
}
|
|
1861
|
-
const model = requested ?? (threadId !== void 0 ? await this.threadModel(threadId) : null);
|
|
1881
|
+
const model = requested ?? (threadId !== void 0 ? await (reads?.model() ?? this.threadModel(threadId)) : null);
|
|
1862
1882
|
if (model === null || model === void 0) {
|
|
1863
1883
|
return void 0;
|
|
1864
1884
|
}
|
|
@@ -1918,10 +1938,11 @@ var AgentService2 = class {
|
|
|
1918
1938
|
if ("proposalDecision" in decision) return decision;
|
|
1919
1939
|
}
|
|
1920
1940
|
await this.assertWithinQuota(params.actor);
|
|
1921
|
-
const
|
|
1941
|
+
const reads = params.threadId !== void 0 ? this.threadReads(params.threadId) : void 0;
|
|
1942
|
+
const target = this.deps.resolveAgent(await this.resolveAgentName(params.agentName, params.threadId, reads));
|
|
1922
1943
|
const agentName = target.agentName;
|
|
1923
|
-
const persona = await this.resolvePersona(agentName, params.personaId ?? target.persona, params.threadId);
|
|
1924
|
-
const model = await this.resolveModel(params.actor, agentName, params.model, params.threadId);
|
|
1944
|
+
const persona = await this.resolvePersona(agentName, params.personaId ?? target.persona, params.threadId, reads);
|
|
1945
|
+
const model = await this.resolveModel(params.actor, agentName, params.model, params.threadId, reads);
|
|
1925
1946
|
const attachments = await this.resolveAttachments(params.actor, params.attachments ?? []);
|
|
1926
1947
|
let threadId = params.threadId;
|
|
1927
1948
|
if (threadId === void 0) {
|
|
@@ -1945,9 +1966,9 @@ var AgentService2 = class {
|
|
|
1945
1966
|
});
|
|
1946
1967
|
threadId = created.id;
|
|
1947
1968
|
} else {
|
|
1948
|
-
if (params.authorized !== true) await this.assertOwnsThread(params.actor, threadId);
|
|
1969
|
+
if (params.authorized !== true) await this.assertOwnsThread(params.actor, threadId, reads);
|
|
1949
1970
|
if (params.personaId !== void 0) {
|
|
1950
|
-
await this.pinThreadPersona(threadId, params.personaId);
|
|
1971
|
+
await this.pinThreadPersona(threadId, params.personaId, reads);
|
|
1951
1972
|
}
|
|
1952
1973
|
}
|
|
1953
1974
|
const input = {
|
|
@@ -2273,8 +2294,8 @@ var AgentService2 = class {
|
|
|
2273
2294
|
* {@link subscribeAs} instead: a runId is the only thing standing between a caller and another
|
|
2274
2295
|
* actor's answer, tool arguments and tool results.
|
|
2275
2296
|
*/
|
|
2276
|
-
subscribe(runId) {
|
|
2277
|
-
return this.deps.forAgent().sink.subscribe(runId);
|
|
2297
|
+
subscribe(runId, options) {
|
|
2298
|
+
return this.deps.forAgent().sink.subscribe(runId, options);
|
|
2278
2299
|
}
|
|
2279
2300
|
/**
|
|
2280
2301
|
* {@link subscribe}, gated the way {@link cancel} is: only the actor whose thread is currently
|
|
@@ -2282,9 +2303,9 @@ var AgentService2 = class {
|
|
|
2282
2303
|
* replayed — the runner clears the thread's active stream as the run ends, and that field is what
|
|
2283
2304
|
* ownership is derived from.
|
|
2284
2305
|
*/
|
|
2285
|
-
async subscribeAs(actor, runId) {
|
|
2306
|
+
async subscribeAs(actor, runId, options) {
|
|
2286
2307
|
await this.assertOwnsActiveStream(actor, runId);
|
|
2287
|
-
return this.subscribe(runId);
|
|
2308
|
+
return this.subscribe(runId, options);
|
|
2288
2309
|
}
|
|
2289
2310
|
/**
|
|
2290
2311
|
* Approve a parked action call as `actor`. Who may is the call's recorded approver's business
|
|
@@ -2437,9 +2458,28 @@ var AgentService2 = class {
|
|
|
2437
2458
|
await this.assertOwnsThread(actor, threadId);
|
|
2438
2459
|
return this.store.softDeleteThread(threadId);
|
|
2439
2460
|
}
|
|
2440
|
-
|
|
2441
|
-
|
|
2442
|
-
|
|
2461
|
+
/**
|
|
2462
|
+
* Copy a thread up to `fromMessageId` (inclusive) into a new one. By default only the thread's
|
|
2463
|
+
* owner may, and the copy is theirs. With `params.authorized`, the host has vouched for `actor`
|
|
2464
|
+
* (a share link it checked) and the copy is `actor`'s — see {@link ForkThreadParams}.
|
|
2465
|
+
*/
|
|
2466
|
+
async forkThread(actor, threadId, fromMessageId, params = {}) {
|
|
2467
|
+
if (params.authorized === true) {
|
|
2468
|
+
if (await this.store.ownerOfThread(threadId) === null) {
|
|
2469
|
+
throw new NotFoundException2(`thread ${threadId} not found`);
|
|
2470
|
+
}
|
|
2471
|
+
} else {
|
|
2472
|
+
await this.assertOwnsThread(actor, threadId);
|
|
2473
|
+
}
|
|
2474
|
+
const options = {
|
|
2475
|
+
...params.authorized === true ? {
|
|
2476
|
+
actorRef: actor.id
|
|
2477
|
+
} : {},
|
|
2478
|
+
...params.tenantRef !== void 0 ? {
|
|
2479
|
+
tenantRef: params.tenantRef
|
|
2480
|
+
} : {}
|
|
2481
|
+
};
|
|
2482
|
+
return this.store.forkThread(threadId, fromMessageId, options);
|
|
2443
2483
|
}
|
|
2444
2484
|
/** Kept for source compatibility — a thin wrapper over the more general `updateThread`. */
|
|
2445
2485
|
async renameThread(actor, threadId, title) {
|
|
@@ -2491,7 +2531,7 @@ var AgentService2 = class {
|
|
|
2491
2531
|
* The persona this send runs under — see {@link AgentDepsFactory.resolvePersona}. The thread's
|
|
2492
2532
|
* pinned persona is read only when the send names none AND the agent has personas to pick from.
|
|
2493
2533
|
*/
|
|
2494
|
-
async resolvePersona(agentName, requested, threadId) {
|
|
2534
|
+
async resolvePersona(agentName, requested, threadId, reads) {
|
|
2495
2535
|
const needsThread = requested === void 0 && threadId !== void 0 && this.deps.personaCatalog(agentName).length > 0;
|
|
2496
2536
|
return this.deps.resolvePersona({
|
|
2497
2537
|
agentName,
|
|
@@ -2499,16 +2539,16 @@ var AgentService2 = class {
|
|
|
2499
2539
|
requested
|
|
2500
2540
|
} : {},
|
|
2501
2541
|
...needsThread ? {
|
|
2502
|
-
threadPersona: await threadPersona(this.store, threadId)
|
|
2542
|
+
threadPersona: await (reads?.persona() ?? threadPersona(this.store, threadId))
|
|
2503
2543
|
} : {}
|
|
2504
2544
|
});
|
|
2505
2545
|
}
|
|
2506
2546
|
/** Pin `persona` on the thread when it is not already — a no-op on a store that cannot. */
|
|
2507
|
-
async pinThreadPersona(threadId, persona) {
|
|
2547
|
+
async pinThreadPersona(threadId, persona, reads) {
|
|
2508
2548
|
if (this.store.updateThread === void 0) {
|
|
2509
2549
|
return;
|
|
2510
2550
|
}
|
|
2511
|
-
if (await threadPersona(this.store, threadId) !== persona) {
|
|
2551
|
+
if (await (reads?.persona() ?? threadPersona(this.store, threadId)) !== persona) {
|
|
2512
2552
|
await this.store.updateThread(threadId, {
|
|
2513
2553
|
persona
|
|
2514
2554
|
});
|
|
@@ -2535,18 +2575,27 @@ var AgentService2 = class {
|
|
|
2535
2575
|
* workflow, for a string. A store predating {@link ThreadDefaultAgentReader} still answers, via
|
|
2536
2576
|
* the full read.
|
|
2537
2577
|
*/
|
|
2538
|
-
async resolveAgentName(agentName, threadId) {
|
|
2578
|
+
async resolveAgentName(agentName, threadId, reads) {
|
|
2539
2579
|
if (agentName !== void 0) {
|
|
2540
2580
|
return agentName;
|
|
2541
2581
|
}
|
|
2542
2582
|
if (threadId !== void 0) {
|
|
2543
|
-
const threadDefault = await this.threadDefaultAgent(threadId);
|
|
2583
|
+
const threadDefault = await (reads?.defaultAgent() ?? this.threadDefaultAgent(threadId));
|
|
2544
2584
|
if (threadDefault !== null) {
|
|
2545
2585
|
return threadDefault;
|
|
2546
2586
|
}
|
|
2547
2587
|
}
|
|
2548
2588
|
return this.deps.defaultAgentName();
|
|
2549
2589
|
}
|
|
2590
|
+
/** Everything a send reads off `threadId`, in one read where the store allows it. */
|
|
2591
|
+
threadReads(threadId) {
|
|
2592
|
+
return threadReads(this.store, threadId, {
|
|
2593
|
+
owner: /* @__PURE__ */ __name(() => this.store.ownerOfThread(threadId), "owner"),
|
|
2594
|
+
defaultAgent: /* @__PURE__ */ __name(() => this.threadDefaultAgent(threadId), "defaultAgent"),
|
|
2595
|
+
persona: /* @__PURE__ */ __name(() => threadPersona(this.store, threadId), "persona"),
|
|
2596
|
+
model: /* @__PURE__ */ __name(() => this.threadModel(threadId), "model")
|
|
2597
|
+
});
|
|
2598
|
+
}
|
|
2550
2599
|
async threadDefaultAgent(threadId) {
|
|
2551
2600
|
const projecting = this.store;
|
|
2552
2601
|
if (typeof projecting.defaultAgentForThread === "function") {
|
|
@@ -2716,8 +2765,8 @@ var AgentService2 = class {
|
|
|
2716
2765
|
* Authorization seam for thread-scoped endpoints: the caller must own the thread. A missing
|
|
2717
2766
|
* thread is a 404; someone else's thread is a 403 — one actor never touches another's thread.
|
|
2718
2767
|
*/
|
|
2719
|
-
async assertOwnsThread(actor, threadId) {
|
|
2720
|
-
const owner = await this.store.ownerOfThread(threadId);
|
|
2768
|
+
async assertOwnsThread(actor, threadId, reads) {
|
|
2769
|
+
const owner = await (reads?.owner() ?? this.store.ownerOfThread(threadId));
|
|
2721
2770
|
if (owner === null) {
|
|
2722
2771
|
throw new NotFoundException2(`thread ${threadId} not found`);
|
|
2723
2772
|
}
|
|
@@ -3157,6 +3206,18 @@ AttachmentsController = _ts_decorate8([
|
|
|
3157
3206
|
import { AGENT_ACTOR_RESOLVER as AGENT_ACTOR_RESOLVER2, AgentStreamError, streamFailure } from "@dudousxd/nestjs-agent-core";
|
|
3158
3207
|
import { validateUiCapabilities } from "@dudousxd/nestjs-agent-core/genui";
|
|
3159
3208
|
import { BadRequestException as BadRequestException4, Body, Controller as Controller3, Get as Get3, Inject as Inject8, Param, Post as Post2, Query, Req as Req2, Res } from "@nestjs/common";
|
|
3209
|
+
|
|
3210
|
+
// src/controller/reader-gone.ts
|
|
3211
|
+
function readerGone(res) {
|
|
3212
|
+
const controller = new AbortController();
|
|
3213
|
+
res.once("close", () => controller.abort());
|
|
3214
|
+
return {
|
|
3215
|
+
signal: controller.signal
|
|
3216
|
+
};
|
|
3217
|
+
}
|
|
3218
|
+
__name(readerGone, "readerGone");
|
|
3219
|
+
|
|
3220
|
+
// src/controller/chat.controller.ts
|
|
3160
3221
|
function _ts_decorate9(decorators, target, key, desc) {
|
|
3161
3222
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3162
3223
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
|
|
@@ -3290,7 +3351,8 @@ var ChatController = class {
|
|
|
3290
3351
|
return;
|
|
3291
3352
|
}
|
|
3292
3353
|
const { runId, threadId } = result;
|
|
3293
|
-
|
|
3354
|
+
const gone = readerGone(res);
|
|
3355
|
+
await this.pipe(res, runId, this.agent.subscribe(runId, gone), threadId, 0, gone.signal);
|
|
3294
3356
|
}
|
|
3295
3357
|
/**
|
|
3296
3358
|
* Attach to a run's stream: every buffered frame, then live ones. `?after=<seq>` (or the SSE
|
|
@@ -3300,7 +3362,8 @@ var ChatController = class {
|
|
|
3300
3362
|
async stream(req, runId, res, after) {
|
|
3301
3363
|
const actor = await this.actorResolver.resolve(req);
|
|
3302
3364
|
const cursor = parseCursor(after) ?? parseCursor(req.headers["last-event-id"]) ?? 0;
|
|
3303
|
-
|
|
3365
|
+
const gone = readerGone(res);
|
|
3366
|
+
await this.pipe(res, runId, await this.agent.subscribeAs(actor, runId, gone), void 0, cursor, gone.signal);
|
|
3304
3367
|
}
|
|
3305
3368
|
async cancel(req, runId) {
|
|
3306
3369
|
const actor = await this.actorResolver.resolve(req);
|
|
@@ -3316,8 +3379,11 @@ var ChatController = class {
|
|
|
3316
3379
|
* and on any later `GET …/stream`, whichever replica serves it. A reconnecting client passes the
|
|
3317
3380
|
* last one it saw as `?after=`; frames at or below it are read off the sink but not re-sent.
|
|
3318
3381
|
* `meta`, `done` and `error` carry no id: `meta` is re-sent on every attach, the terminals once.
|
|
3382
|
+
*
|
|
3383
|
+
* A reader that disconnects aborts `gone`, which the sink honours by ending the subscription even
|
|
3384
|
+
* while the run is silent (parked on a person, or never writing again).
|
|
3319
3385
|
*/
|
|
3320
|
-
async pipe(res, runId, events, threadId, after = 0) {
|
|
3386
|
+
async pipe(res, runId, events, threadId, after = 0, gone) {
|
|
3321
3387
|
res.setHeader("Content-Type", "text/event-stream");
|
|
3322
3388
|
res.setHeader("Cache-Control", "no-cache");
|
|
3323
3389
|
res.setHeader("Connection", "keep-alive");
|
|
@@ -3346,6 +3412,9 @@ data: ${line}
|
|
|
3346
3412
|
}, "forward");
|
|
3347
3413
|
try {
|
|
3348
3414
|
for await (const chunk of events) {
|
|
3415
|
+
if (gone?.aborted) {
|
|
3416
|
+
return;
|
|
3417
|
+
}
|
|
3349
3418
|
buffer += decoder.decode(chunk, {
|
|
3350
3419
|
stream: true
|
|
3351
3420
|
});
|
|
@@ -3359,11 +3428,17 @@ data: ${line}
|
|
|
3359
3428
|
newline = buffer.indexOf("\n");
|
|
3360
3429
|
}
|
|
3361
3430
|
}
|
|
3431
|
+
if (gone?.aborted) {
|
|
3432
|
+
return;
|
|
3433
|
+
}
|
|
3362
3434
|
if (buffer.length > 0) {
|
|
3363
3435
|
forward(buffer);
|
|
3364
3436
|
}
|
|
3365
3437
|
res.write("event: done\ndata: {}\n\n");
|
|
3366
3438
|
} catch (error) {
|
|
3439
|
+
if (gone?.aborted) {
|
|
3440
|
+
return;
|
|
3441
|
+
}
|
|
3367
3442
|
const payload = error instanceof AgentStreamError ? {
|
|
3368
3443
|
code: error.code,
|
|
3369
3444
|
message: error.message
|
|
@@ -5293,49 +5368,121 @@ SkillDiscoveryService = _ts_decorate22([
|
|
|
5293
5368
|
|
|
5294
5369
|
// src/in-process-sink.ts
|
|
5295
5370
|
import { AgentStreamError as AgentStreamError2 } from "@dudousxd/nestjs-agent-core";
|
|
5371
|
+
var LIVE_TTL_MS = 36e5;
|
|
5372
|
+
var ENDED_GRACE_MS = 6e4;
|
|
5296
5373
|
var InProcessTokenStreamSink = class {
|
|
5297
5374
|
static {
|
|
5298
5375
|
__name(this, "InProcessTokenStreamSink");
|
|
5299
5376
|
}
|
|
5300
5377
|
runs = /* @__PURE__ */ new Map();
|
|
5378
|
+
/** Subscribers of a run nothing has opened yet, woken by its `open()`. */
|
|
5379
|
+
waiting = /* @__PURE__ */ new Map();
|
|
5301
5380
|
buffer(runId) {
|
|
5302
5381
|
let buf = this.runs.get(runId);
|
|
5303
5382
|
if (buf === void 0) {
|
|
5304
5383
|
buf = {
|
|
5305
5384
|
chunks: [],
|
|
5306
5385
|
ended: false,
|
|
5307
|
-
notify: /* @__PURE__ */ new Set()
|
|
5386
|
+
notify: /* @__PURE__ */ new Set(),
|
|
5387
|
+
lastWriteAt: Date.now(),
|
|
5388
|
+
expiry: void 0
|
|
5308
5389
|
};
|
|
5309
5390
|
this.runs.set(runId, buf);
|
|
5391
|
+
this.expireAfter(runId, buf, LIVE_TTL_MS);
|
|
5392
|
+
const waiters = this.waiting.get(runId);
|
|
5393
|
+
this.waiting.delete(runId);
|
|
5394
|
+
for (const resolve2 of waiters ?? []) {
|
|
5395
|
+
resolve2();
|
|
5396
|
+
}
|
|
5310
5397
|
}
|
|
5311
5398
|
return buf;
|
|
5312
5399
|
}
|
|
5400
|
+
expireAfter(runId, buf, ms) {
|
|
5401
|
+
if (buf.expiry !== void 0) {
|
|
5402
|
+
clearTimeout(buf.expiry);
|
|
5403
|
+
}
|
|
5404
|
+
buf.expiry = setTimeout(() => {
|
|
5405
|
+
buf.expiry = void 0;
|
|
5406
|
+
const idle = Date.now() - buf.lastWriteAt;
|
|
5407
|
+
if (!buf.ended && idle < LIVE_TTL_MS) {
|
|
5408
|
+
this.expireAfter(runId, buf, LIVE_TTL_MS - idle);
|
|
5409
|
+
return;
|
|
5410
|
+
}
|
|
5411
|
+
this.drop(runId, buf);
|
|
5412
|
+
}, ms);
|
|
5413
|
+
buf.expiry.unref?.();
|
|
5414
|
+
}
|
|
5415
|
+
/** Forget the run, and let anyone still following it finish as if it had ended. */
|
|
5416
|
+
drop(runId, buf) {
|
|
5417
|
+
if (buf.expiry !== void 0) {
|
|
5418
|
+
clearTimeout(buf.expiry);
|
|
5419
|
+
buf.expiry = void 0;
|
|
5420
|
+
}
|
|
5421
|
+
if (this.runs.get(runId) === buf) {
|
|
5422
|
+
this.runs.delete(runId);
|
|
5423
|
+
}
|
|
5424
|
+
buf.ended = true;
|
|
5425
|
+
this.wake(buf);
|
|
5426
|
+
}
|
|
5313
5427
|
wake(buf) {
|
|
5314
5428
|
for (const resolve2 of buf.notify) {
|
|
5315
5429
|
resolve2();
|
|
5316
5430
|
}
|
|
5317
5431
|
buf.notify.clear();
|
|
5318
5432
|
}
|
|
5433
|
+
finish(runId, buf) {
|
|
5434
|
+
buf.ended = true;
|
|
5435
|
+
this.wake(buf);
|
|
5436
|
+
this.expireAfter(runId, buf, ENDED_GRACE_MS);
|
|
5437
|
+
}
|
|
5438
|
+
/**
|
|
5439
|
+
* The run's writer. Each call finds the run's buffer afresh, so a run that went quiet past the
|
|
5440
|
+
* live TTL (parked on a person) and then writes again starts a new buffer its next subscriber
|
|
5441
|
+
* follows, rather than writing into one nothing reads.
|
|
5442
|
+
*/
|
|
5319
5443
|
open(runId) {
|
|
5320
|
-
|
|
5444
|
+
this.buffer(runId);
|
|
5321
5445
|
return {
|
|
5322
5446
|
write: /* @__PURE__ */ __name((chunk) => {
|
|
5447
|
+
const buf = this.buffer(runId);
|
|
5323
5448
|
buf.chunks.push(chunk);
|
|
5449
|
+
buf.lastWriteAt = Date.now();
|
|
5324
5450
|
this.wake(buf);
|
|
5325
5451
|
}, "write"),
|
|
5326
5452
|
end: /* @__PURE__ */ __name(() => {
|
|
5327
|
-
|
|
5328
|
-
this.wake(buf);
|
|
5453
|
+
this.finish(runId, this.buffer(runId));
|
|
5329
5454
|
}, "end"),
|
|
5330
5455
|
fail: /* @__PURE__ */ __name((error) => {
|
|
5456
|
+
const buf = this.buffer(runId);
|
|
5331
5457
|
buf.failure = error;
|
|
5332
|
-
|
|
5333
|
-
this.wake(buf);
|
|
5458
|
+
this.finish(runId, buf);
|
|
5334
5459
|
}, "fail")
|
|
5335
5460
|
};
|
|
5336
5461
|
}
|
|
5337
|
-
async *subscribe(runId) {
|
|
5338
|
-
const
|
|
5462
|
+
async *subscribe(runId, options = {}) {
|
|
5463
|
+
const { signal } = options;
|
|
5464
|
+
let buf = this.runs.get(runId);
|
|
5465
|
+
while (buf === void 0) {
|
|
5466
|
+
const waiters = this.waiting.get(runId) ?? /* @__PURE__ */ new Set();
|
|
5467
|
+
this.waiting.set(runId, waiters);
|
|
5468
|
+
let resolve2 = /* @__PURE__ */ __name(() => {
|
|
5469
|
+
}, "resolve");
|
|
5470
|
+
const opened = new Promise((r) => {
|
|
5471
|
+
resolve2 = r;
|
|
5472
|
+
});
|
|
5473
|
+
waiters.add(resolve2);
|
|
5474
|
+
try {
|
|
5475
|
+
if (!await untilAborted(opened, signal)) {
|
|
5476
|
+
return;
|
|
5477
|
+
}
|
|
5478
|
+
} finally {
|
|
5479
|
+
waiters.delete(resolve2);
|
|
5480
|
+
if (waiters.size === 0 && this.waiting.get(runId) === waiters) {
|
|
5481
|
+
this.waiting.delete(runId);
|
|
5482
|
+
}
|
|
5483
|
+
}
|
|
5484
|
+
buf = this.runs.get(runId);
|
|
5485
|
+
}
|
|
5339
5486
|
let index = 0;
|
|
5340
5487
|
while (true) {
|
|
5341
5488
|
while (index < buf.chunks.length) {
|
|
@@ -5351,13 +5498,56 @@ var InProcessTokenStreamSink = class {
|
|
|
5351
5498
|
}
|
|
5352
5499
|
return;
|
|
5353
5500
|
}
|
|
5354
|
-
|
|
5501
|
+
const current = buf;
|
|
5502
|
+
let resolve2 = /* @__PURE__ */ __name(() => {
|
|
5503
|
+
}, "resolve");
|
|
5504
|
+
const woken = new Promise((r) => {
|
|
5505
|
+
resolve2 = r;
|
|
5506
|
+
});
|
|
5507
|
+
current.notify.add(resolve2);
|
|
5508
|
+
try {
|
|
5509
|
+
if (!await untilAborted(woken, signal)) {
|
|
5510
|
+
return;
|
|
5511
|
+
}
|
|
5512
|
+
} finally {
|
|
5513
|
+
current.notify.delete(resolve2);
|
|
5514
|
+
}
|
|
5355
5515
|
}
|
|
5356
5516
|
}
|
|
5357
5517
|
close(runId) {
|
|
5518
|
+
const buf = this.runs.get(runId);
|
|
5519
|
+
if (buf?.expiry !== void 0) {
|
|
5520
|
+
clearTimeout(buf.expiry);
|
|
5521
|
+
}
|
|
5358
5522
|
this.runs.delete(runId);
|
|
5359
5523
|
}
|
|
5360
5524
|
};
|
|
5525
|
+
async function untilAborted(promise, signal) {
|
|
5526
|
+
if (signal === void 0) {
|
|
5527
|
+
await promise;
|
|
5528
|
+
return true;
|
|
5529
|
+
}
|
|
5530
|
+
if (signal.aborted) {
|
|
5531
|
+
return false;
|
|
5532
|
+
}
|
|
5533
|
+
let onAbort = /* @__PURE__ */ __name(() => {
|
|
5534
|
+
}, "onAbort");
|
|
5535
|
+
const aborted = new Promise((resolve2) => {
|
|
5536
|
+
onAbort = /* @__PURE__ */ __name(() => resolve2(false), "onAbort");
|
|
5537
|
+
signal.addEventListener("abort", onAbort, {
|
|
5538
|
+
once: true
|
|
5539
|
+
});
|
|
5540
|
+
});
|
|
5541
|
+
try {
|
|
5542
|
+
return await Promise.race([
|
|
5543
|
+
promise.then(() => true),
|
|
5544
|
+
aborted
|
|
5545
|
+
]);
|
|
5546
|
+
} finally {
|
|
5547
|
+
signal.removeEventListener("abort", onAbort);
|
|
5548
|
+
}
|
|
5549
|
+
}
|
|
5550
|
+
__name(untilAborted, "untilAborted");
|
|
5361
5551
|
|
|
5362
5552
|
// src/ledger-quota-provider.ts
|
|
5363
5553
|
import { exhaustedWindow, quotaPeriodRange, quotaWarning } from "@dudousxd/nestjs-agent-core";
|
|
@@ -5376,13 +5566,22 @@ var LedgerQuotaProvider = class {
|
|
|
5376
5566
|
async report(query) {
|
|
5377
5567
|
const now = query.now ?? /* @__PURE__ */ new Date();
|
|
5378
5568
|
const actorRef = query.actor.id;
|
|
5379
|
-
const
|
|
5380
|
-
|
|
5381
|
-
];
|
|
5382
|
-
if (this.store.
|
|
5383
|
-
const
|
|
5384
|
-
|
|
5385
|
-
|
|
5569
|
+
const day = quotaPeriodRange("day", now);
|
|
5570
|
+
const month = quotaPeriodRange("month", now);
|
|
5571
|
+
const windows = [];
|
|
5572
|
+
if (this.store.usageWindows !== void 0) {
|
|
5573
|
+
const [dayUsed, monthUsed] = await this.store.usageWindows(actorRef, [
|
|
5574
|
+
day,
|
|
5575
|
+
month
|
|
5576
|
+
]);
|
|
5577
|
+
windows.push(this.usedWindow("day", dayUsed, day.resetsAt));
|
|
5578
|
+
windows.push(this.usedWindow("month", monthUsed, month.resetsAt));
|
|
5579
|
+
} else {
|
|
5580
|
+
windows.push(this.usedWindow("day", await this.store.quotaToday(actorRef, day.fromDay), day.resetsAt));
|
|
5581
|
+
if (this.store.usageBetween !== void 0) {
|
|
5582
|
+
const used = await this.store.usageBetween(actorRef, month.fromDay, month.toDay);
|
|
5583
|
+
windows.push(this.usedWindow("month", used, month.resetsAt));
|
|
5584
|
+
}
|
|
5386
5585
|
}
|
|
5387
5586
|
const blocked = exhaustedWindow(windows);
|
|
5388
5587
|
const warning = quotaWarning(windows);
|
|
@@ -5396,10 +5595,8 @@ var LedgerQuotaProvider = class {
|
|
|
5396
5595
|
} : {}
|
|
5397
5596
|
};
|
|
5398
5597
|
}
|
|
5399
|
-
|
|
5400
|
-
|
|
5401
|
-
const used = await this.store.quotaToday(actorRef, range.fromDay);
|
|
5402
|
-
return this.window("day", used.usedTokens, this.usd(used), range.resetsAt);
|
|
5598
|
+
usedWindow(period, used, resetsAt) {
|
|
5599
|
+
return this.window(period, used?.usedTokens ?? 0, used === void 0 ? 0 : this.usd(used), resetsAt);
|
|
5403
5600
|
}
|
|
5404
5601
|
/** The window's USD: every priced row, or (with `countEstimatedCost: false`) reported cost only. */
|
|
5405
5602
|
usd(used) {
|
|
@@ -7244,7 +7441,7 @@ var AgUiRunHandler = class {
|
|
|
7244
7441
|
seq: 0
|
|
7245
7442
|
};
|
|
7246
7443
|
try {
|
|
7247
|
-
const frames = agUiFramesFromNdjson(this.agent.subscribe(runId));
|
|
7444
|
+
const frames = agUiFramesFromNdjson(this.agent.subscribe(runId, readerGone(res)));
|
|
7248
7445
|
for await (const event of agUiEvents(frames, {
|
|
7249
7446
|
...options,
|
|
7250
7447
|
cursor
|
|
@@ -7575,7 +7772,7 @@ var A2uiRunHandler = class {
|
|
|
7575
7772
|
`);
|
|
7576
7773
|
}, "write");
|
|
7577
7774
|
try {
|
|
7578
|
-
const frames = agUiFramesFromNdjson2(this.agent.subscribe(runId));
|
|
7775
|
+
const frames = agUiFramesFromNdjson2(this.agent.subscribe(runId, readerGone(res)));
|
|
7579
7776
|
for await (const event of agUiEvents2(frames, {
|
|
7580
7777
|
threadId: options.threadId ?? runId,
|
|
7581
7778
|
runId,
|