@dudousxd/nestjs-agent 1.23.1 → 1.24.1
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
package/dist/index.cjs
CHANGED
|
@@ -673,6 +673,31 @@ function childSinkWriter(writer) {
|
|
|
673
673
|
}
|
|
674
674
|
__name(childSinkWriter, "childSinkWriter");
|
|
675
675
|
|
|
676
|
+
// src/attachment-limits.ts
|
|
677
|
+
var DEFAULT_MAX_ATTACHMENT_BYTES = 20 * 1024 * 1024;
|
|
678
|
+
var DEFAULT_ALLOWED_ATTACHMENT_CONTENT_TYPES = [
|
|
679
|
+
"image/png",
|
|
680
|
+
"image/jpeg",
|
|
681
|
+
"image/gif",
|
|
682
|
+
"image/webp",
|
|
683
|
+
"application/pdf",
|
|
684
|
+
"text/plain",
|
|
685
|
+
"text/csv"
|
|
686
|
+
];
|
|
687
|
+
var MAX_ATTACHMENTS_PER_MESSAGE = 10;
|
|
688
|
+
function attachmentLimits(options, staging) {
|
|
689
|
+
const declared = staging?.describe?.();
|
|
690
|
+
const own = options?.attachments;
|
|
691
|
+
return {
|
|
692
|
+
enabled: staging !== void 0,
|
|
693
|
+
upload: staging === void 0 ? null : declared?.upload ?? "multipart",
|
|
694
|
+
maxBytes: declared?.maxBytes ?? own?.maxBytes ?? DEFAULT_MAX_ATTACHMENT_BYTES,
|
|
695
|
+
allowedContentTypes: declared?.allowedContentTypes ?? own?.allowedContentTypes ?? DEFAULT_ALLOWED_ATTACHMENT_CONTENT_TYPES,
|
|
696
|
+
maxPerMessage: MAX_ATTACHMENTS_PER_MESSAGE
|
|
697
|
+
};
|
|
698
|
+
}
|
|
699
|
+
__name(attachmentLimits, "attachmentLimits");
|
|
700
|
+
|
|
676
701
|
// src/proposals/action-proposal.service.ts
|
|
677
702
|
var import_nestjs_agent_core5 = require("@dudousxd/nestjs-agent-core");
|
|
678
703
|
var import_common3 = require("@nestjs/common");
|
|
@@ -829,6 +854,10 @@ var ActionProposalService = class {
|
|
|
829
854
|
text: this.reply(result, decision)
|
|
830
855
|
};
|
|
831
856
|
}
|
|
857
|
+
/** The configured words a text decision is made of (`actionProposalText.vocabulary`). */
|
|
858
|
+
textVocabulary() {
|
|
859
|
+
return this.vocabulary;
|
|
860
|
+
}
|
|
832
861
|
/** The configured reply to a decision the store answered with `result`. */
|
|
833
862
|
reply(result, decision) {
|
|
834
863
|
return (0, import_nestjs_agent_core5.textActionProposalReply)(result, decision, this.replies);
|
|
@@ -1455,6 +1484,65 @@ var AgentService = class {
|
|
|
1455
1484
|
};
|
|
1456
1485
|
return this.proposals.handleTextDecision(threadId, actor, text);
|
|
1457
1486
|
}
|
|
1487
|
+
/** How `action` tools wait for their approval here — `AgentModule.forRoot({ actionApprovalMode })`. */
|
|
1488
|
+
actionApprovalMode() {
|
|
1489
|
+
return this.options?.actionApprovalMode ?? "blocking";
|
|
1490
|
+
}
|
|
1491
|
+
/**
|
|
1492
|
+
* The words a text decision is made of (`actionProposalText.vocabulary`, English by default) — what
|
|
1493
|
+
* a surface without buttons tells the person to reply.
|
|
1494
|
+
*/
|
|
1495
|
+
actionProposalVocabulary() {
|
|
1496
|
+
return this.proposals?.textVocabulary() ?? import_nestjs_agent_core9.DEFAULT_TEXT_ACTION_PROPOSAL_VOCABULARY;
|
|
1497
|
+
}
|
|
1498
|
+
/** The configured reply (`actionProposalText.replies`) to a decision the store answered with `result`. */
|
|
1499
|
+
actionProposalReply(result, decision) {
|
|
1500
|
+
return this.proposals?.reply(result, decision) ?? (0, import_nestjs_agent_core9.textActionProposalReply)(result, decision);
|
|
1501
|
+
}
|
|
1502
|
+
/**
|
|
1503
|
+
* The proposals of a thread this actor may see — the thread's own actor, or one the policy lets
|
|
1504
|
+
* decide them; what `GET <base>/threads/:threadId/action-proposals` serves (its first page). `404`
|
|
1505
|
+
* when independent approvals are not on.
|
|
1506
|
+
*/
|
|
1507
|
+
async listActionProposals(actor, threadId) {
|
|
1508
|
+
if (this.options?.actionApprovalMode !== "independent" || !this.proposals) {
|
|
1509
|
+
throw new import_common6.NotFoundException("Proposal not found");
|
|
1510
|
+
}
|
|
1511
|
+
return this.proposals.list(threadId, actor);
|
|
1512
|
+
}
|
|
1513
|
+
/**
|
|
1514
|
+
* The attachment rules in force — what `GET <base>/config` serves and `POST <base>/attachments`
|
|
1515
|
+
* enforces. `enabled: false` when no `AGENT_ATTACHMENT_STAGING` provider is bound.
|
|
1516
|
+
*/
|
|
1517
|
+
attachmentLimits() {
|
|
1518
|
+
return attachmentLimits(this.options, this.staging);
|
|
1519
|
+
}
|
|
1520
|
+
/**
|
|
1521
|
+
* Stage a file for a later turn, held to the same limits as `POST <base>/attachments` — for a
|
|
1522
|
+
* surface that receives files itself (a messaging webhook). Refuses with `501` when attachments are
|
|
1523
|
+
* off, `415` for a type outside the allowlist and `413` past the size cap; send the returned
|
|
1524
|
+
* `mediaId` as `attachments: [{ mediaId }]`.
|
|
1525
|
+
*/
|
|
1526
|
+
async stageAttachment(actor, file) {
|
|
1527
|
+
if (this.staging === void 0) {
|
|
1528
|
+
throw new import_common6.NotImplementedException("Attachments are not configured on this server: bind AGENT_ATTACHMENT_STAGING (e.g. import AgentMediaAttachmentsModule).");
|
|
1529
|
+
}
|
|
1530
|
+
const { allowedContentTypes, maxBytes } = this.attachmentLimits();
|
|
1531
|
+
const contentType = file.contentType.split(";")[0]?.trim().toLowerCase() ?? "";
|
|
1532
|
+
if (!allowedContentTypes.includes(contentType)) {
|
|
1533
|
+
throw new import_common6.UnsupportedMediaTypeException(`content type "${contentType}" is not allowed (allowed: ${allowedContentTypes.join(", ")})`);
|
|
1534
|
+
}
|
|
1535
|
+
if (file.data.byteLength > maxBytes) {
|
|
1536
|
+
throw new import_common6.PayloadTooLargeException(`file exceeds the ${maxBytes}-byte limit`);
|
|
1537
|
+
}
|
|
1538
|
+
return this.staging.stage({
|
|
1539
|
+
data: file.data,
|
|
1540
|
+
filename: file.filename,
|
|
1541
|
+
contentType,
|
|
1542
|
+
sizeBytes: file.data.byteLength,
|
|
1543
|
+
actor
|
|
1544
|
+
});
|
|
1545
|
+
}
|
|
1458
1546
|
/** The queue service when the bound store can hold a queue, else `undefined`. */
|
|
1459
1547
|
queueing() {
|
|
1460
1548
|
return this.queue?.supported === true ? this.queue : void 0;
|
|
@@ -2738,33 +2826,6 @@ AgentsController = _ts_decorate7([
|
|
|
2738
2826
|
var import_nestjs_agent_core11 = require("@dudousxd/nestjs-agent-core");
|
|
2739
2827
|
var import_common9 = require("@nestjs/common");
|
|
2740
2828
|
var import_platform_express = require("@nestjs/platform-express");
|
|
2741
|
-
|
|
2742
|
-
// src/attachment-limits.ts
|
|
2743
|
-
var DEFAULT_MAX_ATTACHMENT_BYTES = 20 * 1024 * 1024;
|
|
2744
|
-
var DEFAULT_ALLOWED_ATTACHMENT_CONTENT_TYPES = [
|
|
2745
|
-
"image/png",
|
|
2746
|
-
"image/jpeg",
|
|
2747
|
-
"image/gif",
|
|
2748
|
-
"image/webp",
|
|
2749
|
-
"application/pdf",
|
|
2750
|
-
"text/plain",
|
|
2751
|
-
"text/csv"
|
|
2752
|
-
];
|
|
2753
|
-
var MAX_ATTACHMENTS_PER_MESSAGE = 10;
|
|
2754
|
-
function attachmentLimits(options, staging) {
|
|
2755
|
-
const declared = staging?.describe?.();
|
|
2756
|
-
const own = options?.attachments;
|
|
2757
|
-
return {
|
|
2758
|
-
enabled: staging !== void 0,
|
|
2759
|
-
upload: staging === void 0 ? null : declared?.upload ?? "multipart",
|
|
2760
|
-
maxBytes: declared?.maxBytes ?? own?.maxBytes ?? DEFAULT_MAX_ATTACHMENT_BYTES,
|
|
2761
|
-
allowedContentTypes: declared?.allowedContentTypes ?? own?.allowedContentTypes ?? DEFAULT_ALLOWED_ATTACHMENT_CONTENT_TYPES,
|
|
2762
|
-
maxPerMessage: MAX_ATTACHMENTS_PER_MESSAGE
|
|
2763
|
-
};
|
|
2764
|
-
}
|
|
2765
|
-
__name(attachmentLimits, "attachmentLimits");
|
|
2766
|
-
|
|
2767
|
-
// src/controller/attachments.controller.ts
|
|
2768
2829
|
function _ts_decorate8(decorators, target, key, desc) {
|
|
2769
2830
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
2770
2831
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
|
|
@@ -5167,6 +5228,34 @@ var ActionProposalWorkerService = class _ActionProposalWorkerService {
|
|
|
5167
5228
|
deps;
|
|
5168
5229
|
worker;
|
|
5169
5230
|
logger = new import_common24.Logger(_ActionProposalWorkerService.name);
|
|
5231
|
+
settledListeners = /* @__PURE__ */ new Set();
|
|
5232
|
+
/**
|
|
5233
|
+
* Run `listener` after every proposal this process's worker settles — how a module relays an
|
|
5234
|
+
* outcome somewhere the turn's stream no longer reaches (a text channel's conversation). Next to
|
|
5235
|
+
* `actionProposalWorker.onSettled`; a listener that throws is logged and does not stop the others.
|
|
5236
|
+
* Returns the unsubscribe. Only the replicas that run the worker (not `surface: 'http'`) call it.
|
|
5237
|
+
*/
|
|
5238
|
+
onSettled(listener) {
|
|
5239
|
+
this.settledListeners.add(listener);
|
|
5240
|
+
return () => {
|
|
5241
|
+
this.settledListeners.delete(listener);
|
|
5242
|
+
};
|
|
5243
|
+
}
|
|
5244
|
+
async settled(proposal) {
|
|
5245
|
+
const configured = this.options.actionProposalWorker?.onSettled;
|
|
5246
|
+
for (const listener of [
|
|
5247
|
+
...configured ? [
|
|
5248
|
+
configured
|
|
5249
|
+
] : [],
|
|
5250
|
+
...this.settledListeners
|
|
5251
|
+
]) {
|
|
5252
|
+
try {
|
|
5253
|
+
await listener(proposal);
|
|
5254
|
+
} catch (error) {
|
|
5255
|
+
this.logger.error(error);
|
|
5256
|
+
}
|
|
5257
|
+
}
|
|
5258
|
+
}
|
|
5170
5259
|
constructor(store, options, deps) {
|
|
5171
5260
|
this.store = store;
|
|
5172
5261
|
this.options = options;
|
|
@@ -5182,6 +5271,7 @@ var ActionProposalWorkerService = class _ActionProposalWorkerService {
|
|
|
5182
5271
|
store: this.store,
|
|
5183
5272
|
workerId: (0, import_node_crypto2.randomUUID)(),
|
|
5184
5273
|
...this.options.actionProposalWorker,
|
|
5274
|
+
onSettled: /* @__PURE__ */ __name((proposal) => this.settled(proposal), "onSettled"),
|
|
5185
5275
|
executor: new import_nestjs_agent_core29.ActionProposalExecutor({
|
|
5186
5276
|
resolver,
|
|
5187
5277
|
resolveExecution: /* @__PURE__ */ __name(async (proposal, actor) => {
|