@dudousxd/nestjs-agent 0.11.1 → 0.13.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 +60 -0
- package/dist/{agent-deps.factory-D7GdhqdK.d.cts → agent-deps.factory-y2hvoQ6U.d.cts} +200 -16
- package/dist/{agent-deps.factory-D7GdhqdK.d.ts → agent-deps.factory-y2hvoQ6U.d.ts} +200 -16
- package/dist/durable/index.cjs +1735 -499
- package/dist/durable/index.cjs.map +1 -1
- package/dist/durable/index.d.cts +84 -38
- package/dist/durable/index.d.ts +84 -38
- package/dist/durable/index.js +1675 -439
- package/dist/durable/index.js.map +1 -1
- package/dist/index.cjs +1349 -284
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +415 -26
- package/dist/index.d.ts +415 -26
- package/dist/index.js +1289 -234
- package/dist/index.js.map +1 -1
- package/package.json +5 -4
package/README.md
CHANGED
|
@@ -41,6 +41,66 @@ The module mounts SSE + REST endpoints under `/agent` (`POST /agent/chat`, tool-
|
|
|
41
41
|
threads, quota). Add `durable: true` + `AgentDurableModule` for the durable runner;
|
|
42
42
|
`AgentModule.forFeature([…])` for multi-agent orchestration.
|
|
43
43
|
|
|
44
|
+
### Message attachments
|
|
45
|
+
|
|
46
|
+
A chat turn attaches a file by **`mediaId` only**:
|
|
47
|
+
|
|
48
|
+
```jsonc
|
|
49
|
+
POST /agent/chat
|
|
50
|
+
{ "message": "what is in this?", "attachments": [{ "mediaId": "med_8f21…" }] }
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Every other field a client sends with it is discarded. The url the model provider fetches is read
|
|
54
|
+
back from the `AttachmentStagingStore` bound to `AGENT_ATTACHMENT_STAGING`, whose `resolve({ mediaId,
|
|
55
|
+
actor })` returns the attachment or `null` when the id is unknown or is not that actor's — so a
|
|
56
|
+
caller can never point the server at a url it chose (link-local metadata, an internal service), and
|
|
57
|
+
never at another actor's file. Resolution happens per turn, so a short-lived presigned url is minted
|
|
58
|
+
fresh rather than replayed from the stored message.
|
|
59
|
+
|
|
60
|
+
With nothing bound to `AGENT_ATTACHMENT_STAGING` there is no way to tell whose media an id is, so a
|
|
61
|
+
turn carrying attachments is refused with `501`. Text-only turns are unaffected. At most 10
|
|
62
|
+
attachments per turn.
|
|
63
|
+
|
|
64
|
+
The optional `POST /agent/attachments` upload route (`attachments: { upload: true }`) aborts a body
|
|
65
|
+
larger than `HARD_MAX_ATTACHMENT_BYTES` (32 MiB) while it streams; `attachments.maxBytes` narrows
|
|
66
|
+
that ceiling at request time and cannot raise it.
|
|
67
|
+
|
|
68
|
+
### Sweeping attachments nobody sent
|
|
69
|
+
|
|
70
|
+
`stage()` writes bytes before any message exists, so a user who attaches a file and then never sends
|
|
71
|
+
it leaves media with nothing pointing at it. Two optional methods make that findable — `list` on
|
|
72
|
+
your `AttachmentStagingStore` (you stored the bytes, so only you can enumerate them) and
|
|
73
|
+
`referencedMediaIds` on your `AgentStore` (only it can see which media a live message carries).
|
|
74
|
+
|
|
75
|
+
```ts
|
|
76
|
+
// a job the host runs; nothing here is reachable over HTTP
|
|
77
|
+
const olderThan = new Date(Date.now() - 48 * 60 * 60 * 1000);
|
|
78
|
+
for (const entry of await agents.collectableAttachments(actor, { olderThan })) {
|
|
79
|
+
await myMediaStore.delete(entry.mediaId); // the library never deletes your bytes
|
|
80
|
+
}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
`olderThan` is required and has no default: freshly staged media is an upload in flight, not
|
|
84
|
+
garbage, and only you know how long one of your composers may sit open. It is pushed down to `list`
|
|
85
|
+
and re-applied to the result, so a store that ignores the hint still cannot delete a live upload.
|
|
86
|
+
|
|
87
|
+
References are re-derived on every call rather than latched, because `truncateFrom` — which is what
|
|
88
|
+
regenerating a turn does — deletes messages and frees their media again. If either method is
|
|
89
|
+
missing the call raises `501` rather than reporting everything as collectable.
|
|
90
|
+
|
|
91
|
+
`GET /agent/attachments` returns the caller's own staged files as metadata (no urls — those are
|
|
92
|
+
minted per turn by `resolve`), bounded to `ATTACHMENT_PAGE_SIZE`, and rides the same
|
|
93
|
+
`attachments: { upload: true }` flag. It takes no `threadId` filter: a thread's attachments already
|
|
94
|
+
ride on its messages in `GET /agent/threads/:id`.
|
|
95
|
+
|
|
96
|
+
### Who may read a run
|
|
97
|
+
|
|
98
|
+
`GET /agent/chat/:runId/stream` and `POST /agent/chat/:runId/cancel` both resolve the acting actor
|
|
99
|
+
and require they own the run currently streaming — `403` for another actor's run, `404` for a run
|
|
100
|
+
nobody is streaming (including one that has already finished). In-process callers that are
|
|
101
|
+
authorized elsewhere use `AgentService.subscribe(runId)`; anything reachable from a request must go
|
|
102
|
+
through `AgentService.subscribeAs(actor, runId)`.
|
|
103
|
+
|
|
44
104
|
### Deploying split API/worker pods
|
|
45
105
|
|
|
46
106
|
By default `AgentModule`/`AgentDurableModule` wire everything: every controller, the `agent.run`
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { ModelProvider, AgentStore, ToolRegistry, RolesPolicy, QuotaStore, TokenStreamSink, PromptBuilder, PromptContributor, ToolTransientRetrySetting, Retriever, AgentPricingStore, ToolSpec, ToolHandler, ActorResolver, AgentRegistry } from '@dudousxd/nestjs-agent-core';
|
|
1
|
+
import { ModelProvider, AgentStore, ToolRegistry, RolesPolicy, 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';
|
|
2
|
+
import { StandardSchemaV1 } from '@standard-schema/spec';
|
|
2
3
|
import { Provider, FactoryProvider, Type, CanActivate, ModuleMetadata, InjectionToken, OptionalFactoryDependency } from '@nestjs/common';
|
|
3
4
|
|
|
4
5
|
/** Everything `runAgentLoop` needs, minus the per-run `day` the runner stamps. */
|
|
@@ -15,6 +16,10 @@ interface AgentDeps {
|
|
|
15
16
|
/** App-wide `@SystemPromptContributor()` sections appended after the agent's base prompt. */
|
|
16
17
|
promptContributors: PromptContributor[];
|
|
17
18
|
maxSteps: number;
|
|
19
|
+
/** Nesting ceiling for delegation below this agent. Undefined → the loop's default. */
|
|
20
|
+
maxDelegationDepth?: number;
|
|
21
|
+
/** How many times one agent may appear on a chain. Undefined → the loop's default. */
|
|
22
|
+
maxAgentAppearances?: number;
|
|
18
23
|
/** Agent-level tool allow-list. Undefined → all tools (after role filtering). */
|
|
19
24
|
toolAllowList?: string[];
|
|
20
25
|
/** Per-tool execution timeout in ms (from module options). Undefined → no timeout. */
|
|
@@ -32,6 +37,30 @@ interface AgentDeps {
|
|
|
32
37
|
retrievalTopK?: number;
|
|
33
38
|
/** Bound `AGENT_PRICING_STORE`, when a module (e.g. a store's) provides one. Undefined → no pricing. */
|
|
34
39
|
pricingStore?: AgentPricingStore;
|
|
40
|
+
/** The agent's history ceiling, resolved from `@Agent({ history })` / module options. Undefined → unbounded. */
|
|
41
|
+
historyPolicy?: HistoryPolicy;
|
|
42
|
+
/** Module-wide prompt rewriters, applied before every model call. Empty → none. */
|
|
43
|
+
inputProcessors: InputProcessor[];
|
|
44
|
+
/** Module-wide answer gates. NON-EMPTY MEANS THE TURN'S MODEL OUTPUT IS BUFFERED, not streamed. */
|
|
45
|
+
outputProcessors: OutputProcessor[];
|
|
46
|
+
/** The agent's `@Agent({ outputSchema })`, resolved from DI — never over the wire. Undefined → free text. */
|
|
47
|
+
outputSchema?: StandardSchemaV1;
|
|
48
|
+
/** Extra model calls allowed to repair an answer that failed `outputSchema`. Undefined → 1. */
|
|
49
|
+
outputRepairAttempts?: number;
|
|
50
|
+
/** The agent's `@Agent({ intake })` question set, asked before the turn starts. Undefined → none. */
|
|
51
|
+
intake?: AgentIntake;
|
|
52
|
+
/** Whether the model may call the built-in `ask` tool this turn. Undefined/false → it never sees it. */
|
|
53
|
+
ask?: boolean;
|
|
54
|
+
/**
|
|
55
|
+
* The resolved skills seam (`forRoot({ skills })` + discovered `@Skill` providers). Undefined →
|
|
56
|
+
* no catalog, no `skill` tool, and the turn spends no checkpoint on either.
|
|
57
|
+
*/
|
|
58
|
+
skills?: SkillsConfig;
|
|
59
|
+
/**
|
|
60
|
+
* The resolved memory seam (`forRoot({ memory })`). Undefined → no block, no `remember` tool, and
|
|
61
|
+
* the turn spends no checkpoint on either.
|
|
62
|
+
*/
|
|
63
|
+
memory?: MemoryConfig;
|
|
35
64
|
}
|
|
36
65
|
declare function utcDay(date?: Date): string;
|
|
37
66
|
|
|
@@ -96,6 +125,61 @@ interface AgentAttachmentsOptions {
|
|
|
96
125
|
*/
|
|
97
126
|
upload?: boolean;
|
|
98
127
|
}
|
|
128
|
+
/**
|
|
129
|
+
* `AgentModuleOptions.skills` — where a turn's skills come from, and which scopes an actor draws
|
|
130
|
+
* them from. Its PRESENCE turns skills on: `skills: {}` offers whatever the `@Skill`-decorated
|
|
131
|
+
* providers declare, resolved against the actor's own, their tenant's and the deployment's scopes.
|
|
132
|
+
*/
|
|
133
|
+
interface AgentSkillsOptions {
|
|
134
|
+
/**
|
|
135
|
+
* A provider of your own — skills a host stores and administers itself (per user, per sector, per
|
|
136
|
+
* base). Merged with the discovered `@Skill` classes, and outranking them for a name published at
|
|
137
|
+
* the same scope. Omit → the decorated classes are the whole catalog.
|
|
138
|
+
*/
|
|
139
|
+
provider?: SkillProvider;
|
|
140
|
+
/**
|
|
141
|
+
* Which scope tokens an actor draws from, most specific first — the precedence order. Omit → the
|
|
142
|
+
* actor's own (`actor:<id>`), their tenant's (`tenant:<ref>`, when they have one), and `global`.
|
|
143
|
+
* Supply one to add an axis this library has no key for: a sector, a squadron, a shift.
|
|
144
|
+
*/
|
|
145
|
+
scopes?: ScopeResolver;
|
|
146
|
+
/**
|
|
147
|
+
* How many skills the catalog block offers before it starts leaving the widest ones out. Omit →
|
|
148
|
+
* 20. A ceiling on what the SYSTEM PROMPT carries, not on how many a deployment may hold.
|
|
149
|
+
*/
|
|
150
|
+
maxSkills?: number;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* `AgentModuleOptions.memory` — where what the assistant concluded about a person is stored, and how
|
|
154
|
+
* much of it a turn may carry. Its PRESENCE turns memory on.
|
|
155
|
+
*
|
|
156
|
+
* Unlike `skills`, there is no decorator and no zero-config form: a memory is by definition something
|
|
157
|
+
* the agent worked out about someone, so a memory a developer wrote in a class would be an
|
|
158
|
+
* instruction wearing a memory's clothes — which is what `@Skill` and `@SystemPromptContributor()`
|
|
159
|
+
* are for. The rows are the host's from the start.
|
|
160
|
+
*/
|
|
161
|
+
interface AgentMemoryOptions {
|
|
162
|
+
/**
|
|
163
|
+
* Where the rows live. `forget` is required on it; `write` is what decides the `remember` tool;
|
|
164
|
+
* `search` is what decides whether a turn's block is selected by relevance or read whole. Supply
|
|
165
|
+
* `search` once the applicable set outgrows `maxMemories` — without it the ceiling selects by
|
|
166
|
+
* scope, and the widest scopes are the ones it starves.
|
|
167
|
+
*/
|
|
168
|
+
provider: MemoryProvider;
|
|
169
|
+
/**
|
|
170
|
+
* Which scope tokens an actor draws from, most specific first — the precedence order, and the same
|
|
171
|
+
* seam `skills` uses. Omit → the actor's own, their tenant's, and `global`.
|
|
172
|
+
*/
|
|
173
|
+
scopes?: ScopeResolver;
|
|
174
|
+
/**
|
|
175
|
+
* How many memories the block carries. Omit → 20. A budget on the PROMPT, never on the store: with
|
|
176
|
+
* a provider that can `search`, this is how many matter right now rather than how many a person
|
|
177
|
+
* may have. Always-on (`pinned`) memories are taken from it first.
|
|
178
|
+
*/
|
|
179
|
+
maxMemories?: number;
|
|
180
|
+
/** How long one memory may be, checked when it is written. Omit → 240. */
|
|
181
|
+
maxFactChars?: number;
|
|
182
|
+
}
|
|
99
183
|
interface AgentModuleOptions {
|
|
100
184
|
/** The LLM provider (e.g. a Vercel AI SDK wrapper). Required. */
|
|
101
185
|
model: ModelProvider;
|
|
@@ -139,11 +223,19 @@ interface AgentModuleOptions {
|
|
|
139
223
|
durable?: boolean;
|
|
140
224
|
/**
|
|
141
225
|
* Dispatch the turn's model call and tool executions as routed durable steps
|
|
142
|
-
* (`AgentRunSteps.llm` / `AgentRunSteps.tool`) instead of in-process `ctx.localStep`s.
|
|
143
|
-
*
|
|
144
|
-
*
|
|
145
|
-
*
|
|
146
|
-
*
|
|
226
|
+
* (`AgentRunSteps.llm` / `AgentRunSteps.tool`) instead of in-process `ctx.localStep`s. OMITTED
|
|
227
|
+
* keeps them in-process; `true` without `durable: true` throws at module build.
|
|
228
|
+
*
|
|
229
|
+
* WHAT IT BUYS: the run is not pinned to one pod for the two long parts of a turn, so a fleet can
|
|
230
|
+
* scale the model call and tool execution separately from the workflow itself.
|
|
231
|
+
*
|
|
232
|
+
* WHY IT IS NOT A DEFAULT. It relocates the HOST's own code. A tool handler no longer runs inside
|
|
233
|
+
* the turn's workflow body but inside whichever worker serves the routed group, and the `llm`
|
|
234
|
+
* step re-runs the host's tool-visibility callbacks there to rebuild its tool list. A handler
|
|
235
|
+
* that resolves anything per invocation from its caller's execution context — a request-scoped
|
|
236
|
+
* ORM EntityManager, an AsyncLocalStorage tenant, a CLS transaction — finds nothing in that
|
|
237
|
+
* worker, and the library has no way to know which handlers do that. Turn this on once the tools
|
|
238
|
+
* this deployment registers establish whatever context they need themselves.
|
|
147
239
|
*
|
|
148
240
|
* The cross-process-sink requirement is a property of `durable: true` itself, not of this flag:
|
|
149
241
|
* the turn already runs on whichever worker takes `agent.run`, which may not be the pod holding
|
|
@@ -191,6 +283,75 @@ interface AgentModuleOptions {
|
|
|
191
283
|
retriever: Retriever;
|
|
192
284
|
topK?: number;
|
|
193
285
|
};
|
|
286
|
+
/**
|
|
287
|
+
* Bounds how much of a thread rides into each turn. Omit and a turn carries EVERY message the
|
|
288
|
+
* thread holds, so a long-lived thread costs more each time and eventually exceeds the model's
|
|
289
|
+
* context limit outright. `{ maxMessages }` and/or `{ maxTokens }` keep the newest that fit;
|
|
290
|
+
* `{ summarize: true }` folds what they left out into a leading summary, at the price of one extra
|
|
291
|
+
* model call per run (recorded as `history_summary` usage). An agent can override this for itself
|
|
292
|
+
* with `@Agent({ history })`.
|
|
293
|
+
*/
|
|
294
|
+
history?: AgentHistoryWindow;
|
|
295
|
+
/**
|
|
296
|
+
* A {@link HistoryPolicy} of your own — for a window the built-in can't express (pinning the
|
|
297
|
+
* thread's opening brief, keeping every message that carries a tool result, a budget that varies
|
|
298
|
+
* by actor). A convenience-vs-custom pair like `quotaLimitTokens`/`quota`: this outranks a
|
|
299
|
+
* module-wide `history`, and `@Agent({ history })` outranks both for the agent that declares it.
|
|
300
|
+
* `select` MUST be pure — see the SPI's determinism contract.
|
|
301
|
+
*/
|
|
302
|
+
historyPolicy?: HistoryPolicy;
|
|
303
|
+
/**
|
|
304
|
+
* Rewrites the prompt before every model call — masking identifiers, stamping a policy preamble,
|
|
305
|
+
* trimming an oversized tool result. Applies to EVERY agent: a transformation one persona can opt
|
|
306
|
+
* out of is not a control. Transformation only; `history`/`historyPolicy` still own which messages
|
|
307
|
+
* are there to transform. A processor needing DI-resolved dependencies is built in
|
|
308
|
+
* `forRootAsync`'s `useFactory` (which has `inject`), the same way `retrieval.retriever` is.
|
|
309
|
+
*/
|
|
310
|
+
inputProcessors?: InputProcessor[];
|
|
311
|
+
/**
|
|
312
|
+
* Gates every model answer before the stream, the store or the next step sees it — redact,
|
|
313
|
+
* replace, or refuse the turn outright (which fails it with an `output_rejected` stream error).
|
|
314
|
+
*
|
|
315
|
+
* REGISTERING ONE TURNS OFF LIVE TOKEN STREAMING. Reading the whole answer and streaming it as it
|
|
316
|
+
* is generated cannot both be true, so the turn's model output is buffered and released in one
|
|
317
|
+
* frame once the chain passes. That is the price of a gate that actually gates; see
|
|
318
|
+
* `AgentLoopDeps.outputProcessors` for exactly what a subscriber still receives live.
|
|
319
|
+
*/
|
|
320
|
+
outputProcessors?: OutputProcessor[];
|
|
321
|
+
/**
|
|
322
|
+
* Offer every agent the built-in `ask` tool, so the model can put its own clarifying question set
|
|
323
|
+
* to the user when it judges the scope is missing. The turn parks on the answers exactly as it
|
|
324
|
+
* parks on a HITL approval, and they arrive through `POST /agent/tool-call/answer`.
|
|
325
|
+
*
|
|
326
|
+
* `ask` is not a registered tool and has no handler — the loop settles it against a person — so no
|
|
327
|
+
* `RolesPolicy` gates it: asking a question performs nothing. An `@Agent({ ask })` overrides this
|
|
328
|
+
* for one persona. Omit → the model never sees it, and nothing about a turn changes.
|
|
329
|
+
*/
|
|
330
|
+
ask?: boolean;
|
|
331
|
+
/**
|
|
332
|
+
* Authored procedures any agent may pull in when a task calls for one — per-user, per-tenant or
|
|
333
|
+
* deployment-wide, with the most specific winning. Declared as `@Skill`-decorated providers and/or
|
|
334
|
+
* served by a `provider` of your own; offered to the model as a one-line-each catalog it loads
|
|
335
|
+
* from on demand, so an instruction costs a prompt only on the turns that need it.
|
|
336
|
+
*
|
|
337
|
+
* Omit → no catalog, no `skill` tool, and a turn's checkpoint sequence is byte-identical to one
|
|
338
|
+
* that never had the option. See {@link AgentSkillsOptions}.
|
|
339
|
+
*/
|
|
340
|
+
skills?: AgentSkillsOptions;
|
|
341
|
+
/**
|
|
342
|
+
* What the assistant has concluded about the actor and their organisation, carried into every turn
|
|
343
|
+
* as a bounded block of one-line facts and written by the model through a built-in `remember` tool.
|
|
344
|
+
*
|
|
345
|
+
* NOT the same thing as retrieval, and not a second name for it: `retrieval` answers from documents
|
|
346
|
+
* a person curated and can fix at the source, memory answers from the agent's own inferences about
|
|
347
|
+
* someone who never saw them written. That is why the rows carry an origin, why the block tells the
|
|
348
|
+
* model they may be wrong, and why `GET /agent/memories` + `DELETE /agent/memories/:id` are part of
|
|
349
|
+
* the feature rather than an optional console.
|
|
350
|
+
*
|
|
351
|
+
* Omit → no block, no `remember` tool, and a turn's checkpoint sequence is byte-identical to one
|
|
352
|
+
* that never had the option. See {@link AgentMemoryOptions}.
|
|
353
|
+
*/
|
|
354
|
+
memory?: AgentMemoryOptions;
|
|
194
355
|
/**
|
|
195
356
|
* The name of the agent a turn uses when the caller doesn't select one. Omit → the single
|
|
196
357
|
* discovered `@Agent` (when there is exactly one), else `'default'` (a bare assistant if no
|
|
@@ -230,12 +391,11 @@ interface AgentModuleAsyncOptions extends Pick<ModuleMetadata, 'imports'> {
|
|
|
230
391
|
*/
|
|
231
392
|
durable?: boolean;
|
|
232
393
|
/**
|
|
233
|
-
* Dispatch the turn's model call and tool executions as routed durable steps.
|
|
234
|
-
*
|
|
235
|
-
*
|
|
236
|
-
*
|
|
237
|
-
* `
|
|
238
|
-
* contract.
|
|
394
|
+
* Dispatch the turn's model call and tool executions as routed durable steps. Omitted keeps the
|
|
395
|
+
* turn's steps in-process localSteps. Same static-wiring reasoning as `durable` above — it lives
|
|
396
|
+
* here (not in the async factory result) because it decides how `AgentRunWorkflow` builds its
|
|
397
|
+
* hooks at module build time. `true` without `durable: true` throws at module build. See
|
|
398
|
+
* `AgentModuleOptions.dispatchedSteps` for the full contract.
|
|
239
399
|
*/
|
|
240
400
|
dispatchedSteps?: boolean;
|
|
241
401
|
/**
|
|
@@ -273,8 +433,18 @@ interface AgentModuleAsyncOptions extends Pick<ModuleMetadata, 'imports'> {
|
|
|
273
433
|
surface?: AgentSurface;
|
|
274
434
|
}
|
|
275
435
|
|
|
276
|
-
/**
|
|
277
|
-
|
|
436
|
+
/**
|
|
437
|
+
* The synthesized `agent`-kind tool name an orchestrator uses to hand off to `target`.
|
|
438
|
+
*
|
|
439
|
+
* A detached edge gets its own verb — `start_research` next to `ask_research` — for two reasons.
|
|
440
|
+
* One agent can be both awaited AND backgrounded by the same orchestrator, and one name cannot
|
|
441
|
+
* carry both. And the name is the part of a tool the model reads first: `ask` promises an answer,
|
|
442
|
+
* `start` does not.
|
|
443
|
+
*/
|
|
444
|
+
declare function delegateToolName(args: {
|
|
445
|
+
target: string;
|
|
446
|
+
detached?: boolean;
|
|
447
|
+
}): string;
|
|
278
448
|
/** Builds the per-agent loop deps. The single-agent case is just the one registered `@Agent`. */
|
|
279
449
|
declare class AgentDepsFactory {
|
|
280
450
|
private readonly options;
|
|
@@ -287,7 +457,13 @@ declare class AgentDepsFactory {
|
|
|
287
457
|
private readonly promptContributors;
|
|
288
458
|
private readonly quota;
|
|
289
459
|
private readonly pricingStore;
|
|
290
|
-
|
|
460
|
+
private readonly skills;
|
|
461
|
+
private readonly memory;
|
|
462
|
+
constructor(options: AgentModuleOptions, model: ModelProvider, store: AgentStore, sink: TokenStreamSink, rolesPolicy: RolesPolicy, registry: ToolRegistry, agents: AgentRegistry, promptContributors: PromptContributor[], quota: QuotaStore | undefined, pricingStore: AgentPricingStore | undefined, skills: SkillsConfig | undefined, memory: MemoryConfig | undefined);
|
|
463
|
+
/** The turn's memory seam, shared with the read-back endpoint. Undefined → memory is not configured. */
|
|
464
|
+
memoryConfig(): MemoryConfig | undefined;
|
|
465
|
+
/** The turn's skills seam, shared with the listing endpoint. Undefined → skills are not configured. */
|
|
466
|
+
skillsConfig(): SkillsConfig | undefined;
|
|
291
467
|
/**
|
|
292
468
|
* The agent a turn uses when the caller names none: the explicit `defaultAgent` option, else the
|
|
293
469
|
* sole registered `@Agent` when there is exactly one, else `'default'` (a bare assistant).
|
|
@@ -295,8 +471,16 @@ declare class AgentDepsFactory {
|
|
|
295
471
|
defaultAgentName(): string;
|
|
296
472
|
private effectiveTools;
|
|
297
473
|
forAgent(agentName?: string): AgentDeps;
|
|
474
|
+
/**
|
|
475
|
+
* The ceiling on how much of a thread this agent's turns carry, most specific wins: the agent's
|
|
476
|
+
* own `@Agent({ history })`, else a module-wide custom `historyPolicy`, else the module-wide
|
|
477
|
+
* `history` window. Undefined → unbounded, the behaviour of a module that configures none.
|
|
478
|
+
*/
|
|
479
|
+
private historyPolicy;
|
|
480
|
+
/** Build the built-in window policy from the declarative `{ maxMessages, maxTokens, summarize }`. */
|
|
481
|
+
private window;
|
|
298
482
|
/** Normalize the `followUps` option (`true` → 3, `{ count }` → count) to a number, or undefined. */
|
|
299
483
|
private followUpsCount;
|
|
300
484
|
}
|
|
301
485
|
|
|
302
|
-
export { AgentDepsFactory as A, type FunctionalTool as F, type AgentSurface as a, type AgentModuleOptions as b, type AgentModuleAsyncOptions as c,
|
|
486
|
+
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, delegateToolName as i, provideAgentTool as p, utcDay as u };
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { ModelProvider, AgentStore, ToolRegistry, RolesPolicy, QuotaStore, TokenStreamSink, PromptBuilder, PromptContributor, ToolTransientRetrySetting, Retriever, AgentPricingStore, ToolSpec, ToolHandler, ActorResolver, AgentRegistry } from '@dudousxd/nestjs-agent-core';
|
|
1
|
+
import { ModelProvider, AgentStore, ToolRegistry, RolesPolicy, 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';
|
|
2
|
+
import { StandardSchemaV1 } from '@standard-schema/spec';
|
|
2
3
|
import { Provider, FactoryProvider, Type, CanActivate, ModuleMetadata, InjectionToken, OptionalFactoryDependency } from '@nestjs/common';
|
|
3
4
|
|
|
4
5
|
/** Everything `runAgentLoop` needs, minus the per-run `day` the runner stamps. */
|
|
@@ -15,6 +16,10 @@ interface AgentDeps {
|
|
|
15
16
|
/** App-wide `@SystemPromptContributor()` sections appended after the agent's base prompt. */
|
|
16
17
|
promptContributors: PromptContributor[];
|
|
17
18
|
maxSteps: number;
|
|
19
|
+
/** Nesting ceiling for delegation below this agent. Undefined → the loop's default. */
|
|
20
|
+
maxDelegationDepth?: number;
|
|
21
|
+
/** How many times one agent may appear on a chain. Undefined → the loop's default. */
|
|
22
|
+
maxAgentAppearances?: number;
|
|
18
23
|
/** Agent-level tool allow-list. Undefined → all tools (after role filtering). */
|
|
19
24
|
toolAllowList?: string[];
|
|
20
25
|
/** Per-tool execution timeout in ms (from module options). Undefined → no timeout. */
|
|
@@ -32,6 +37,30 @@ interface AgentDeps {
|
|
|
32
37
|
retrievalTopK?: number;
|
|
33
38
|
/** Bound `AGENT_PRICING_STORE`, when a module (e.g. a store's) provides one. Undefined → no pricing. */
|
|
34
39
|
pricingStore?: AgentPricingStore;
|
|
40
|
+
/** The agent's history ceiling, resolved from `@Agent({ history })` / module options. Undefined → unbounded. */
|
|
41
|
+
historyPolicy?: HistoryPolicy;
|
|
42
|
+
/** Module-wide prompt rewriters, applied before every model call. Empty → none. */
|
|
43
|
+
inputProcessors: InputProcessor[];
|
|
44
|
+
/** Module-wide answer gates. NON-EMPTY MEANS THE TURN'S MODEL OUTPUT IS BUFFERED, not streamed. */
|
|
45
|
+
outputProcessors: OutputProcessor[];
|
|
46
|
+
/** The agent's `@Agent({ outputSchema })`, resolved from DI — never over the wire. Undefined → free text. */
|
|
47
|
+
outputSchema?: StandardSchemaV1;
|
|
48
|
+
/** Extra model calls allowed to repair an answer that failed `outputSchema`. Undefined → 1. */
|
|
49
|
+
outputRepairAttempts?: number;
|
|
50
|
+
/** The agent's `@Agent({ intake })` question set, asked before the turn starts. Undefined → none. */
|
|
51
|
+
intake?: AgentIntake;
|
|
52
|
+
/** Whether the model may call the built-in `ask` tool this turn. Undefined/false → it never sees it. */
|
|
53
|
+
ask?: boolean;
|
|
54
|
+
/**
|
|
55
|
+
* The resolved skills seam (`forRoot({ skills })` + discovered `@Skill` providers). Undefined →
|
|
56
|
+
* no catalog, no `skill` tool, and the turn spends no checkpoint on either.
|
|
57
|
+
*/
|
|
58
|
+
skills?: SkillsConfig;
|
|
59
|
+
/**
|
|
60
|
+
* The resolved memory seam (`forRoot({ memory })`). Undefined → no block, no `remember` tool, and
|
|
61
|
+
* the turn spends no checkpoint on either.
|
|
62
|
+
*/
|
|
63
|
+
memory?: MemoryConfig;
|
|
35
64
|
}
|
|
36
65
|
declare function utcDay(date?: Date): string;
|
|
37
66
|
|
|
@@ -96,6 +125,61 @@ interface AgentAttachmentsOptions {
|
|
|
96
125
|
*/
|
|
97
126
|
upload?: boolean;
|
|
98
127
|
}
|
|
128
|
+
/**
|
|
129
|
+
* `AgentModuleOptions.skills` — where a turn's skills come from, and which scopes an actor draws
|
|
130
|
+
* them from. Its PRESENCE turns skills on: `skills: {}` offers whatever the `@Skill`-decorated
|
|
131
|
+
* providers declare, resolved against the actor's own, their tenant's and the deployment's scopes.
|
|
132
|
+
*/
|
|
133
|
+
interface AgentSkillsOptions {
|
|
134
|
+
/**
|
|
135
|
+
* A provider of your own — skills a host stores and administers itself (per user, per sector, per
|
|
136
|
+
* base). Merged with the discovered `@Skill` classes, and outranking them for a name published at
|
|
137
|
+
* the same scope. Omit → the decorated classes are the whole catalog.
|
|
138
|
+
*/
|
|
139
|
+
provider?: SkillProvider;
|
|
140
|
+
/**
|
|
141
|
+
* Which scope tokens an actor draws from, most specific first — the precedence order. Omit → the
|
|
142
|
+
* actor's own (`actor:<id>`), their tenant's (`tenant:<ref>`, when they have one), and `global`.
|
|
143
|
+
* Supply one to add an axis this library has no key for: a sector, a squadron, a shift.
|
|
144
|
+
*/
|
|
145
|
+
scopes?: ScopeResolver;
|
|
146
|
+
/**
|
|
147
|
+
* How many skills the catalog block offers before it starts leaving the widest ones out. Omit →
|
|
148
|
+
* 20. A ceiling on what the SYSTEM PROMPT carries, not on how many a deployment may hold.
|
|
149
|
+
*/
|
|
150
|
+
maxSkills?: number;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* `AgentModuleOptions.memory` — where what the assistant concluded about a person is stored, and how
|
|
154
|
+
* much of it a turn may carry. Its PRESENCE turns memory on.
|
|
155
|
+
*
|
|
156
|
+
* Unlike `skills`, there is no decorator and no zero-config form: a memory is by definition something
|
|
157
|
+
* the agent worked out about someone, so a memory a developer wrote in a class would be an
|
|
158
|
+
* instruction wearing a memory's clothes — which is what `@Skill` and `@SystemPromptContributor()`
|
|
159
|
+
* are for. The rows are the host's from the start.
|
|
160
|
+
*/
|
|
161
|
+
interface AgentMemoryOptions {
|
|
162
|
+
/**
|
|
163
|
+
* Where the rows live. `forget` is required on it; `write` is what decides the `remember` tool;
|
|
164
|
+
* `search` is what decides whether a turn's block is selected by relevance or read whole. Supply
|
|
165
|
+
* `search` once the applicable set outgrows `maxMemories` — without it the ceiling selects by
|
|
166
|
+
* scope, and the widest scopes are the ones it starves.
|
|
167
|
+
*/
|
|
168
|
+
provider: MemoryProvider;
|
|
169
|
+
/**
|
|
170
|
+
* Which scope tokens an actor draws from, most specific first — the precedence order, and the same
|
|
171
|
+
* seam `skills` uses. Omit → the actor's own, their tenant's, and `global`.
|
|
172
|
+
*/
|
|
173
|
+
scopes?: ScopeResolver;
|
|
174
|
+
/**
|
|
175
|
+
* How many memories the block carries. Omit → 20. A budget on the PROMPT, never on the store: with
|
|
176
|
+
* a provider that can `search`, this is how many matter right now rather than how many a person
|
|
177
|
+
* may have. Always-on (`pinned`) memories are taken from it first.
|
|
178
|
+
*/
|
|
179
|
+
maxMemories?: number;
|
|
180
|
+
/** How long one memory may be, checked when it is written. Omit → 240. */
|
|
181
|
+
maxFactChars?: number;
|
|
182
|
+
}
|
|
99
183
|
interface AgentModuleOptions {
|
|
100
184
|
/** The LLM provider (e.g. a Vercel AI SDK wrapper). Required. */
|
|
101
185
|
model: ModelProvider;
|
|
@@ -139,11 +223,19 @@ interface AgentModuleOptions {
|
|
|
139
223
|
durable?: boolean;
|
|
140
224
|
/**
|
|
141
225
|
* Dispatch the turn's model call and tool executions as routed durable steps
|
|
142
|
-
* (`AgentRunSteps.llm` / `AgentRunSteps.tool`) instead of in-process `ctx.localStep`s.
|
|
143
|
-
*
|
|
144
|
-
*
|
|
145
|
-
*
|
|
146
|
-
*
|
|
226
|
+
* (`AgentRunSteps.llm` / `AgentRunSteps.tool`) instead of in-process `ctx.localStep`s. OMITTED
|
|
227
|
+
* keeps them in-process; `true` without `durable: true` throws at module build.
|
|
228
|
+
*
|
|
229
|
+
* WHAT IT BUYS: the run is not pinned to one pod for the two long parts of a turn, so a fleet can
|
|
230
|
+
* scale the model call and tool execution separately from the workflow itself.
|
|
231
|
+
*
|
|
232
|
+
* WHY IT IS NOT A DEFAULT. It relocates the HOST's own code. A tool handler no longer runs inside
|
|
233
|
+
* the turn's workflow body but inside whichever worker serves the routed group, and the `llm`
|
|
234
|
+
* step re-runs the host's tool-visibility callbacks there to rebuild its tool list. A handler
|
|
235
|
+
* that resolves anything per invocation from its caller's execution context — a request-scoped
|
|
236
|
+
* ORM EntityManager, an AsyncLocalStorage tenant, a CLS transaction — finds nothing in that
|
|
237
|
+
* worker, and the library has no way to know which handlers do that. Turn this on once the tools
|
|
238
|
+
* this deployment registers establish whatever context they need themselves.
|
|
147
239
|
*
|
|
148
240
|
* The cross-process-sink requirement is a property of `durable: true` itself, not of this flag:
|
|
149
241
|
* the turn already runs on whichever worker takes `agent.run`, which may not be the pod holding
|
|
@@ -191,6 +283,75 @@ interface AgentModuleOptions {
|
|
|
191
283
|
retriever: Retriever;
|
|
192
284
|
topK?: number;
|
|
193
285
|
};
|
|
286
|
+
/**
|
|
287
|
+
* Bounds how much of a thread rides into each turn. Omit and a turn carries EVERY message the
|
|
288
|
+
* thread holds, so a long-lived thread costs more each time and eventually exceeds the model's
|
|
289
|
+
* context limit outright. `{ maxMessages }` and/or `{ maxTokens }` keep the newest that fit;
|
|
290
|
+
* `{ summarize: true }` folds what they left out into a leading summary, at the price of one extra
|
|
291
|
+
* model call per run (recorded as `history_summary` usage). An agent can override this for itself
|
|
292
|
+
* with `@Agent({ history })`.
|
|
293
|
+
*/
|
|
294
|
+
history?: AgentHistoryWindow;
|
|
295
|
+
/**
|
|
296
|
+
* A {@link HistoryPolicy} of your own — for a window the built-in can't express (pinning the
|
|
297
|
+
* thread's opening brief, keeping every message that carries a tool result, a budget that varies
|
|
298
|
+
* by actor). A convenience-vs-custom pair like `quotaLimitTokens`/`quota`: this outranks a
|
|
299
|
+
* module-wide `history`, and `@Agent({ history })` outranks both for the agent that declares it.
|
|
300
|
+
* `select` MUST be pure — see the SPI's determinism contract.
|
|
301
|
+
*/
|
|
302
|
+
historyPolicy?: HistoryPolicy;
|
|
303
|
+
/**
|
|
304
|
+
* Rewrites the prompt before every model call — masking identifiers, stamping a policy preamble,
|
|
305
|
+
* trimming an oversized tool result. Applies to EVERY agent: a transformation one persona can opt
|
|
306
|
+
* out of is not a control. Transformation only; `history`/`historyPolicy` still own which messages
|
|
307
|
+
* are there to transform. A processor needing DI-resolved dependencies is built in
|
|
308
|
+
* `forRootAsync`'s `useFactory` (which has `inject`), the same way `retrieval.retriever` is.
|
|
309
|
+
*/
|
|
310
|
+
inputProcessors?: InputProcessor[];
|
|
311
|
+
/**
|
|
312
|
+
* Gates every model answer before the stream, the store or the next step sees it — redact,
|
|
313
|
+
* replace, or refuse the turn outright (which fails it with an `output_rejected` stream error).
|
|
314
|
+
*
|
|
315
|
+
* REGISTERING ONE TURNS OFF LIVE TOKEN STREAMING. Reading the whole answer and streaming it as it
|
|
316
|
+
* is generated cannot both be true, so the turn's model output is buffered and released in one
|
|
317
|
+
* frame once the chain passes. That is the price of a gate that actually gates; see
|
|
318
|
+
* `AgentLoopDeps.outputProcessors` for exactly what a subscriber still receives live.
|
|
319
|
+
*/
|
|
320
|
+
outputProcessors?: OutputProcessor[];
|
|
321
|
+
/**
|
|
322
|
+
* Offer every agent the built-in `ask` tool, so the model can put its own clarifying question set
|
|
323
|
+
* to the user when it judges the scope is missing. The turn parks on the answers exactly as it
|
|
324
|
+
* parks on a HITL approval, and they arrive through `POST /agent/tool-call/answer`.
|
|
325
|
+
*
|
|
326
|
+
* `ask` is not a registered tool and has no handler — the loop settles it against a person — so no
|
|
327
|
+
* `RolesPolicy` gates it: asking a question performs nothing. An `@Agent({ ask })` overrides this
|
|
328
|
+
* for one persona. Omit → the model never sees it, and nothing about a turn changes.
|
|
329
|
+
*/
|
|
330
|
+
ask?: boolean;
|
|
331
|
+
/**
|
|
332
|
+
* Authored procedures any agent may pull in when a task calls for one — per-user, per-tenant or
|
|
333
|
+
* deployment-wide, with the most specific winning. Declared as `@Skill`-decorated providers and/or
|
|
334
|
+
* served by a `provider` of your own; offered to the model as a one-line-each catalog it loads
|
|
335
|
+
* from on demand, so an instruction costs a prompt only on the turns that need it.
|
|
336
|
+
*
|
|
337
|
+
* Omit → no catalog, no `skill` tool, and a turn's checkpoint sequence is byte-identical to one
|
|
338
|
+
* that never had the option. See {@link AgentSkillsOptions}.
|
|
339
|
+
*/
|
|
340
|
+
skills?: AgentSkillsOptions;
|
|
341
|
+
/**
|
|
342
|
+
* What the assistant has concluded about the actor and their organisation, carried into every turn
|
|
343
|
+
* as a bounded block of one-line facts and written by the model through a built-in `remember` tool.
|
|
344
|
+
*
|
|
345
|
+
* NOT the same thing as retrieval, and not a second name for it: `retrieval` answers from documents
|
|
346
|
+
* a person curated and can fix at the source, memory answers from the agent's own inferences about
|
|
347
|
+
* someone who never saw them written. That is why the rows carry an origin, why the block tells the
|
|
348
|
+
* model they may be wrong, and why `GET /agent/memories` + `DELETE /agent/memories/:id` are part of
|
|
349
|
+
* the feature rather than an optional console.
|
|
350
|
+
*
|
|
351
|
+
* Omit → no block, no `remember` tool, and a turn's checkpoint sequence is byte-identical to one
|
|
352
|
+
* that never had the option. See {@link AgentMemoryOptions}.
|
|
353
|
+
*/
|
|
354
|
+
memory?: AgentMemoryOptions;
|
|
194
355
|
/**
|
|
195
356
|
* The name of the agent a turn uses when the caller doesn't select one. Omit → the single
|
|
196
357
|
* discovered `@Agent` (when there is exactly one), else `'default'` (a bare assistant if no
|
|
@@ -230,12 +391,11 @@ interface AgentModuleAsyncOptions extends Pick<ModuleMetadata, 'imports'> {
|
|
|
230
391
|
*/
|
|
231
392
|
durable?: boolean;
|
|
232
393
|
/**
|
|
233
|
-
* Dispatch the turn's model call and tool executions as routed durable steps.
|
|
234
|
-
*
|
|
235
|
-
*
|
|
236
|
-
*
|
|
237
|
-
* `
|
|
238
|
-
* contract.
|
|
394
|
+
* Dispatch the turn's model call and tool executions as routed durable steps. Omitted keeps the
|
|
395
|
+
* turn's steps in-process localSteps. Same static-wiring reasoning as `durable` above — it lives
|
|
396
|
+
* here (not in the async factory result) because it decides how `AgentRunWorkflow` builds its
|
|
397
|
+
* hooks at module build time. `true` without `durable: true` throws at module build. See
|
|
398
|
+
* `AgentModuleOptions.dispatchedSteps` for the full contract.
|
|
239
399
|
*/
|
|
240
400
|
dispatchedSteps?: boolean;
|
|
241
401
|
/**
|
|
@@ -273,8 +433,18 @@ interface AgentModuleAsyncOptions extends Pick<ModuleMetadata, 'imports'> {
|
|
|
273
433
|
surface?: AgentSurface;
|
|
274
434
|
}
|
|
275
435
|
|
|
276
|
-
/**
|
|
277
|
-
|
|
436
|
+
/**
|
|
437
|
+
* The synthesized `agent`-kind tool name an orchestrator uses to hand off to `target`.
|
|
438
|
+
*
|
|
439
|
+
* A detached edge gets its own verb — `start_research` next to `ask_research` — for two reasons.
|
|
440
|
+
* One agent can be both awaited AND backgrounded by the same orchestrator, and one name cannot
|
|
441
|
+
* carry both. And the name is the part of a tool the model reads first: `ask` promises an answer,
|
|
442
|
+
* `start` does not.
|
|
443
|
+
*/
|
|
444
|
+
declare function delegateToolName(args: {
|
|
445
|
+
target: string;
|
|
446
|
+
detached?: boolean;
|
|
447
|
+
}): string;
|
|
278
448
|
/** Builds the per-agent loop deps. The single-agent case is just the one registered `@Agent`. */
|
|
279
449
|
declare class AgentDepsFactory {
|
|
280
450
|
private readonly options;
|
|
@@ -287,7 +457,13 @@ declare class AgentDepsFactory {
|
|
|
287
457
|
private readonly promptContributors;
|
|
288
458
|
private readonly quota;
|
|
289
459
|
private readonly pricingStore;
|
|
290
|
-
|
|
460
|
+
private readonly skills;
|
|
461
|
+
private readonly memory;
|
|
462
|
+
constructor(options: AgentModuleOptions, model: ModelProvider, store: AgentStore, sink: TokenStreamSink, rolesPolicy: RolesPolicy, registry: ToolRegistry, agents: AgentRegistry, promptContributors: PromptContributor[], quota: QuotaStore | undefined, pricingStore: AgentPricingStore | undefined, skills: SkillsConfig | undefined, memory: MemoryConfig | undefined);
|
|
463
|
+
/** The turn's memory seam, shared with the read-back endpoint. Undefined → memory is not configured. */
|
|
464
|
+
memoryConfig(): MemoryConfig | undefined;
|
|
465
|
+
/** The turn's skills seam, shared with the listing endpoint. Undefined → skills are not configured. */
|
|
466
|
+
skillsConfig(): SkillsConfig | undefined;
|
|
291
467
|
/**
|
|
292
468
|
* The agent a turn uses when the caller names none: the explicit `defaultAgent` option, else the
|
|
293
469
|
* sole registered `@Agent` when there is exactly one, else `'default'` (a bare assistant).
|
|
@@ -295,8 +471,16 @@ declare class AgentDepsFactory {
|
|
|
295
471
|
defaultAgentName(): string;
|
|
296
472
|
private effectiveTools;
|
|
297
473
|
forAgent(agentName?: string): AgentDeps;
|
|
474
|
+
/**
|
|
475
|
+
* The ceiling on how much of a thread this agent's turns carry, most specific wins: the agent's
|
|
476
|
+
* own `@Agent({ history })`, else a module-wide custom `historyPolicy`, else the module-wide
|
|
477
|
+
* `history` window. Undefined → unbounded, the behaviour of a module that configures none.
|
|
478
|
+
*/
|
|
479
|
+
private historyPolicy;
|
|
480
|
+
/** Build the built-in window policy from the declarative `{ maxMessages, maxTokens, summarize }`. */
|
|
481
|
+
private window;
|
|
298
482
|
/** Normalize the `followUps` option (`true` → 3, `{ count }` → count) to a number, or undefined. */
|
|
299
483
|
private followUpsCount;
|
|
300
484
|
}
|
|
301
485
|
|
|
302
|
-
export { AgentDepsFactory as A, type FunctionalTool as F, type AgentSurface as a, type AgentModuleOptions as b, type AgentModuleAsyncOptions as c,
|
|
486
|
+
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, delegateToolName as i, provideAgentTool as p, utcDay as u };
|