@anvia/core 0.26.0 → 1.0.0-rc.10
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 +400 -94
- package/dist/agent/index.d.ts +67 -71
- package/dist/agent/index.js +36 -18
- package/dist/agent/interactions/index.d.ts +122 -0
- package/dist/agent/interactions/index.js +20 -0
- package/dist/agent-DWzW9SoH.d.ts +150 -0
- package/dist/chunk-3RM57ZT2.js +31 -0
- package/dist/chunk-3RM57ZT2.js.map +1 -0
- package/dist/chunk-3RWESPUG.js +331 -0
- package/dist/chunk-3RWESPUG.js.map +1 -0
- package/dist/{chunk-NCPN4SJR.js → chunk-3SKZ2BKP.js} +15 -13
- package/dist/chunk-3SKZ2BKP.js.map +1 -0
- package/dist/chunk-3XQGVDU5.js +69 -0
- package/dist/chunk-3XQGVDU5.js.map +1 -0
- package/dist/{chunk-MRQLEK2B.js → chunk-5C6B6ZRH.js} +69 -51
- package/dist/chunk-5C6B6ZRH.js.map +1 -0
- package/dist/chunk-6BBOCFHV.js +323 -0
- package/dist/chunk-6BBOCFHV.js.map +1 -0
- package/dist/chunk-7JLAIN6E.js +15 -0
- package/dist/chunk-7JLAIN6E.js.map +1 -0
- package/dist/chunk-7PHMK7W4.js +1516 -0
- package/dist/chunk-7PHMK7W4.js.map +1 -0
- package/dist/{chunk-CWUJUSOS.js → chunk-AZB6N7P4.js} +94 -65
- package/dist/chunk-AZB6N7P4.js.map +1 -0
- package/dist/chunk-D4PACGPA.js +37 -0
- package/dist/chunk-D4PACGPA.js.map +1 -0
- package/dist/chunk-EFLT7XZD.js +51 -0
- package/dist/chunk-EFLT7XZD.js.map +1 -0
- package/dist/chunk-EMZKPRE6.js +667 -0
- package/dist/chunk-EMZKPRE6.js.map +1 -0
- package/dist/chunk-I3Q7XSBB.js +59 -0
- package/dist/chunk-I3Q7XSBB.js.map +1 -0
- package/dist/chunk-J6LVLV6P.js +13 -0
- package/dist/chunk-J6LVLV6P.js.map +1 -0
- package/dist/chunk-LTXABCOO.js +127 -0
- package/dist/chunk-LTXABCOO.js.map +1 -0
- package/dist/chunk-OJBFDBLG.js +164 -0
- package/dist/chunk-OJBFDBLG.js.map +1 -0
- package/dist/chunk-QGX73TSQ.js +177 -0
- package/dist/chunk-QGX73TSQ.js.map +1 -0
- package/dist/chunk-QOUPWOGW.js +29 -0
- package/dist/chunk-QOUPWOGW.js.map +1 -0
- package/dist/chunk-SJMSS5SI.js +171 -0
- package/dist/chunk-SJMSS5SI.js.map +1 -0
- package/dist/chunk-T2C3CGDQ.js +56 -0
- package/dist/chunk-T2C3CGDQ.js.map +1 -0
- package/dist/chunk-VX3HS6PE.js +4569 -0
- package/dist/chunk-VX3HS6PE.js.map +1 -0
- package/dist/chunk-X4LK4ODN.js +86 -0
- package/dist/chunk-X4LK4ODN.js.map +1 -0
- package/dist/chunk-ZA564323.js +331 -0
- package/dist/chunk-ZA564323.js.map +1 -0
- package/dist/completion/index.d.ts +6 -36
- package/dist/completion/index.js +34 -29
- package/dist/documents/index.d.ts +34 -0
- package/dist/documents/index.js +340 -0
- package/dist/documents/index.js.map +1 -0
- package/dist/dynamic-tools-aIZlg5x1.d.ts +45 -0
- package/dist/embeddings/index.d.ts +11 -9
- package/dist/embeddings/index.js +3 -4
- package/dist/evals/index.d.ts +57 -21
- package/dist/evals/index.js +209 -104
- package/dist/evals/index.js.map +1 -1
- package/dist/extractor/index.d.ts +27 -42
- package/dist/extractor/index.js +9 -22
- package/dist/guardrails/index.d.ts +7 -129
- package/dist/guardrails/index.js +1 -1
- package/dist/image-generation/index.d.ts +23 -23
- package/dist/image-generation/index.js +7 -39
- package/dist/image-generation/index.js.map +1 -1
- package/dist/index.d.ts +24 -22
- package/dist/index.js +85 -68
- package/dist/internal/agent.d.ts +156 -10
- package/dist/internal/agent.js +58 -18
- package/dist/internal/agent.js.map +1 -1
- package/dist/mcp/index.d.ts +7 -15
- package/dist/mcp/index.js +3 -348
- package/dist/mcp/index.js.map +1 -1
- package/dist/memory/index.d.ts +20 -6
- package/dist/memory/index.js +11 -10
- package/dist/middleware-kcF8AusP.d.ts +59 -0
- package/dist/model-call-options-CZkSw_xN.d.ts +6 -0
- package/dist/model-listing/index.d.ts +3 -1
- package/dist/observability/index.d.ts +23 -4
- package/dist/observability/index.js +10 -5
- package/dist/observability/index.js.map +1 -1
- package/dist/pipeline/index.d.ts +111 -73
- package/dist/pipeline/index.js +471 -286
- package/dist/pipeline/index.js.map +1 -1
- package/dist/provider-output-error-BEwDgVv3.d.ts +99 -0
- package/dist/retry-CjvSlKGW.d.ts +16 -0
- package/dist/skills/index.d.ts +5 -4
- package/dist/skills/index.js +8 -8
- package/dist/speech-generation/index.d.ts +37 -0
- package/dist/speech-generation/index.js +10 -0
- package/dist/streaming/index.js +37 -3
- package/dist/streaming/index.js.map +1 -1
- package/dist/text-ZLECpQE7.d.ts +32 -0
- package/dist/think-tool-BwCsJ365.d.ts +40 -0
- package/dist/tool/index.d.ts +11 -6
- package/dist/tool/index.js +21 -21
- package/dist/tool-BpqpoRSE.d.ts +58 -0
- package/dist/transcription/index.d.ts +29 -22
- package/dist/transcription/index.js +7 -57
- package/dist/transcription/index.js.map +1 -1
- package/dist/type-utils-CtHVDRn_.d.ts +6 -0
- package/dist/types-CXNE592e.d.ts +130 -0
- package/dist/types-Cr4uiYo5.d.ts +99 -0
- package/dist/{types-04LqWrmy.d.ts → types-DC1U1XwW.d.ts} +1 -1
- package/dist/types-DKOXVTcq.d.ts +155 -0
- package/dist/types-DgvozfPc.d.ts +349 -0
- package/dist/types-DhkodEft.d.ts +105 -0
- package/dist/types-DjqRHeAi.d.ts +31 -0
- package/dist/types-Sue2hb_L.d.ts +403 -0
- package/dist/vector-store/index.d.ts +34 -34
- package/dist/vector-store/index.js +10 -6
- package/package.json +22 -24
- package/dist/agent-x3YTyv5i.d.ts +0 -222
- package/dist/audio-generation/index.d.ts +0 -33
- package/dist/audio-generation/index.js +0 -42
- package/dist/audio-generation/index.js.map +0 -1
- package/dist/chunk-2ODTMRHP.js +0 -54
- package/dist/chunk-2ODTMRHP.js.map +0 -1
- package/dist/chunk-ADH7NNCS.js +0 -512
- package/dist/chunk-ADH7NNCS.js.map +0 -1
- package/dist/chunk-BALBBVI3.js +0 -2732
- package/dist/chunk-BALBBVI3.js.map +0 -1
- package/dist/chunk-CQNNSZPG.js +0 -9
- package/dist/chunk-CQNNSZPG.js.map +0 -1
- package/dist/chunk-CWUJUSOS.js.map +0 -1
- package/dist/chunk-DALYP4PX.js +0 -225
- package/dist/chunk-DALYP4PX.js.map +0 -1
- package/dist/chunk-HYUYZEAJ.js +0 -223
- package/dist/chunk-HYUYZEAJ.js.map +0 -1
- package/dist/chunk-I6XOQ4LK.js +0 -466
- package/dist/chunk-I6XOQ4LK.js.map +0 -1
- package/dist/chunk-JI5YZWNT.js +0 -220
- package/dist/chunk-JI5YZWNT.js.map +0 -1
- package/dist/chunk-MC3CCKEB.js +0 -221
- package/dist/chunk-MC3CCKEB.js.map +0 -1
- package/dist/chunk-MELYDKWQ.js +0 -337
- package/dist/chunk-MELYDKWQ.js.map +0 -1
- package/dist/chunk-MNWK2USR.js +0 -243
- package/dist/chunk-MNWK2USR.js.map +0 -1
- package/dist/chunk-MRQLEK2B.js.map +0 -1
- package/dist/chunk-NCPN4SJR.js.map +0 -1
- package/dist/chunk-OIMLU4SF.js +0 -20
- package/dist/chunk-OIMLU4SF.js.map +0 -1
- package/dist/chunk-Q25IWLBT.js +0 -138
- package/dist/chunk-Q25IWLBT.js.map +0 -1
- package/dist/chunk-UQX6EXWG.js +0 -33
- package/dist/chunk-UQX6EXWG.js.map +0 -1
- package/dist/chunk-WQKHFADH.js +0 -12
- package/dist/chunk-WQKHFADH.js.map +0 -1
- package/dist/chunk-XUUY2L2D.js +0 -42
- package/dist/chunk-XUUY2L2D.js.map +0 -1
- package/dist/chunk-XWUC7CIT.js +0 -1
- package/dist/chunk-XWUC7CIT.js.map +0 -1
- package/dist/chunk-YLMDBQO4.js +0 -141
- package/dist/chunk-YLMDBQO4.js.map +0 -1
- package/dist/errors-2moLDuuN.d.ts +0 -17
- package/dist/hooks/index.d.ts +0 -12
- package/dist/hooks/index.js +0 -17
- package/dist/index-BxSbmOMr.d.ts +0 -257
- package/dist/json-BVPssigK.d.ts +0 -39
- package/dist/loaders/index.d.ts +0 -91
- package/dist/loaders/index.js +0 -299
- package/dist/loaders/index.js.map +0 -1
- package/dist/middleware-Dp3d_pxi.d.ts +0 -90
- package/dist/request/index.d.ts +0 -28
- package/dist/request/index.js +0 -25
- package/dist/think-tool-DfCMuO8e.d.ts +0 -26
- package/dist/tool-Cohdv5GC.d.ts +0 -65
- package/dist/types-BCTRUGex.d.ts +0 -47
- package/dist/types-BrLbKnEz.d.ts +0 -119
- package/dist/types-D9JpeAPF.d.ts +0 -114
- package/dist/types-G12i56s2.d.ts +0 -354
- package/dist/types-JJCxRnaZ.d.ts +0 -70
- package/dist/types-O-abTIin.d.ts +0 -79
- package/dist/ui/index.d.ts +0 -107
- package/dist/ui/index.js +0 -10
- package/dist/ui/index.js.map +0 -1
- /package/dist/{hooks → agent/interactions}/index.js.map +0 -0
- /package/dist/{request → speech-generation}/index.js.map +0 -0
package/README.md
CHANGED
|
@@ -12,10 +12,17 @@ The package is dependency-injection oriented: create provider models, typed tool
|
|
|
12
12
|
|
|
13
13
|
## Installation
|
|
14
14
|
|
|
15
|
+
Anvia 1.0 is currently published on npm under the `rc` tag. The unqualified `latest` tag remains
|
|
16
|
+
on the maintenance-only v0 line until 1.0 reaches general availability. Keep Core and every Anvia
|
|
17
|
+
adapter on the same release channel.
|
|
18
|
+
|
|
15
19
|
```sh
|
|
16
|
-
pnpm add @anvia/core
|
|
20
|
+
pnpm add @anvia/core@rc
|
|
17
21
|
```
|
|
18
22
|
|
|
23
|
+
See the repository's [1.0 release policy](../../docs/releases/v1.md) for channel and support
|
|
24
|
+
details.
|
|
25
|
+
|
|
19
26
|
In this monorepo, the package is available through the workspace:
|
|
20
27
|
|
|
21
28
|
```sh
|
|
@@ -26,177 +33,379 @@ pnpm --filter @anvia/core build
|
|
|
26
33
|
|
|
27
34
|
```ts
|
|
28
35
|
import { z } from "zod";
|
|
29
|
-
import {
|
|
36
|
+
import { Agent, createTool } from "@anvia/core";
|
|
30
37
|
import { OpenAIClient } from "@anvia/openai";
|
|
31
38
|
|
|
32
39
|
const client = new OpenAIClient({
|
|
33
40
|
apiKey,
|
|
34
41
|
});
|
|
35
42
|
|
|
36
|
-
const model = client.completionModel("gpt-5");
|
|
43
|
+
const model = client.completionModel({ modelId: "gpt-5", api: "responses" });
|
|
37
44
|
|
|
38
45
|
const lookupOrder = createTool({
|
|
39
46
|
name: "lookup_order",
|
|
40
47
|
description: "Look up an order by id.",
|
|
41
|
-
|
|
48
|
+
inputSchema: z.object({ orderId: z.string() }),
|
|
42
49
|
execute: async ({ orderId }) => ({ orderId, status: "processing" }),
|
|
43
50
|
});
|
|
44
51
|
|
|
45
|
-
const agent = new
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
.
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
+
const agent = new Agent({
|
|
53
|
+
id: "support",
|
|
54
|
+
model,
|
|
55
|
+
instructions: "Help customers with order questions.",
|
|
56
|
+
maxTurns: 4,
|
|
57
|
+
tools: [lookupOrder],
|
|
58
|
+
});
|
|
52
59
|
|
|
53
|
-
|
|
60
|
+
const result = await agent.generate({ prompt: "What is happening with order A123?" });
|
|
61
|
+
if (result.status === "completed") console.log(result.output);
|
|
54
62
|
```
|
|
55
63
|
|
|
56
64
|
## Direct Completions
|
|
57
65
|
|
|
58
|
-
Use `
|
|
59
|
-
|
|
66
|
+
Use `generateCompletion` for one provider call without Agent turns, memory, or local tool
|
|
67
|
+
execution. The model and input are part of one options object:
|
|
60
68
|
|
|
61
69
|
```ts
|
|
62
|
-
import {
|
|
70
|
+
import { generateCompletion } from "@anvia/core";
|
|
63
71
|
import { OpenAIClient } from "@anvia/openai";
|
|
64
72
|
|
|
65
|
-
const model = new OpenAIClient({ apiKey }).completionModel("gpt-5");
|
|
73
|
+
const model = new OpenAIClient({ apiKey }).completionModel({ modelId: "gpt-5", api: "responses" });
|
|
66
74
|
|
|
67
|
-
const result = await
|
|
68
|
-
|
|
75
|
+
const result = await generateCompletion({
|
|
76
|
+
model,
|
|
77
|
+
prompt: "Summarize Anvia in one sentence.",
|
|
69
78
|
instructions: "Answer clearly and concisely.",
|
|
70
79
|
});
|
|
71
80
|
|
|
72
|
-
console.log(result.
|
|
81
|
+
console.log(result.output); // string
|
|
73
82
|
```
|
|
74
83
|
|
|
75
|
-
Use `messages` when
|
|
76
|
-
|
|
84
|
+
Use `messages` when the application already owns the transcript. Exactly one of `prompt` or
|
|
85
|
+
`messages` is required:
|
|
77
86
|
|
|
78
87
|
```ts
|
|
79
|
-
import {
|
|
88
|
+
import { generateCompletion, type Message } from "@anvia/core";
|
|
80
89
|
|
|
81
|
-
const result = await
|
|
90
|
+
const result = await generateCompletion({
|
|
91
|
+
model,
|
|
82
92
|
messages: [
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
],
|
|
93
|
+
{ role: "system", content: "You are concise." },
|
|
94
|
+
{ role: "user", content: "Explain Anvia." },
|
|
95
|
+
] satisfies readonly Message[],
|
|
86
96
|
maxTokens: 300,
|
|
87
|
-
|
|
97
|
+
providerOptions: {
|
|
88
98
|
reasoning: { effort: "low" },
|
|
89
99
|
},
|
|
90
100
|
});
|
|
91
101
|
```
|
|
92
102
|
|
|
93
|
-
|
|
103
|
+
Messages are plain, readonly `{ role, content }` objects. Use structural literals with
|
|
104
|
+
`satisfies Message` or `satisfies readonly Message[]`; there is no message factory namespace.
|
|
105
|
+
Multimodal user content uses `text`, `image`, and `file` parts, while assistant tool calls use
|
|
106
|
+
`{ type: "tool-call", toolCallId, toolName, input }`. At external boundaries, validate with
|
|
107
|
+
`parseMessage`, `parseMessages`, `messageSchema`, or an application-specific
|
|
108
|
+
`createMessageSchema({ metadataSchema })`.
|
|
109
|
+
|
|
110
|
+
Add `outputSchema` to the same function for typed, schema-validated output:
|
|
111
|
+
|
|
112
|
+
```ts
|
|
113
|
+
import { generateCompletion } from "@anvia/core";
|
|
114
|
+
import { z } from "zod";
|
|
115
|
+
|
|
116
|
+
const result = await generateCompletion({
|
|
117
|
+
model,
|
|
118
|
+
prompt: "Extract: Acme reports a high-priority checkout failure.",
|
|
119
|
+
outputSchema: z.object({
|
|
120
|
+
customer: z.string(),
|
|
121
|
+
priority: z.enum(["low", "medium", "high"]),
|
|
122
|
+
}),
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
console.log(result.output.priority); // fully typed
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
`CompletionResult` consistently contains `output`, the original `text`, normalized `content`,
|
|
129
|
+
`usage`, and `rawResponse`, plus optional message, context, source, provider-tool, and finish-reason
|
|
130
|
+
metadata. First-party adapters normalize provider termination into `finishReason` (`stop`, `length`,
|
|
131
|
+
`content-filter`, `tool-calls`, or `other`) while preserving the provider value separately as
|
|
132
|
+
`providerFinishReason`.
|
|
133
|
+
|
|
134
|
+
Schema-backed completion checks termination before JSON parsing. `finishReason: "length"` throws
|
|
135
|
+
`CompletionStructuredOutputError` with `phase: "truncated"`; `finishReason: "content-filter"`
|
|
136
|
+
throws it with `phase: "content-filter"` and is not retried by the default policy. Ordinary text
|
|
137
|
+
completion remains intentional: partial text is returned unchanged with its finish reason so the
|
|
138
|
+
application decides whether to display, continue, or discard it. A direct structured stream can
|
|
139
|
+
similarly end with one typed error event after any already-emitted deltas; it does not silently
|
|
140
|
+
retract public stream progress.
|
|
141
|
+
|
|
142
|
+
Use `streamCompletion` for the streaming form:
|
|
94
143
|
|
|
95
144
|
```ts
|
|
96
|
-
import {
|
|
145
|
+
import { streamCompletion } from "@anvia/core";
|
|
97
146
|
|
|
98
|
-
for await (const event of
|
|
99
|
-
|
|
147
|
+
for await (const event of streamCompletion({
|
|
148
|
+
model,
|
|
149
|
+
prompt: "Write a short launch note.",
|
|
100
150
|
})) {
|
|
101
151
|
if (event.type === "text_delta") process.stdout.write(event.delta);
|
|
152
|
+
if (event.type === "final") console.log(event.result.usage);
|
|
153
|
+
if (event.type === "error") console.error(event.error);
|
|
102
154
|
}
|
|
103
155
|
```
|
|
104
156
|
|
|
105
|
-
|
|
106
|
-
|
|
157
|
+
Tool-call deltas are always emitted when a provider supplies them; there is no opt-in flag. A
|
|
158
|
+
high-level stream emits at most one terminal `error` event and then closes. Provider model adapters
|
|
159
|
+
use the lower-level `CompletionModelStreamEvent`, whose terminal event is `{ type: "final",
|
|
160
|
+
response }`; `streamCompletion` normalizes it to `{ type: "final", result }`.
|
|
107
161
|
|
|
108
|
-
|
|
109
|
-
import { createCompletionStream } from "@anvia/core";
|
|
110
|
-
import type { UIStreamRequest } from "@anvia/core/ui";
|
|
162
|
+
Client requests carry core `Message[]`, so an endpoint can validate and pass them directly:
|
|
111
163
|
|
|
112
|
-
|
|
164
|
+
```ts
|
|
165
|
+
import { completionToClientStream, parseClientStreamRequest } from "@anvia/client";
|
|
166
|
+
import { streamCompletion } from "@anvia/core";
|
|
167
|
+
import { createClientStreamResponse } from "@anvia/server";
|
|
113
168
|
|
|
114
|
-
const
|
|
115
|
-
|
|
169
|
+
const body = parseClientStreamRequest(await request.json());
|
|
170
|
+
const events = completionToClientStream({
|
|
171
|
+
events: streamCompletion({ model, messages: body.messages }),
|
|
116
172
|
});
|
|
173
|
+
return createClientStreamResponse({ events });
|
|
117
174
|
```
|
|
118
175
|
|
|
119
|
-
|
|
176
|
+
Core does not own UI messages, HTTP transports, or the public wire protocol. Those boundaries live
|
|
177
|
+
in `@anvia/client`, `@anvia/server`, and framework packages such as `@anvia/react`.
|
|
178
|
+
|
|
179
|
+
## Retries, Provider Options, and Cancellation
|
|
180
|
+
|
|
181
|
+
Direct completion and media calls accept `retries?: RetryOptions | false`. An omitted or `false`
|
|
182
|
+
value makes one provider attempt; `{}` enables the default retry policy. Only retry-safe provider
|
|
183
|
+
calls are repeated.
|
|
120
184
|
|
|
121
185
|
```ts
|
|
122
|
-
|
|
123
|
-
|
|
186
|
+
const controller = new AbortController();
|
|
187
|
+
|
|
188
|
+
const result = await generateCompletion({
|
|
189
|
+
model,
|
|
190
|
+
prompt: "Summarize this incident.",
|
|
191
|
+
retries: { maxAttempts: 3, initialDelayMs: 100, maxDelayMs: 1_000 },
|
|
192
|
+
abortSignal: controller.signal,
|
|
193
|
+
providerOptions: { reasoning: { effort: "medium" } },
|
|
194
|
+
});
|
|
195
|
+
```
|
|
124
196
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
197
|
+
`providerOptions` contains a strict JSON object passed to an adapter. Runtime values such as
|
|
198
|
+
`undefined`, non-finite numbers, cycles, a top-level array, and class instances are rejected rather
|
|
199
|
+
than coerced. Nested arrays are valid JSON. Canonical Anvia fields such as model, input,
|
|
200
|
+
temperature, tools, dimensions, text, and voice take precedence over conflicting provider keys.
|
|
201
|
+
Cancellation is forwarded to provider SDK calls and is never retried.
|
|
202
|
+
|
|
203
|
+
## Agents
|
|
204
|
+
|
|
205
|
+
Agents own their default retry policy. A run with no `retries` value inherits the Agent setting;
|
|
206
|
+
`false` disables it for that run; an object replaces it for that run. Retries apply to the current
|
|
207
|
+
completion only, so completed tools and earlier turns are never replayed. `maxAttempts` is the
|
|
208
|
+
total number of model attempts for that completion, including the initial attempt; it is not the
|
|
209
|
+
number of additional retries.
|
|
210
|
+
|
|
211
|
+
```ts
|
|
212
|
+
const agent = new Agent({
|
|
213
|
+
id: "support",
|
|
214
|
+
model,
|
|
215
|
+
retries: { maxAttempts: 3 },
|
|
128
216
|
});
|
|
129
217
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
218
|
+
await agent.generate({ prompt: "Try normally." });
|
|
219
|
+
await agent.generate({ prompt: "Do not retry this run.", retries: false });
|
|
220
|
+
await agent.generate({
|
|
221
|
+
prompt: "Use one custom policy.",
|
|
222
|
+
retries: { maxAttempts: 2, initialDelayMs: 0, maxDelayMs: 0 },
|
|
133
223
|
});
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
When an Agent has `outputSchema`, truncation, JSON parsing, and schema-validation failures use the
|
|
227
|
+
same retry budget when retries are explicitly enabled. Each retry starts from the original request
|
|
228
|
+
rather than recursively accumulating failed attempts. Truncated output and reasoning are omitted;
|
|
229
|
+
parse and schema repairs include only a bounded, text-only preview of the latest failed response.
|
|
230
|
+
The correction asks for shorter raw JSON matching the schema, without Markdown or commentary.
|
|
231
|
+
Transport failures and structured-output failures therefore cannot exceed `maxAttempts` in total.
|
|
232
|
+
Completed Agent results expose the last generation's `finishReason` and `providerFinishReason`, and
|
|
233
|
+
the same fields remain attached to each assistant message's Anvia generation metadata.
|
|
234
|
+
|
|
235
|
+
Malformed, incomplete, or non-JSON provider tool arguments fail with
|
|
236
|
+
`CompletionProviderOutputError`. The default policy retries only explicitly retry-safe provider
|
|
237
|
+
output failures when retries are enabled; it does not make arbitrary `SyntaxError` instances
|
|
238
|
+
retryable. Tool calls are validated as a complete set before any tool executes, and filtered tool
|
|
239
|
+
calls are never retried by default. Raw provider arguments are not retained in the error or retry
|
|
240
|
+
metadata. A no-argument tool call must still contain the JSON value `{}`; blank argument text is
|
|
241
|
+
malformed provider output and is never replaced with invented input.
|
|
242
|
+
|
|
243
|
+
Streaming attempts are retried only before any provider event has been exposed. Once progress has
|
|
244
|
+
been emitted, Anvia returns the failure without starting another provider attempt, because replaying
|
|
245
|
+
the stream could duplicate text, tool-call deltas, or other observable events. Applications that
|
|
246
|
+
want post-progress recovery must buffer attempts and define their own reset or resume protocol.
|
|
247
|
+
|
|
248
|
+
Structured output remains strict: Core trims surrounding whitespace, parses JSON, and validates the
|
|
249
|
+
result with the configured Zod schema. As a compatibility fallback for OpenAI-compatible providers
|
|
250
|
+
that violate strict JSON mode, Core also accepts a response consisting entirely of one lowercase
|
|
251
|
+
`json` Markdown fence or one unlabeled Markdown fence. It does not search prose for JSON, accept
|
|
252
|
+
content before or after a fence, or bypass schema validation. `AgentStructuredOutputError` reports
|
|
253
|
+
the `truncated`, `content-filter`, `parse`, or `schema` phase, attempt counts, output length/format
|
|
254
|
+
metadata, per-attempt and cumulative usage, finish reasons, and the original `cause` when one
|
|
255
|
+
exists; its message never contains the rejected model response. The `completion.retry` observer
|
|
256
|
+
event records the same safe diagnostics and whether failed output was omitted or previewed, never
|
|
257
|
+
the model output itself.
|
|
258
|
+
|
|
259
|
+
Agent results are discriminated by `status`. Completed results include typed `output` and `text`;
|
|
260
|
+
guardrail blocks return `status: "blocked"`, `stage`, and `text`; tool approvals and first-class
|
|
261
|
+
questions return a JSON-safe `status: "suspended"` result.
|
|
134
262
|
|
|
135
|
-
|
|
263
|
+
```ts
|
|
264
|
+
const result = await agent.generate({ prompt: "Help with this request." });
|
|
265
|
+
|
|
266
|
+
if (result.status === "completed") console.log(result.output);
|
|
267
|
+
if (result.status === "blocked") console.log(result.stage, result.text);
|
|
268
|
+
if (result.status === "suspended") {
|
|
269
|
+
const resumed = await agent.generate({
|
|
270
|
+
continuation: result.continuation,
|
|
271
|
+
response:
|
|
272
|
+
result.interaction.type === "tool-approval"
|
|
273
|
+
? { type: "tool-approval", approved: true }
|
|
274
|
+
: {
|
|
275
|
+
type: "tool-question",
|
|
276
|
+
answers: result.interaction.questions.map((question) => ({
|
|
277
|
+
questionId: question.id,
|
|
278
|
+
value: "application-provided answer",
|
|
279
|
+
})),
|
|
280
|
+
},
|
|
281
|
+
});
|
|
282
|
+
console.log(resumed.status, resumed.resumedFrom);
|
|
283
|
+
}
|
|
136
284
|
```
|
|
137
285
|
|
|
138
|
-
|
|
286
|
+
Keep continuations server-side. A resumed phase receives a new `runId`; Core validates the
|
|
287
|
+
continuation and current Agent/tool registration but does not provide a durable continuation store
|
|
288
|
+
or exactly-once execution. Use `createQuestionTool({ name, description })` when a model must ask for
|
|
289
|
+
structured free-text or choice answers.
|
|
139
290
|
|
|
140
|
-
|
|
291
|
+
Import JSON-safe interaction contracts and parsers from their browser-safe subpath. This entrypoint
|
|
292
|
+
does not load the Agent runtime, MCP clients, or Node infrastructure:
|
|
141
293
|
|
|
142
294
|
```ts
|
|
143
|
-
|
|
295
|
+
import {
|
|
296
|
+
type AgentInteractionResponse,
|
|
297
|
+
parseAgentInteractionRequest,
|
|
298
|
+
parseAgentInteractionResponse,
|
|
299
|
+
} from "@anvia/core/agent/interactions";
|
|
144
300
|
```
|
|
145
301
|
|
|
146
|
-
|
|
302
|
+
An Agent with `outputSchema` carries that output type through `generate`, `stream`, `asTool`, and
|
|
303
|
+
Pipeline Agent stages. Agent stream finals use the same result shape:
|
|
147
304
|
|
|
148
305
|
```ts
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
Message.user("What is my project named?"),
|
|
156
|
-
])
|
|
157
|
-
.send();
|
|
306
|
+
for await (const event of agent.stream({ prompt: "Help with this request." })) {
|
|
307
|
+
if (event.type === "final") {
|
|
308
|
+
if (event.result.status === "completed") console.log(event.result.output);
|
|
309
|
+
else console.log(event.result.stage, event.result.text);
|
|
310
|
+
}
|
|
311
|
+
}
|
|
158
312
|
```
|
|
159
313
|
|
|
160
|
-
|
|
314
|
+
Pass `abortSignal` on a run to cancel the active provider call, tools, and nested Agent tools.
|
|
315
|
+
|
|
316
|
+
## Memory
|
|
317
|
+
|
|
318
|
+
Configure durable conversation memory on the Agent, then run through a session:
|
|
161
319
|
|
|
162
320
|
```ts
|
|
163
|
-
import {
|
|
164
|
-
import type {
|
|
321
|
+
import { Agent, type MemoryStore, type Message } from "@anvia/core";
|
|
322
|
+
import type { MemoryAppendOptions, MemoryScope } from "@anvia/core/memory";
|
|
165
323
|
|
|
166
324
|
class AppMemoryStore implements MemoryStore {
|
|
167
325
|
private readonly sessions = new Map<string, Message[]>();
|
|
168
326
|
|
|
169
|
-
async load(
|
|
170
|
-
return [...(this.sessions.get(
|
|
327
|
+
async load({ scope }: { scope: MemoryScope }): Promise<Message[]> {
|
|
328
|
+
return [...(this.sessions.get(scope.sessionId) ?? [])];
|
|
171
329
|
}
|
|
172
330
|
|
|
173
|
-
async append(input:
|
|
174
|
-
const current = this.sessions.get(input.
|
|
175
|
-
this.sessions.set(input.
|
|
331
|
+
async append(input: MemoryAppendOptions): Promise<void> {
|
|
332
|
+
const current = this.sessions.get(input.scope.sessionId) ?? [];
|
|
333
|
+
this.sessions.set(input.scope.sessionId, [...current, ...input.messages]);
|
|
176
334
|
}
|
|
177
335
|
|
|
178
|
-
async clear(
|
|
179
|
-
this.sessions.delete(
|
|
336
|
+
async clear({ scope }: { scope: MemoryScope }): Promise<void> {
|
|
337
|
+
this.sessions.delete(scope.sessionId);
|
|
180
338
|
}
|
|
181
339
|
}
|
|
182
340
|
|
|
183
341
|
const memory = new AppMemoryStore();
|
|
184
|
-
const agent = new
|
|
342
|
+
const agent = new Agent({
|
|
343
|
+
id: "support",
|
|
344
|
+
model: model,
|
|
345
|
+
memory: { store: memory },
|
|
346
|
+
});
|
|
185
347
|
|
|
186
|
-
|
|
187
|
-
await agent.
|
|
348
|
+
const session = { sessionId: "thread_123", userId: "user_456" };
|
|
349
|
+
await agent.generate({ prompt: "Remember my plan.", session });
|
|
350
|
+
await agent.generate({ prompt: "What is my plan?", session });
|
|
188
351
|
```
|
|
189
352
|
|
|
190
353
|
Memory defaults to `savePolicy: "message"`, which saves the user prompt, each completed assistant message, and each completed tool result as soon as they are ready. You can choose `"turn"` or `"run"` at configuration time:
|
|
191
354
|
|
|
192
355
|
```ts
|
|
193
|
-
new
|
|
356
|
+
new Agent({
|
|
357
|
+
id: "support",
|
|
358
|
+
model,
|
|
359
|
+
memory: { store: memory, savePolicy: "turn" },
|
|
360
|
+
});
|
|
194
361
|
```
|
|
195
362
|
|
|
363
|
+
Without `session`, the same Agent is stateless. Pass `{ messages }` when the caller already owns a
|
|
364
|
+
complete transcript; transcripts cannot be combined with persisted sessions.
|
|
365
|
+
|
|
366
|
+
Compaction is an explicit Agent policy over a store capability. The adapter persists the summary as
|
|
367
|
+
an ordinary system message with `metadata.anvia.memoryCompaction`, so `load()` and inspectors expose
|
|
368
|
+
exactly what future runs receive:
|
|
369
|
+
|
|
370
|
+
```ts
|
|
371
|
+
import { createSummaryMemoryCompactor } from "@anvia/core/memory";
|
|
372
|
+
|
|
373
|
+
const compactor = createSummaryMemoryCompactor({
|
|
374
|
+
model: summaryModel,
|
|
375
|
+
maxTokens: 1024,
|
|
376
|
+
retries: { maxAttempts: 2 },
|
|
377
|
+
});
|
|
378
|
+
|
|
379
|
+
const agent = new Agent({
|
|
380
|
+
id: "support",
|
|
381
|
+
model,
|
|
382
|
+
memory: {
|
|
383
|
+
store: memory,
|
|
384
|
+
savePolicy: "message",
|
|
385
|
+
compaction: {
|
|
386
|
+
trigger: { afterMessages: 50 },
|
|
387
|
+
retention: { recentUserTurns: 4 },
|
|
388
|
+
compactor,
|
|
389
|
+
conflictRetries: false,
|
|
390
|
+
},
|
|
391
|
+
},
|
|
392
|
+
});
|
|
393
|
+
|
|
394
|
+
for await (const event of agent.stream({ prompt: "What did we decide?", session })) {
|
|
395
|
+
if (event.type === "memory_compaction") {
|
|
396
|
+
console.log(event.compactedMessageCount, event.usage);
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
The trigger is a threshold, not a hard storage limit. Summary-provider retries belong to the
|
|
402
|
+
compactor; full snapshot-to-replacement conflict retries are separately opt-in.
|
|
403
|
+
|
|
196
404
|
## Structured Extraction
|
|
197
405
|
|
|
198
406
|
```ts
|
|
199
|
-
import {
|
|
407
|
+
import { extract } from "@anvia/core/extractor";
|
|
408
|
+
import { z } from "zod";
|
|
200
409
|
|
|
201
410
|
const ticketSchema = z.object({
|
|
202
411
|
customer: z.string(),
|
|
@@ -204,45 +413,142 @@ const ticketSchema = z.object({
|
|
|
204
413
|
summary: z.string(),
|
|
205
414
|
});
|
|
206
415
|
|
|
207
|
-
const
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
416
|
+
const { output: ticket } = await extract({
|
|
417
|
+
model,
|
|
418
|
+
text: "Acme Co. reports checkout failures. Priority is high.",
|
|
419
|
+
outputSchema: ticketSchema,
|
|
420
|
+
retries: { maxAttempts: 2 },
|
|
421
|
+
});
|
|
212
422
|
```
|
|
213
423
|
|
|
214
424
|
## Pipelines
|
|
215
425
|
|
|
216
426
|
```ts
|
|
217
|
-
import {
|
|
427
|
+
import { Pipeline } from "@anvia/core/pipeline";
|
|
218
428
|
import { z } from "zod";
|
|
219
429
|
|
|
220
|
-
const pipeline = new
|
|
221
|
-
.
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
430
|
+
const pipeline = new Pipeline({ id: "support-flow", inputSchema: z.string() })
|
|
431
|
+
.agent({
|
|
432
|
+
id: "draft",
|
|
433
|
+
agent,
|
|
434
|
+
suspension: "reject",
|
|
435
|
+
request: ({ input }) => ({ prompt: `Draft a reply for this ticket:\n\n${input}` }),
|
|
436
|
+
})
|
|
437
|
+
.extract({
|
|
438
|
+
id: "parse",
|
|
439
|
+
model,
|
|
440
|
+
outputSchema: ticketSchema,
|
|
441
|
+
text: ({ input }) => input,
|
|
442
|
+
});
|
|
443
|
+
|
|
444
|
+
const { runId, output } = await pipeline.run({
|
|
445
|
+
input: "Customer cannot complete checkout.",
|
|
446
|
+
});
|
|
447
|
+
```
|
|
448
|
+
|
|
449
|
+
## Documents
|
|
450
|
+
|
|
451
|
+
Applications own file discovery, file reads, source metadata, and per-file error policy. Core only
|
|
452
|
+
provides deterministic in-memory chunking and scoped PDF text extraction:
|
|
453
|
+
|
|
454
|
+
PDF extraction uses the optional `pdfjs-dist` peer dependency. Install it in applications that call
|
|
455
|
+
`extractPdfText`:
|
|
456
|
+
|
|
457
|
+
```sh
|
|
458
|
+
pnpm add pdfjs-dist
|
|
459
|
+
```
|
|
460
|
+
|
|
461
|
+
```ts
|
|
462
|
+
import { readFile } from "node:fs/promises";
|
|
463
|
+
import { chunkText, extractPdfText } from "@anvia/core/documents";
|
|
464
|
+
|
|
465
|
+
const text = await readFile("guide.txt", "utf8");
|
|
466
|
+
const chunks = chunkText({
|
|
467
|
+
text,
|
|
468
|
+
strategy: "recursive",
|
|
469
|
+
maxSize: 1_000,
|
|
470
|
+
overlap: 100,
|
|
471
|
+
separators: ["\n\n", "\n", " "],
|
|
472
|
+
});
|
|
473
|
+
|
|
474
|
+
const { pages } = await extractPdfText({
|
|
475
|
+
data: new Uint8Array(await readFile("guide.pdf")),
|
|
476
|
+
abortSignal,
|
|
477
|
+
});
|
|
478
|
+
```
|
|
479
|
+
|
|
480
|
+
Use `strategy: "fixed"` for deterministic sliding windows. Recursive chunking requires an explicit
|
|
481
|
+
separator order and falls back to fixed-size splitting when none of those separators can divide an
|
|
482
|
+
oversized section. Chunk offsets use JavaScript string indices and always identify the exact source
|
|
483
|
+
slice. PDF pages are one-based, and the parser task is disposed before extraction settles.
|
|
484
|
+
If parsing or abort handling fails together with parser cleanup, extraction rejects with an
|
|
485
|
+
`AggregateError` containing the operation failure first and the cleanup failure second.
|
|
486
|
+
|
|
487
|
+
## Media
|
|
488
|
+
|
|
489
|
+
Media helpers follow the same one-object API and share `providerOptions`, `retries`, and
|
|
490
|
+
`abortSignal`:
|
|
491
|
+
|
|
492
|
+
```ts
|
|
493
|
+
import { generateImage, generateSpeech, transcribe } from "@anvia/core";
|
|
494
|
+
|
|
495
|
+
const image = await generateImage({
|
|
496
|
+
model: client.imageGenerationModel({ modelId: "gpt-image-1" }),
|
|
497
|
+
prompt: "A compact robot drawing an architecture diagram.",
|
|
498
|
+
width: 1024,
|
|
499
|
+
height: 1024,
|
|
500
|
+
});
|
|
501
|
+
console.log(image.images[0].data);
|
|
225
502
|
|
|
226
|
-
const
|
|
503
|
+
const speech = await generateSpeech({
|
|
504
|
+
model: client.speechGenerationModel({ modelId: "gpt-4o-mini-tts" }),
|
|
505
|
+
text: "Hello from Anvia.",
|
|
506
|
+
voice: "alloy",
|
|
507
|
+
});
|
|
508
|
+
|
|
509
|
+
const transcript = await transcribe({
|
|
510
|
+
model: client.transcriptionModel({ modelId: "gpt-4o-mini-transcribe" }),
|
|
511
|
+
audio: {
|
|
512
|
+
data: speech.audio.data,
|
|
513
|
+
filename: "speech.mp3",
|
|
514
|
+
mediaType: speech.audio.mediaType,
|
|
515
|
+
},
|
|
516
|
+
});
|
|
517
|
+
console.log(transcript.text);
|
|
518
|
+
```
|
|
519
|
+
|
|
520
|
+
## MCP
|
|
521
|
+
|
|
522
|
+
MCP clients live in the optional `@anvia/mcp` package. Core retains the lightweight registration
|
|
523
|
+
contracts that let agents receive immutable MCP server snapshots without owning or closing their
|
|
524
|
+
underlying transports:
|
|
525
|
+
|
|
526
|
+
```sh
|
|
527
|
+
pnpm add @anvia/mcp
|
|
227
528
|
```
|
|
228
529
|
|
|
530
|
+
Import `McpClient` and `McpClientGroup` from `@anvia/mcp`, connect them, and pass the resulting
|
|
531
|
+
`servers` to `new Agent({ mcpServers })`. See the `@anvia/mcp` README for transport configuration,
|
|
532
|
+
connection ownership, URL safety, and cleanup.
|
|
533
|
+
|
|
229
534
|
## Public Areas
|
|
230
535
|
|
|
231
|
-
- `agent`:
|
|
536
|
+
- `agent`: typed Agent runtime, retries, and stream events
|
|
537
|
+
- `agent/interactions`: browser-safe interaction contracts, schemas, assertions, and parsers
|
|
232
538
|
- `tool`: typed tool creation and tool sets
|
|
233
|
-
- `completion`:
|
|
539
|
+
- `completion`: direct completion helpers and provider-neutral model contracts
|
|
234
540
|
- `memory`: durable session memory interfaces and in-memory store
|
|
235
541
|
- `extractor`: schema-first structured extraction
|
|
236
542
|
- `pipeline`: typed sequential and parallel workflows
|
|
237
543
|
- `embeddings`: embedding helpers and document embedding utilities
|
|
238
544
|
- `vector-store`: in-memory vector search and vector search tools
|
|
239
545
|
- `streaming`: normalized stream helpers
|
|
240
|
-
- `mcp`: MCP server
|
|
546
|
+
- `mcp`: lightweight MCP tool and server registration contracts used by Agent
|
|
241
547
|
- `skills`: local skill loading
|
|
242
548
|
- `observability`: observer interfaces for runs, generations, and tool calls
|
|
243
549
|
- `evals`: evaluation helpers and reporters
|
|
244
|
-
- `
|
|
245
|
-
- `
|
|
550
|
+
- `documents`: in-memory text chunking and PDF text extraction
|
|
551
|
+
- `speech-generation`, `image-generation`, `transcription`: provider-neutral media interfaces
|
|
246
552
|
|
|
247
553
|
## Development
|
|
248
554
|
|