@anteros/core 0.0.41 → 0.0.42
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/database/audit.ts +9 -59
- package/database/collection.ts +3 -1
- package/database/deleteLog.ts +67 -3
- package/database/file.ts +4 -3
- package/database/mongodbadapter.ts +103 -42
- package/database/replication.ts +110 -32
- package/database/ttl.ts +68 -0
- package/database/workflow.ts +466 -240
- package/index.ts +6 -0
- package/lib/agent.ts +1327 -0
- package/lib/agentMemory.ts +586 -0
- package/lib/agents.ts +157 -0
- package/lib/ai.ts +0 -0
- package/lib/api.ts +246 -0
- package/lib/attachment.ts +351 -0
- package/lib/auditResult.ts +13 -0
- package/lib/define.ts +43 -1
- package/lib/endpoints.ts +80 -0
- package/lib/files.ts +2 -1
- package/lib/jsonSchema.ts +183 -0
- package/lib/lifecycle.ts +7 -1
- package/lib/load.ts +17 -0
- package/lib/mcp.ts +3 -2
- package/lib/messages.ts +299 -0
- package/lib/providers.ts +867 -0
- package/lib/routes.ts +14 -1
- package/lib/scriptWorker.ts +4 -1
- package/lib/scripts.ts +6 -1
- package/lib/sockets.ts +3 -1
- package/lib/workflow.ts +209 -37
- package/lib/zip.ts +109 -0
- package/package.json +1 -1
- package/server/access.ts +96 -0
- package/server/agents.ts +451 -0
- package/server/api.ts +14 -72
- package/server/boot.ts +11 -0
- package/server/hono.ts +8 -3
- package/server/mcp.ts +17 -63
- package/server/routes.ts +19 -24
- package/tests/agent-memory.test.ts +617 -0
- package/tests/agent-working-memory.test.ts +402 -0
- package/tests/agent.test.ts +1239 -0
- package/tests/agents-api.test.ts +593 -0
- package/tests/api.test.ts +51 -0
- package/tests/attachment.test.ts +241 -0
- package/tests/audit-operations.test.ts +1 -1
- package/tests/audit-redact.test.ts +29 -3
- package/tests/audit-run-action.test.ts +1 -1
- package/tests/endpoints.test.ts +80 -0
- package/tests/fixtures/agent-tenant/agents/support.agent.ts +9 -0
- package/tests/fixtures/agent-tenant/agents/weather.agent.ts +21 -0
- package/tests/fixtures/agents-api/agents/assistant.agent.ts +46 -0
- package/tests/fixtures/agents-api/agents/plain.agent.ts +23 -0
- package/tests/fixtures/agents-api/agents/private.agent.ts +15 -0
- package/tests/fixtures/agents-api/collections/notes.model.ts +26 -0
- package/tests/fixtures/agents-api/routes/probe.route.ts +21 -0
- package/tests/fixtures/agents-api/services/probe.service.ts +19 -0
- package/tests/fixtures/attachment/data.csv +2 -0
- package/tests/fixtures/fake-provider.ts +128 -0
- package/tests/fixtures/replication-meta/agents/chat.agent.ts +16 -0
- package/tests/fixtures/replication-meta/collections/counters.model.ts +13 -0
- package/tests/fixtures/replication-meta/collections/orders.model.ts +9 -0
- package/tests/fixtures/replication-meta/workflows/run.workflow.ts +8 -0
- package/tests/fixtures/vars-tenant/vars/private.var.ts +4 -1
- package/tests/fixtures/workflow-engine/workflows/failing.workflow.ts +34 -0
- package/tests/fixtures/workflow-engine/workflows/flaky.workflow.ts +23 -0
- package/tests/fixtures/workflow-engine/workflows/hang.workflow.ts +17 -0
- package/tests/fixtures/workflow-engine/workflows/simple.workflow.ts +19 -0
- package/tests/fixtures/workflow-engine/workflows/slow.workflow.ts +23 -0
- package/tests/fixtures/workflow-engine/workflows/versioned.workflow.ts +19 -0
- package/tests/fixtures/workflow-tenant/workflows/broken.workflow.ts +3 -0
- package/tests/fixtures/workflow-tenant/workflows/disabled.workflow.ts +8 -0
- package/tests/fixtures/workflow-tenant/workflows/invoice.workflow.ts +21 -0
- package/tests/fixtures/workflow-tenant/workflows/no-id.workflow.ts +7 -0
- package/tests/fixtures/workflow-tenant/workflows/order-duplicate.workflow.ts +13 -0
- package/tests/fixtures/workflow-tenant/workflows/order.workflow.ts +17 -0
- package/tests/hono.test.ts +6 -3
- package/tests/locks.test.ts +120 -0
- package/tests/mcp.test.ts +11 -11
- package/tests/messages.test.ts +258 -0
- package/tests/replication-control.test.ts +2 -2
- package/tests/replication-meta.test.ts +243 -0
- package/tests/upload.test.ts +44 -12
- package/tests/vars-api.test.ts +1 -1
- package/tests/vars-replication.test.ts +3 -2
- package/tests/workflow-engine.test.ts +340 -0
- package/tests/workflow-retention.test.ts +103 -0
- package/tests/workflow.test.ts +186 -0
- package/types/agent.d.ts +837 -0
- package/types/config.d.ts +16 -0
- package/types/file.d.ts +7 -7
- package/types/hook.d.ts +6 -0
- package/types/lifecycle.d.ts +6 -0
- package/types/mcp.d.ts +11 -1
- package/types/replication.d.ts +29 -0
- package/types/route.d.ts +7 -1
- package/types/scripts.d.ts +6 -0
- package/types/service.d.ts +7 -1
- package/types/tenant.d.ts +13 -0
- package/types/vars.d.ts +2 -2
- package/types/websocket.d.ts +6 -0
- package/types/workflow.d.ts +50 -3
package/types/agent.d.ts
ADDED
|
@@ -0,0 +1,837 @@
|
|
|
1
|
+
import type Joi from "joi";
|
|
2
|
+
import type { useRest } from "../database/rest";
|
|
3
|
+
import type { fn } from "../lib/error";
|
|
4
|
+
import type { jwt } from "../utils/func";
|
|
5
|
+
import type { Agent } from "../lib/agent";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Wire protocol spoken by a model provider.
|
|
9
|
+
*
|
|
10
|
+
* `'openai'` (the default) also covers every OpenAI-compatible gateway
|
|
11
|
+
* (Groq, Mistral, OpenRouter, Ollama, LM Studio, vLLM…) — only `baseUrl` changes.
|
|
12
|
+
*/
|
|
13
|
+
export type AgentCompatible = "openai" | "anthropic";
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Model provider — **where** the agent's reasoning comes from: the model, the
|
|
17
|
+
* credentials, the endpoint, and how it is called.
|
|
18
|
+
*
|
|
19
|
+
* ```ts
|
|
20
|
+
* provider: { model: 'gpt-4o-mini', apiKey: 'sk-…' } // OpenAI
|
|
21
|
+
* provider: { model: 'claude-sonnet-4-5', apiKey: 'sk-ant-…', compatible: 'anthropic' }
|
|
22
|
+
* provider: { model: 'llama3.1', compatible: 'openai', baseUrl: 'http://localhost:11434/v1' }
|
|
23
|
+
* ```
|
|
24
|
+
*
|
|
25
|
+
* The key falls back to the environment when omitted:
|
|
26
|
+
* `ANTEROS_AI_API_KEY`, then `OPENAI_API_KEY` / `ANTHROPIC_API_KEY` according to
|
|
27
|
+
* `compatible`. It is therefore never required in the source.
|
|
28
|
+
*/
|
|
29
|
+
export type AgentProvider = {
|
|
30
|
+
/** Model id sent to the API (e.g. `gpt-4o-mini`, `claude-sonnet-4-5`). */
|
|
31
|
+
model: string;
|
|
32
|
+
/** API key — falls back to the environment (see above). */
|
|
33
|
+
apiKey?: string;
|
|
34
|
+
/** Wire protocol (default `'openai'`). */
|
|
35
|
+
compatible?: AgentCompatible;
|
|
36
|
+
/** API root override — default `https://api.openai.com/v1` or `https://api.anthropic.com`. */
|
|
37
|
+
baseUrl?: string;
|
|
38
|
+
/** Extra headers sent with every request. */
|
|
39
|
+
headers?: Record<string, string>;
|
|
40
|
+
/** Sampling and transport — `{ temperature, maxTokens, topP, timeout, retries }`. */
|
|
41
|
+
options?: AgentOptions;
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* How the provider is called — declared under `provider.options`, overridable
|
|
46
|
+
* per call (`{ provider: { options: { … } } }`, merged).
|
|
47
|
+
*
|
|
48
|
+
* ```ts
|
|
49
|
+
* provider: { model: 'gpt-4o-mini', options: { temperature: 0.2, maxTokens: 1000 } }
|
|
50
|
+
* ```
|
|
51
|
+
*/
|
|
52
|
+
export type AgentOptions = {
|
|
53
|
+
/** Sampling temperature. */
|
|
54
|
+
temperature?: number;
|
|
55
|
+
/** Max tokens generated per model call (default 4096). */
|
|
56
|
+
maxTokens?: number;
|
|
57
|
+
/** Nucleus sampling. */
|
|
58
|
+
topP?: number;
|
|
59
|
+
/** Request timeout in ms (default 120000). */
|
|
60
|
+
timeout?: number;
|
|
61
|
+
/** Retries on network errors, 429 and 5xx (default 2). */
|
|
62
|
+
retries?: number;
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
/** Text part of a multimodal message. */
|
|
66
|
+
export type AgentTextPart = { type: "text"; text: string };
|
|
67
|
+
/**
|
|
68
|
+
* An image — by **URL** or as **base64**.
|
|
69
|
+
*
|
|
70
|
+
* `url` is an `https://…` (the provider fetches it) or a `data:` URL; `data` is
|
|
71
|
+
* the raw base64 (no `data:` prefix), the form an upload or a `File` produces.
|
|
72
|
+
* One of the two is required.
|
|
73
|
+
*/
|
|
74
|
+
export type AgentImagePart = { type: "image"; url?: string; data?: string; mimeType?: string };
|
|
75
|
+
/**
|
|
76
|
+
* A document — a PDF today — by **URL** or as **base64** (`data` is raw base64).
|
|
77
|
+
*
|
|
78
|
+
* Native input where the model supports it; a text extraction happens upstream
|
|
79
|
+
* for everything else. A **remote file URL is downloaded and inlined** before the
|
|
80
|
+
* call (OpenAI-compatible endpoints only accept base64), with the same 10 MB cap
|
|
81
|
+
* as an attachment.
|
|
82
|
+
*/
|
|
83
|
+
export type AgentFilePart = {
|
|
84
|
+
type: "file";
|
|
85
|
+
/** Name shown to the model — the extension is part of what it reads. */
|
|
86
|
+
name?: string;
|
|
87
|
+
url?: string;
|
|
88
|
+
data?: string;
|
|
89
|
+
mimeType?: string;
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* A tool call, expressed as a **content part** — the spelling other LLM
|
|
94
|
+
* libraries use. `normalizeMessages()` hoists it onto the assistant message's
|
|
95
|
+
* `toolCalls`, so a conversation coming from anywhere lands on the same shape.
|
|
96
|
+
*/
|
|
97
|
+
export type AgentToolCallPart = {
|
|
98
|
+
type: "tool-call";
|
|
99
|
+
id: string;
|
|
100
|
+
name: string;
|
|
101
|
+
/** Parsed arguments — `args` / `argsText` are the historical spellings. */
|
|
102
|
+
arguments?: unknown;
|
|
103
|
+
args?: Record<string, any>;
|
|
104
|
+
argsText?: string;
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* A tool result, expressed as a content part. Accepted on a `tool` message — or
|
|
109
|
+
* on a `user` message, which is how a whole tool round is replayed without
|
|
110
|
+
* leaving the `user` role. It is hoisted to a `tool` message.
|
|
111
|
+
*/
|
|
112
|
+
export type AgentToolResultPart = {
|
|
113
|
+
type: "tool-result";
|
|
114
|
+
/** Id of the `tool-call` this answers. */
|
|
115
|
+
id: string;
|
|
116
|
+
name?: string;
|
|
117
|
+
/** The tool's return value — serialized for the model if it is not a string. */
|
|
118
|
+
result?: unknown;
|
|
119
|
+
/** Set instead of `result` when the tool failed. */
|
|
120
|
+
error?: string;
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
/** What a model actually receives — the media an attachment resolves to. */
|
|
124
|
+
export type AgentMediaPart = AgentTextPart | AgentImagePart | AgentFilePart;
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* What a caller may put in a message's `content` — the media **and** the tool
|
|
128
|
+
* parts, so a conversation built by another library is accepted as-is.
|
|
129
|
+
*/
|
|
130
|
+
export type AgentContentPart = AgentMediaPart | AgentToolCallPart | AgentToolResultPart;
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* What a caller can attach to a run — resolved to content parts before the model
|
|
134
|
+
* sees them (see `lib/attachment.ts`).
|
|
135
|
+
*
|
|
136
|
+
* - **server-side**: a **path** (`'./invoices/2026-01.pdf'`), relative to `filesBaseDir`
|
|
137
|
+
* - **front-end / SDK**: a `File`/`Blob`, raw bytes, or `{ name, data }` in base64
|
|
138
|
+
*/
|
|
139
|
+
export type AgentAttachment =
|
|
140
|
+
| string
|
|
141
|
+
| Uint8Array
|
|
142
|
+
| Blob
|
|
143
|
+
| {
|
|
144
|
+
/** File name — its extension decides how it is read. */
|
|
145
|
+
name?: string;
|
|
146
|
+
/** MIME type, when the name is not enough. */
|
|
147
|
+
mimeType?: string;
|
|
148
|
+
/** The payload: base64 (default) or UTF-8 text with `encoding: 'utf8'`. */
|
|
149
|
+
data: string | Uint8Array;
|
|
150
|
+
encoding?: "base64" | "utf8";
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
export type AgentUserMessage = { role: "user"; content: string | AgentMediaPart[]; name?: string };
|
|
154
|
+
/**
|
|
155
|
+
* A system message. `developer` is the role OpenAI-compatible endpoints use for
|
|
156
|
+
* an instruction that outranks a user turn — Anthropic has no such role, so it is
|
|
157
|
+
* folded into the system prompt there.
|
|
158
|
+
*/
|
|
159
|
+
export type AgentSystemMessage = { role: "system" | "developer"; content: string; name?: string };
|
|
160
|
+
export type AgentAssistantMessage = {
|
|
161
|
+
role: "assistant";
|
|
162
|
+
content: string | null;
|
|
163
|
+
/** Set when the model asked to call tools (echoed back on the next turn). */
|
|
164
|
+
toolCalls?: AgentToolCall[];
|
|
165
|
+
/**
|
|
166
|
+
* The model's reasoning blocks, kept **raw** — Anthropic requires the original
|
|
167
|
+
* signed blocks to be echoed back when a tool round continues a thinking turn.
|
|
168
|
+
*/
|
|
169
|
+
thinking?: AgentThinkingBlock[];
|
|
170
|
+
name?: string;
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
/** A reasoning block, exactly as the provider returned it (signature included). */
|
|
174
|
+
export type AgentThinkingBlock = Record<string, any>;
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Extended thinking — off by default.
|
|
178
|
+
*
|
|
179
|
+
* ```ts
|
|
180
|
+
* await agent.generate('Prove that …', { thinking: 'high' });
|
|
181
|
+
* ```
|
|
182
|
+
*
|
|
183
|
+
* Mapped per protocol: Anthropic gets a real **thinking budget**, an
|
|
184
|
+
* OpenAI-compatible endpoint gets a `reasoning_effort` (the two knobs are not the
|
|
185
|
+
* same thing — a budget is a number, an effort is a level). On OpenAI-compatible
|
|
186
|
+
* gateways only the reasoning models honour it.
|
|
187
|
+
*/
|
|
188
|
+
export type AgentThinking =
|
|
189
|
+
/** `true` → the provider's default: `'medium'` effort / a 4 096-token budget. */
|
|
190
|
+
| boolean
|
|
191
|
+
/** Pure level — the budget becomes 2 048 / 4 096 / 8 192 tokens. */
|
|
192
|
+
| "low"
|
|
193
|
+
| "medium"
|
|
194
|
+
| "high"
|
|
195
|
+
/** Explicit Anthropic budget (OpenAI-compatible receives `'medium'`, the closest level). */
|
|
196
|
+
| { budgetTokens: number };
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* How the model may use the tools it is given, per protocol.
|
|
200
|
+
*
|
|
201
|
+
* - `'auto'` (default) — every tool is sent, the model decides
|
|
202
|
+
* - `'none'` — the tools are sent but the model must answer directly
|
|
203
|
+
* - `'required'` — it must call a tool (Anthropic: `tool_choice: any`)
|
|
204
|
+
* - `{ name }` — it must call that one
|
|
205
|
+
*
|
|
206
|
+
* The framework never picks a tool itself: what reaches the model is decided by
|
|
207
|
+
* the tools of the run (see `tools`), and by this alone.
|
|
208
|
+
*/
|
|
209
|
+
export type AgentToolChoice = "auto" | "none" | "required" | { name: string };
|
|
210
|
+
|
|
211
|
+
export type AgentToolMessage = {
|
|
212
|
+
role: "tool";
|
|
213
|
+
/** Id of the `tool_use` / `tool_call` this message answers. */
|
|
214
|
+
toolCallId: string;
|
|
215
|
+
name: string;
|
|
216
|
+
content: string;
|
|
217
|
+
isError?: boolean;
|
|
218
|
+
};
|
|
219
|
+
|
|
220
|
+
/** A single conversation message — the model-agnostic shape used everywhere. */
|
|
221
|
+
export type AgentMessage = AgentUserMessage | AgentSystemMessage | AgentAssistantMessage | AgentToolMessage;
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* What a caller may **pass**: the canonical messages, plus the unified content
|
|
225
|
+
* parts (`image` / `file` by URL or base64, `tool-call` / `tool-result`) another
|
|
226
|
+
* LLM library uses. `normalizeMessages()` folds them onto the canonical shape —
|
|
227
|
+
* a `tool-call` part becomes `toolCalls`, a `tool-result` part becomes a `tool`
|
|
228
|
+
* message, a `system`/`developer` message may carry a part array.
|
|
229
|
+
*/
|
|
230
|
+
export type AgentMessageInput =
|
|
231
|
+
| { role: "system" | "developer"; content: string | AgentContentPart[]; name?: string }
|
|
232
|
+
| { role: "user"; content: string | AgentContentPart[]; name?: string }
|
|
233
|
+
| {
|
|
234
|
+
role: "assistant";
|
|
235
|
+
content?: string | AgentContentPart[] | null;
|
|
236
|
+
toolCalls?: AgentToolCall[];
|
|
237
|
+
thinking?: AgentThinkingBlock[];
|
|
238
|
+
name?: string;
|
|
239
|
+
}
|
|
240
|
+
| {
|
|
241
|
+
role: "tool";
|
|
242
|
+
content: string | AgentContentPart[];
|
|
243
|
+
toolCallId?: string;
|
|
244
|
+
name?: string;
|
|
245
|
+
isError?: boolean;
|
|
246
|
+
};
|
|
247
|
+
|
|
248
|
+
/** What `generate()` / `stream()` accept as input. */
|
|
249
|
+
export type AgentInput = string | AgentMessageInput | AgentMessageInput[];
|
|
250
|
+
|
|
251
|
+
/** A tool call requested by the model. */
|
|
252
|
+
export type AgentToolCall = {
|
|
253
|
+
id: string;
|
|
254
|
+
name: string;
|
|
255
|
+
/** Parsed arguments (`{}` when the model produced invalid JSON). */
|
|
256
|
+
args: Record<string, any>;
|
|
257
|
+
/** Raw JSON string as returned by the model. */
|
|
258
|
+
argsText?: string;
|
|
259
|
+
};
|
|
260
|
+
|
|
261
|
+
/** The outcome of executing one tool call. */
|
|
262
|
+
export type AgentToolResultEntry = {
|
|
263
|
+
id: string;
|
|
264
|
+
name: string;
|
|
265
|
+
args: Record<string, any>;
|
|
266
|
+
result?: any;
|
|
267
|
+
/** Set when the tool threw, was unknown, or its arguments were invalid. */
|
|
268
|
+
error?: string;
|
|
269
|
+
durationMs: number;
|
|
270
|
+
};
|
|
271
|
+
|
|
272
|
+
/** Normalized finish reason (`'max_steps'` is added by the agent itself). */
|
|
273
|
+
export type AgentFinishReason = "stop" | "tool_use" | "length" | "content_filter" | "aborted" | "error" | "max_steps";
|
|
274
|
+
|
|
275
|
+
export type AgentUsage = {
|
|
276
|
+
inputTokens: number;
|
|
277
|
+
outputTokens: number;
|
|
278
|
+
totalTokens: number;
|
|
279
|
+
/** How many model calls the run needed (1 + one per tool round). */
|
|
280
|
+
requests: number;
|
|
281
|
+
};
|
|
282
|
+
|
|
283
|
+
/** One model call of a run, with the tools it asked for. */
|
|
284
|
+
export type AgentStep = {
|
|
285
|
+
step: number;
|
|
286
|
+
text: string;
|
|
287
|
+
/** The model's reasoning for this step, when extended thinking is on. */
|
|
288
|
+
reasoning?: string;
|
|
289
|
+
/** Ids of the tools sent for this step — every tool the run allowed. */
|
|
290
|
+
tools?: string[];
|
|
291
|
+
toolCalls: AgentToolCall[];
|
|
292
|
+
toolResults: AgentToolResultEntry[];
|
|
293
|
+
finishReason: string;
|
|
294
|
+
};
|
|
295
|
+
|
|
296
|
+
/** Execution context handed to a tool. */
|
|
297
|
+
export type AgentToolContext = {
|
|
298
|
+
rest?: InstanceType<typeof useRest>;
|
|
299
|
+
/** The agent currently running. */
|
|
300
|
+
agent: Agent;
|
|
301
|
+
/** Tenant of the agent (`_tenant_`), when loaded from a tenant folder. */
|
|
302
|
+
tenant?: string;
|
|
303
|
+
toolCallId: string;
|
|
304
|
+
step: number;
|
|
305
|
+
signal?: AbortSignal;
|
|
306
|
+
/** Throw an `AppError` with a stable code. */
|
|
307
|
+
error: typeof fn.error;
|
|
308
|
+
};
|
|
309
|
+
|
|
310
|
+
/**
|
|
311
|
+
* A tool an agent can call.
|
|
312
|
+
*
|
|
313
|
+
* ```ts
|
|
314
|
+
* tools: {
|
|
315
|
+
* forecast: {
|
|
316
|
+
* id: 'forecast',
|
|
317
|
+
* description: 'Current weather for a city',
|
|
318
|
+
* inputSchema: v.object({ city: v.string().required() }),
|
|
319
|
+
* execute: async ({ city }, { rest }) => ({ city, celsius: 21 }),
|
|
320
|
+
* },
|
|
321
|
+
* }
|
|
322
|
+
* ```
|
|
323
|
+
*
|
|
324
|
+
* An MCP tool (`define.McpTool`) is accepted as-is: its `exec` is adapted and
|
|
325
|
+
* its `{ content: [...] }` result is flattened to text. It carries the protocol's
|
|
326
|
+
* `name` instead of an `id` — the resolved tool name is `id ?? name`.
|
|
327
|
+
*/
|
|
328
|
+
export type AgentTool = {
|
|
329
|
+
_isTool_?: boolean;
|
|
330
|
+
_isMcpTool_?: boolean;
|
|
331
|
+
_tenant_?: string;
|
|
332
|
+
/**
|
|
333
|
+
* Tool id — **required**, and the name the model calls. When a tool is declared
|
|
334
|
+
* in a record (`tools: { forecast }`), the key must be that same id.
|
|
335
|
+
*/
|
|
336
|
+
id?: string;
|
|
337
|
+
/** MCP tools carry a `name`; agents resolve `id ?? name`. */
|
|
338
|
+
name?: string;
|
|
339
|
+
/** Shown to the model — say what it does and when to use it. */
|
|
340
|
+
description?: string;
|
|
341
|
+
enabled?: boolean;
|
|
342
|
+
/** Arguments schema: Joi, zod or a plain JSON Schema (defaults to an open object). */
|
|
343
|
+
inputSchema?: Joi.Schema | any;
|
|
344
|
+
/** Handler. The returned value is serialized back to the model. */
|
|
345
|
+
execute?: (input: any, ctx: AgentToolContext) => any | Promise<any>;
|
|
346
|
+
/** MCP-compatible handler (`define.McpTool`) — adapted automatically. */
|
|
347
|
+
exec?: (ctx: any) => any | Promise<any>;
|
|
348
|
+
};
|
|
349
|
+
|
|
350
|
+
/** What a tool must carry to be **declared** — `define.Tool` enforces the id. */
|
|
351
|
+
export type AgentToolDefinition = AgentTool & { id: string };
|
|
352
|
+
|
|
353
|
+
export type AgentTools = Record<string, AgentTool> | AgentTool[];
|
|
354
|
+
|
|
355
|
+
/**
|
|
356
|
+
* Conversation store. The agent reads the thread before a run and writes the
|
|
357
|
+
* whole updated conversation after it.
|
|
358
|
+
*
|
|
359
|
+
* The optional `ctx` carries what a store may need — the client to write with
|
|
360
|
+
* (`rest`), the tenant, the agent and the caller identity. A store that ignores
|
|
361
|
+
* it (a plain `Map`) stays valid.
|
|
362
|
+
*/
|
|
363
|
+
export type AgentMemory = {
|
|
364
|
+
get(threadId: string, ctx?: AgentMemoryContext): Promise<AgentMessage[]> | AgentMessage[];
|
|
365
|
+
save(threadId: string, messages: AgentMessage[], ctx?: AgentMemoryContext): Promise<void> | void;
|
|
366
|
+
clear(threadId: string, ctx?: AgentMemoryContext): Promise<void> | void;
|
|
367
|
+
/** Optional — a caller's threads, most recent first (a chat UI needs it). */
|
|
368
|
+
list?(ctx?: AgentMemoryContext & { limit?: number }): Promise<AgentThread[]> | AgentThread[];
|
|
369
|
+
/**
|
|
370
|
+
* Optional — the agent's **working memory**: one durable value per scope key
|
|
371
|
+
* (a profile, a scratchpad). A store that omits it makes `workingMemory`
|
|
372
|
+
* inert — the agent simply has no scratchpad.
|
|
373
|
+
*/
|
|
374
|
+
getState?(key: string, ctx?: AgentMemoryContext): Promise<AgentMemoryState | undefined> | AgentMemoryState | undefined;
|
|
375
|
+
setState?(key: string, value: AgentMemoryState, ctx?: AgentMemoryContext): Promise<void> | void;
|
|
376
|
+
/** Optional — forget a scratchpad. */
|
|
377
|
+
clearState?(key: string, ctx?: AgentMemoryContext): Promise<void> | void;
|
|
378
|
+
/**
|
|
379
|
+
* Optional — the **MongoDB collections** the store writes to. The agent loader
|
|
380
|
+
* publishes them so the replication engine copies them like a declared
|
|
381
|
+
* collection (a store outside MongoDB returns nothing).
|
|
382
|
+
*/
|
|
383
|
+
collections?(): string[];
|
|
384
|
+
};
|
|
385
|
+
|
|
386
|
+
/** One durable value of the working memory — a markdown block, or a JSON object. */
|
|
387
|
+
export type AgentMemoryState = {
|
|
388
|
+
value: any;
|
|
389
|
+
updatedAt?: Date;
|
|
390
|
+
};
|
|
391
|
+
|
|
392
|
+
/**
|
|
393
|
+
* A memory processor — the extension point of a store, at the two moments a
|
|
394
|
+
* memory matters:
|
|
395
|
+
*
|
|
396
|
+
* - `load` — after the thread, the injected turns and the input are assembled,
|
|
397
|
+
* **before** the model sees them. Rewrite them (redact, translate, drop a
|
|
398
|
+
* branch, inject what your own search found — see the Semantic recall section
|
|
399
|
+
* of the Memory page), or return nothing to leave them as they are.
|
|
400
|
+
* - `save` — before the conversation is persisted. Rewrite it, or **throw** to
|
|
401
|
+
* keep it out of the store entirely (a guardrail): the run still returns its
|
|
402
|
+
* answer, only the write is skipped.
|
|
403
|
+
*
|
|
404
|
+
* Processors run in declaration order, and a returned array replaces the
|
|
405
|
+
* messages for the next one.
|
|
406
|
+
*/
|
|
407
|
+
export type AgentMemoryProcessor = {
|
|
408
|
+
/** A label for the logs — optional. */
|
|
409
|
+
id?: string;
|
|
410
|
+
load?: (
|
|
411
|
+
messages: AgentMessage[],
|
|
412
|
+
ctx: AgentMemoryContext,
|
|
413
|
+
) => AgentMessage[] | void | Promise<AgentMessage[] | void>;
|
|
414
|
+
save?: (
|
|
415
|
+
messages: AgentMessage[],
|
|
416
|
+
ctx: AgentMemoryContext,
|
|
417
|
+
) => AgentMessage[] | void | Promise<AgentMessage[] | void>;
|
|
418
|
+
};
|
|
419
|
+
|
|
420
|
+
/** What a memory store knows about the run asking for a thread. */
|
|
421
|
+
export type AgentMemoryContext = {
|
|
422
|
+
agentId?: string;
|
|
423
|
+
tenant?: string;
|
|
424
|
+
/** The run's client — a Mongo-backed store reads and writes through it. */
|
|
425
|
+
rest?: InstanceType<typeof useRest>;
|
|
426
|
+
/**
|
|
427
|
+
* Opaque caller identity. **Namespaces** the threads of a caller
|
|
428
|
+
* (`threadId` becomes `resourceId:threadId`) — it is **not** an authorization
|
|
429
|
+
* boundary: gate `history` / `clear` with `api.access`.
|
|
430
|
+
*/
|
|
431
|
+
resourceId?: string;
|
|
432
|
+
};
|
|
433
|
+
|
|
434
|
+
/** A thread as listed by a memory store (`agents.memory.Mongo().list()`). */
|
|
435
|
+
export type AgentThread = {
|
|
436
|
+
threadId: string;
|
|
437
|
+
resourceId?: string;
|
|
438
|
+
/** Derived from the first user message, at creation. */
|
|
439
|
+
title?: string;
|
|
440
|
+
/** Number of stored messages. */
|
|
441
|
+
messages: number;
|
|
442
|
+
createdAt?: Date;
|
|
443
|
+
updatedAt: Date;
|
|
444
|
+
};
|
|
445
|
+
|
|
446
|
+
/** Shared options of the built-in stores (`agents.memory.InMemory` / `.Mongo`). */
|
|
447
|
+
export type AgentMemoryOptions = {
|
|
448
|
+
/**
|
|
449
|
+
* Messages kept per thread (default 100). On every save the oldest are
|
|
450
|
+
* dropped: a conversation must not grow until it blows the context window.
|
|
451
|
+
*/
|
|
452
|
+
maxMessages?: number;
|
|
453
|
+
/** Namespace each thread under its `resourceId` (default `true`). */
|
|
454
|
+
scoped?: boolean;
|
|
455
|
+
};
|
|
456
|
+
|
|
457
|
+
/**
|
|
458
|
+
* The agent's **working memory** — a durable scratchpad it keeps up to date
|
|
459
|
+
* (a user profile, the state of a task):
|
|
460
|
+
*
|
|
461
|
+
* ```ts
|
|
462
|
+
* define.Agent({
|
|
463
|
+
* memory: new agents.memory.Mongo({ collection: 'support_threads' }),
|
|
464
|
+
* workingMemory: {
|
|
465
|
+
* template: '# Profile\n- Name:\n- Timezone:\n- Preferences:',
|
|
466
|
+
* },
|
|
467
|
+
* })
|
|
468
|
+
* ```
|
|
469
|
+
*
|
|
470
|
+
* It is injected into the system prompt, and the model updates it through an
|
|
471
|
+
* auto-generated `updateWorkingMemory` tool. A **`template`** is free text the
|
|
472
|
+
* model replaces on each update; a **`schema`** is a validated JSON object that is
|
|
473
|
+
* **deep merged** (`null` removes a field, an array replaces an array). One of the
|
|
474
|
+
* two, not both.
|
|
475
|
+
*/
|
|
476
|
+
export type AgentWorkingMemory = {
|
|
477
|
+
/** The markdown block the model fills in (replace semantics). */
|
|
478
|
+
template?: string;
|
|
479
|
+
/** Or a schema (Joi, zod, plain JSON Schema) — the update is a **partial** merge. */
|
|
480
|
+
schema?: Joi.Schema | any;
|
|
481
|
+
/**
|
|
482
|
+
* `'resource'` (default) — one scratchpad per caller, shared by all their
|
|
483
|
+
* threads (what a profile wants). `'thread'` — one per conversation.
|
|
484
|
+
*/
|
|
485
|
+
scope?: "resource" | "thread";
|
|
486
|
+
/** Expose the update tool to the model (default `true`; `false` for a read-only prompt). */
|
|
487
|
+
tool?: boolean;
|
|
488
|
+
};
|
|
489
|
+
|
|
490
|
+
/** Options of `agents.memory.Mongo()`. */
|
|
491
|
+
export type MongoAgentMemoryOptions = AgentMemoryOptions & {
|
|
492
|
+
/**
|
|
493
|
+
* **Required** — the collection holding the threads, in the tenant database.
|
|
494
|
+
* The tenant names it (`_memories_`, `support_threads`…); the store never
|
|
495
|
+
* invents one, and the replication engine copies whatever you choose.
|
|
496
|
+
*/
|
|
497
|
+
collection: string;
|
|
498
|
+
/**
|
|
499
|
+
* Opt-in retention on `updatedAt` (MongoDB TTL) — a duration string like
|
|
500
|
+
* `'180d'` or `'24h'`. `false` → explicitly disabled (drops the TTL index),
|
|
501
|
+
* omitted → threads are kept forever. Same vocabulary as the audit and
|
|
502
|
+
* workflow retention.
|
|
503
|
+
*/
|
|
504
|
+
ttl?: string | false;
|
|
505
|
+
};
|
|
506
|
+
|
|
507
|
+
/**
|
|
508
|
+
* The subset of a Redis client the store uses — `ioredis` satisfies it.
|
|
509
|
+
* Structural on purpose: a test (or another driver) only has to implement these.
|
|
510
|
+
*/
|
|
511
|
+
export type RedisClientLike = {
|
|
512
|
+
get(key: string): Promise<string | null>;
|
|
513
|
+
set(key: string, value: string, ...args: any[]): Promise<any>;
|
|
514
|
+
del(...keys: string[]): Promise<any>;
|
|
515
|
+
mget(...keys: string[]): Promise<Array<string | null>>;
|
|
516
|
+
expire(key: string, seconds: number): Promise<any>;
|
|
517
|
+
zadd(key: string, score: number, member: string): Promise<any>;
|
|
518
|
+
zrevrange(key: string, start: number, stop: number): Promise<string[]>;
|
|
519
|
+
zrem(key: string, ...members: string[]): Promise<any>;
|
|
520
|
+
};
|
|
521
|
+
|
|
522
|
+
/** Options of `agents.memory.Redis()`. */
|
|
523
|
+
export type RedisAgentMemoryOptions = AgentMemoryOptions & {
|
|
524
|
+
/** An existing client — the store never closes it. Takes precedence over the connection options. */
|
|
525
|
+
client?: RedisClientLike;
|
|
526
|
+
/** `redis://` connection string (default: `REDIS_URL`, then host/port/password, then `localhost:6379`). */
|
|
527
|
+
url?: string;
|
|
528
|
+
host?: string;
|
|
529
|
+
port?: number;
|
|
530
|
+
password?: string;
|
|
531
|
+
/** Key namespace (default `anteros:agent-memory`). */
|
|
532
|
+
prefix?: string;
|
|
533
|
+
/**
|
|
534
|
+
* Expiry of a thread — a duration string like `'7d'`, refreshed on every save.
|
|
535
|
+
* `false` → no expiry, omitted → kept forever.
|
|
536
|
+
*/
|
|
537
|
+
ttl?: string | false;
|
|
538
|
+
};
|
|
539
|
+
|
|
540
|
+
/** Structured output request — the answer is parsed and validated against `schema`. */
|
|
541
|
+
export type AgentStructuredOutput = {
|
|
542
|
+
schema: Joi.Schema | any;
|
|
543
|
+
/** Only used by OpenAI-compatible providers (`response_format.json_schema`). */
|
|
544
|
+
name?: string;
|
|
545
|
+
description?: string;
|
|
546
|
+
};
|
|
547
|
+
|
|
548
|
+
export type AgentCallOptions = {
|
|
549
|
+
/** Thread to read from / write to the memory (same as `memory.thread`). */
|
|
550
|
+
thread?: string;
|
|
551
|
+
/** @deprecated Alias of `thread` — kept for compatibility. */
|
|
552
|
+
threadId?: string;
|
|
553
|
+
/** Opaque caller identity (same as `memory.resource`). */
|
|
554
|
+
resource?: string;
|
|
555
|
+
/** @deprecated Alias of `resource` — kept for compatibility. */
|
|
556
|
+
resourceId?: string;
|
|
557
|
+
/** Max model calls for this run (default: the agent's `maxSteps`, then 5). */
|
|
558
|
+
maxSteps?: number;
|
|
559
|
+
/** Window on the replayed history for this run — the **last N** messages. */
|
|
560
|
+
lastMessages?: number;
|
|
561
|
+
/** Override the provider for this call — including `provider.options` (merged). */
|
|
562
|
+
provider?: Partial<AgentProvider>;
|
|
563
|
+
/** Override the instructions for this run. */
|
|
564
|
+
instructions?: string;
|
|
565
|
+
/**
|
|
566
|
+
* Files and images sent with this run — a path (server-side) or a
|
|
567
|
+
* `File`/`Blob`/base64 payload (front-end, SDK).
|
|
568
|
+
*
|
|
569
|
+
* ```ts
|
|
570
|
+
* await agent.generate('Summarize this invoice', { files: ['./invoices/2026-01.pdf'] });
|
|
571
|
+
* ```
|
|
572
|
+
*/
|
|
573
|
+
files?: AgentAttachment | AgentAttachment[];
|
|
574
|
+
/** Where a **path** attachment is resolved from (default: the process cwd). */
|
|
575
|
+
filesBaseDir?: string;
|
|
576
|
+
/**
|
|
577
|
+
* Tools of this run:
|
|
578
|
+
*
|
|
579
|
+
* - `true` (default) — **every** tool the agent declares
|
|
580
|
+
* - `false` — **none**: the run answers directly (the definitions are not even sent)
|
|
581
|
+
* - `['forecast', 'echo']` — **only these** (an allow-list; an unknown name is ignored)
|
|
582
|
+
* - `{ … }` / `[{ … }]` — extra tools, **merged** with the agent's own
|
|
583
|
+
*
|
|
584
|
+
* ```ts
|
|
585
|
+
* await agent.generate('Trie ce texte.', { tools: false });
|
|
586
|
+
* await agent.generate('Météo ?', { tools: ['forecast'] });
|
|
587
|
+
* ```
|
|
588
|
+
*/
|
|
589
|
+
tools?: boolean | string[] | AgentTools;
|
|
590
|
+
/** How the model may use the tools (default `'auto'` — it decides). */
|
|
591
|
+
toolChoice?: AgentToolChoice;
|
|
592
|
+
/**
|
|
593
|
+
* Turns injected into the run — **after** the thread history, **before** the
|
|
594
|
+
* input. They are sent to the model *and* saved into the thread, so they are
|
|
595
|
+
* how a conversation is seeded or a history imported:
|
|
596
|
+
*
|
|
597
|
+
* ```ts
|
|
598
|
+
* await agent.generate('Et pour Lyon ?', {
|
|
599
|
+
* thread: 'chat-1',
|
|
600
|
+
* messages: [
|
|
601
|
+
* { role: 'user', content: 'Quel temps à Paris ?' },
|
|
602
|
+
* { role: 'assistant', content: '18°C et ensoleillé.' },
|
|
603
|
+
* ],
|
|
604
|
+
* });
|
|
605
|
+
* ```
|
|
606
|
+
*
|
|
607
|
+
* The block may end on an `assistant` turn (continue a conversation, prime a
|
|
608
|
+
* reply); it is normalized like the input and needs no `thread` to be sent.
|
|
609
|
+
* To write a thread **without** a model call, use `agent.remember()`.
|
|
610
|
+
*/
|
|
611
|
+
messages?: AgentInput;
|
|
612
|
+
/** Extended thinking for this run — overrides the agent's `thinking` default. */
|
|
613
|
+
thinking?: AgentThinking;
|
|
614
|
+
/** Abort the run — the partial result is returned, not thrown. */
|
|
615
|
+
signal?: AbortSignal;
|
|
616
|
+
/** Shortcut for `structuredOutput: { schema }`. */
|
|
617
|
+
schema?: Joi.Schema | any;
|
|
618
|
+
/** Ask for a typed object instead of free text. */
|
|
619
|
+
structuredOutput?: AgentStructuredOutput;
|
|
620
|
+
/**
|
|
621
|
+
* Memory of this run — the Mastra-style shorthand:
|
|
622
|
+
*
|
|
623
|
+
* ```ts
|
|
624
|
+
* await agent.generate('Remember my favorite color is blue.', {
|
|
625
|
+
* memory: { resource: 'user-123', thread: 'conversation-123' },
|
|
626
|
+
* })
|
|
627
|
+
* ```
|
|
628
|
+
*
|
|
629
|
+
* The `memory` block wins over the flat `thread` / `resource` options.
|
|
630
|
+
* `threadId` / `resourceId` are accepted as deprecated aliases.
|
|
631
|
+
*/
|
|
632
|
+
memory?: {
|
|
633
|
+
/** Thread to read from and write to (with `resource`, its namespace). */
|
|
634
|
+
thread?: string;
|
|
635
|
+
/** @deprecated Alias of `thread`. */
|
|
636
|
+
threadId?: string;
|
|
637
|
+
/** Caller identity — namespaces the thread and feeds dynamic instructions. */
|
|
638
|
+
resource?: string;
|
|
639
|
+
/** @deprecated Alias of `resource`. */
|
|
640
|
+
resourceId?: string;
|
|
641
|
+
/** Read the history but do not write the run back. */
|
|
642
|
+
readOnly?: boolean;
|
|
643
|
+
};
|
|
644
|
+
/** Called after each model call, before its tools run. */
|
|
645
|
+
onStepFinish?: (step: AgentStep) => void | Promise<void>;
|
|
646
|
+
};
|
|
647
|
+
|
|
648
|
+
export type AgentGenerateResult<T = any> = {
|
|
649
|
+
text: string;
|
|
650
|
+
/** Present when a `schema` / `structuredOutput` was requested. */
|
|
651
|
+
object?: T;
|
|
652
|
+
/** Everything the model thought, when `thinking` was on (all steps joined). */
|
|
653
|
+
reasoning?: string;
|
|
654
|
+
toolCalls: AgentToolCall[];
|
|
655
|
+
toolResults: AgentToolResultEntry[];
|
|
656
|
+
steps: AgentStep[];
|
|
657
|
+
usage: AgentUsage;
|
|
658
|
+
finishReason: string;
|
|
659
|
+
/** The complete conversation, ready to be persisted. */
|
|
660
|
+
messages: AgentMessage[];
|
|
661
|
+
error?: string;
|
|
662
|
+
};
|
|
663
|
+
|
|
664
|
+
/** Incremental event of `agent.stream()`. */
|
|
665
|
+
export type AgentStreamChunk =
|
|
666
|
+
| { type: "text"; text: string }
|
|
667
|
+
/** Thinking output — never mixed with the answer. */
|
|
668
|
+
| { type: "reasoning"; text: string }
|
|
669
|
+
| { type: "tool_call"; toolCall: AgentToolCall }
|
|
670
|
+
| { type: "tool_result"; toolResult: AgentToolResultEntry }
|
|
671
|
+
| { type: "step"; step: AgentStep }
|
|
672
|
+
| { type: "finish"; finishReason: string; usage: AgentUsage };
|
|
673
|
+
|
|
674
|
+
/**
|
|
675
|
+
* `agent.stream()` result — start consuming `textStream` immediately, the
|
|
676
|
+
* promises resolve when the run (tool rounds included) is over.
|
|
677
|
+
*/
|
|
678
|
+
export type AgentStreamResult<T = any> = {
|
|
679
|
+
/** Every event, tool calls and results included. */
|
|
680
|
+
fullStream: AsyncIterable<AgentStreamChunk>;
|
|
681
|
+
/** Just the text tokens, as they arrive. */
|
|
682
|
+
textStream: AsyncIterable<string>;
|
|
683
|
+
text: Promise<string>;
|
|
684
|
+
/** Everything the model thought, when `thinking` was on — same as `generate()`. */
|
|
685
|
+
reasoning: Promise<string | undefined>;
|
|
686
|
+
object: Promise<T | undefined>;
|
|
687
|
+
toolCalls: Promise<AgentToolCall[]>;
|
|
688
|
+
toolResults: Promise<AgentToolResultEntry[]>;
|
|
689
|
+
steps: Promise<AgentStep[]>;
|
|
690
|
+
usage: Promise<AgentUsage>;
|
|
691
|
+
finishReason: Promise<string>;
|
|
692
|
+
messages: Promise<AgentMessage[]>;
|
|
693
|
+
/** Stop the run — the promises resolve with what has been produced so far. */
|
|
694
|
+
abort: (reason?: string) => void;
|
|
695
|
+
};
|
|
696
|
+
|
|
697
|
+
/** Instructions — static text, or computed per call (A/B tests, dynamic prompts). */
|
|
698
|
+
export type AgentInstructions =
|
|
699
|
+
| string
|
|
700
|
+
| ((ctx: {
|
|
701
|
+
agent: Agent;
|
|
702
|
+
/** Memory thread of the run. */
|
|
703
|
+
thread?: string;
|
|
704
|
+
/** Caller identity — what a per-user prompt branches on. */
|
|
705
|
+
resource?: string;
|
|
706
|
+
/** @deprecated Alias of `thread`. */
|
|
707
|
+
threadId?: string;
|
|
708
|
+
/** @deprecated Alias of `resource`. */
|
|
709
|
+
resourceId?: string;
|
|
710
|
+
rest?: InstanceType<typeof useRest>;
|
|
711
|
+
}) => string | Promise<string>);
|
|
712
|
+
|
|
713
|
+
/** Actions exposed by the agents HTTP API (`POST /api/:tenant_id/agents/:agent/:action`). */
|
|
714
|
+
export type AgentActions =
|
|
715
|
+
/** Agent metadata (tools, model, options) — no model call. */
|
|
716
|
+
| "info"
|
|
717
|
+
/** Run the agent to completion and return the answer. */
|
|
718
|
+
| "generate"
|
|
719
|
+
/** Same run, streamed as Server-Sent Events. */
|
|
720
|
+
| "stream"
|
|
721
|
+
/** Structured output — requires `api.object` to be declared. */
|
|
722
|
+
| "object"
|
|
723
|
+
/** Read a memory thread. */
|
|
724
|
+
| "history"
|
|
725
|
+
/** List a caller's memory threads — requires a store that supports `list`. */
|
|
726
|
+
| "threads"
|
|
727
|
+
/** Forget a memory thread. */
|
|
728
|
+
| "clear";
|
|
729
|
+
|
|
730
|
+
/** Context handed to an `api.access` rule of an agent. */
|
|
731
|
+
export type AgentAccessContext = {
|
|
732
|
+
rest: InstanceType<typeof useRest>;
|
|
733
|
+
/** The agent the request targets. */
|
|
734
|
+
agent: InstanceType<typeof Agent>;
|
|
735
|
+
/** Action being attempted (`generate`, `stream`…). */
|
|
736
|
+
action: string;
|
|
737
|
+
/** Raw request body. */
|
|
738
|
+
body: any;
|
|
739
|
+
/** Input the run would receive. */
|
|
740
|
+
input?: AgentInput;
|
|
741
|
+
/** Memory thread of the run, when the body carried one. */
|
|
742
|
+
thread?: string;
|
|
743
|
+
/** @deprecated Alias of `thread`. */
|
|
744
|
+
threadId?: string;
|
|
745
|
+
error: typeof fn.error;
|
|
746
|
+
jwt: typeof jwt;
|
|
747
|
+
token: { value: string | null; decoded: Record<string, unknown> | null; provided: boolean; expired: boolean };
|
|
748
|
+
};
|
|
749
|
+
|
|
750
|
+
/** Per-action access rules — `'*'` wildcard, same pattern as collections and vars. */
|
|
751
|
+
export type AgentAccess = {
|
|
752
|
+
[key in AgentActions | (string & {})]?: boolean | ((ctx: AgentAccessContext) => boolean | Promise<boolean>);
|
|
753
|
+
};
|
|
754
|
+
|
|
755
|
+
/**
|
|
756
|
+
* HTTP API of an agent (declared in `define.Agent({ api })`).
|
|
757
|
+
*
|
|
758
|
+
* ```ts
|
|
759
|
+
* api: {
|
|
760
|
+
* access: {
|
|
761
|
+
* info: true, // public metadata
|
|
762
|
+
* generate: (ctx) => !!ctx.token.value, // any authenticated caller
|
|
763
|
+
* stream: (ctx) => !!ctx.token.value,
|
|
764
|
+
* },
|
|
765
|
+
* object: { schema: v.object({ … }) }, // enables the `object` action
|
|
766
|
+
* }
|
|
767
|
+
* ```
|
|
768
|
+
*/
|
|
769
|
+
export type AgentApi = {
|
|
770
|
+
/** Access rules per action — **no rules = denied** (secure by default). */
|
|
771
|
+
access?: AgentAccess;
|
|
772
|
+
/**
|
|
773
|
+
* Schema returned by the `object` action. Declared **server-side** on purpose:
|
|
774
|
+
* a client never dictates the shape, and the answer is really validated.
|
|
775
|
+
*/
|
|
776
|
+
object?: AgentStructuredOutput;
|
|
777
|
+
};
|
|
778
|
+
|
|
779
|
+
/**
|
|
780
|
+
* An agent definition — `{tenant.dir}/agents/**\/*.agent.ts`, declared with
|
|
781
|
+
* `define.Agent({ … })`.
|
|
782
|
+
*/
|
|
783
|
+
export type AgentConfig = {
|
|
784
|
+
_isAgent_?: boolean;
|
|
785
|
+
/** Injected by the loader — the tenant this definition belongs to. */
|
|
786
|
+
_tenant_?: string;
|
|
787
|
+
/** Identifier — required, unique per tenant. */
|
|
788
|
+
id?: string;
|
|
789
|
+
name?: string;
|
|
790
|
+
/** What the agent is for — required (served by `info`, read by humans). */
|
|
791
|
+
description?: string;
|
|
792
|
+
instructions: AgentInstructions;
|
|
793
|
+
provider: AgentProvider;
|
|
794
|
+
tools?: AgentTools;
|
|
795
|
+
memory?: AgentMemory;
|
|
796
|
+
/** Max model calls per run (default 5). */
|
|
797
|
+
maxSteps?: number;
|
|
798
|
+
/** Default tool choice for every run (default `'auto'`). */
|
|
799
|
+
toolChoice?: AgentToolChoice;
|
|
800
|
+
/** Default reasoning for every run (default off) — overridable per call. */
|
|
801
|
+
thinking?: AgentThinking;
|
|
802
|
+
/**
|
|
803
|
+
* Default window on the replayed history — the **last N** messages of the
|
|
804
|
+
* thread, whatever the store keeps. A cheap way to bound the prompt (a tool
|
|
805
|
+
* round stores several messages, so count is a proxy, not a measure).
|
|
806
|
+
*/
|
|
807
|
+
lastMessages?: number;
|
|
808
|
+
/**
|
|
809
|
+
* The agent's durable scratchpad — see `AgentWorkingMemory`. Needs a store that
|
|
810
|
+
* supports it (the three built-in ones do) and, for the default scope, a
|
|
811
|
+
* `resource` at call time.
|
|
812
|
+
*/
|
|
813
|
+
workingMemory?: AgentWorkingMemory;
|
|
814
|
+
/**
|
|
815
|
+
* Memory processors — run in declaration order around the model call:
|
|
816
|
+
* `load` on what it will see, `save` on what will be stored (Mastra-style).
|
|
817
|
+
*/
|
|
818
|
+
processors?: AgentMemoryProcessor[];
|
|
819
|
+
enabled?: boolean;
|
|
820
|
+
/** HTTP API — reachable at `POST /api/:tenant_id/agents/:id/:action` once declared. */
|
|
821
|
+
api?: AgentApi;
|
|
822
|
+
};
|
|
823
|
+
|
|
824
|
+
/** Alias of `AgentConfig` — what the loader registers in `cfg.agents`. */
|
|
825
|
+
export type AgentDefinition = AgentConfig;
|
|
826
|
+
|
|
827
|
+
/** Tenant-scoped agent registry — the `agents` member of every context. */
|
|
828
|
+
export type TenantAgents = {
|
|
829
|
+
/** The agent instance (tenant-bound), or `undefined`. */
|
|
830
|
+
get(id: string): InstanceType<typeof Agent> | undefined;
|
|
831
|
+
has(id: string): boolean;
|
|
832
|
+
/** Declared agent ids of this tenant. */
|
|
833
|
+
ids(): string[];
|
|
834
|
+
list(): InstanceType<typeof Agent>[];
|
|
835
|
+
/** Re-scan `{tenant.dir}/agents` and rebuild the registry. */
|
|
836
|
+
reload(): Promise<void>;
|
|
837
|
+
};
|