@dudousxd/nestjs-agent 1.21.0 → 1.22.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -0
- package/dist/{chat-queue.service-XG9RQCjU.d.ts → chat-queue.service-CTyX_yNr.d.ts} +33 -2
- package/dist/{chat-queue.service-CGsR40Ct.d.cts → chat-queue.service-Dx9OsjcF.d.cts} +33 -2
- package/dist/durable/index.cjs +334 -237
- 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 -25
- package/dist/durable/index.js.map +1 -1
- package/dist/genui/index.cjs +1 -0
- package/dist/genui/index.cjs.map +1 -1
- package/dist/genui/index.js +1 -0
- package/dist/genui/index.js.map +1 -1
- package/dist/index.cjs +404 -250
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +43 -14
- package/dist/index.d.ts +43 -14
- package/dist/index.js +185 -32
- package/dist/index.js.map +1 -1
- package/dist/sink-redis/index.cjs +7 -2
- package/dist/sink-redis/index.cjs.map +1 -1
- package/dist/sink-redis/index.d.cts +6 -3
- package/dist/sink-redis/index.d.ts +6 -3
- package/dist/sink-redis/index.js +7 -2
- package/dist/sink-redis/index.js.map +1 -1
- package/package.json +4 -4
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-Dx9OsjcF.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-CTyX_yNr.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
|
@@ -1186,6 +1186,7 @@ import { defineCatalog, genuiTools } from "@dudousxd/nestjs-agent-core/genui";
|
|
|
1186
1186
|
import { Inject as Inject4, Module as Module2 } from "@nestjs/common";
|
|
1187
1187
|
|
|
1188
1188
|
// src/functional-tool.ts
|
|
1189
|
+
import { createFunctionalTool } from "@dudousxd/nestjs-agent-core";
|
|
1189
1190
|
var AGENT_TOOL_BRAND = /* @__PURE__ */ Symbol.for("@dudousxd/nestjs-agent:functional-tool");
|
|
1190
1191
|
function brand(tool) {
|
|
1191
1192
|
return {
|
|
@@ -1721,7 +1722,7 @@ import { AGENT_ATTACHMENT_STAGING as AGENT_ATTACHMENT_STAGING2, AGENT_DEPS_FACTO
|
|
|
1721
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";
|
|
1722
1723
|
|
|
1723
1724
|
// src/proposals/action-proposal.service.ts
|
|
1724
|
-
import { AGENT_OPTIONS as AGENT_OPTIONS2, AGENT_STORE as AGENT_STORE4, mayDecideApproval, parseTextActionProposalCommand, resolveTextActionProposalDecision } from "@dudousxd/nestjs-agent-core";
|
|
1725
|
+
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";
|
|
1725
1726
|
import { ForbiddenException, Inject as Inject6, Injectable as Injectable5, NotFoundException, NotImplementedException } from "@nestjs/common";
|
|
1726
1727
|
function _ts_decorate7(decorators, target, key, desc) {
|
|
1727
1728
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
@@ -1758,7 +1759,19 @@ var ActionProposalService = class {
|
|
|
1758
1759
|
constructor(store, options) {
|
|
1759
1760
|
this.store = store;
|
|
1760
1761
|
this.options = options;
|
|
1762
|
+
const text = options.actionProposalText;
|
|
1763
|
+
this.vocabulary = {
|
|
1764
|
+
...DEFAULT_TEXT_ACTION_PROPOSAL_VOCABULARY,
|
|
1765
|
+
...text?.vocabulary
|
|
1766
|
+
};
|
|
1767
|
+
this.replies = {
|
|
1768
|
+
...DEFAULT_TEXT_ACTION_PROPOSAL_REPLIES,
|
|
1769
|
+
...text?.replies
|
|
1770
|
+
};
|
|
1761
1771
|
}
|
|
1772
|
+
/** The words a text decision is made of, and what the agent answers — English unless configured. */
|
|
1773
|
+
vocabulary;
|
|
1774
|
+
replies;
|
|
1762
1775
|
capability() {
|
|
1763
1776
|
const store = this.store;
|
|
1764
1777
|
if (typeof store.getThreadActionProposalScope !== "function" || typeof store.listActionProposals !== "function") throw new NotImplementedException("Action proposals are unavailable");
|
|
@@ -1787,7 +1800,8 @@ var ActionProposalService = class {
|
|
|
1787
1800
|
for (const row of rows) if (scope.actorRef === actor.id || await this.mayDecide(actor, row)) visible.push(row);
|
|
1788
1801
|
const last = rows.at(-1);
|
|
1789
1802
|
return {
|
|
1790
|
-
|
|
1803
|
+
// The public view: a row carries the worker's lease token and the tool's idempotency key.
|
|
1804
|
+
items: visible.map(toActionProposalView),
|
|
1791
1805
|
...rows.length === 1e3 && last ? {
|
|
1792
1806
|
next: {
|
|
1793
1807
|
createdAt: last.createdAt,
|
|
@@ -1804,7 +1818,7 @@ var ActionProposalService = class {
|
|
|
1804
1818
|
const proposal = await this.capability().getActionProposal(scope, proposalId);
|
|
1805
1819
|
if (!proposal) throw new NotFoundException("Proposal not found");
|
|
1806
1820
|
if (!await this.mayDecide(actor, proposal)) throw new ForbiddenException("May not decide this proposal");
|
|
1807
|
-
|
|
1821
|
+
const result = await this.capability().decideActionProposal(scope, proposalId, {
|
|
1808
1822
|
decision: command.decision,
|
|
1809
1823
|
actorRef: actor.id,
|
|
1810
1824
|
via: command.via ?? "web",
|
|
@@ -1815,9 +1829,10 @@ var ActionProposalService = class {
|
|
|
1815
1829
|
reason: command.reason
|
|
1816
1830
|
} : {}
|
|
1817
1831
|
});
|
|
1832
|
+
return toActionProposalMutationView(result);
|
|
1818
1833
|
}
|
|
1819
1834
|
async handleTextDecision(threadId, actor, text) {
|
|
1820
|
-
const command = parseTextActionProposalCommand(text);
|
|
1835
|
+
const command = parseTextActionProposalCommand(text, this.vocabulary);
|
|
1821
1836
|
if (command.status === "unmatched") return command;
|
|
1822
1837
|
if (command.proposalId !== void 0) {
|
|
1823
1838
|
const result2 = await this.decide(threadId, command.proposalId, actor, {
|
|
@@ -1825,7 +1840,7 @@ var ActionProposalService = class {
|
|
|
1825
1840
|
remember: command.remember,
|
|
1826
1841
|
via: "text"
|
|
1827
1842
|
});
|
|
1828
|
-
return this.textReceipt(threadId, result2);
|
|
1843
|
+
return this.textReceipt(threadId, result2, command.decision);
|
|
1829
1844
|
}
|
|
1830
1845
|
const candidates = [];
|
|
1831
1846
|
const scope = await this.scope(threadId, actor);
|
|
@@ -1834,30 +1849,38 @@ var ActionProposalService = class {
|
|
|
1834
1849
|
limit: 1e3
|
|
1835
1850
|
});
|
|
1836
1851
|
for (const proposal of pending) if (await this.mayDecide(actor, proposal)) candidates.push(proposal);
|
|
1837
|
-
const resolution = resolveTextActionProposalDecision(text, candidates);
|
|
1852
|
+
const resolution = resolveTextActionProposalDecision(text, candidates, this.vocabulary);
|
|
1838
1853
|
if (resolution.status === "unmatched") return resolution;
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1854
|
+
const saturated = pending.length === 1e3 && !text.includes("#");
|
|
1855
|
+
if (resolution.status === "ambiguous" || saturated) {
|
|
1856
|
+
const proposalIds = candidates.map(({ id }) => id);
|
|
1857
|
+
return {
|
|
1858
|
+
threadId,
|
|
1859
|
+
proposalDecision: {
|
|
1860
|
+
status: "ambiguous",
|
|
1861
|
+
proposalIds
|
|
1862
|
+
},
|
|
1863
|
+
text: saturated ? this.replies.tooMany : this.replies.ambiguous(proposalIds)
|
|
1864
|
+
};
|
|
1865
|
+
}
|
|
1847
1866
|
const result = await this.decide(threadId, resolution.proposalId, actor, {
|
|
1848
1867
|
decision: resolution.decision,
|
|
1849
1868
|
remember: resolution.remember,
|
|
1850
1869
|
via: "text"
|
|
1851
1870
|
});
|
|
1852
|
-
return this.textReceipt(threadId, result);
|
|
1871
|
+
return this.textReceipt(threadId, result, resolution.decision);
|
|
1853
1872
|
}
|
|
1854
|
-
textReceipt(threadId, result) {
|
|
1873
|
+
textReceipt(threadId, result, decision) {
|
|
1855
1874
|
return {
|
|
1856
1875
|
threadId,
|
|
1857
1876
|
proposalDecision: result,
|
|
1858
|
-
text:
|
|
1877
|
+
text: this.reply(result, decision)
|
|
1859
1878
|
};
|
|
1860
1879
|
}
|
|
1880
|
+
/** The configured reply to a decision the store answered with `result`. */
|
|
1881
|
+
reply(result, decision) {
|
|
1882
|
+
return textActionProposalReply(result, decision, this.replies);
|
|
1883
|
+
}
|
|
1861
1884
|
};
|
|
1862
1885
|
ActionProposalService = _ts_decorate7([
|
|
1863
1886
|
Injectable5(),
|
|
@@ -1874,6 +1897,33 @@ ActionProposalService = _ts_decorate7([
|
|
|
1874
1897
|
import { AGENT_ATTACHMENT_STAGING, AGENT_DEPS_FACTORY as AGENT_DEPS_FACTORY3, AGENT_OPTIONS as AGENT_OPTIONS3, AGENT_QUOTA_PROVIDER, AGENT_SINK as AGENT_SINK3, AGENT_STORE as AGENT_STORE5, encodeStreamEvent as encodeStreamEvent4, isChatQueueStore, queuedMessageView } from "@dudousxd/nestjs-agent-core";
|
|
1875
1898
|
import { Inject as Inject7, Injectable as Injectable6, Logger as Logger3, NotImplementedException as NotImplementedException2, Optional as Optional4 } from "@nestjs/common";
|
|
1876
1899
|
|
|
1900
|
+
// src/quota-exceeded.ts
|
|
1901
|
+
import { publishAgentQuotaExceeded } from "@dudousxd/nestjs-agent-core";
|
|
1902
|
+
function publishQuotaBlocked(actor, report, blocked) {
|
|
1903
|
+
const window = report.windows.find((candidate) => candidate.period === blocked.period);
|
|
1904
|
+
const payload = {
|
|
1905
|
+
actorId: actor.id,
|
|
1906
|
+
period: blocked.period,
|
|
1907
|
+
...blocked.reason !== void 0 ? {
|
|
1908
|
+
reason: blocked.reason
|
|
1909
|
+
} : {},
|
|
1910
|
+
...window?.usedTokens !== void 0 ? {
|
|
1911
|
+
usedTokens: window.usedTokens
|
|
1912
|
+
} : {},
|
|
1913
|
+
...window?.limitTokens !== void 0 ? {
|
|
1914
|
+
limitTokens: window.limitTokens
|
|
1915
|
+
} : {},
|
|
1916
|
+
...window !== void 0 ? {
|
|
1917
|
+
usedUsd: window.usedUsd
|
|
1918
|
+
} : {},
|
|
1919
|
+
...window?.limitUsd !== void 0 ? {
|
|
1920
|
+
limitUsd: window.limitUsd
|
|
1921
|
+
} : {}
|
|
1922
|
+
};
|
|
1923
|
+
publishAgentQuotaExceeded(payload);
|
|
1924
|
+
}
|
|
1925
|
+
__name(publishQuotaBlocked, "publishQuotaBlocked");
|
|
1926
|
+
|
|
1877
1927
|
// src/thread-persona.ts
|
|
1878
1928
|
async function threadPersona(store, threadId) {
|
|
1879
1929
|
const projecting = store;
|
|
@@ -2217,12 +2267,14 @@ var ChatQueueService2 = class _ChatQueueService {
|
|
|
2217
2267
|
return null;
|
|
2218
2268
|
}
|
|
2219
2269
|
try {
|
|
2220
|
-
const
|
|
2270
|
+
const report = await this.quotaProvider.report({
|
|
2221
2271
|
actor
|
|
2222
2272
|
});
|
|
2273
|
+
const { blocked } = report;
|
|
2223
2274
|
if (blocked === void 0) {
|
|
2224
2275
|
return null;
|
|
2225
2276
|
}
|
|
2277
|
+
publishQuotaBlocked(actor, report, blocked);
|
|
2226
2278
|
return blocked.reason ?? `The ${blocked.period === "day" ? "daily" : "monthly"} quota is used up`;
|
|
2227
2279
|
} catch {
|
|
2228
2280
|
return null;
|
|
@@ -2424,6 +2476,21 @@ var AgentService = class {
|
|
|
2424
2476
|
this.queue = queue;
|
|
2425
2477
|
this.proposals = proposals;
|
|
2426
2478
|
}
|
|
2479
|
+
/**
|
|
2480
|
+
* Decide one independent proposal through the scoped proposal service — what the native
|
|
2481
|
+
* `action-proposals/:id/approve|reject` routes call — and the reply to show for it. `404` when
|
|
2482
|
+
* proposals are not on, `403`/`404` when this actor may not decide it.
|
|
2483
|
+
*/
|
|
2484
|
+
async decideActionProposal(actor, threadId, proposalId, command) {
|
|
2485
|
+
if (this.options?.actionApprovalMode !== "independent" || !this.proposals) {
|
|
2486
|
+
throw new NotFoundException2("Proposal not found");
|
|
2487
|
+
}
|
|
2488
|
+
const result = await this.proposals.decide(threadId, proposalId, actor, command);
|
|
2489
|
+
return {
|
|
2490
|
+
proposalDecision: result,
|
|
2491
|
+
text: this.proposals.reply(result, command.decision)
|
|
2492
|
+
};
|
|
2493
|
+
}
|
|
2427
2494
|
async handleTextDecision(threadId, actor, text) {
|
|
2428
2495
|
if (this.options?.actionApprovalMode !== "independent" || !this.proposals) return {
|
|
2429
2496
|
status: "unmatched"
|
|
@@ -2471,10 +2538,12 @@ var AgentService = class {
|
|
|
2471
2538
|
if (this.options?.quota === void 0 || this.quotaProvider === void 0) {
|
|
2472
2539
|
return;
|
|
2473
2540
|
}
|
|
2474
|
-
const
|
|
2541
|
+
const report = await this.quotaProvider.report({
|
|
2475
2542
|
actor
|
|
2476
2543
|
});
|
|
2544
|
+
const { blocked } = report;
|
|
2477
2545
|
if (blocked !== void 0) {
|
|
2546
|
+
publishQuotaBlocked(actor, report, blocked);
|
|
2478
2547
|
throw new HttpException({
|
|
2479
2548
|
statusCode: HttpStatus.TOO_MANY_REQUESTS,
|
|
2480
2549
|
code: "quota_exceeded",
|
|
@@ -5727,6 +5796,9 @@ var AiToolDiscoveryService = class _AiToolDiscoveryService {
|
|
|
5727
5796
|
} : {}
|
|
5728
5797
|
}, {
|
|
5729
5798
|
execute: /* @__PURE__ */ __name((input, ctx) => instance.execute(input, ctx), "execute"),
|
|
5799
|
+
...typeof handler.present === "function" ? {
|
|
5800
|
+
present: /* @__PURE__ */ __name((output, ctx) => instance.present(output, ctx), "present")
|
|
5801
|
+
} : {},
|
|
5730
5802
|
...typeof handler.preflight === "function" ? {
|
|
5731
5803
|
preflight: /* @__PURE__ */ __name((input, ctx, options) => instance.preflight(input, ctx, options), "preflight")
|
|
5732
5804
|
} : {},
|
|
@@ -6763,15 +6835,15 @@ function _ts_decorate30(decorators, target, key, desc) {
|
|
|
6763
6835
|
__name(_ts_decorate30, "_ts_decorate");
|
|
6764
6836
|
var DEFAULT_PATH = "agent";
|
|
6765
6837
|
var logger = new Logger9("AgentModule");
|
|
6766
|
-
function
|
|
6838
|
+
function externalWrapper(modules, token) {
|
|
6767
6839
|
for (const module of modules.values()) {
|
|
6768
6840
|
if (module.metatype === AgentModule) continue;
|
|
6769
|
-
const wrapper = module.providers.get(
|
|
6841
|
+
const wrapper = module.providers.get(token);
|
|
6770
6842
|
if (wrapper !== void 0) return wrapper;
|
|
6771
6843
|
}
|
|
6772
6844
|
return void 0;
|
|
6773
6845
|
}
|
|
6774
|
-
__name(
|
|
6846
|
+
__name(externalWrapper, "externalWrapper");
|
|
6775
6847
|
function forwardingStore(wrapper) {
|
|
6776
6848
|
const target = /* @__PURE__ */ __name(() => {
|
|
6777
6849
|
const instance = wrapper.instance;
|
|
@@ -6794,12 +6866,36 @@ function forwardingStore(wrapper) {
|
|
|
6794
6866
|
__name(forwardingStore, "forwardingStore");
|
|
6795
6867
|
function resolveStore(options, modules) {
|
|
6796
6868
|
if (options.store !== void 0) return options.store;
|
|
6797
|
-
const external =
|
|
6869
|
+
const external = externalWrapper(modules, AGENT_STORE9);
|
|
6798
6870
|
if (external !== void 0) return forwardingStore(external);
|
|
6799
6871
|
logger.warn("No `store` configured and no store module imported \u2014 using the in-memory store. Threads are lost on restart and not shared between processes: not for production. Pass `store`, or import a store module (e.g. MikroOrmAgentStoreModule.forFeature()).");
|
|
6800
6872
|
return new InMemoryAgentStore();
|
|
6801
6873
|
}
|
|
6802
6874
|
__name(resolveStore, "resolveStore");
|
|
6875
|
+
function resolveRolesPolicy(options, modules) {
|
|
6876
|
+
const external = externalWrapper(modules, AGENT_ROLES_POLICY2);
|
|
6877
|
+
if (options.rolesPolicy !== void 0) {
|
|
6878
|
+
if (external !== void 0) {
|
|
6879
|
+
logger.warn("Both a `rolesPolicy` option and a module binding AGENT_ROLES_POLICY (e.g. AgentAuthzModule) are configured \u2014 the `rolesPolicy` option wins.");
|
|
6880
|
+
}
|
|
6881
|
+
return options.rolesPolicy;
|
|
6882
|
+
}
|
|
6883
|
+
if (external !== void 0) return forwardingPolicy(external);
|
|
6884
|
+
return options.emptyRoles === "deny" ? new ClosedRolesPolicy(options.defaultRoles) : new DefaultRolesPolicy(options.defaultRoles);
|
|
6885
|
+
}
|
|
6886
|
+
__name(resolveRolesPolicy, "resolveRolesPolicy");
|
|
6887
|
+
function forwardingPolicy(wrapper) {
|
|
6888
|
+
return {
|
|
6889
|
+
can(actor, tool) {
|
|
6890
|
+
const policy = wrapper.instance;
|
|
6891
|
+
if (policy === void 0 || policy === null) {
|
|
6892
|
+
throw new Error("AgentModule: the AGENT_ROLES_POLICY bound by another module is not ready yet");
|
|
6893
|
+
}
|
|
6894
|
+
return policy.can(actor, tool);
|
|
6895
|
+
}
|
|
6896
|
+
};
|
|
6897
|
+
}
|
|
6898
|
+
__name(forwardingPolicy, "forwardingPolicy");
|
|
6803
6899
|
function isQuotaProvider(quota) {
|
|
6804
6900
|
return quota !== void 0 && typeof quota.report === "function";
|
|
6805
6901
|
}
|
|
@@ -6861,9 +6957,10 @@ function sharedProviders(durable) {
|
|
|
6861
6957
|
},
|
|
6862
6958
|
{
|
|
6863
6959
|
provide: AGENT_ROLES_POLICY2,
|
|
6864
|
-
useFactory: /* @__PURE__ */ __name((options) =>
|
|
6960
|
+
useFactory: /* @__PURE__ */ __name((options, modules) => resolveRolesPolicy(options, modules), "useFactory"),
|
|
6865
6961
|
inject: [
|
|
6866
|
-
AGENT_OPTIONS9
|
|
6962
|
+
AGENT_OPTIONS9,
|
|
6963
|
+
ModulesContainer
|
|
6867
6964
|
]
|
|
6868
6965
|
},
|
|
6869
6966
|
{
|