@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/durable/index.d.cts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { AgentStore, AgentRunInput, AgentLoopResult, LlmStepEnvelope, BufferedModelTurnResult, ToolStepEnvelope, AgentRunner, TokenStreamSink, AgentRunStartOptions, HumanReply } from '@dudousxd/nestjs-agent-core';
|
|
2
2
|
import { WorkflowService } from '@dudousxd/nestjs-durable';
|
|
3
3
|
import { RunGateway, WorkflowCtx } from '@dudousxd/nestjs-durable-core';
|
|
4
|
-
import { A as AgentDepsFactory, C as ChatQueueService, a as AgentSurface, b as AgentModuleOptions } from '../chat-queue.service-
|
|
4
|
+
import { A as AgentDepsFactory, C as ChatQueueService, a as AgentSurface, b as AgentModuleOptions } from '../chat-queue.service-Crf9uwum.cjs';
|
|
5
5
|
import { DynamicModule } from '@nestjs/common';
|
|
6
6
|
import '@dudousxd/nestjs-agent-core/genui';
|
|
7
7
|
import '@standard-schema/spec';
|
package/dist/durable/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { AgentStore, AgentRunInput, AgentLoopResult, LlmStepEnvelope, BufferedModelTurnResult, ToolStepEnvelope, AgentRunner, TokenStreamSink, AgentRunStartOptions, HumanReply } from '@dudousxd/nestjs-agent-core';
|
|
2
2
|
import { WorkflowService } from '@dudousxd/nestjs-durable';
|
|
3
3
|
import { RunGateway, WorkflowCtx } from '@dudousxd/nestjs-durable-core';
|
|
4
|
-
import { A as AgentDepsFactory, C as ChatQueueService, a as AgentSurface, b as AgentModuleOptions } from '../chat-queue.service-
|
|
4
|
+
import { A as AgentDepsFactory, C as ChatQueueService, a as AgentSurface, b as AgentModuleOptions } from '../chat-queue.service-ZQkqb1Yw.js';
|
|
5
5
|
import { DynamicModule } from '@nestjs/common';
|
|
6
6
|
import '@dudousxd/nestjs-agent-core/genui';
|
|
7
7
|
import '@standard-schema/spec';
|
package/dist/durable/index.js
CHANGED
|
@@ -1718,8 +1718,33 @@ AgentDepsFactory2 = _ts_decorate6([
|
|
|
1718
1718
|
], AgentDepsFactory2);
|
|
1719
1719
|
|
|
1720
1720
|
// src/agent.service.ts
|
|
1721
|
-
import { AGENT_ATTACHMENT_STAGING as AGENT_ATTACHMENT_STAGING2, AGENT_DEPS_FACTORY as AGENT_DEPS_FACTORY4, AGENT_MODEL_CATALOG, AGENT_OPTIONS as AGENT_OPTIONS4, AGENT_QUOTA_PROVIDER as AGENT_QUOTA_PROVIDER2, AGENT_RUNNER, AGENT_STORE as AGENT_STORE6, REQUESTER_APPROVER, findCatalogModel, mayDecideApproval as mayDecideApproval2, readElicitationQuestions, settleDeadRun as settleDeadRun2, validateElicitationAnswer } from "@dudousxd/nestjs-agent-core";
|
|
1722
|
-
import { BadRequestException as BadRequestException2, ConflictException as ConflictException2, ForbiddenException as ForbiddenException2, GoneException, HttpException, HttpStatus, Inject as Inject8, Injectable as Injectable7, NotFoundException as NotFoundException2, NotImplementedException as NotImplementedException3, Optional as Optional5 } from "@nestjs/common";
|
|
1721
|
+
import { AGENT_ATTACHMENT_STAGING as AGENT_ATTACHMENT_STAGING2, AGENT_DEPS_FACTORY as AGENT_DEPS_FACTORY4, AGENT_MODEL_CATALOG, AGENT_OPTIONS as AGENT_OPTIONS4, AGENT_QUOTA_PROVIDER as AGENT_QUOTA_PROVIDER2, AGENT_RUNNER, AGENT_STORE as AGENT_STORE6, DEFAULT_TEXT_ACTION_PROPOSAL_VOCABULARY as DEFAULT_TEXT_ACTION_PROPOSAL_VOCABULARY2, REQUESTER_APPROVER, findCatalogModel, mayDecideApproval as mayDecideApproval2, readElicitationQuestions, settleDeadRun as settleDeadRun2, textActionProposalReply as textActionProposalReply2, validateElicitationAnswer } from "@dudousxd/nestjs-agent-core";
|
|
1722
|
+
import { BadRequestException as BadRequestException2, ConflictException as ConflictException2, ForbiddenException as ForbiddenException2, GoneException, HttpException, HttpStatus, Inject as Inject8, Injectable as Injectable7, NotFoundException as NotFoundException2, NotImplementedException as NotImplementedException3, Optional as Optional5, PayloadTooLargeException, UnsupportedMediaTypeException } from "@nestjs/common";
|
|
1723
|
+
|
|
1724
|
+
// src/attachment-limits.ts
|
|
1725
|
+
var DEFAULT_MAX_ATTACHMENT_BYTES = 20 * 1024 * 1024;
|
|
1726
|
+
var DEFAULT_ALLOWED_ATTACHMENT_CONTENT_TYPES = [
|
|
1727
|
+
"image/png",
|
|
1728
|
+
"image/jpeg",
|
|
1729
|
+
"image/gif",
|
|
1730
|
+
"image/webp",
|
|
1731
|
+
"application/pdf",
|
|
1732
|
+
"text/plain",
|
|
1733
|
+
"text/csv"
|
|
1734
|
+
];
|
|
1735
|
+
var MAX_ATTACHMENTS_PER_MESSAGE = 10;
|
|
1736
|
+
function attachmentLimits(options, staging) {
|
|
1737
|
+
const declared = staging?.describe?.();
|
|
1738
|
+
const own = options?.attachments;
|
|
1739
|
+
return {
|
|
1740
|
+
enabled: staging !== void 0,
|
|
1741
|
+
upload: staging === void 0 ? null : declared?.upload ?? "multipart",
|
|
1742
|
+
maxBytes: declared?.maxBytes ?? own?.maxBytes ?? DEFAULT_MAX_ATTACHMENT_BYTES,
|
|
1743
|
+
allowedContentTypes: declared?.allowedContentTypes ?? own?.allowedContentTypes ?? DEFAULT_ALLOWED_ATTACHMENT_CONTENT_TYPES,
|
|
1744
|
+
maxPerMessage: MAX_ATTACHMENTS_PER_MESSAGE
|
|
1745
|
+
};
|
|
1746
|
+
}
|
|
1747
|
+
__name(attachmentLimits, "attachmentLimits");
|
|
1723
1748
|
|
|
1724
1749
|
// src/proposals/action-proposal.service.ts
|
|
1725
1750
|
import { AGENT_OPTIONS as AGENT_OPTIONS2, AGENT_STORE as AGENT_STORE4, DEFAULT_TEXT_ACTION_PROPOSAL_REPLIES, DEFAULT_TEXT_ACTION_PROPOSAL_VOCABULARY, mayDecideApproval, parseTextActionProposalCommand, resolveTextActionProposalDecision, textActionProposalReply, toActionProposalMutationView, toActionProposalView } from "@dudousxd/nestjs-agent-core";
|
|
@@ -1877,6 +1902,10 @@ var ActionProposalService = class {
|
|
|
1877
1902
|
text: this.reply(result, decision)
|
|
1878
1903
|
};
|
|
1879
1904
|
}
|
|
1905
|
+
/** The configured words a text decision is made of (`actionProposalText.vocabulary`). */
|
|
1906
|
+
textVocabulary() {
|
|
1907
|
+
return this.vocabulary;
|
|
1908
|
+
}
|
|
1880
1909
|
/** The configured reply to a decision the store answered with `result`. */
|
|
1881
1910
|
reply(result, decision) {
|
|
1882
1911
|
return textActionProposalReply(result, decision, this.replies);
|
|
@@ -2503,6 +2532,65 @@ var AgentService = class {
|
|
|
2503
2532
|
};
|
|
2504
2533
|
return this.proposals.handleTextDecision(threadId, actor, text);
|
|
2505
2534
|
}
|
|
2535
|
+
/** How `action` tools wait for their approval here — `AgentModule.forRoot({ actionApprovalMode })`. */
|
|
2536
|
+
actionApprovalMode() {
|
|
2537
|
+
return this.options?.actionApprovalMode ?? "blocking";
|
|
2538
|
+
}
|
|
2539
|
+
/**
|
|
2540
|
+
* The words a text decision is made of (`actionProposalText.vocabulary`, English by default) — what
|
|
2541
|
+
* a surface without buttons tells the person to reply.
|
|
2542
|
+
*/
|
|
2543
|
+
actionProposalVocabulary() {
|
|
2544
|
+
return this.proposals?.textVocabulary() ?? DEFAULT_TEXT_ACTION_PROPOSAL_VOCABULARY2;
|
|
2545
|
+
}
|
|
2546
|
+
/** The configured reply (`actionProposalText.replies`) to a decision the store answered with `result`. */
|
|
2547
|
+
actionProposalReply(result, decision) {
|
|
2548
|
+
return this.proposals?.reply(result, decision) ?? textActionProposalReply2(result, decision);
|
|
2549
|
+
}
|
|
2550
|
+
/**
|
|
2551
|
+
* The proposals of a thread this actor may see — the thread's own actor, or one the policy lets
|
|
2552
|
+
* decide them; what `GET <base>/threads/:threadId/action-proposals` serves (its first page). `404`
|
|
2553
|
+
* when independent approvals are not on.
|
|
2554
|
+
*/
|
|
2555
|
+
async listActionProposals(actor, threadId) {
|
|
2556
|
+
if (this.options?.actionApprovalMode !== "independent" || !this.proposals) {
|
|
2557
|
+
throw new NotFoundException2("Proposal not found");
|
|
2558
|
+
}
|
|
2559
|
+
return this.proposals.list(threadId, actor);
|
|
2560
|
+
}
|
|
2561
|
+
/**
|
|
2562
|
+
* The attachment rules in force — what `GET <base>/config` serves and `POST <base>/attachments`
|
|
2563
|
+
* enforces. `enabled: false` when no `AGENT_ATTACHMENT_STAGING` provider is bound.
|
|
2564
|
+
*/
|
|
2565
|
+
attachmentLimits() {
|
|
2566
|
+
return attachmentLimits(this.options, this.staging);
|
|
2567
|
+
}
|
|
2568
|
+
/**
|
|
2569
|
+
* Stage a file for a later turn, held to the same limits as `POST <base>/attachments` — for a
|
|
2570
|
+
* surface that receives files itself (a messaging webhook). Refuses with `501` when attachments are
|
|
2571
|
+
* off, `415` for a type outside the allowlist and `413` past the size cap; send the returned
|
|
2572
|
+
* `mediaId` as `attachments: [{ mediaId }]`.
|
|
2573
|
+
*/
|
|
2574
|
+
async stageAttachment(actor, file) {
|
|
2575
|
+
if (this.staging === void 0) {
|
|
2576
|
+
throw new NotImplementedException3("Attachments are not configured on this server: bind AGENT_ATTACHMENT_STAGING (e.g. import AgentMediaAttachmentsModule).");
|
|
2577
|
+
}
|
|
2578
|
+
const { allowedContentTypes, maxBytes } = this.attachmentLimits();
|
|
2579
|
+
const contentType = file.contentType.split(";")[0]?.trim().toLowerCase() ?? "";
|
|
2580
|
+
if (!allowedContentTypes.includes(contentType)) {
|
|
2581
|
+
throw new UnsupportedMediaTypeException(`content type "${contentType}" is not allowed (allowed: ${allowedContentTypes.join(", ")})`);
|
|
2582
|
+
}
|
|
2583
|
+
if (file.data.byteLength > maxBytes) {
|
|
2584
|
+
throw new PayloadTooLargeException(`file exceeds the ${maxBytes}-byte limit`);
|
|
2585
|
+
}
|
|
2586
|
+
return this.staging.stage({
|
|
2587
|
+
data: file.data,
|
|
2588
|
+
filename: file.filename,
|
|
2589
|
+
contentType,
|
|
2590
|
+
sizeBytes: file.data.byteLength,
|
|
2591
|
+
actor
|
|
2592
|
+
});
|
|
2593
|
+
}
|
|
2506
2594
|
/** The queue service when the bound store can hold a queue, else `undefined`. */
|
|
2507
2595
|
queueing() {
|
|
2508
2596
|
return this.queue?.supported === true ? this.queue : void 0;
|
|
@@ -3784,35 +3872,8 @@ AgentsController = _ts_decorate11([
|
|
|
3784
3872
|
|
|
3785
3873
|
// src/controller/attachments.controller.ts
|
|
3786
3874
|
import { AGENT_ACTOR_RESOLVER, AGENT_ATTACHMENT_STAGING as AGENT_ATTACHMENT_STAGING3, AGENT_OPTIONS as AGENT_OPTIONS5 } from "@dudousxd/nestjs-agent-core";
|
|
3787
|
-
import { BadRequestException as BadRequestException3, Controller as Controller2, Get as Get2, Inject as Inject10, NotImplementedException as NotImplementedException5, Optional as Optional7, PayloadTooLargeException, Post, Req, UnsupportedMediaTypeException, UploadedFile, UseInterceptors } from "@nestjs/common";
|
|
3875
|
+
import { BadRequestException as BadRequestException3, Controller as Controller2, Get as Get2, Inject as Inject10, NotImplementedException as NotImplementedException5, Optional as Optional7, PayloadTooLargeException as PayloadTooLargeException2, Post, Req, UnsupportedMediaTypeException as UnsupportedMediaTypeException2, UploadedFile, UseInterceptors } from "@nestjs/common";
|
|
3788
3876
|
import { FileInterceptor } from "@nestjs/platform-express";
|
|
3789
|
-
|
|
3790
|
-
// src/attachment-limits.ts
|
|
3791
|
-
var DEFAULT_MAX_ATTACHMENT_BYTES = 20 * 1024 * 1024;
|
|
3792
|
-
var DEFAULT_ALLOWED_ATTACHMENT_CONTENT_TYPES = [
|
|
3793
|
-
"image/png",
|
|
3794
|
-
"image/jpeg",
|
|
3795
|
-
"image/gif",
|
|
3796
|
-
"image/webp",
|
|
3797
|
-
"application/pdf",
|
|
3798
|
-
"text/plain",
|
|
3799
|
-
"text/csv"
|
|
3800
|
-
];
|
|
3801
|
-
var MAX_ATTACHMENTS_PER_MESSAGE = 10;
|
|
3802
|
-
function attachmentLimits(options, staging) {
|
|
3803
|
-
const declared = staging?.describe?.();
|
|
3804
|
-
const own = options?.attachments;
|
|
3805
|
-
return {
|
|
3806
|
-
enabled: staging !== void 0,
|
|
3807
|
-
upload: staging === void 0 ? null : declared?.upload ?? "multipart",
|
|
3808
|
-
maxBytes: declared?.maxBytes ?? own?.maxBytes ?? DEFAULT_MAX_ATTACHMENT_BYTES,
|
|
3809
|
-
allowedContentTypes: declared?.allowedContentTypes ?? own?.allowedContentTypes ?? DEFAULT_ALLOWED_ATTACHMENT_CONTENT_TYPES,
|
|
3810
|
-
maxPerMessage: MAX_ATTACHMENTS_PER_MESSAGE
|
|
3811
|
-
};
|
|
3812
|
-
}
|
|
3813
|
-
__name(attachmentLimits, "attachmentLimits");
|
|
3814
|
-
|
|
3815
|
-
// src/controller/attachments.controller.ts
|
|
3816
3877
|
function _ts_decorate12(decorators, target, key, desc) {
|
|
3817
3878
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3818
3879
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
|
|
@@ -3879,10 +3940,10 @@ var AttachmentsController = class {
|
|
|
3879
3940
|
}
|
|
3880
3941
|
const { allowedContentTypes, maxBytes } = attachmentLimits(this.options, this.staging);
|
|
3881
3942
|
if (!allowedContentTypes.includes(file.mimetype)) {
|
|
3882
|
-
throw new
|
|
3943
|
+
throw new UnsupportedMediaTypeException2(`content type "${file.mimetype}" is not allowed (allowed: ${allowedContentTypes.join(", ")})`);
|
|
3883
3944
|
}
|
|
3884
3945
|
if (file.size > maxBytes) {
|
|
3885
|
-
throw new
|
|
3946
|
+
throw new PayloadTooLargeException2(`file exceeds the ${maxBytes}-byte limit`);
|
|
3886
3947
|
}
|
|
3887
3948
|
const actor = await this.actorResolver.resolve(req);
|
|
3888
3949
|
return this.staging.stage({
|
|
@@ -6103,6 +6164,34 @@ var ActionProposalWorkerService = class _ActionProposalWorkerService {
|
|
|
6103
6164
|
deps;
|
|
6104
6165
|
worker;
|
|
6105
6166
|
logger = new Logger7(_ActionProposalWorkerService.name);
|
|
6167
|
+
settledListeners = /* @__PURE__ */ new Set();
|
|
6168
|
+
/**
|
|
6169
|
+
* Run `listener` after every proposal this process's worker settles — how a module relays an
|
|
6170
|
+
* outcome somewhere the turn's stream no longer reaches (a text channel's conversation). Next to
|
|
6171
|
+
* `actionProposalWorker.onSettled`; a listener that throws is logged and does not stop the others.
|
|
6172
|
+
* Returns the unsubscribe. Only the replicas that run the worker (not `surface: 'http'`) call it.
|
|
6173
|
+
*/
|
|
6174
|
+
onSettled(listener) {
|
|
6175
|
+
this.settledListeners.add(listener);
|
|
6176
|
+
return () => {
|
|
6177
|
+
this.settledListeners.delete(listener);
|
|
6178
|
+
};
|
|
6179
|
+
}
|
|
6180
|
+
async settled(proposal) {
|
|
6181
|
+
const configured = this.options.actionProposalWorker?.onSettled;
|
|
6182
|
+
for (const listener of [
|
|
6183
|
+
...configured ? [
|
|
6184
|
+
configured
|
|
6185
|
+
] : [],
|
|
6186
|
+
...this.settledListeners
|
|
6187
|
+
]) {
|
|
6188
|
+
try {
|
|
6189
|
+
await listener(proposal);
|
|
6190
|
+
} catch (error) {
|
|
6191
|
+
this.logger.error(error);
|
|
6192
|
+
}
|
|
6193
|
+
}
|
|
6194
|
+
}
|
|
6106
6195
|
constructor(store, options, deps) {
|
|
6107
6196
|
this.store = store;
|
|
6108
6197
|
this.options = options;
|
|
@@ -6118,6 +6207,7 @@ var ActionProposalWorkerService = class _ActionProposalWorkerService {
|
|
|
6118
6207
|
store: this.store,
|
|
6119
6208
|
workerId: randomUUID2(),
|
|
6120
6209
|
...this.options.actionProposalWorker,
|
|
6210
|
+
onSettled: /* @__PURE__ */ __name((proposal) => this.settled(proposal), "onSettled"),
|
|
6121
6211
|
executor: new ActionProposalExecutor({
|
|
6122
6212
|
resolver,
|
|
6123
6213
|
resolveExecution: /* @__PURE__ */ __name(async (proposal, actor) => {
|