@dudousxd/nestjs-agent 1.23.1 → 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 +117 -27
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +64 -20
- package/dist/index.d.ts +64 -20
- package/dist/index.js +122 -32
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ResolveToolUiCatalog, ModelProvider, AgentStore, ToolRegistry, RolesPolicy, ApprovalPolicy, QuotaStore, TokenStreamSink, PromptBuilder, PromptContributor, Persona, ToolTransientRetrySetting, Retriever, AgentPricingStore, HistoryPolicy, InputProcessor, OutputProcessor, AgentIntake, SkillsConfig, MemoryConfig, ToolSpec, ToolHandler, createFunctionalTool, QuotaProvider, QuotaQuery, QuotaReport, ActionApprovalMode, BackgroundActorResolver, TextActionProposalConfig, ModelCatalog, EmptyRoles, ActorResolver, AgentHistoryWindow, SkillProvider, ScopeResolver, MemoryProvider, AgentRegistry, PersonaCatalogEntry,
|
|
1
|
+
import { ResolveToolUiCatalog, ModelProvider, AgentStore, ToolRegistry, RolesPolicy, ApprovalPolicy, QuotaStore, TokenStreamSink, PromptBuilder, PromptContributor, Persona, ToolTransientRetrySetting, Retriever, AgentPricingStore, HistoryPolicy, InputProcessor, OutputProcessor, AgentIntake, SkillsConfig, MemoryConfig, ToolSpec, ToolHandler, createFunctionalTool, QuotaProvider, QuotaQuery, QuotaReport, ActionApprovalMode, BackgroundActorResolver, ActionProposal, TextActionProposalConfig, ModelCatalog, EmptyRoles, ActorResolver, AgentHistoryWindow, SkillProvider, ScopeResolver, MemoryProvider, AgentRegistry, PersonaCatalogEntry, Actor, AttachmentStagingStore, ChatQueueStore, ChatQueueState, AgentRunner, AgentRunInput, AgentStreamEvent, QueuePauseReason } from '@dudousxd/nestjs-agent-core';
|
|
2
2
|
import { Catalog } from '@dudousxd/nestjs-agent-core/genui';
|
|
3
3
|
import { StandardSchemaV1 } from '@standard-schema/spec';
|
|
4
4
|
import { Provider, InjectionToken, Type, FactoryProvider, CanActivate, ModuleMetadata, OptionalFactoryDependency } from '@nestjs/common';
|
|
@@ -296,12 +296,16 @@ interface AgentModuleOptions {
|
|
|
296
296
|
* (started with the module unless `surface: 'http'`). `pollIntervalMs` — how often it looks for
|
|
297
297
|
* queued work, default 1000; `leaseMs` — how long a claim holds before another worker may recover
|
|
298
298
|
* it, default 30000; `maxConcurrency` — proposals claimed per poll, default 1. All positive
|
|
299
|
-
* integers, and `pollIntervalMs` must stay below a third of `leaseMs`.
|
|
299
|
+
* integers, and `pollIntervalMs` must stay below a third of `leaseMs`. `onSettled` runs after each
|
|
300
|
+
* proposal the worker settles (executed or failed), with the stored proposal — its `outcome` and
|
|
301
|
+
* `executionContext.pageContext` included; a module can subscribe the same way through
|
|
302
|
+
* `ActionProposalWorkerService.onSettled`.
|
|
300
303
|
*/
|
|
301
304
|
actionProposalWorker?: {
|
|
302
305
|
pollIntervalMs?: number;
|
|
303
306
|
leaseMs?: number;
|
|
304
307
|
maxConcurrency?: number;
|
|
308
|
+
onSettled?(proposal: ActionProposal): void | Promise<void>;
|
|
305
309
|
};
|
|
306
310
|
/**
|
|
307
311
|
* The words a chat message must consist of to approve or reject a proposal by text, and what the
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ResolveToolUiCatalog, ModelProvider, AgentStore, ToolRegistry, RolesPolicy, ApprovalPolicy, QuotaStore, TokenStreamSink, PromptBuilder, PromptContributor, Persona, ToolTransientRetrySetting, Retriever, AgentPricingStore, HistoryPolicy, InputProcessor, OutputProcessor, AgentIntake, SkillsConfig, MemoryConfig, ToolSpec, ToolHandler, createFunctionalTool, QuotaProvider, QuotaQuery, QuotaReport, ActionApprovalMode, BackgroundActorResolver, TextActionProposalConfig, ModelCatalog, EmptyRoles, ActorResolver, AgentHistoryWindow, SkillProvider, ScopeResolver, MemoryProvider, AgentRegistry, PersonaCatalogEntry,
|
|
1
|
+
import { ResolveToolUiCatalog, ModelProvider, AgentStore, ToolRegistry, RolesPolicy, ApprovalPolicy, QuotaStore, TokenStreamSink, PromptBuilder, PromptContributor, Persona, ToolTransientRetrySetting, Retriever, AgentPricingStore, HistoryPolicy, InputProcessor, OutputProcessor, AgentIntake, SkillsConfig, MemoryConfig, ToolSpec, ToolHandler, createFunctionalTool, QuotaProvider, QuotaQuery, QuotaReport, ActionApprovalMode, BackgroundActorResolver, ActionProposal, TextActionProposalConfig, ModelCatalog, EmptyRoles, ActorResolver, AgentHistoryWindow, SkillProvider, ScopeResolver, MemoryProvider, AgentRegistry, PersonaCatalogEntry, Actor, AttachmentStagingStore, ChatQueueStore, ChatQueueState, AgentRunner, AgentRunInput, AgentStreamEvent, QueuePauseReason } from '@dudousxd/nestjs-agent-core';
|
|
2
2
|
import { Catalog } from '@dudousxd/nestjs-agent-core/genui';
|
|
3
3
|
import { StandardSchemaV1 } from '@standard-schema/spec';
|
|
4
4
|
import { Provider, InjectionToken, Type, FactoryProvider, CanActivate, ModuleMetadata, OptionalFactoryDependency } from '@nestjs/common';
|
|
@@ -296,12 +296,16 @@ interface AgentModuleOptions {
|
|
|
296
296
|
* (started with the module unless `surface: 'http'`). `pollIntervalMs` — how often it looks for
|
|
297
297
|
* queued work, default 1000; `leaseMs` — how long a claim holds before another worker may recover
|
|
298
298
|
* it, default 30000; `maxConcurrency` — proposals claimed per poll, default 1. All positive
|
|
299
|
-
* integers, and `pollIntervalMs` must stay below a third of `leaseMs`.
|
|
299
|
+
* integers, and `pollIntervalMs` must stay below a third of `leaseMs`. `onSettled` runs after each
|
|
300
|
+
* proposal the worker settles (executed or failed), with the stored proposal — its `outcome` and
|
|
301
|
+
* `executionContext.pageContext` included; a module can subscribe the same way through
|
|
302
|
+
* `ActionProposalWorkerService.onSettled`.
|
|
300
303
|
*/
|
|
301
304
|
actionProposalWorker?: {
|
|
302
305
|
pollIntervalMs?: number;
|
|
303
306
|
leaseMs?: number;
|
|
304
307
|
maxConcurrency?: number;
|
|
308
|
+
onSettled?(proposal: ActionProposal): void | Promise<void>;
|
|
305
309
|
};
|
|
306
310
|
/**
|
|
307
311
|
* The words a chat message must consist of to approve or reject a proposal by text, and what the
|
package/dist/durable/index.cjs
CHANGED
|
@@ -1749,6 +1749,31 @@ AgentDepsFactory2 = _ts_decorate6([
|
|
|
1749
1749
|
var import_nestjs_agent_core16 = require("@dudousxd/nestjs-agent-core");
|
|
1750
1750
|
var import_common10 = require("@nestjs/common");
|
|
1751
1751
|
|
|
1752
|
+
// src/attachment-limits.ts
|
|
1753
|
+
var DEFAULT_MAX_ATTACHMENT_BYTES = 20 * 1024 * 1024;
|
|
1754
|
+
var DEFAULT_ALLOWED_ATTACHMENT_CONTENT_TYPES = [
|
|
1755
|
+
"image/png",
|
|
1756
|
+
"image/jpeg",
|
|
1757
|
+
"image/gif",
|
|
1758
|
+
"image/webp",
|
|
1759
|
+
"application/pdf",
|
|
1760
|
+
"text/plain",
|
|
1761
|
+
"text/csv"
|
|
1762
|
+
];
|
|
1763
|
+
var MAX_ATTACHMENTS_PER_MESSAGE = 10;
|
|
1764
|
+
function attachmentLimits(options, staging) {
|
|
1765
|
+
const declared = staging?.describe?.();
|
|
1766
|
+
const own = options?.attachments;
|
|
1767
|
+
return {
|
|
1768
|
+
enabled: staging !== void 0,
|
|
1769
|
+
upload: staging === void 0 ? null : declared?.upload ?? "multipart",
|
|
1770
|
+
maxBytes: declared?.maxBytes ?? own?.maxBytes ?? DEFAULT_MAX_ATTACHMENT_BYTES,
|
|
1771
|
+
allowedContentTypes: declared?.allowedContentTypes ?? own?.allowedContentTypes ?? DEFAULT_ALLOWED_ATTACHMENT_CONTENT_TYPES,
|
|
1772
|
+
maxPerMessage: MAX_ATTACHMENTS_PER_MESSAGE
|
|
1773
|
+
};
|
|
1774
|
+
}
|
|
1775
|
+
__name(attachmentLimits, "attachmentLimits");
|
|
1776
|
+
|
|
1752
1777
|
// src/proposals/action-proposal.service.ts
|
|
1753
1778
|
var import_nestjs_agent_core12 = require("@dudousxd/nestjs-agent-core");
|
|
1754
1779
|
var import_common7 = require("@nestjs/common");
|
|
@@ -1905,6 +1930,10 @@ var ActionProposalService = class {
|
|
|
1905
1930
|
text: this.reply(result, decision)
|
|
1906
1931
|
};
|
|
1907
1932
|
}
|
|
1933
|
+
/** The configured words a text decision is made of (`actionProposalText.vocabulary`). */
|
|
1934
|
+
textVocabulary() {
|
|
1935
|
+
return this.vocabulary;
|
|
1936
|
+
}
|
|
1908
1937
|
/** The configured reply to a decision the store answered with `result`. */
|
|
1909
1938
|
reply(result, decision) {
|
|
1910
1939
|
return (0, import_nestjs_agent_core12.textActionProposalReply)(result, decision, this.replies);
|
|
@@ -2531,6 +2560,65 @@ var AgentService = class {
|
|
|
2531
2560
|
};
|
|
2532
2561
|
return this.proposals.handleTextDecision(threadId, actor, text);
|
|
2533
2562
|
}
|
|
2563
|
+
/** How `action` tools wait for their approval here — `AgentModule.forRoot({ actionApprovalMode })`. */
|
|
2564
|
+
actionApprovalMode() {
|
|
2565
|
+
return this.options?.actionApprovalMode ?? "blocking";
|
|
2566
|
+
}
|
|
2567
|
+
/**
|
|
2568
|
+
* The words a text decision is made of (`actionProposalText.vocabulary`, English by default) — what
|
|
2569
|
+
* a surface without buttons tells the person to reply.
|
|
2570
|
+
*/
|
|
2571
|
+
actionProposalVocabulary() {
|
|
2572
|
+
return this.proposals?.textVocabulary() ?? import_nestjs_agent_core16.DEFAULT_TEXT_ACTION_PROPOSAL_VOCABULARY;
|
|
2573
|
+
}
|
|
2574
|
+
/** The configured reply (`actionProposalText.replies`) to a decision the store answered with `result`. */
|
|
2575
|
+
actionProposalReply(result, decision) {
|
|
2576
|
+
return this.proposals?.reply(result, decision) ?? (0, import_nestjs_agent_core16.textActionProposalReply)(result, decision);
|
|
2577
|
+
}
|
|
2578
|
+
/**
|
|
2579
|
+
* The proposals of a thread this actor may see — the thread's own actor, or one the policy lets
|
|
2580
|
+
* decide them; what `GET <base>/threads/:threadId/action-proposals` serves (its first page). `404`
|
|
2581
|
+
* when independent approvals are not on.
|
|
2582
|
+
*/
|
|
2583
|
+
async listActionProposals(actor, threadId) {
|
|
2584
|
+
if (this.options?.actionApprovalMode !== "independent" || !this.proposals) {
|
|
2585
|
+
throw new import_common10.NotFoundException("Proposal not found");
|
|
2586
|
+
}
|
|
2587
|
+
return this.proposals.list(threadId, actor);
|
|
2588
|
+
}
|
|
2589
|
+
/**
|
|
2590
|
+
* The attachment rules in force — what `GET <base>/config` serves and `POST <base>/attachments`
|
|
2591
|
+
* enforces. `enabled: false` when no `AGENT_ATTACHMENT_STAGING` provider is bound.
|
|
2592
|
+
*/
|
|
2593
|
+
attachmentLimits() {
|
|
2594
|
+
return attachmentLimits(this.options, this.staging);
|
|
2595
|
+
}
|
|
2596
|
+
/**
|
|
2597
|
+
* Stage a file for a later turn, held to the same limits as `POST <base>/attachments` — for a
|
|
2598
|
+
* surface that receives files itself (a messaging webhook). Refuses with `501` when attachments are
|
|
2599
|
+
* off, `415` for a type outside the allowlist and `413` past the size cap; send the returned
|
|
2600
|
+
* `mediaId` as `attachments: [{ mediaId }]`.
|
|
2601
|
+
*/
|
|
2602
|
+
async stageAttachment(actor, file) {
|
|
2603
|
+
if (this.staging === void 0) {
|
|
2604
|
+
throw new import_common10.NotImplementedException("Attachments are not configured on this server: bind AGENT_ATTACHMENT_STAGING (e.g. import AgentMediaAttachmentsModule).");
|
|
2605
|
+
}
|
|
2606
|
+
const { allowedContentTypes, maxBytes } = this.attachmentLimits();
|
|
2607
|
+
const contentType = file.contentType.split(";")[0]?.trim().toLowerCase() ?? "";
|
|
2608
|
+
if (!allowedContentTypes.includes(contentType)) {
|
|
2609
|
+
throw new import_common10.UnsupportedMediaTypeException(`content type "${contentType}" is not allowed (allowed: ${allowedContentTypes.join(", ")})`);
|
|
2610
|
+
}
|
|
2611
|
+
if (file.data.byteLength > maxBytes) {
|
|
2612
|
+
throw new import_common10.PayloadTooLargeException(`file exceeds the ${maxBytes}-byte limit`);
|
|
2613
|
+
}
|
|
2614
|
+
return this.staging.stage({
|
|
2615
|
+
data: file.data,
|
|
2616
|
+
filename: file.filename,
|
|
2617
|
+
contentType,
|
|
2618
|
+
sizeBytes: file.data.byteLength,
|
|
2619
|
+
actor
|
|
2620
|
+
});
|
|
2621
|
+
}
|
|
2534
2622
|
/** The queue service when the bound store can hold a queue, else `undefined`. */
|
|
2535
2623
|
queueing() {
|
|
2536
2624
|
return this.queue?.supported === true ? this.queue : void 0;
|
|
@@ -3814,33 +3902,6 @@ AgentsController = _ts_decorate11([
|
|
|
3814
3902
|
var import_nestjs_agent_core18 = require("@dudousxd/nestjs-agent-core");
|
|
3815
3903
|
var import_common13 = require("@nestjs/common");
|
|
3816
3904
|
var import_platform_express = require("@nestjs/platform-express");
|
|
3817
|
-
|
|
3818
|
-
// src/attachment-limits.ts
|
|
3819
|
-
var DEFAULT_MAX_ATTACHMENT_BYTES = 20 * 1024 * 1024;
|
|
3820
|
-
var DEFAULT_ALLOWED_ATTACHMENT_CONTENT_TYPES = [
|
|
3821
|
-
"image/png",
|
|
3822
|
-
"image/jpeg",
|
|
3823
|
-
"image/gif",
|
|
3824
|
-
"image/webp",
|
|
3825
|
-
"application/pdf",
|
|
3826
|
-
"text/plain",
|
|
3827
|
-
"text/csv"
|
|
3828
|
-
];
|
|
3829
|
-
var MAX_ATTACHMENTS_PER_MESSAGE = 10;
|
|
3830
|
-
function attachmentLimits(options, staging) {
|
|
3831
|
-
const declared = staging?.describe?.();
|
|
3832
|
-
const own = options?.attachments;
|
|
3833
|
-
return {
|
|
3834
|
-
enabled: staging !== void 0,
|
|
3835
|
-
upload: staging === void 0 ? null : declared?.upload ?? "multipart",
|
|
3836
|
-
maxBytes: declared?.maxBytes ?? own?.maxBytes ?? DEFAULT_MAX_ATTACHMENT_BYTES,
|
|
3837
|
-
allowedContentTypes: declared?.allowedContentTypes ?? own?.allowedContentTypes ?? DEFAULT_ALLOWED_ATTACHMENT_CONTENT_TYPES,
|
|
3838
|
-
maxPerMessage: MAX_ATTACHMENTS_PER_MESSAGE
|
|
3839
|
-
};
|
|
3840
|
-
}
|
|
3841
|
-
__name(attachmentLimits, "attachmentLimits");
|
|
3842
|
-
|
|
3843
|
-
// src/controller/attachments.controller.ts
|
|
3844
3905
|
function _ts_decorate12(decorators, target, key, desc) {
|
|
3845
3906
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3846
3907
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
|
|
@@ -6131,6 +6192,34 @@ var ActionProposalWorkerService = class _ActionProposalWorkerService {
|
|
|
6131
6192
|
deps;
|
|
6132
6193
|
worker;
|
|
6133
6194
|
logger = new import_common28.Logger(_ActionProposalWorkerService.name);
|
|
6195
|
+
settledListeners = /* @__PURE__ */ new Set();
|
|
6196
|
+
/**
|
|
6197
|
+
* Run `listener` after every proposal this process's worker settles — how a module relays an
|
|
6198
|
+
* outcome somewhere the turn's stream no longer reaches (a text channel's conversation). Next to
|
|
6199
|
+
* `actionProposalWorker.onSettled`; a listener that throws is logged and does not stop the others.
|
|
6200
|
+
* Returns the unsubscribe. Only the replicas that run the worker (not `surface: 'http'`) call it.
|
|
6201
|
+
*/
|
|
6202
|
+
onSettled(listener) {
|
|
6203
|
+
this.settledListeners.add(listener);
|
|
6204
|
+
return () => {
|
|
6205
|
+
this.settledListeners.delete(listener);
|
|
6206
|
+
};
|
|
6207
|
+
}
|
|
6208
|
+
async settled(proposal) {
|
|
6209
|
+
const configured = this.options.actionProposalWorker?.onSettled;
|
|
6210
|
+
for (const listener of [
|
|
6211
|
+
...configured ? [
|
|
6212
|
+
configured
|
|
6213
|
+
] : [],
|
|
6214
|
+
...this.settledListeners
|
|
6215
|
+
]) {
|
|
6216
|
+
try {
|
|
6217
|
+
await listener(proposal);
|
|
6218
|
+
} catch (error) {
|
|
6219
|
+
this.logger.error(error);
|
|
6220
|
+
}
|
|
6221
|
+
}
|
|
6222
|
+
}
|
|
6134
6223
|
constructor(store, options, deps) {
|
|
6135
6224
|
this.store = store;
|
|
6136
6225
|
this.options = options;
|
|
@@ -6146,6 +6235,7 @@ var ActionProposalWorkerService = class _ActionProposalWorkerService {
|
|
|
6146
6235
|
store: this.store,
|
|
6147
6236
|
workerId: (0, import_node_crypto3.randomUUID)(),
|
|
6148
6237
|
...this.options.actionProposalWorker,
|
|
6238
|
+
onSettled: /* @__PURE__ */ __name((proposal) => this.settled(proposal), "onSettled"),
|
|
6149
6239
|
executor: new import_nestjs_agent_core35.ActionProposalExecutor({
|
|
6150
6240
|
resolver,
|
|
6151
6241
|
resolveExecution: /* @__PURE__ */ __name(async (proposal, actor) => {
|