@dudousxd/nestjs-agent 1.6.0 → 1.8.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 +54 -0
- package/dist/{agent-deps.factory-CUyVPsa1.d.cts → agent-deps.factory-Cus_RqwJ.d.cts} +49 -2
- package/dist/{agent-deps.factory-CUyVPsa1.d.ts → agent-deps.factory-Cus_RqwJ.d.ts} +49 -2
- package/dist/durable/index.cjs +618 -309
- 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 +533 -224
- package/dist/durable/index.js.map +1 -1
- package/dist/index.cjs +622 -312
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +53 -5
- package/dist/index.d.ts +53 -5
- package/dist/index.js +531 -223
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -144,6 +144,60 @@ one of the caller's threads (`null` clears it) and answers `{ feedback }`; `GET
|
|
|
144
144
|
returns it on the message. It needs a store with `threadOfMessage` + `setMessageFeedback` (both
|
|
145
145
|
bundled stores and `InMemoryAgentStore` have them) — `501` otherwise.
|
|
146
146
|
|
|
147
|
+
### Letting callers pick a model
|
|
148
|
+
|
|
149
|
+
```ts
|
|
150
|
+
AgentModule.forRoot({
|
|
151
|
+
model: aiSdkModel('openai/gpt-4o-mini', { resolveModel: (id) => gateway(id) }),
|
|
152
|
+
models: {
|
|
153
|
+
list: ({ actor }) => ({
|
|
154
|
+
default: 'openai/gpt-4o-mini',
|
|
155
|
+
providers: [
|
|
156
|
+
{
|
|
157
|
+
id: 'openai',
|
|
158
|
+
label: 'OpenAI',
|
|
159
|
+
models: [
|
|
160
|
+
{ id: 'openai/gpt-4o-mini', label: 'GPT-4o mini', badges: ['fast'], available: true },
|
|
161
|
+
{
|
|
162
|
+
id: 'openai/o3',
|
|
163
|
+
label: 'o3',
|
|
164
|
+
badges: ['reasoning'],
|
|
165
|
+
available: actor.roles?.includes('PRO') === true,
|
|
166
|
+
unavailableReason: 'Pro plan',
|
|
167
|
+
},
|
|
168
|
+
],
|
|
169
|
+
},
|
|
170
|
+
],
|
|
171
|
+
}),
|
|
172
|
+
},
|
|
173
|
+
});
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
`GET /agent/models?agent=` answers the catalog for the caller (empty without one). A turn runs on
|
|
177
|
+
the send's `model`, else the thread's pinned one (`PATCH /agent/threads/:id { model }`), else the
|
|
178
|
+
provider's default; the id reaches the provider as `ModelTurnArgs.model` for every call of the turn.
|
|
179
|
+
A model the catalog does not list as available for that actor and agent is refused with `400` —
|
|
180
|
+
when pinned and again on each turn. `staticModelCatalog(view)` wraps a fixed list.
|
|
181
|
+
|
|
182
|
+
### Budgets: `GET /agent/quota`
|
|
183
|
+
|
|
184
|
+
`GET /agent/quota` reports `{ windows: [{ period: 'day' | 'month', usedTokens, limitTokens?,
|
|
185
|
+
usedUsd, limitUsd?, resetsAt? }], blocked? }` from a `QuotaProvider`. The default,
|
|
186
|
+
`LedgerQuotaProvider`, reads the usage ledger (day, plus month when the store has `usageBetween`)
|
|
187
|
+
and only reports. Configure it and it also gates sends — a `blocked` report refuses `POST
|
|
188
|
+
/agent/chat` with `429 { code: 'quota_exceeded', period }` before the turn starts:
|
|
189
|
+
|
|
190
|
+
```ts
|
|
191
|
+
AgentModule.forRoot({
|
|
192
|
+
// ceilings on the default ledger provider
|
|
193
|
+
quotaLimits: { day: { tokens: 200_000 }, month: { usd: 20 } },
|
|
194
|
+
// …or your own budget, e.g. an AI-gateway spend cap:
|
|
195
|
+
// quotaProvider: { report: async ({ actor }) => myGatewayBudget(actor.id) },
|
|
196
|
+
});
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
`GET /agent/quota/today` stays as it was.
|
|
200
|
+
|
|
147
201
|
### Who approves an action, and for how long
|
|
148
202
|
|
|
149
203
|
Every `action` tool call waits on the person chatting by default. `approvalPolicy` changes that per
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ModelProvider, AgentStore, ToolRegistry, RolesPolicy, ApprovalPolicy, QuotaStore, TokenStreamSink, PromptBuilder, PromptContributor, ToolTransientRetrySetting, Retriever, AgentPricingStore, HistoryPolicy, InputProcessor, OutputProcessor, AgentIntake, SkillsConfig, MemoryConfig, ToolSpec, ToolHandler, ActorResolver, AgentHistoryWindow, SkillProvider, ScopeResolver, MemoryProvider, AgentRegistry } from '@dudousxd/nestjs-agent-core';
|
|
1
|
+
import { ModelProvider, AgentStore, ToolRegistry, RolesPolicy, ApprovalPolicy, QuotaStore, TokenStreamSink, PromptBuilder, PromptContributor, ToolTransientRetrySetting, Retriever, AgentPricingStore, HistoryPolicy, InputProcessor, OutputProcessor, AgentIntake, SkillsConfig, MemoryConfig, ToolSpec, ToolHandler, QuotaProvider, QuotaQuery, QuotaReport, ModelCatalog, ActorResolver, AgentHistoryWindow, SkillProvider, ScopeResolver, MemoryProvider, AgentRegistry } from '@dudousxd/nestjs-agent-core';
|
|
2
2
|
import { StandardSchemaV1 } from '@standard-schema/spec';
|
|
3
3
|
import { Provider, FactoryProvider, Type, CanActivate, ModuleMetadata, InjectionToken, OptionalFactoryDependency } from '@nestjs/common';
|
|
4
4
|
|
|
@@ -87,6 +87,36 @@ interface FunctionalTool {
|
|
|
87
87
|
declare function provideAgentTool(tool: FunctionalTool): Provider;
|
|
88
88
|
declare function provideAgentTool(factory: (...deps: never[]) => FunctionalTool, inject?: FactoryProvider['inject']): Provider;
|
|
89
89
|
|
|
90
|
+
/** Ceilings for a {@link LedgerQuotaProvider} window. Either, both, or neither. */
|
|
91
|
+
interface QuotaWindowLimits {
|
|
92
|
+
tokens?: number;
|
|
93
|
+
usd?: number;
|
|
94
|
+
}
|
|
95
|
+
/** Per-window ceilings: `AgentModule.forRoot({ quotaLimits })`. */
|
|
96
|
+
interface QuotaLimits {
|
|
97
|
+
day?: QuotaWindowLimits;
|
|
98
|
+
month?: QuotaWindowLimits;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* The default {@link QuotaProvider}: windows read off the usage ledger the loop already writes.
|
|
102
|
+
*
|
|
103
|
+
* - `day` — always; `usedTokens`/limit come from the bound {@link QuotaStore} when there is one (so
|
|
104
|
+
* the report matches what the loop enforces), spend from the ledger.
|
|
105
|
+
* - `month` — when the store implements `usageBetween`.
|
|
106
|
+
*
|
|
107
|
+
* `limits` add ceilings per window (tokens and/or USD). A window that reaches one makes the report
|
|
108
|
+
* `blocked`.
|
|
109
|
+
*/
|
|
110
|
+
declare class LedgerQuotaProvider implements QuotaProvider {
|
|
111
|
+
private readonly store;
|
|
112
|
+
private readonly quota?;
|
|
113
|
+
private readonly limits;
|
|
114
|
+
constructor(store: AgentStore, quota?: QuotaStore | undefined, limits?: QuotaLimits);
|
|
115
|
+
report(query: QuotaQuery): Promise<QuotaReport>;
|
|
116
|
+
private dayWindow;
|
|
117
|
+
private window;
|
|
118
|
+
}
|
|
119
|
+
|
|
90
120
|
/**
|
|
91
121
|
* Which half of the module this process mounts — the split that lets an API pod and a WORKER pod
|
|
92
122
|
* each load `AgentModule` without either one doing the other's job:
|
|
@@ -199,6 +229,23 @@ interface AgentModuleOptions {
|
|
|
199
229
|
* `quotaLimitTokens` instead, which binds the built-in ledger-backed store.
|
|
200
230
|
*/
|
|
201
231
|
quota?: QuotaStore;
|
|
232
|
+
/**
|
|
233
|
+
* Which models a caller may pick — `GET <base>/models`, a send's `model`, a thread's pinned model
|
|
234
|
+
* (`PATCH <base>/threads/:id { model }`). The picked id reaches the {@link ModelProvider} as
|
|
235
|
+
* `ModelTurnArgs.model`. Omit → an empty catalog, and a request naming a model is refused.
|
|
236
|
+
*/
|
|
237
|
+
models?: ModelCatalog;
|
|
238
|
+
/**
|
|
239
|
+
* The actor's budget across windows, for `GET <base>/quota` — and, once set, a gate: a send whose
|
|
240
|
+
* report comes back `blocked` is refused with `429` before the turn starts. Default: a
|
|
241
|
+
* {@link LedgerQuotaProvider} over the usage ledger (reporting only, unless `quotaLimits` is set).
|
|
242
|
+
*/
|
|
243
|
+
quotaProvider?: QuotaProvider;
|
|
244
|
+
/**
|
|
245
|
+
* Ceilings for the default ledger provider's windows — `{ day?: { tokens?, usd? }, month?: {
|
|
246
|
+
* tokens?, usd? } }`. Setting it turns the send gate on. Ignored when `quotaProvider` is given.
|
|
247
|
+
*/
|
|
248
|
+
quotaLimits?: QuotaLimits;
|
|
202
249
|
/**
|
|
203
250
|
* Daily per-actor token budget, enforced against the persisted usage ledger by the built-in
|
|
204
251
|
* `LedgerQuotaStore`. A convenience over wiring a {@link QuotaStore} by hand — set this and quotas
|
|
@@ -473,4 +520,4 @@ declare class AgentDepsFactory {
|
|
|
473
520
|
private followUpsCount;
|
|
474
521
|
}
|
|
475
522
|
|
|
476
|
-
export { AgentDepsFactory as A, type FunctionalTool as F, type AgentSurface as a, type AgentModuleOptions as b, type AgentModuleAsyncOptions as c, type AgentSkillsOptions as d, AGENT_TOOL_BRAND as e, type AgentAttachmentsOptions as f, type AgentDeps as g, type AgentMemoryOptions as h,
|
|
523
|
+
export { AgentDepsFactory as A, type FunctionalTool as F, LedgerQuotaProvider as L, type QuotaLimits as Q, type AgentSurface as a, type AgentModuleOptions as b, type AgentModuleAsyncOptions as c, type AgentSkillsOptions as d, AGENT_TOOL_BRAND as e, type AgentAttachmentsOptions as f, type AgentDeps as g, type AgentMemoryOptions as h, type QuotaWindowLimits as i, delegateToolName as j, provideAgentTool as p, utcDay as u };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ModelProvider, AgentStore, ToolRegistry, RolesPolicy, ApprovalPolicy, QuotaStore, TokenStreamSink, PromptBuilder, PromptContributor, ToolTransientRetrySetting, Retriever, AgentPricingStore, HistoryPolicy, InputProcessor, OutputProcessor, AgentIntake, SkillsConfig, MemoryConfig, ToolSpec, ToolHandler, ActorResolver, AgentHistoryWindow, SkillProvider, ScopeResolver, MemoryProvider, AgentRegistry } from '@dudousxd/nestjs-agent-core';
|
|
1
|
+
import { ModelProvider, AgentStore, ToolRegistry, RolesPolicy, ApprovalPolicy, QuotaStore, TokenStreamSink, PromptBuilder, PromptContributor, ToolTransientRetrySetting, Retriever, AgentPricingStore, HistoryPolicy, InputProcessor, OutputProcessor, AgentIntake, SkillsConfig, MemoryConfig, ToolSpec, ToolHandler, QuotaProvider, QuotaQuery, QuotaReport, ModelCatalog, ActorResolver, AgentHistoryWindow, SkillProvider, ScopeResolver, MemoryProvider, AgentRegistry } from '@dudousxd/nestjs-agent-core';
|
|
2
2
|
import { StandardSchemaV1 } from '@standard-schema/spec';
|
|
3
3
|
import { Provider, FactoryProvider, Type, CanActivate, ModuleMetadata, InjectionToken, OptionalFactoryDependency } from '@nestjs/common';
|
|
4
4
|
|
|
@@ -87,6 +87,36 @@ interface FunctionalTool {
|
|
|
87
87
|
declare function provideAgentTool(tool: FunctionalTool): Provider;
|
|
88
88
|
declare function provideAgentTool(factory: (...deps: never[]) => FunctionalTool, inject?: FactoryProvider['inject']): Provider;
|
|
89
89
|
|
|
90
|
+
/** Ceilings for a {@link LedgerQuotaProvider} window. Either, both, or neither. */
|
|
91
|
+
interface QuotaWindowLimits {
|
|
92
|
+
tokens?: number;
|
|
93
|
+
usd?: number;
|
|
94
|
+
}
|
|
95
|
+
/** Per-window ceilings: `AgentModule.forRoot({ quotaLimits })`. */
|
|
96
|
+
interface QuotaLimits {
|
|
97
|
+
day?: QuotaWindowLimits;
|
|
98
|
+
month?: QuotaWindowLimits;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* The default {@link QuotaProvider}: windows read off the usage ledger the loop already writes.
|
|
102
|
+
*
|
|
103
|
+
* - `day` — always; `usedTokens`/limit come from the bound {@link QuotaStore} when there is one (so
|
|
104
|
+
* the report matches what the loop enforces), spend from the ledger.
|
|
105
|
+
* - `month` — when the store implements `usageBetween`.
|
|
106
|
+
*
|
|
107
|
+
* `limits` add ceilings per window (tokens and/or USD). A window that reaches one makes the report
|
|
108
|
+
* `blocked`.
|
|
109
|
+
*/
|
|
110
|
+
declare class LedgerQuotaProvider implements QuotaProvider {
|
|
111
|
+
private readonly store;
|
|
112
|
+
private readonly quota?;
|
|
113
|
+
private readonly limits;
|
|
114
|
+
constructor(store: AgentStore, quota?: QuotaStore | undefined, limits?: QuotaLimits);
|
|
115
|
+
report(query: QuotaQuery): Promise<QuotaReport>;
|
|
116
|
+
private dayWindow;
|
|
117
|
+
private window;
|
|
118
|
+
}
|
|
119
|
+
|
|
90
120
|
/**
|
|
91
121
|
* Which half of the module this process mounts — the split that lets an API pod and a WORKER pod
|
|
92
122
|
* each load `AgentModule` without either one doing the other's job:
|
|
@@ -199,6 +229,23 @@ interface AgentModuleOptions {
|
|
|
199
229
|
* `quotaLimitTokens` instead, which binds the built-in ledger-backed store.
|
|
200
230
|
*/
|
|
201
231
|
quota?: QuotaStore;
|
|
232
|
+
/**
|
|
233
|
+
* Which models a caller may pick — `GET <base>/models`, a send's `model`, a thread's pinned model
|
|
234
|
+
* (`PATCH <base>/threads/:id { model }`). The picked id reaches the {@link ModelProvider} as
|
|
235
|
+
* `ModelTurnArgs.model`. Omit → an empty catalog, and a request naming a model is refused.
|
|
236
|
+
*/
|
|
237
|
+
models?: ModelCatalog;
|
|
238
|
+
/**
|
|
239
|
+
* The actor's budget across windows, for `GET <base>/quota` — and, once set, a gate: a send whose
|
|
240
|
+
* report comes back `blocked` is refused with `429` before the turn starts. Default: a
|
|
241
|
+
* {@link LedgerQuotaProvider} over the usage ledger (reporting only, unless `quotaLimits` is set).
|
|
242
|
+
*/
|
|
243
|
+
quotaProvider?: QuotaProvider;
|
|
244
|
+
/**
|
|
245
|
+
* Ceilings for the default ledger provider's windows — `{ day?: { tokens?, usd? }, month?: {
|
|
246
|
+
* tokens?, usd? } }`. Setting it turns the send gate on. Ignored when `quotaProvider` is given.
|
|
247
|
+
*/
|
|
248
|
+
quotaLimits?: QuotaLimits;
|
|
202
249
|
/**
|
|
203
250
|
* Daily per-actor token budget, enforced against the persisted usage ledger by the built-in
|
|
204
251
|
* `LedgerQuotaStore`. A convenience over wiring a {@link QuotaStore} by hand — set this and quotas
|
|
@@ -473,4 +520,4 @@ declare class AgentDepsFactory {
|
|
|
473
520
|
private followUpsCount;
|
|
474
521
|
}
|
|
475
522
|
|
|
476
|
-
export { AgentDepsFactory as A, type FunctionalTool as F, type AgentSurface as a, type AgentModuleOptions as b, type AgentModuleAsyncOptions as c, type AgentSkillsOptions as d, AGENT_TOOL_BRAND as e, type AgentAttachmentsOptions as f, type AgentDeps as g, type AgentMemoryOptions as h,
|
|
523
|
+
export { AgentDepsFactory as A, type FunctionalTool as F, LedgerQuotaProvider as L, type QuotaLimits as Q, type AgentSurface as a, type AgentModuleOptions as b, type AgentModuleAsyncOptions as c, type AgentSkillsOptions as d, AGENT_TOOL_BRAND as e, type AgentAttachmentsOptions as f, type AgentDeps as g, type AgentMemoryOptions as h, type QuotaWindowLimits as i, delegateToolName as j, provideAgentTool as p, utcDay as u };
|