@dudousxd/nestjs-agent 1.23.0 → 1.24.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/{chat-queue.service-D1z3WjFI.d.cts → chat-queue.service-Crf9uwum.d.cts} +6 -2
- package/dist/{chat-queue.service-CwxJDrBM.d.ts → chat-queue.service-ZQkqb1Yw.d.ts} +6 -2
- package/dist/durable/index.cjs +117 -27
- 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 +122 -32
- package/dist/durable/index.js.map +1 -1
- package/dist/index.cjs +152 -35
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +68 -21
- package/dist/index.d.ts +68 -21
- package/dist/index.js +157 -40
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.d.cts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { DynamicModule, Type, OnApplicationBootstrap, OnModuleInit, ConflictException, OnModuleDestroy } from '@nestjs/common';
|
|
2
|
-
import { b as AgentModuleOptions, c as AgentModuleAsyncOptions, A as AgentDepsFactory, C as ChatQueueService, d as AgentProtocolAdapter, e as AgentSkillsOptions } 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, A as AgentDepsFactory, C as ChatQueueService, d as AgentProtocolAdapter, e as AgentSkillsOptions } from './chat-queue.service-Crf9uwum.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-Crf9uwum.cjs';
|
|
4
4
|
import * as _dudousxd_nestjs_agent_core from '@dudousxd/nestjs-agent-core';
|
|
5
|
-
import { AgentStore, Actor, ListActionProposals, ActionProposalMutationView,
|
|
5
|
+
import { AgentAttachmentConfig, AttachmentStagingStore, AgentStore, Actor, ListActionProposals, ActionProposalMutationView, TextActionProposalVocabulary, AgentRunner, ModelCatalog, QuotaProvider, ActionApprovalMode, ActionProposalView, MessageAttachment, QuotaReport, ModelCatalogView, AgentHostContext, AttachmentRef, PageContext, ChatQueueState, HumanReply, ThreadSummary, ThreadDetail, UpdateThreadInput, MessageFeedbackValue, MessageFeedback, StagedAttachment, ActorResolver, AgentApprovalPort, AgentClientConfig, ToolSpec, ToolPresentation, AgentHistoryWindow, AgentIntake, Persona, SkillContext, ToolRegistry, AgentRegistry, PromptContributor, SkillsConfig, SkillCatalogEntry, ToolCatalogEntry, MemoryConfig, MemoryDigestEntry, SkillProvider, AgentRunInput, AgentRunStartOptions, TokenStreamSink, SinkWriter, 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 { Request, Response } from 'express';
|
|
@@ -16,6 +16,20 @@ declare class AgentModule {
|
|
|
16
16
|
static forRootAsync(options: AgentModuleAsyncOptions): DynamicModule;
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
+
/** Default per-file size cap (20 MiB). */
|
|
20
|
+
declare const DEFAULT_MAX_ATTACHMENT_BYTES: number;
|
|
21
|
+
/** Default allowlist: what multimodal model providers commonly accept as native image/file parts. */
|
|
22
|
+
declare const DEFAULT_ALLOWED_ATTACHMENT_CONTENT_TYPES: readonly string[];
|
|
23
|
+
/** How many attachments one message may name. */
|
|
24
|
+
declare const MAX_ATTACHMENTS_PER_MESSAGE = 10;
|
|
25
|
+
/** The attachment rules in force — `AgentAttachmentConfig`, as `GET <base>/config` serves it. */
|
|
26
|
+
type AttachmentLimits = AgentAttachmentConfig;
|
|
27
|
+
/**
|
|
28
|
+
* One source for attachment limits: the staging store's own `describe()` when it declares them
|
|
29
|
+
* (`AgentMediaAttachmentsModule` does), else `AgentModule`'s `attachments` option, else the defaults.
|
|
30
|
+
*/
|
|
31
|
+
declare function attachmentLimits(options: Pick<AgentModuleOptions, 'attachments'> | undefined, staging: AttachmentStagingStore | undefined): AttachmentLimits;
|
|
32
|
+
|
|
19
33
|
declare class ActionProposalService {
|
|
20
34
|
private readonly store;
|
|
21
35
|
private readonly options;
|
|
@@ -55,8 +69,10 @@ declare class ActionProposalService {
|
|
|
55
69
|
text: string;
|
|
56
70
|
}>;
|
|
57
71
|
private textReceipt;
|
|
72
|
+
/** The configured words a text decision is made of (`actionProposalText.vocabulary`). */
|
|
73
|
+
textVocabulary(): TextActionProposalVocabulary;
|
|
58
74
|
/** The configured reply to a decision the store answered with `result`. */
|
|
59
|
-
reply(result: ActionProposalMutationView, decision: 'approved' | 'rejected'): string;
|
|
75
|
+
reply(result: Pick<ActionProposalMutationView, 'status' | 'proposal'>, decision: 'approved' | 'rejected'): string;
|
|
60
76
|
}
|
|
61
77
|
|
|
62
78
|
/**
|
|
@@ -165,7 +181,7 @@ declare class AgentService {
|
|
|
165
181
|
private readonly options?;
|
|
166
182
|
private readonly queue?;
|
|
167
183
|
private readonly proposals?;
|
|
168
|
-
constructor(runner: AgentRunner, store: AgentStore, deps: AgentDepsFactory, staging?: AttachmentStagingStore | undefined, models?: ModelCatalog | undefined, quotaProvider?: QuotaProvider | undefined, options?: Pick<AgentModuleOptions, "quota" | "actionApprovalMode"> | undefined, queue?: ChatQueueService | undefined, proposals?: ActionProposalService | undefined);
|
|
184
|
+
constructor(runner: AgentRunner, store: AgentStore, deps: AgentDepsFactory, staging?: AttachmentStagingStore | undefined, models?: ModelCatalog | undefined, quotaProvider?: QuotaProvider | undefined, options?: Pick<AgentModuleOptions, "quota" | "actionApprovalMode" | "attachments"> | undefined, queue?: ChatQueueService | undefined, proposals?: ActionProposalService | undefined);
|
|
169
185
|
/**
|
|
170
186
|
* Decide one independent proposal through the scoped proposal service — what the native
|
|
171
187
|
* `action-proposals/:id/approve|reject` routes call — and the reply to show for it. `404` when
|
|
@@ -194,6 +210,37 @@ declare class AgentService {
|
|
|
194
210
|
};
|
|
195
211
|
text: string;
|
|
196
212
|
}>;
|
|
213
|
+
/** How `action` tools wait for their approval here — `AgentModule.forRoot({ actionApprovalMode })`. */
|
|
214
|
+
actionApprovalMode(): ActionApprovalMode;
|
|
215
|
+
/**
|
|
216
|
+
* The words a text decision is made of (`actionProposalText.vocabulary`, English by default) — what
|
|
217
|
+
* a surface without buttons tells the person to reply.
|
|
218
|
+
*/
|
|
219
|
+
actionProposalVocabulary(): TextActionProposalVocabulary;
|
|
220
|
+
/** The configured reply (`actionProposalText.replies`) to a decision the store answered with `result`. */
|
|
221
|
+
actionProposalReply(result: Pick<ActionProposalMutationView, 'status' | 'proposal'>, decision: 'approved' | 'rejected'): string;
|
|
222
|
+
/**
|
|
223
|
+
* The proposals of a thread this actor may see — the thread's own actor, or one the policy lets
|
|
224
|
+
* decide them; what `GET <base>/threads/:threadId/action-proposals` serves (its first page). `404`
|
|
225
|
+
* when independent approvals are not on.
|
|
226
|
+
*/
|
|
227
|
+
listActionProposals(actor: Actor, threadId: string): Promise<ActionProposalView[]>;
|
|
228
|
+
/**
|
|
229
|
+
* The attachment rules in force — what `GET <base>/config` serves and `POST <base>/attachments`
|
|
230
|
+
* enforces. `enabled: false` when no `AGENT_ATTACHMENT_STAGING` provider is bound.
|
|
231
|
+
*/
|
|
232
|
+
attachmentLimits(): AttachmentLimits;
|
|
233
|
+
/**
|
|
234
|
+
* Stage a file for a later turn, held to the same limits as `POST <base>/attachments` — for a
|
|
235
|
+
* surface that receives files itself (a messaging webhook). Refuses with `501` when attachments are
|
|
236
|
+
* off, `415` for a type outside the allowlist and `413` past the size cap; send the returned
|
|
237
|
+
* `mediaId` as `attachments: [{ mediaId }]`.
|
|
238
|
+
*/
|
|
239
|
+
stageAttachment(actor: Actor, file: {
|
|
240
|
+
data: Buffer;
|
|
241
|
+
contentType: string;
|
|
242
|
+
filename: string;
|
|
243
|
+
}): Promise<MessageAttachment>;
|
|
197
244
|
/** The queue service when the bound store can hold a queue, else `undefined`. */
|
|
198
245
|
private queueing;
|
|
199
246
|
/** The queue service, or a 501 naming what is missing. */
|
|
@@ -539,7 +586,10 @@ declare class AgUiRunHandler {
|
|
|
539
586
|
protected readonly quietMs: number | undefined;
|
|
540
587
|
constructor(agent: AgentService, actorResolver: ActorResolver, options: AgentModuleOptions, staging: AttachmentStagingStore | undefined, quietMs: number | undefined);
|
|
541
588
|
handle(req: Request, res: Response, body: unknown): Promise<void>;
|
|
542
|
-
/**
|
|
589
|
+
/**
|
|
590
|
+
* The turn's attachments: the ones already staged (by mediaId), then its inline media staged
|
|
591
|
+
* through the bound store — all within the store's limits; say what was not used.
|
|
592
|
+
*/
|
|
543
593
|
private stage;
|
|
544
594
|
/**
|
|
545
595
|
* Deliver what a resume list decided, through the same calls the native decision routes make.
|
|
@@ -674,20 +724,6 @@ declare class AttachmentsController {
|
|
|
674
724
|
upload(req: Request, file: Express.Multer.File | undefined): Promise<MessageAttachment>;
|
|
675
725
|
}
|
|
676
726
|
|
|
677
|
-
/** Default per-file size cap (20 MiB). */
|
|
678
|
-
declare const DEFAULT_MAX_ATTACHMENT_BYTES: number;
|
|
679
|
-
/** Default allowlist: what multimodal model providers commonly accept as native image/file parts. */
|
|
680
|
-
declare const DEFAULT_ALLOWED_ATTACHMENT_CONTENT_TYPES: readonly string[];
|
|
681
|
-
/** How many attachments one message may name. */
|
|
682
|
-
declare const MAX_ATTACHMENTS_PER_MESSAGE = 10;
|
|
683
|
-
/** The attachment rules in force — `AgentAttachmentConfig`, as `GET <base>/config` serves it. */
|
|
684
|
-
type AttachmentLimits = AgentAttachmentConfig;
|
|
685
|
-
/**
|
|
686
|
-
* One source for attachment limits: the staging store's own `describe()` when it declares them
|
|
687
|
-
* (`AgentMediaAttachmentsModule` does), else `AgentModule`'s `attachments` option, else the defaults.
|
|
688
|
-
*/
|
|
689
|
-
declare function attachmentLimits(options: Pick<AgentModuleOptions, 'attachments'> | undefined, staging: AttachmentStagingStore | undefined): AttachmentLimits;
|
|
690
|
-
|
|
691
727
|
declare class ConfigController {
|
|
692
728
|
private readonly options;
|
|
693
729
|
private readonly actorResolver;
|
|
@@ -1462,15 +1498,26 @@ declare class ActionProposalController {
|
|
|
1462
1498
|
reject(threadId: string, proposalId: string, request: Request, body: unknown): Promise<_dudousxd_nestjs_agent_core.ActionProposalMutationView>;
|
|
1463
1499
|
}
|
|
1464
1500
|
|
|
1501
|
+
/** Called with a proposal the worker just settled (executed, or failed executing). */
|
|
1502
|
+
type ActionProposalSettledListener = (proposal: ActionProposal) => void | Promise<void>;
|
|
1465
1503
|
declare class ActionProposalWorkerService implements OnModuleInit, OnModuleDestroy {
|
|
1466
1504
|
private readonly store;
|
|
1467
1505
|
private readonly options;
|
|
1468
1506
|
private readonly deps;
|
|
1469
1507
|
private worker;
|
|
1470
1508
|
private readonly logger;
|
|
1509
|
+
private readonly settledListeners;
|
|
1510
|
+
/**
|
|
1511
|
+
* Run `listener` after every proposal this process's worker settles — how a module relays an
|
|
1512
|
+
* outcome somewhere the turn's stream no longer reaches (a text channel's conversation). Next to
|
|
1513
|
+
* `actionProposalWorker.onSettled`; a listener that throws is logged and does not stop the others.
|
|
1514
|
+
* Returns the unsubscribe. Only the replicas that run the worker (not `surface: 'http'`) call it.
|
|
1515
|
+
*/
|
|
1516
|
+
onSettled(listener: ActionProposalSettledListener): () => void;
|
|
1517
|
+
private settled;
|
|
1471
1518
|
constructor(store: AgentStore, options: AgentModuleOptions, deps: AgentDepsFactory);
|
|
1472
1519
|
onModuleInit(): void;
|
|
1473
1520
|
onModuleDestroy(): Promise<void>;
|
|
1474
1521
|
}
|
|
1475
1522
|
|
|
1476
|
-
export { AGENT_CHAT_QUEUE, AGENT_METADATA, AI_TOOL_METADATA, ATTACHMENT_PAGE_SIZE, ActionProposalController, ActionProposalService, ActionProposalWorkerService, type AgUiAdapterOptions, AgUiRunHandler, Agent, AgentApprovalPortAdapter, AgentDepsFactory, AgentDiscoveryService, AgentModule, AgentModuleAsyncOptions, AgentModuleOptions, type AgentOptions, AgentProtocolAdapter, AgentService, AgentSkillsOptions, AiTool, AiToolDiscoveryService, type AiToolOptions, type AnonymousActorOptions, AnonymousActorResolver, type AttachmentLimits, AttachmentsController, type ChatParams, ChatQueueService, type ChatSendMode, type ChatSendResult, ConfigController, DEFAULT_ALLOWED_ATTACHMENT_CONTENT_TYPES, DEFAULT_MAX_ATTACHMENT_BYTES, type DeclaredSkill, HeaderActorResolver, InProcessTokenStreamSink, InlineAgentRunner, MAX_ATTACHMENTS_PER_MESSAGE, MemoriesController, MessagesController, ModelsController, QueueController, type QueuedSend, type RequestUserMapper, type ResolvedAiToolOptions, RunNotActiveException, SKILL_METADATA, SYSTEM_PROMPT_CONTRIBUTOR_METADATA, SYSTEM_PROMPT_METADATA, Skill, type SkillBody, SkillDiscoveryService, type SkillOptions, SkillsController, SystemPrompt, SystemPromptContributor, type ThreadDefaultAgentReader, type ThreadModelReader, type ThreadPersonaReader, ToolsController, agUiAdapter, attachmentLimits, declaredSkillProvider, defaultRequestUserMapper, readAgentMetadata, readAiToolMetadata, readSkillMetadata, requestUserActorResolver, resolveSkillsConfig, skillScope, threadPersona, toolNameFromClass };
|
|
1523
|
+
export { AGENT_CHAT_QUEUE, AGENT_METADATA, AI_TOOL_METADATA, ATTACHMENT_PAGE_SIZE, ActionProposalController, ActionProposalService, type ActionProposalSettledListener, ActionProposalWorkerService, type AgUiAdapterOptions, AgUiRunHandler, Agent, AgentApprovalPortAdapter, AgentDepsFactory, AgentDiscoveryService, AgentModule, AgentModuleAsyncOptions, AgentModuleOptions, type AgentOptions, AgentProtocolAdapter, AgentService, AgentSkillsOptions, AiTool, AiToolDiscoveryService, type AiToolOptions, type AnonymousActorOptions, AnonymousActorResolver, type AttachmentLimits, AttachmentsController, type ChatParams, ChatQueueService, type ChatSendMode, type ChatSendResult, ConfigController, DEFAULT_ALLOWED_ATTACHMENT_CONTENT_TYPES, DEFAULT_MAX_ATTACHMENT_BYTES, type DeclaredSkill, HeaderActorResolver, InProcessTokenStreamSink, InlineAgentRunner, MAX_ATTACHMENTS_PER_MESSAGE, MemoriesController, MessagesController, ModelsController, QueueController, type QueuedSend, type RequestUserMapper, type ResolvedAiToolOptions, RunNotActiveException, SKILL_METADATA, SYSTEM_PROMPT_CONTRIBUTOR_METADATA, SYSTEM_PROMPT_METADATA, Skill, type SkillBody, SkillDiscoveryService, type SkillOptions, SkillsController, SystemPrompt, SystemPromptContributor, type ThreadDefaultAgentReader, type ThreadModelReader, type ThreadPersonaReader, ToolsController, agUiAdapter, attachmentLimits, declaredSkillProvider, defaultRequestUserMapper, readAgentMetadata, readAiToolMetadata, readSkillMetadata, requestUserActorResolver, resolveSkillsConfig, skillScope, threadPersona, toolNameFromClass };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { DynamicModule, Type, OnApplicationBootstrap, OnModuleInit, ConflictException, OnModuleDestroy } from '@nestjs/common';
|
|
2
|
-
import { b as AgentModuleOptions, c as AgentModuleAsyncOptions, A as AgentDepsFactory, C as ChatQueueService, d as AgentProtocolAdapter, e as AgentSkillsOptions } 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, A as AgentDepsFactory, C as ChatQueueService, d as AgentProtocolAdapter, e as AgentSkillsOptions } from './chat-queue.service-ZQkqb1Yw.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-ZQkqb1Yw.js';
|
|
4
4
|
import * as _dudousxd_nestjs_agent_core from '@dudousxd/nestjs-agent-core';
|
|
5
|
-
import { AgentStore, Actor, ListActionProposals, ActionProposalMutationView,
|
|
5
|
+
import { AgentAttachmentConfig, AttachmentStagingStore, AgentStore, Actor, ListActionProposals, ActionProposalMutationView, TextActionProposalVocabulary, AgentRunner, ModelCatalog, QuotaProvider, ActionApprovalMode, ActionProposalView, MessageAttachment, QuotaReport, ModelCatalogView, AgentHostContext, AttachmentRef, PageContext, ChatQueueState, HumanReply, ThreadSummary, ThreadDetail, UpdateThreadInput, MessageFeedbackValue, MessageFeedback, StagedAttachment, ActorResolver, AgentApprovalPort, AgentClientConfig, ToolSpec, ToolPresentation, AgentHistoryWindow, AgentIntake, Persona, SkillContext, ToolRegistry, AgentRegistry, PromptContributor, SkillsConfig, SkillCatalogEntry, ToolCatalogEntry, MemoryConfig, MemoryDigestEntry, SkillProvider, AgentRunInput, AgentRunStartOptions, TokenStreamSink, SinkWriter, 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 { Request, Response } from 'express';
|
|
@@ -16,6 +16,20 @@ declare class AgentModule {
|
|
|
16
16
|
static forRootAsync(options: AgentModuleAsyncOptions): DynamicModule;
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
+
/** Default per-file size cap (20 MiB). */
|
|
20
|
+
declare const DEFAULT_MAX_ATTACHMENT_BYTES: number;
|
|
21
|
+
/** Default allowlist: what multimodal model providers commonly accept as native image/file parts. */
|
|
22
|
+
declare const DEFAULT_ALLOWED_ATTACHMENT_CONTENT_TYPES: readonly string[];
|
|
23
|
+
/** How many attachments one message may name. */
|
|
24
|
+
declare const MAX_ATTACHMENTS_PER_MESSAGE = 10;
|
|
25
|
+
/** The attachment rules in force — `AgentAttachmentConfig`, as `GET <base>/config` serves it. */
|
|
26
|
+
type AttachmentLimits = AgentAttachmentConfig;
|
|
27
|
+
/**
|
|
28
|
+
* One source for attachment limits: the staging store's own `describe()` when it declares them
|
|
29
|
+
* (`AgentMediaAttachmentsModule` does), else `AgentModule`'s `attachments` option, else the defaults.
|
|
30
|
+
*/
|
|
31
|
+
declare function attachmentLimits(options: Pick<AgentModuleOptions, 'attachments'> | undefined, staging: AttachmentStagingStore | undefined): AttachmentLimits;
|
|
32
|
+
|
|
19
33
|
declare class ActionProposalService {
|
|
20
34
|
private readonly store;
|
|
21
35
|
private readonly options;
|
|
@@ -55,8 +69,10 @@ declare class ActionProposalService {
|
|
|
55
69
|
text: string;
|
|
56
70
|
}>;
|
|
57
71
|
private textReceipt;
|
|
72
|
+
/** The configured words a text decision is made of (`actionProposalText.vocabulary`). */
|
|
73
|
+
textVocabulary(): TextActionProposalVocabulary;
|
|
58
74
|
/** The configured reply to a decision the store answered with `result`. */
|
|
59
|
-
reply(result: ActionProposalMutationView, decision: 'approved' | 'rejected'): string;
|
|
75
|
+
reply(result: Pick<ActionProposalMutationView, 'status' | 'proposal'>, decision: 'approved' | 'rejected'): string;
|
|
60
76
|
}
|
|
61
77
|
|
|
62
78
|
/**
|
|
@@ -165,7 +181,7 @@ declare class AgentService {
|
|
|
165
181
|
private readonly options?;
|
|
166
182
|
private readonly queue?;
|
|
167
183
|
private readonly proposals?;
|
|
168
|
-
constructor(runner: AgentRunner, store: AgentStore, deps: AgentDepsFactory, staging?: AttachmentStagingStore | undefined, models?: ModelCatalog | undefined, quotaProvider?: QuotaProvider | undefined, options?: Pick<AgentModuleOptions, "quota" | "actionApprovalMode"> | undefined, queue?: ChatQueueService | undefined, proposals?: ActionProposalService | undefined);
|
|
184
|
+
constructor(runner: AgentRunner, store: AgentStore, deps: AgentDepsFactory, staging?: AttachmentStagingStore | undefined, models?: ModelCatalog | undefined, quotaProvider?: QuotaProvider | undefined, options?: Pick<AgentModuleOptions, "quota" | "actionApprovalMode" | "attachments"> | undefined, queue?: ChatQueueService | undefined, proposals?: ActionProposalService | undefined);
|
|
169
185
|
/**
|
|
170
186
|
* Decide one independent proposal through the scoped proposal service — what the native
|
|
171
187
|
* `action-proposals/:id/approve|reject` routes call — and the reply to show for it. `404` when
|
|
@@ -194,6 +210,37 @@ declare class AgentService {
|
|
|
194
210
|
};
|
|
195
211
|
text: string;
|
|
196
212
|
}>;
|
|
213
|
+
/** How `action` tools wait for their approval here — `AgentModule.forRoot({ actionApprovalMode })`. */
|
|
214
|
+
actionApprovalMode(): ActionApprovalMode;
|
|
215
|
+
/**
|
|
216
|
+
* The words a text decision is made of (`actionProposalText.vocabulary`, English by default) — what
|
|
217
|
+
* a surface without buttons tells the person to reply.
|
|
218
|
+
*/
|
|
219
|
+
actionProposalVocabulary(): TextActionProposalVocabulary;
|
|
220
|
+
/** The configured reply (`actionProposalText.replies`) to a decision the store answered with `result`. */
|
|
221
|
+
actionProposalReply(result: Pick<ActionProposalMutationView, 'status' | 'proposal'>, decision: 'approved' | 'rejected'): string;
|
|
222
|
+
/**
|
|
223
|
+
* The proposals of a thread this actor may see — the thread's own actor, or one the policy lets
|
|
224
|
+
* decide them; what `GET <base>/threads/:threadId/action-proposals` serves (its first page). `404`
|
|
225
|
+
* when independent approvals are not on.
|
|
226
|
+
*/
|
|
227
|
+
listActionProposals(actor: Actor, threadId: string): Promise<ActionProposalView[]>;
|
|
228
|
+
/**
|
|
229
|
+
* The attachment rules in force — what `GET <base>/config` serves and `POST <base>/attachments`
|
|
230
|
+
* enforces. `enabled: false` when no `AGENT_ATTACHMENT_STAGING` provider is bound.
|
|
231
|
+
*/
|
|
232
|
+
attachmentLimits(): AttachmentLimits;
|
|
233
|
+
/**
|
|
234
|
+
* Stage a file for a later turn, held to the same limits as `POST <base>/attachments` — for a
|
|
235
|
+
* surface that receives files itself (a messaging webhook). Refuses with `501` when attachments are
|
|
236
|
+
* off, `415` for a type outside the allowlist and `413` past the size cap; send the returned
|
|
237
|
+
* `mediaId` as `attachments: [{ mediaId }]`.
|
|
238
|
+
*/
|
|
239
|
+
stageAttachment(actor: Actor, file: {
|
|
240
|
+
data: Buffer;
|
|
241
|
+
contentType: string;
|
|
242
|
+
filename: string;
|
|
243
|
+
}): Promise<MessageAttachment>;
|
|
197
244
|
/** The queue service when the bound store can hold a queue, else `undefined`. */
|
|
198
245
|
private queueing;
|
|
199
246
|
/** The queue service, or a 501 naming what is missing. */
|
|
@@ -539,7 +586,10 @@ declare class AgUiRunHandler {
|
|
|
539
586
|
protected readonly quietMs: number | undefined;
|
|
540
587
|
constructor(agent: AgentService, actorResolver: ActorResolver, options: AgentModuleOptions, staging: AttachmentStagingStore | undefined, quietMs: number | undefined);
|
|
541
588
|
handle(req: Request, res: Response, body: unknown): Promise<void>;
|
|
542
|
-
/**
|
|
589
|
+
/**
|
|
590
|
+
* The turn's attachments: the ones already staged (by mediaId), then its inline media staged
|
|
591
|
+
* through the bound store — all within the store's limits; say what was not used.
|
|
592
|
+
*/
|
|
543
593
|
private stage;
|
|
544
594
|
/**
|
|
545
595
|
* Deliver what a resume list decided, through the same calls the native decision routes make.
|
|
@@ -674,20 +724,6 @@ declare class AttachmentsController {
|
|
|
674
724
|
upload(req: Request, file: Express.Multer.File | undefined): Promise<MessageAttachment>;
|
|
675
725
|
}
|
|
676
726
|
|
|
677
|
-
/** Default per-file size cap (20 MiB). */
|
|
678
|
-
declare const DEFAULT_MAX_ATTACHMENT_BYTES: number;
|
|
679
|
-
/** Default allowlist: what multimodal model providers commonly accept as native image/file parts. */
|
|
680
|
-
declare const DEFAULT_ALLOWED_ATTACHMENT_CONTENT_TYPES: readonly string[];
|
|
681
|
-
/** How many attachments one message may name. */
|
|
682
|
-
declare const MAX_ATTACHMENTS_PER_MESSAGE = 10;
|
|
683
|
-
/** The attachment rules in force — `AgentAttachmentConfig`, as `GET <base>/config` serves it. */
|
|
684
|
-
type AttachmentLimits = AgentAttachmentConfig;
|
|
685
|
-
/**
|
|
686
|
-
* One source for attachment limits: the staging store's own `describe()` when it declares them
|
|
687
|
-
* (`AgentMediaAttachmentsModule` does), else `AgentModule`'s `attachments` option, else the defaults.
|
|
688
|
-
*/
|
|
689
|
-
declare function attachmentLimits(options: Pick<AgentModuleOptions, 'attachments'> | undefined, staging: AttachmentStagingStore | undefined): AttachmentLimits;
|
|
690
|
-
|
|
691
727
|
declare class ConfigController {
|
|
692
728
|
private readonly options;
|
|
693
729
|
private readonly actorResolver;
|
|
@@ -1462,15 +1498,26 @@ declare class ActionProposalController {
|
|
|
1462
1498
|
reject(threadId: string, proposalId: string, request: Request, body: unknown): Promise<_dudousxd_nestjs_agent_core.ActionProposalMutationView>;
|
|
1463
1499
|
}
|
|
1464
1500
|
|
|
1501
|
+
/** Called with a proposal the worker just settled (executed, or failed executing). */
|
|
1502
|
+
type ActionProposalSettledListener = (proposal: ActionProposal) => void | Promise<void>;
|
|
1465
1503
|
declare class ActionProposalWorkerService implements OnModuleInit, OnModuleDestroy {
|
|
1466
1504
|
private readonly store;
|
|
1467
1505
|
private readonly options;
|
|
1468
1506
|
private readonly deps;
|
|
1469
1507
|
private worker;
|
|
1470
1508
|
private readonly logger;
|
|
1509
|
+
private readonly settledListeners;
|
|
1510
|
+
/**
|
|
1511
|
+
* Run `listener` after every proposal this process's worker settles — how a module relays an
|
|
1512
|
+
* outcome somewhere the turn's stream no longer reaches (a text channel's conversation). Next to
|
|
1513
|
+
* `actionProposalWorker.onSettled`; a listener that throws is logged and does not stop the others.
|
|
1514
|
+
* Returns the unsubscribe. Only the replicas that run the worker (not `surface: 'http'`) call it.
|
|
1515
|
+
*/
|
|
1516
|
+
onSettled(listener: ActionProposalSettledListener): () => void;
|
|
1517
|
+
private settled;
|
|
1471
1518
|
constructor(store: AgentStore, options: AgentModuleOptions, deps: AgentDepsFactory);
|
|
1472
1519
|
onModuleInit(): void;
|
|
1473
1520
|
onModuleDestroy(): Promise<void>;
|
|
1474
1521
|
}
|
|
1475
1522
|
|
|
1476
|
-
export { AGENT_CHAT_QUEUE, AGENT_METADATA, AI_TOOL_METADATA, ATTACHMENT_PAGE_SIZE, ActionProposalController, ActionProposalService, ActionProposalWorkerService, type AgUiAdapterOptions, AgUiRunHandler, Agent, AgentApprovalPortAdapter, AgentDepsFactory, AgentDiscoveryService, AgentModule, AgentModuleAsyncOptions, AgentModuleOptions, type AgentOptions, AgentProtocolAdapter, AgentService, AgentSkillsOptions, AiTool, AiToolDiscoveryService, type AiToolOptions, type AnonymousActorOptions, AnonymousActorResolver, type AttachmentLimits, AttachmentsController, type ChatParams, ChatQueueService, type ChatSendMode, type ChatSendResult, ConfigController, DEFAULT_ALLOWED_ATTACHMENT_CONTENT_TYPES, DEFAULT_MAX_ATTACHMENT_BYTES, type DeclaredSkill, HeaderActorResolver, InProcessTokenStreamSink, InlineAgentRunner, MAX_ATTACHMENTS_PER_MESSAGE, MemoriesController, MessagesController, ModelsController, QueueController, type QueuedSend, type RequestUserMapper, type ResolvedAiToolOptions, RunNotActiveException, SKILL_METADATA, SYSTEM_PROMPT_CONTRIBUTOR_METADATA, SYSTEM_PROMPT_METADATA, Skill, type SkillBody, SkillDiscoveryService, type SkillOptions, SkillsController, SystemPrompt, SystemPromptContributor, type ThreadDefaultAgentReader, type ThreadModelReader, type ThreadPersonaReader, ToolsController, agUiAdapter, attachmentLimits, declaredSkillProvider, defaultRequestUserMapper, readAgentMetadata, readAiToolMetadata, readSkillMetadata, requestUserActorResolver, resolveSkillsConfig, skillScope, threadPersona, toolNameFromClass };
|
|
1523
|
+
export { AGENT_CHAT_QUEUE, AGENT_METADATA, AI_TOOL_METADATA, ATTACHMENT_PAGE_SIZE, ActionProposalController, ActionProposalService, type ActionProposalSettledListener, ActionProposalWorkerService, type AgUiAdapterOptions, AgUiRunHandler, Agent, AgentApprovalPortAdapter, AgentDepsFactory, AgentDiscoveryService, AgentModule, AgentModuleAsyncOptions, AgentModuleOptions, type AgentOptions, AgentProtocolAdapter, AgentService, AgentSkillsOptions, AiTool, AiToolDiscoveryService, type AiToolOptions, type AnonymousActorOptions, AnonymousActorResolver, type AttachmentLimits, AttachmentsController, type ChatParams, ChatQueueService, type ChatSendMode, type ChatSendResult, ConfigController, DEFAULT_ALLOWED_ATTACHMENT_CONTENT_TYPES, DEFAULT_MAX_ATTACHMENT_BYTES, type DeclaredSkill, HeaderActorResolver, InProcessTokenStreamSink, InlineAgentRunner, MAX_ATTACHMENTS_PER_MESSAGE, MemoriesController, MessagesController, ModelsController, QueueController, type QueuedSend, type RequestUserMapper, type ResolvedAiToolOptions, RunNotActiveException, SKILL_METADATA, SYSTEM_PROMPT_CONTRIBUTOR_METADATA, SYSTEM_PROMPT_METADATA, Skill, type SkillBody, SkillDiscoveryService, type SkillOptions, SkillsController, SystemPrompt, SystemPromptContributor, type ThreadDefaultAgentReader, type ThreadModelReader, type ThreadPersonaReader, ToolsController, agUiAdapter, attachmentLimits, declaredSkillProvider, defaultRequestUserMapper, readAgentMetadata, readAiToolMetadata, readSkillMetadata, requestUserActorResolver, resolveSkillsConfig, skillScope, threadPersona, toolNameFromClass };
|
package/dist/index.js
CHANGED
|
@@ -565,8 +565,8 @@ AgentDepsFactory2 = _ts_decorate2([
|
|
|
565
565
|
], AgentDepsFactory2);
|
|
566
566
|
|
|
567
567
|
// src/agent.service.ts
|
|
568
|
-
import { AGENT_ATTACHMENT_STAGING as AGENT_ATTACHMENT_STAGING2, AGENT_DEPS_FACTORY as AGENT_DEPS_FACTORY2, AGENT_MODEL_CATALOG, AGENT_OPTIONS as AGENT_OPTIONS4, AGENT_QUOTA_PROVIDER as AGENT_QUOTA_PROVIDER2, AGENT_RUNNER, AGENT_STORE as AGENT_STORE4, REQUESTER_APPROVER, findCatalogModel, mayDecideApproval as mayDecideApproval2, readElicitationQuestions, settleDeadRun, validateElicitationAnswer } from "@dudousxd/nestjs-agent-core";
|
|
569
|
-
import { BadRequestException as BadRequestException2, ConflictException as ConflictException2, ForbiddenException as ForbiddenException2, GoneException, HttpException, HttpStatus, Inject as Inject5, Injectable as Injectable4, NotFoundException as NotFoundException2, NotImplementedException as NotImplementedException3, Optional as Optional3 } from "@nestjs/common";
|
|
568
|
+
import { AGENT_ATTACHMENT_STAGING as AGENT_ATTACHMENT_STAGING2, AGENT_DEPS_FACTORY as AGENT_DEPS_FACTORY2, AGENT_MODEL_CATALOG, AGENT_OPTIONS as AGENT_OPTIONS4, AGENT_QUOTA_PROVIDER as AGENT_QUOTA_PROVIDER2, AGENT_RUNNER, AGENT_STORE as AGENT_STORE4, DEFAULT_TEXT_ACTION_PROPOSAL_VOCABULARY as DEFAULT_TEXT_ACTION_PROPOSAL_VOCABULARY2, REQUESTER_APPROVER, findCatalogModel, mayDecideApproval as mayDecideApproval2, readElicitationQuestions, settleDeadRun, textActionProposalReply as textActionProposalReply2, validateElicitationAnswer } from "@dudousxd/nestjs-agent-core";
|
|
569
|
+
import { BadRequestException as BadRequestException2, ConflictException as ConflictException2, ForbiddenException as ForbiddenException2, GoneException, HttpException, HttpStatus, Inject as Inject5, Injectable as Injectable4, NotFoundException as NotFoundException2, NotImplementedException as NotImplementedException3, Optional as Optional3, PayloadTooLargeException, UnsupportedMediaTypeException } from "@nestjs/common";
|
|
570
570
|
|
|
571
571
|
// src/agent-deps.ts
|
|
572
572
|
function utcDay(date = /* @__PURE__ */ new Date()) {
|
|
@@ -590,6 +590,31 @@ function childSinkWriter(writer) {
|
|
|
590
590
|
}
|
|
591
591
|
__name(childSinkWriter, "childSinkWriter");
|
|
592
592
|
|
|
593
|
+
// src/attachment-limits.ts
|
|
594
|
+
var DEFAULT_MAX_ATTACHMENT_BYTES = 20 * 1024 * 1024;
|
|
595
|
+
var DEFAULT_ALLOWED_ATTACHMENT_CONTENT_TYPES = [
|
|
596
|
+
"image/png",
|
|
597
|
+
"image/jpeg",
|
|
598
|
+
"image/gif",
|
|
599
|
+
"image/webp",
|
|
600
|
+
"application/pdf",
|
|
601
|
+
"text/plain",
|
|
602
|
+
"text/csv"
|
|
603
|
+
];
|
|
604
|
+
var MAX_ATTACHMENTS_PER_MESSAGE = 10;
|
|
605
|
+
function attachmentLimits(options, staging) {
|
|
606
|
+
const declared = staging?.describe?.();
|
|
607
|
+
const own = options?.attachments;
|
|
608
|
+
return {
|
|
609
|
+
enabled: staging !== void 0,
|
|
610
|
+
upload: staging === void 0 ? null : declared?.upload ?? "multipart",
|
|
611
|
+
maxBytes: declared?.maxBytes ?? own?.maxBytes ?? DEFAULT_MAX_ATTACHMENT_BYTES,
|
|
612
|
+
allowedContentTypes: declared?.allowedContentTypes ?? own?.allowedContentTypes ?? DEFAULT_ALLOWED_ATTACHMENT_CONTENT_TYPES,
|
|
613
|
+
maxPerMessage: MAX_ATTACHMENTS_PER_MESSAGE
|
|
614
|
+
};
|
|
615
|
+
}
|
|
616
|
+
__name(attachmentLimits, "attachmentLimits");
|
|
617
|
+
|
|
593
618
|
// src/proposals/action-proposal.service.ts
|
|
594
619
|
import { AGENT_OPTIONS as AGENT_OPTIONS2, AGENT_STORE as AGENT_STORE2, DEFAULT_TEXT_ACTION_PROPOSAL_REPLIES, DEFAULT_TEXT_ACTION_PROPOSAL_VOCABULARY, mayDecideApproval, parseTextActionProposalCommand, resolveTextActionProposalDecision, textActionProposalReply, toActionProposalMutationView, toActionProposalView } from "@dudousxd/nestjs-agent-core";
|
|
595
620
|
import { ForbiddenException, Inject as Inject3, Injectable as Injectable2, NotFoundException, NotImplementedException } from "@nestjs/common";
|
|
@@ -746,6 +771,10 @@ var ActionProposalService = class {
|
|
|
746
771
|
text: this.reply(result, decision)
|
|
747
772
|
};
|
|
748
773
|
}
|
|
774
|
+
/** The configured words a text decision is made of (`actionProposalText.vocabulary`). */
|
|
775
|
+
textVocabulary() {
|
|
776
|
+
return this.vocabulary;
|
|
777
|
+
}
|
|
749
778
|
/** The configured reply to a decision the store answered with `result`. */
|
|
750
779
|
reply(result, decision) {
|
|
751
780
|
return textActionProposalReply(result, decision, this.replies);
|
|
@@ -1372,6 +1401,65 @@ var AgentService = class {
|
|
|
1372
1401
|
};
|
|
1373
1402
|
return this.proposals.handleTextDecision(threadId, actor, text);
|
|
1374
1403
|
}
|
|
1404
|
+
/** How `action` tools wait for their approval here — `AgentModule.forRoot({ actionApprovalMode })`. */
|
|
1405
|
+
actionApprovalMode() {
|
|
1406
|
+
return this.options?.actionApprovalMode ?? "blocking";
|
|
1407
|
+
}
|
|
1408
|
+
/**
|
|
1409
|
+
* The words a text decision is made of (`actionProposalText.vocabulary`, English by default) — what
|
|
1410
|
+
* a surface without buttons tells the person to reply.
|
|
1411
|
+
*/
|
|
1412
|
+
actionProposalVocabulary() {
|
|
1413
|
+
return this.proposals?.textVocabulary() ?? DEFAULT_TEXT_ACTION_PROPOSAL_VOCABULARY2;
|
|
1414
|
+
}
|
|
1415
|
+
/** The configured reply (`actionProposalText.replies`) to a decision the store answered with `result`. */
|
|
1416
|
+
actionProposalReply(result, decision) {
|
|
1417
|
+
return this.proposals?.reply(result, decision) ?? textActionProposalReply2(result, decision);
|
|
1418
|
+
}
|
|
1419
|
+
/**
|
|
1420
|
+
* The proposals of a thread this actor may see — the thread's own actor, or one the policy lets
|
|
1421
|
+
* decide them; what `GET <base>/threads/:threadId/action-proposals` serves (its first page). `404`
|
|
1422
|
+
* when independent approvals are not on.
|
|
1423
|
+
*/
|
|
1424
|
+
async listActionProposals(actor, threadId) {
|
|
1425
|
+
if (this.options?.actionApprovalMode !== "independent" || !this.proposals) {
|
|
1426
|
+
throw new NotFoundException2("Proposal not found");
|
|
1427
|
+
}
|
|
1428
|
+
return this.proposals.list(threadId, actor);
|
|
1429
|
+
}
|
|
1430
|
+
/**
|
|
1431
|
+
* The attachment rules in force — what `GET <base>/config` serves and `POST <base>/attachments`
|
|
1432
|
+
* enforces. `enabled: false` when no `AGENT_ATTACHMENT_STAGING` provider is bound.
|
|
1433
|
+
*/
|
|
1434
|
+
attachmentLimits() {
|
|
1435
|
+
return attachmentLimits(this.options, this.staging);
|
|
1436
|
+
}
|
|
1437
|
+
/**
|
|
1438
|
+
* Stage a file for a later turn, held to the same limits as `POST <base>/attachments` — for a
|
|
1439
|
+
* surface that receives files itself (a messaging webhook). Refuses with `501` when attachments are
|
|
1440
|
+
* off, `415` for a type outside the allowlist and `413` past the size cap; send the returned
|
|
1441
|
+
* `mediaId` as `attachments: [{ mediaId }]`.
|
|
1442
|
+
*/
|
|
1443
|
+
async stageAttachment(actor, file) {
|
|
1444
|
+
if (this.staging === void 0) {
|
|
1445
|
+
throw new NotImplementedException3("Attachments are not configured on this server: bind AGENT_ATTACHMENT_STAGING (e.g. import AgentMediaAttachmentsModule).");
|
|
1446
|
+
}
|
|
1447
|
+
const { allowedContentTypes, maxBytes } = this.attachmentLimits();
|
|
1448
|
+
const contentType = file.contentType.split(";")[0]?.trim().toLowerCase() ?? "";
|
|
1449
|
+
if (!allowedContentTypes.includes(contentType)) {
|
|
1450
|
+
throw new UnsupportedMediaTypeException(`content type "${contentType}" is not allowed (allowed: ${allowedContentTypes.join(", ")})`);
|
|
1451
|
+
}
|
|
1452
|
+
if (file.data.byteLength > maxBytes) {
|
|
1453
|
+
throw new PayloadTooLargeException(`file exceeds the ${maxBytes}-byte limit`);
|
|
1454
|
+
}
|
|
1455
|
+
return this.staging.stage({
|
|
1456
|
+
data: file.data,
|
|
1457
|
+
filename: file.filename,
|
|
1458
|
+
contentType,
|
|
1459
|
+
sizeBytes: file.data.byteLength,
|
|
1460
|
+
actor
|
|
1461
|
+
});
|
|
1462
|
+
}
|
|
1375
1463
|
/** The queue service when the bound store can hold a queue, else `undefined`. */
|
|
1376
1464
|
queueing() {
|
|
1377
1465
|
return this.queue?.supported === true ? this.queue : void 0;
|
|
@@ -2653,35 +2741,8 @@ AgentsController = _ts_decorate7([
|
|
|
2653
2741
|
|
|
2654
2742
|
// src/controller/attachments.controller.ts
|
|
2655
2743
|
import { AGENT_ACTOR_RESOLVER, AGENT_ATTACHMENT_STAGING as AGENT_ATTACHMENT_STAGING3, AGENT_OPTIONS as AGENT_OPTIONS5 } from "@dudousxd/nestjs-agent-core";
|
|
2656
|
-
import { BadRequestException as BadRequestException3, Controller as Controller2, Get as Get2, Inject as Inject7, NotImplementedException as NotImplementedException5, Optional as Optional5, PayloadTooLargeException, Post, Req, UnsupportedMediaTypeException, UploadedFile, UseInterceptors } from "@nestjs/common";
|
|
2744
|
+
import { BadRequestException as BadRequestException3, Controller as Controller2, Get as Get2, Inject as Inject7, NotImplementedException as NotImplementedException5, Optional as Optional5, PayloadTooLargeException as PayloadTooLargeException2, Post, Req, UnsupportedMediaTypeException as UnsupportedMediaTypeException2, UploadedFile, UseInterceptors } from "@nestjs/common";
|
|
2657
2745
|
import { FileInterceptor } from "@nestjs/platform-express";
|
|
2658
|
-
|
|
2659
|
-
// src/attachment-limits.ts
|
|
2660
|
-
var DEFAULT_MAX_ATTACHMENT_BYTES = 20 * 1024 * 1024;
|
|
2661
|
-
var DEFAULT_ALLOWED_ATTACHMENT_CONTENT_TYPES = [
|
|
2662
|
-
"image/png",
|
|
2663
|
-
"image/jpeg",
|
|
2664
|
-
"image/gif",
|
|
2665
|
-
"image/webp",
|
|
2666
|
-
"application/pdf",
|
|
2667
|
-
"text/plain",
|
|
2668
|
-
"text/csv"
|
|
2669
|
-
];
|
|
2670
|
-
var MAX_ATTACHMENTS_PER_MESSAGE = 10;
|
|
2671
|
-
function attachmentLimits(options, staging) {
|
|
2672
|
-
const declared = staging?.describe?.();
|
|
2673
|
-
const own = options?.attachments;
|
|
2674
|
-
return {
|
|
2675
|
-
enabled: staging !== void 0,
|
|
2676
|
-
upload: staging === void 0 ? null : declared?.upload ?? "multipart",
|
|
2677
|
-
maxBytes: declared?.maxBytes ?? own?.maxBytes ?? DEFAULT_MAX_ATTACHMENT_BYTES,
|
|
2678
|
-
allowedContentTypes: declared?.allowedContentTypes ?? own?.allowedContentTypes ?? DEFAULT_ALLOWED_ATTACHMENT_CONTENT_TYPES,
|
|
2679
|
-
maxPerMessage: MAX_ATTACHMENTS_PER_MESSAGE
|
|
2680
|
-
};
|
|
2681
|
-
}
|
|
2682
|
-
__name(attachmentLimits, "attachmentLimits");
|
|
2683
|
-
|
|
2684
|
-
// src/controller/attachments.controller.ts
|
|
2685
2746
|
function _ts_decorate8(decorators, target, key, desc) {
|
|
2686
2747
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
2687
2748
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
|
|
@@ -2748,10 +2809,10 @@ var AttachmentsController = class {
|
|
|
2748
2809
|
}
|
|
2749
2810
|
const { allowedContentTypes, maxBytes } = attachmentLimits(this.options, this.staging);
|
|
2750
2811
|
if (!allowedContentTypes.includes(file.mimetype)) {
|
|
2751
|
-
throw new
|
|
2812
|
+
throw new UnsupportedMediaTypeException2(`content type "${file.mimetype}" is not allowed (allowed: ${allowedContentTypes.join(", ")})`);
|
|
2752
2813
|
}
|
|
2753
2814
|
if (file.size > maxBytes) {
|
|
2754
|
-
throw new
|
|
2815
|
+
throw new PayloadTooLargeException2(`file exceeds the ${maxBytes}-byte limit`);
|
|
2755
2816
|
}
|
|
2756
2817
|
const actor = await this.actorResolver.resolve(req);
|
|
2757
2818
|
return this.staging.stage({
|
|
@@ -5084,6 +5145,34 @@ var ActionProposalWorkerService = class _ActionProposalWorkerService {
|
|
|
5084
5145
|
deps;
|
|
5085
5146
|
worker;
|
|
5086
5147
|
logger = new Logger5(_ActionProposalWorkerService.name);
|
|
5148
|
+
settledListeners = /* @__PURE__ */ new Set();
|
|
5149
|
+
/**
|
|
5150
|
+
* Run `listener` after every proposal this process's worker settles — how a module relays an
|
|
5151
|
+
* outcome somewhere the turn's stream no longer reaches (a text channel's conversation). Next to
|
|
5152
|
+
* `actionProposalWorker.onSettled`; a listener that throws is logged and does not stop the others.
|
|
5153
|
+
* Returns the unsubscribe. Only the replicas that run the worker (not `surface: 'http'`) call it.
|
|
5154
|
+
*/
|
|
5155
|
+
onSettled(listener) {
|
|
5156
|
+
this.settledListeners.add(listener);
|
|
5157
|
+
return () => {
|
|
5158
|
+
this.settledListeners.delete(listener);
|
|
5159
|
+
};
|
|
5160
|
+
}
|
|
5161
|
+
async settled(proposal) {
|
|
5162
|
+
const configured = this.options.actionProposalWorker?.onSettled;
|
|
5163
|
+
for (const listener of [
|
|
5164
|
+
...configured ? [
|
|
5165
|
+
configured
|
|
5166
|
+
] : [],
|
|
5167
|
+
...this.settledListeners
|
|
5168
|
+
]) {
|
|
5169
|
+
try {
|
|
5170
|
+
await listener(proposal);
|
|
5171
|
+
} catch (error) {
|
|
5172
|
+
this.logger.error(error);
|
|
5173
|
+
}
|
|
5174
|
+
}
|
|
5175
|
+
}
|
|
5087
5176
|
constructor(store, options, deps) {
|
|
5088
5177
|
this.store = store;
|
|
5089
5178
|
this.options = options;
|
|
@@ -5099,6 +5188,7 @@ var ActionProposalWorkerService = class _ActionProposalWorkerService {
|
|
|
5099
5188
|
store: this.store,
|
|
5100
5189
|
workerId: randomUUID(),
|
|
5101
5190
|
...this.options.actionProposalWorker,
|
|
5191
|
+
onSettled: /* @__PURE__ */ __name((proposal) => this.settled(proposal), "onSettled"),
|
|
5102
5192
|
executor: new ActionProposalExecutor({
|
|
5103
5193
|
resolver,
|
|
5104
5194
|
resolveExecution: /* @__PURE__ */ __name(async (proposal, actor) => {
|
|
@@ -6369,7 +6459,10 @@ var AgUiRunHandler = class {
|
|
|
6369
6459
|
if (owner !== null && owner !== actor.id) {
|
|
6370
6460
|
throw new ForbiddenException4("thread belongs to another actor");
|
|
6371
6461
|
}
|
|
6372
|
-
if (
|
|
6462
|
+
if (forwarded.regenerate === true && owner === null) {
|
|
6463
|
+
throw invalid("invalid_input", "regenerate needs a thread that already has an exchange");
|
|
6464
|
+
}
|
|
6465
|
+
if (owner !== null && forwarded.regenerate !== true && turn.media.length === 0 && turn.staged.length === 0) {
|
|
6373
6466
|
const decision = await this.agent.handleTextDecision(input.threadId, actor, turn.text);
|
|
6374
6467
|
if ("proposalDecision" in decision) {
|
|
6375
6468
|
this.writeEvents(res, [
|
|
@@ -6384,7 +6477,7 @@ var AgUiRunHandler = class {
|
|
|
6384
6477
|
return;
|
|
6385
6478
|
}
|
|
6386
6479
|
}
|
|
6387
|
-
const refs = await this.stage(actor, turn.media, warnings);
|
|
6480
|
+
const refs = await this.stage(actor, turn.media, warnings, turn.staged);
|
|
6388
6481
|
if (turn.text.trim().length === 0 && refs.length === 0) {
|
|
6389
6482
|
throw invalid("no_user_message", "the user message to answer is empty");
|
|
6390
6483
|
}
|
|
@@ -6420,6 +6513,9 @@ var AgUiRunHandler = class {
|
|
|
6420
6513
|
} : {},
|
|
6421
6514
|
...refs.length > 0 ? {
|
|
6422
6515
|
attachments: refs
|
|
6516
|
+
} : {},
|
|
6517
|
+
...forwarded.regenerate === true ? {
|
|
6518
|
+
regenerate: true
|
|
6423
6519
|
} : {}
|
|
6424
6520
|
});
|
|
6425
6521
|
await this.pipe(res, started.runId, {
|
|
@@ -6431,10 +6527,25 @@ var AgUiRunHandler = class {
|
|
|
6431
6527
|
preamble: warningEvents(warnings)
|
|
6432
6528
|
});
|
|
6433
6529
|
}
|
|
6434
|
-
/**
|
|
6435
|
-
|
|
6530
|
+
/**
|
|
6531
|
+
* The turn's attachments: the ones already staged (by mediaId), then its inline media staged
|
|
6532
|
+
* through the bound store — all within the store's limits; say what was not used.
|
|
6533
|
+
*/
|
|
6534
|
+
async stage(actor, media, warnings, staged = []) {
|
|
6436
6535
|
const refs = [];
|
|
6437
6536
|
const limits = attachmentLimits(this.options, this.staging);
|
|
6537
|
+
for (const ref of staged) {
|
|
6538
|
+
const label = `The attachment ${ref.mediaId} was not used`;
|
|
6539
|
+
if (this.staging === void 0) {
|
|
6540
|
+
warnings.push(`${label}: attachments are not enabled on this agent.`);
|
|
6541
|
+
} else if (refs.length >= limits.maxPerMessage) {
|
|
6542
|
+
warnings.push(`${label}: a message carries at most ${limits.maxPerMessage} attachments.`);
|
|
6543
|
+
} else {
|
|
6544
|
+
refs.push({
|
|
6545
|
+
mediaId: ref.mediaId
|
|
6546
|
+
});
|
|
6547
|
+
}
|
|
6548
|
+
}
|
|
6438
6549
|
for (const item of media) {
|
|
6439
6550
|
const label = `The ${item.kind} "${item.filename}" was not used`;
|
|
6440
6551
|
if (this.staging === void 0) {
|
|
@@ -6447,7 +6558,7 @@ var AgUiRunHandler = class {
|
|
|
6447
6558
|
warnings.push(`${label}: it is larger than ${limits.maxBytes} bytes.`);
|
|
6448
6559
|
} else {
|
|
6449
6560
|
try {
|
|
6450
|
-
const
|
|
6561
|
+
const staged2 = await this.staging.stage({
|
|
6451
6562
|
data: item.data,
|
|
6452
6563
|
filename: item.filename,
|
|
6453
6564
|
contentType: item.contentType,
|
|
@@ -6455,7 +6566,7 @@ var AgUiRunHandler = class {
|
|
|
6455
6566
|
actor
|
|
6456
6567
|
});
|
|
6457
6568
|
refs.push({
|
|
6458
|
-
mediaId:
|
|
6569
|
+
mediaId: staged2.mediaId
|
|
6459
6570
|
});
|
|
6460
6571
|
} catch {
|
|
6461
6572
|
warnings.push(`${label}: it could not be stored.`);
|
|
@@ -6573,11 +6684,17 @@ var AgUiRunHandler = class {
|
|
|
6573
6684
|
res.setHeader("X-Agent-Run-Id", runId);
|
|
6574
6685
|
res.flushHeaders();
|
|
6575
6686
|
let terminal = false;
|
|
6687
|
+
const cursor = {
|
|
6688
|
+
seq: 0
|
|
6689
|
+
};
|
|
6576
6690
|
try {
|
|
6577
6691
|
const frames = agUiFramesFromNdjson(this.agent.subscribe(runId));
|
|
6578
|
-
for await (const event of agUiEvents(frames,
|
|
6692
|
+
for await (const event of agUiEvents(frames, {
|
|
6693
|
+
...options,
|
|
6694
|
+
cursor
|
|
6695
|
+
})) {
|
|
6579
6696
|
if (event.type === "RUN_FINISHED" || event.type === "RUN_ERROR") terminal = true;
|
|
6580
|
-
res.write(agUiSse(event));
|
|
6697
|
+
res.write(agUiSse(event, cursor.seq));
|
|
6581
6698
|
}
|
|
6582
6699
|
} catch {
|
|
6583
6700
|
if (!terminal) {
|