@agents24/ai-sdk 0.1.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/LICENSE +21 -0
- package/README.md +45 -0
- package/compatibility.json +54 -0
- package/dist/errors.d.ts +10 -0
- package/dist/event-mapper.d.ts +31 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +580 -0
- package/dist/index.js.map +1 -0
- package/dist/request-policy.d.ts +11 -0
- package/dist/state-store.d.ts +2 -0
- package/dist/transport.d.ts +2 -0
- package/dist/types.d.ts +60 -0
- package/package.json +60 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Talmudpedia
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# `@agents24/ai-sdk`
|
|
2
|
+
|
|
3
|
+
Last Updated: 2026-07-16
|
|
4
|
+
|
|
5
|
+
Vercel AI SDK v7 `ChatTransport` backed only by `@agents24/client` networking, authentication, protocol parsing, refresh, and cursor reconnect.
|
|
6
|
+
|
|
7
|
+
```ts
|
|
8
|
+
import { createAgents24ChatTransport } from "@agents24/ai-sdk";
|
|
9
|
+
|
|
10
|
+
const transport = createAgents24ChatTransport({
|
|
11
|
+
client,
|
|
12
|
+
requestPolicy: {
|
|
13
|
+
allowedHeaders: ["x-client-locale"],
|
|
14
|
+
allowedMetadataFields: ["trace_label"],
|
|
15
|
+
},
|
|
16
|
+
});
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
The adapter implements `sendMessages` and `reconnectToStream`. Request headers, body fields, and metadata are rejected unless explicitly allowlisted. Authorization, DPoP, Origin, deployment, session, Agent/version, run, cursor, refresh, tenant, and identity overrides always fail before networking.
|
|
20
|
+
|
|
21
|
+
## V0 regenerate semantic
|
|
22
|
+
|
|
23
|
+
`trigger: "regenerate-message"` always throws typed `Agents24AiSdkError` code `REGENERATE_UNSUPPORTED`. The frozen V0 client-runtime routes do not expose a regenerate operation, so the adapter does not invent a route, replay a prompt, or fall back to ordinary submit.
|
|
24
|
+
|
|
25
|
+
## Information-preserving mapping
|
|
26
|
+
|
|
27
|
+
| Agents24 information | AI SDK v7 projection |
|
|
28
|
+
| --- | --- |
|
|
29
|
+
| Assistant text | `text-start` / `text-delta` / `text-end` |
|
|
30
|
+
| Reasoning | `reasoning-start` / `reasoning-delta` / `reasoning-end` |
|
|
31
|
+
| Tool invocation/result | dynamic provider-executed tool input/output chunks |
|
|
32
|
+
| HTTP(S) source | `source-url` |
|
|
33
|
+
| Citations and UI blocks | `data-agents24-citation`, `data-agents24-ui-blocks` |
|
|
34
|
+
| Context/quota usage | `data-agents24-context` |
|
|
35
|
+
| HITL and MCP authorization | `data-agents24-hitl`, `data-agents24-mcp` |
|
|
36
|
+
| Attachments and rich response blocks | typed Agents24 data parts |
|
|
37
|
+
| Every canonical runtime event | ordered `data-agents24-event` containing the complete validated event |
|
|
38
|
+
| Unsupported response-block semantics | `data-agents24-unsupported` plus the complete response block/event data |
|
|
39
|
+
| Durable identity | message metadata with run ID, thread ID, and cursor |
|
|
40
|
+
|
|
41
|
+
The complete validated runtime event is always emitted as an ordered Agents24 data part. Rich protocol information therefore remains available even when AI SDK has no equivalent native chunk.
|
|
42
|
+
|
|
43
|
+
Ordinary text chat, tools, reasoning, sources, and reconnect map directly. Repeated HITL, MCP OAuth, thread administration, quota UI, attachments, and richer response blocks may require Agents24 data parts or direct `@agents24/client` APIs. User file parts, assistant/tool-driven submit shapes, client-forged history, reconnect mutations, and regenerate fail explicitly rather than being silently dropped.
|
|
44
|
+
|
|
45
|
+
Adapter telemetry never receives credentials or raw identity. Prompt and tool content is excluded unless `includePromptAndToolContentInTelemetry` is explicitly enabled.
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
{
|
|
2
|
+
"contractHash": "de2b507f5d56de2bf7c4d6739c03617c4b4feef6ae827aaaac5f1d6150ec678e",
|
|
3
|
+
"contractVersion": "0.2.0",
|
|
4
|
+
"corpus": "conformance/v1/corpus.json",
|
|
5
|
+
"generatedBy": "@agents24/sdk-contract",
|
|
6
|
+
"packages": {
|
|
7
|
+
"@agents24/ai-sdk": {
|
|
8
|
+
"ai": ">=7 <8",
|
|
9
|
+
"aiSdkReact": ">=4 <5",
|
|
10
|
+
"peer": "@agents24/client"
|
|
11
|
+
},
|
|
12
|
+
"@agents24/chat-react": {
|
|
13
|
+
"peer": "@agents24/react",
|
|
14
|
+
"react": ">=19 <20",
|
|
15
|
+
"reactDom": ">=19 <20"
|
|
16
|
+
},
|
|
17
|
+
"@agents24/client": {
|
|
18
|
+
"contract": "de2b507f5d56de2bf7c4d6739c03617c4b4feef6ae827aaaac5f1d6150ec678e",
|
|
19
|
+
"runtime": "run-stream.v2"
|
|
20
|
+
},
|
|
21
|
+
"@agents24/node": {
|
|
22
|
+
"contract": "de2b507f5d56de2bf7c4d6739c03617c4b4feef6ae827aaaac5f1d6150ec678e",
|
|
23
|
+
"node": "^22.0.0 || ^24.0.0"
|
|
24
|
+
},
|
|
25
|
+
"@agents24/react": {
|
|
26
|
+
"peer": "@agents24/client",
|
|
27
|
+
"react": ">=19 <20"
|
|
28
|
+
},
|
|
29
|
+
"@talmudpedia/runtime-sdk": {
|
|
30
|
+
"contract": "de2b507f5d56de2bf7c4d6739c03617c4b4feef6ae827aaaac5f1d6150ec678e",
|
|
31
|
+
"protocolOwner": "@agents24/client"
|
|
32
|
+
},
|
|
33
|
+
"agents24": {
|
|
34
|
+
"contract": "de2b507f5d56de2bf7c4d6739c03617c4b4feef6ae827aaaac5f1d6150ec678e",
|
|
35
|
+
"python": ">=3.10"
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
"protocols": {
|
|
39
|
+
"runtime": {
|
|
40
|
+
"minimum": "2.0.0",
|
|
41
|
+
"wire": "run-stream.v2"
|
|
42
|
+
},
|
|
43
|
+
"threadSummary": {
|
|
44
|
+
"minimum": "1.0.0",
|
|
45
|
+
"wire": "agents24.thread_summary_event.v1"
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
"schemaVersion": "agents24.compatibility.v1",
|
|
49
|
+
"targetOperationCounts": {
|
|
50
|
+
"client": 19,
|
|
51
|
+
"node": 55,
|
|
52
|
+
"python": 55
|
|
53
|
+
}
|
|
54
|
+
}
|
package/dist/errors.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export type Agents24AiSdkErrorKind = "capability" | "request" | "state" | "unsupported";
|
|
2
|
+
export declare class Agents24AiSdkError extends Error {
|
|
3
|
+
readonly code: string;
|
|
4
|
+
readonly kind: Agents24AiSdkErrorKind;
|
|
5
|
+
constructor(message: string, options: {
|
|
6
|
+
code: string;
|
|
7
|
+
kind: Agents24AiSdkErrorKind;
|
|
8
|
+
});
|
|
9
|
+
}
|
|
10
|
+
export declare function requestError(code: string, message: string): Agents24AiSdkError;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { RuntimeEvent } from "@agents24/client";
|
|
2
|
+
import type { UIMessageChunk } from "ai";
|
|
3
|
+
import type { Agents24MessageMetadata } from "./types.js";
|
|
4
|
+
export declare class Agents24EventMapper {
|
|
5
|
+
private readonly messageId;
|
|
6
|
+
private cursor;
|
|
7
|
+
private finished;
|
|
8
|
+
private reasoningOpen;
|
|
9
|
+
private runId;
|
|
10
|
+
private started;
|
|
11
|
+
private textOpen;
|
|
12
|
+
private threadId;
|
|
13
|
+
private readonly toolCalls;
|
|
14
|
+
private readonly toolOutputs;
|
|
15
|
+
private status;
|
|
16
|
+
constructor(messageId: string, threadId?: string | null);
|
|
17
|
+
get state(): Agents24MessageMetadata;
|
|
18
|
+
private ensureStarted;
|
|
19
|
+
private text;
|
|
20
|
+
private reasoning;
|
|
21
|
+
private toolInput;
|
|
22
|
+
private toolOutput;
|
|
23
|
+
private mapBlock;
|
|
24
|
+
private terminal;
|
|
25
|
+
map(event: RuntimeEvent): UIMessageChunk[];
|
|
26
|
+
finalize(input: {
|
|
27
|
+
aborted?: boolean;
|
|
28
|
+
detached?: boolean;
|
|
29
|
+
error?: string;
|
|
30
|
+
}): UIMessageChunk[];
|
|
31
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { Agents24AiSdkError } from "./errors.js";
|
|
2
|
+
export type { Agents24AiSdkErrorKind } from "./errors.js";
|
|
3
|
+
export { Agents24EventMapper } from "./event-mapper.js";
|
|
4
|
+
export { createInMemoryAgents24ChatStateStore } from "./state-store.js";
|
|
5
|
+
export { createAgents24ChatTransport } from "./transport.js";
|
|
6
|
+
export type { Agents24AdapterTelemetry, Agents24AdapterTelemetryEvent, Agents24ChatStateStore, Agents24ChatTransport, Agents24DataParts, Agents24MessageMetadata, Agents24PersistedChatState, Agents24RequestPolicy, Agents24UIMessage, CreateAgents24ChatTransportOptions, } from "./types.js";
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,580 @@
|
|
|
1
|
+
// src/errors.ts
|
|
2
|
+
var Agents24AiSdkError = class extends Error {
|
|
3
|
+
code;
|
|
4
|
+
kind;
|
|
5
|
+
constructor(message, options) {
|
|
6
|
+
super(message);
|
|
7
|
+
this.name = "Agents24AiSdkError";
|
|
8
|
+
this.code = options.code;
|
|
9
|
+
this.kind = options.kind;
|
|
10
|
+
}
|
|
11
|
+
};
|
|
12
|
+
function requestError(code, message) {
|
|
13
|
+
return new Agents24AiSdkError(message, { code, kind: "request" });
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// src/event-mapper.ts
|
|
17
|
+
var record = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
18
|
+
var text = (value) => typeof value === "string" && value.length > 0 ? value : null;
|
|
19
|
+
function safeWebUrl(value) {
|
|
20
|
+
if (typeof value !== "string") return null;
|
|
21
|
+
try {
|
|
22
|
+
const parsed = new URL(value);
|
|
23
|
+
return parsed.protocol === "https:" || parsed.protocol === "http:" ? parsed.toString() : null;
|
|
24
|
+
} catch {
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
function dataChunk(name, data, id) {
|
|
29
|
+
return {
|
|
30
|
+
type: `data-agents24-${name}`,
|
|
31
|
+
data,
|
|
32
|
+
...id ? { id } : {}
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
var Agents24EventMapper = class {
|
|
36
|
+
constructor(messageId, threadId) {
|
|
37
|
+
this.messageId = messageId;
|
|
38
|
+
this.threadId = threadId ?? null;
|
|
39
|
+
}
|
|
40
|
+
messageId;
|
|
41
|
+
cursor = null;
|
|
42
|
+
finished = false;
|
|
43
|
+
reasoningOpen = false;
|
|
44
|
+
runId = null;
|
|
45
|
+
started = false;
|
|
46
|
+
textOpen = false;
|
|
47
|
+
threadId;
|
|
48
|
+
toolCalls = /* @__PURE__ */ new Set();
|
|
49
|
+
toolOutputs = /* @__PURE__ */ new Set();
|
|
50
|
+
status;
|
|
51
|
+
get state() {
|
|
52
|
+
return {
|
|
53
|
+
cursor: this.cursor,
|
|
54
|
+
runId: this.runId,
|
|
55
|
+
threadId: this.threadId,
|
|
56
|
+
...this.status ? { status: this.status } : {}
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
ensureStarted() {
|
|
60
|
+
if (this.started) return [];
|
|
61
|
+
this.started = true;
|
|
62
|
+
return [
|
|
63
|
+
{ type: "start", messageId: this.messageId, messageMetadata: this.state },
|
|
64
|
+
{ type: "start-step" }
|
|
65
|
+
];
|
|
66
|
+
}
|
|
67
|
+
text(value, id) {
|
|
68
|
+
const chunks = [];
|
|
69
|
+
if (!this.textOpen) {
|
|
70
|
+
this.textOpen = true;
|
|
71
|
+
chunks.push({ type: "text-start", id });
|
|
72
|
+
}
|
|
73
|
+
if (value) chunks.push({ type: "text-delta", id, delta: value });
|
|
74
|
+
return chunks;
|
|
75
|
+
}
|
|
76
|
+
reasoning(value, id) {
|
|
77
|
+
const chunks = [];
|
|
78
|
+
if (!this.reasoningOpen) {
|
|
79
|
+
this.reasoningOpen = true;
|
|
80
|
+
chunks.push({ type: "reasoning-start", id });
|
|
81
|
+
}
|
|
82
|
+
if (value) chunks.push({ type: "reasoning-delta", id, delta: value });
|
|
83
|
+
return chunks;
|
|
84
|
+
}
|
|
85
|
+
toolInput(block, fallbackId) {
|
|
86
|
+
const tool = record(block.tool) || block;
|
|
87
|
+
const toolCallId = text(tool.toolCallId) || text(tool.tool_call_id) || fallbackId;
|
|
88
|
+
const toolName = text(tool.action) || text(tool.title) || text(block.display_name) || "tool";
|
|
89
|
+
if (this.toolCalls.has(toolCallId)) return [];
|
|
90
|
+
this.toolCalls.add(toolCallId);
|
|
91
|
+
return [{
|
|
92
|
+
type: "tool-input-available",
|
|
93
|
+
toolCallId,
|
|
94
|
+
toolName,
|
|
95
|
+
input: tool.input ?? block.input ?? {},
|
|
96
|
+
providerExecuted: true,
|
|
97
|
+
dynamic: true,
|
|
98
|
+
...text(tool.title) || text(block.display_name) ? { title: text(tool.title) || text(block.display_name) || void 0 } : {}
|
|
99
|
+
}];
|
|
100
|
+
}
|
|
101
|
+
toolOutput(block, fallbackId) {
|
|
102
|
+
const tool = record(block.tool) || block;
|
|
103
|
+
const toolCallId = text(tool.toolCallId) || text(tool.tool_call_id) || fallbackId;
|
|
104
|
+
const chunks = this.toolInput(block, fallbackId);
|
|
105
|
+
if (this.toolOutputs.has(toolCallId)) return chunks;
|
|
106
|
+
this.toolOutputs.add(toolCallId);
|
|
107
|
+
const failed = ["failed", "error"].includes(String(block.status || "").toLocaleLowerCase());
|
|
108
|
+
chunks.push(failed ? { type: "tool-output-error", toolCallId, errorText: text(tool.error) || text(block.error) || "Tool execution failed.", providerExecuted: true, dynamic: true } : { type: "tool-output-available", toolCallId, output: tool.output ?? block.output ?? block, providerExecuted: true, dynamic: true });
|
|
109
|
+
return chunks;
|
|
110
|
+
}
|
|
111
|
+
mapBlock(block, fallbackId) {
|
|
112
|
+
const kind = String(block.kind || "unsupported");
|
|
113
|
+
const id = text(block.id) || fallbackId;
|
|
114
|
+
const chunks = [dataChunk("response-block", block, id)];
|
|
115
|
+
if (kind === "assistant_text" && !this.textOpen) {
|
|
116
|
+
chunks.push(...this.text(text(block.text) || "", `${this.runId || "run"}-text`));
|
|
117
|
+
} else if (kind === "reasoning_note" && !this.reasoningOpen) {
|
|
118
|
+
chunks.push(...this.reasoning(text(block.description) || text(block.label) || "", `${this.runId || "run"}-reasoning`));
|
|
119
|
+
} else if (kind === "tool_call") {
|
|
120
|
+
chunks.push(...this.toolOutput(block, id));
|
|
121
|
+
} else if (kind === "source") {
|
|
122
|
+
const url = safeWebUrl(block.url);
|
|
123
|
+
if (url) chunks.push({ type: "source-url", sourceId: id, url, ...text(block.title) ? { title: text(block.title) || void 0 } : {} });
|
|
124
|
+
} else if (kind === "citation") {
|
|
125
|
+
chunks.push(dataChunk("citation", block, id));
|
|
126
|
+
} else if (kind === "ui_blocks") {
|
|
127
|
+
chunks.push(dataChunk("ui-blocks", block, id));
|
|
128
|
+
} else if (kind === "hitl_request") {
|
|
129
|
+
chunks.push(dataChunk("hitl", block, id));
|
|
130
|
+
} else if (kind === "mcp_authorization") {
|
|
131
|
+
chunks.push(dataChunk("mcp", block, id));
|
|
132
|
+
} else if (kind === "attachment") {
|
|
133
|
+
chunks.push(dataChunk("attachment", block, id));
|
|
134
|
+
} else if (kind === "error") {
|
|
135
|
+
chunks.push({ type: "error", errorText: text(record(block.error)?.message) || text(block.text) || "The run failed." });
|
|
136
|
+
} else if (kind === "user_message") {
|
|
137
|
+
chunks.push(dataChunk("unsupported", { feature: "terminal-user-message-block", block }, id));
|
|
138
|
+
}
|
|
139
|
+
return chunks;
|
|
140
|
+
}
|
|
141
|
+
terminal(finishReason, metadata) {
|
|
142
|
+
if (this.finished) return [];
|
|
143
|
+
this.finished = true;
|
|
144
|
+
this.status = metadata.status;
|
|
145
|
+
const chunks = [];
|
|
146
|
+
if (this.textOpen) chunks.push({ type: "text-end", id: `${this.runId || "run"}-text` });
|
|
147
|
+
if (this.reasoningOpen) chunks.push({ type: "reasoning-end", id: `${this.runId || "run"}-reasoning` });
|
|
148
|
+
chunks.push({ type: "finish-step" });
|
|
149
|
+
chunks.push({ type: "finish", finishReason, messageMetadata: metadata });
|
|
150
|
+
return chunks;
|
|
151
|
+
}
|
|
152
|
+
map(event) {
|
|
153
|
+
this.runId = event.run_id;
|
|
154
|
+
this.cursor = event.seq;
|
|
155
|
+
const payload = event.payload;
|
|
156
|
+
this.threadId = text(payload.thread_id) || this.threadId;
|
|
157
|
+
const chunks = this.ensureStarted();
|
|
158
|
+
chunks.push(dataChunk("event", event, `${event.run_id}:${event.seq}`));
|
|
159
|
+
chunks.push({ type: "message-metadata", messageMetadata: this.state });
|
|
160
|
+
if (event.event === "assistant.delta") {
|
|
161
|
+
chunks.push(...this.text(text(payload.content) || "", `${event.run_id}-text`));
|
|
162
|
+
} else if (event.event === "reasoning.update") {
|
|
163
|
+
chunks.push(...this.reasoning(text(payload.delta) || text(payload.description) || text(payload.label) || "", `${event.run_id}-reasoning`));
|
|
164
|
+
} else if (event.event === "tool.started") {
|
|
165
|
+
chunks.push(...this.toolInput(payload, text(payload.tool_call_id) || `${event.run_id}:tool:${event.seq}`));
|
|
166
|
+
} else if (event.event === "tool.completed" || event.event === "tool.failed" || event.event === "tool.cancelled") {
|
|
167
|
+
chunks.push(...this.toolOutput({ ...payload, status: event.event.split(".")[1] }, text(payload.tool_call_id) || `${event.run_id}:tool:${event.seq}`));
|
|
168
|
+
} else if (event.event === "source.added") {
|
|
169
|
+
const source = record(payload.source) || payload;
|
|
170
|
+
const sourceId = text(source.id) || `${event.run_id}:source:${event.seq}`;
|
|
171
|
+
const url = safeWebUrl(source.url);
|
|
172
|
+
if (url) chunks.push({ type: "source-url", sourceId, url, ...text(source.title) ? { title: text(source.title) || void 0 } : {} });
|
|
173
|
+
} else if (event.event === "citation.added") {
|
|
174
|
+
chunks.push(dataChunk("citation", record(payload.source) || payload, `${event.run_id}:citation:${event.seq}`));
|
|
175
|
+
} else if (event.event === "ui_blocks.updated") {
|
|
176
|
+
chunks.push(dataChunk("ui-blocks", payload, `${event.run_id}:ui:${event.seq}`));
|
|
177
|
+
} else if (event.event === "context_window.updated" || event.event === "context.compression.updated" || event.event === "run_usage.updated") {
|
|
178
|
+
chunks.push(dataChunk("context", payload, `${event.run_id}:context:${event.seq}`));
|
|
179
|
+
} else if (event.event === "hitl.requested" || event.event === "hitl.resolved") {
|
|
180
|
+
chunks.push(dataChunk("hitl", payload, `${event.run_id}:hitl:${event.seq}`));
|
|
181
|
+
} else if (event.event.startsWith("mcp.authorization.")) {
|
|
182
|
+
chunks.push(dataChunk("mcp", payload, `${event.run_id}:mcp:${event.seq}`));
|
|
183
|
+
} else if (event.event.startsWith("attachment.")) {
|
|
184
|
+
chunks.push(dataChunk("attachment", payload, `${event.run_id}:attachment:${event.seq}`));
|
|
185
|
+
} else if (event.event === "runtime.error") {
|
|
186
|
+
chunks.push({ type: "error", errorText: text(record(payload.error)?.message) || "The run failed." });
|
|
187
|
+
}
|
|
188
|
+
const blocks = Array.isArray(payload.response_blocks) ? payload.response_blocks : [];
|
|
189
|
+
blocks.forEach((value, index) => {
|
|
190
|
+
const block = record(value);
|
|
191
|
+
if (block) chunks.push(...this.mapBlock(block, `${event.run_id}:block:${event.seq}:${index}`));
|
|
192
|
+
});
|
|
193
|
+
if (event.event === "run.completed") chunks.push(...this.terminal("stop", { ...this.state, status: "completed" }));
|
|
194
|
+
if (event.event === "run.failed") chunks.push(...this.terminal("error", { ...this.state, status: "failed" }));
|
|
195
|
+
if (event.event === "run.cancelled") chunks.push(...this.terminal("other", { ...this.state, status: "cancelled" }));
|
|
196
|
+
return chunks;
|
|
197
|
+
}
|
|
198
|
+
finalize(input) {
|
|
199
|
+
const chunks = this.ensureStarted();
|
|
200
|
+
if (input.aborted) {
|
|
201
|
+
if (!this.finished) {
|
|
202
|
+
this.finished = true;
|
|
203
|
+
chunks.push({ type: "abort", reason: "The local stream was stopped." });
|
|
204
|
+
}
|
|
205
|
+
return chunks;
|
|
206
|
+
}
|
|
207
|
+
if (input.error) {
|
|
208
|
+
chunks.push({ type: "error", errorText: input.error });
|
|
209
|
+
chunks.push(...this.terminal("error", { ...this.state, status: "failed" }));
|
|
210
|
+
return chunks;
|
|
211
|
+
}
|
|
212
|
+
chunks.push(...this.terminal("other", { ...this.state, detached: Boolean(input.detached), status: input.detached ? "detached" : "completed" }));
|
|
213
|
+
return chunks;
|
|
214
|
+
}
|
|
215
|
+
};
|
|
216
|
+
|
|
217
|
+
// src/state-store.ts
|
|
218
|
+
function createInMemoryAgents24ChatStateStore() {
|
|
219
|
+
const states = /* @__PURE__ */ new Map();
|
|
220
|
+
return {
|
|
221
|
+
async load(chatId) {
|
|
222
|
+
const state = states.get(chatId);
|
|
223
|
+
return state ? { ...state } : null;
|
|
224
|
+
},
|
|
225
|
+
async save(chatId, state) {
|
|
226
|
+
states.set(chatId, { ...state });
|
|
227
|
+
}
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
// src/transport.ts
|
|
232
|
+
import { Agents24ClientError } from "@agents24/client";
|
|
233
|
+
|
|
234
|
+
// src/request-policy.ts
|
|
235
|
+
var RESERVED_KEYS = /* @__PURE__ */ new Set([
|
|
236
|
+
"agent",
|
|
237
|
+
"agentid",
|
|
238
|
+
"agentversion",
|
|
239
|
+
"agentversionid",
|
|
240
|
+
"authorization",
|
|
241
|
+
"clientid",
|
|
242
|
+
"cursor",
|
|
243
|
+
"deployment",
|
|
244
|
+
"deploymentid",
|
|
245
|
+
"dpop",
|
|
246
|
+
"identity",
|
|
247
|
+
"origin",
|
|
248
|
+
"refreshgrant",
|
|
249
|
+
"runid",
|
|
250
|
+
"session",
|
|
251
|
+
"sessionid",
|
|
252
|
+
"tenant",
|
|
253
|
+
"tenantid",
|
|
254
|
+
"token",
|
|
255
|
+
"userid",
|
|
256
|
+
"version"
|
|
257
|
+
]);
|
|
258
|
+
var RESERVED_HEADERS = /* @__PURE__ */ new Set([
|
|
259
|
+
"authorization",
|
|
260
|
+
"cookie",
|
|
261
|
+
"dpop",
|
|
262
|
+
"host",
|
|
263
|
+
"origin",
|
|
264
|
+
"proxy-authorization",
|
|
265
|
+
"sec-fetch-site",
|
|
266
|
+
"x-agent-id",
|
|
267
|
+
"x-agent-version",
|
|
268
|
+
"x-agents24-deployment-id",
|
|
269
|
+
"x-client-id",
|
|
270
|
+
"x-deployment-id",
|
|
271
|
+
"x-forwarded-host",
|
|
272
|
+
"x-refresh-grant",
|
|
273
|
+
"x-run-id",
|
|
274
|
+
"x-session-id"
|
|
275
|
+
]);
|
|
276
|
+
function normalizedKey(value) {
|
|
277
|
+
return value.toLowerCase().replace(/[^a-z0-9]/g, "");
|
|
278
|
+
}
|
|
279
|
+
function record2(value) {
|
|
280
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
281
|
+
}
|
|
282
|
+
function assertNoReservedFields(value, path) {
|
|
283
|
+
const object = record2(value);
|
|
284
|
+
if (!object) return;
|
|
285
|
+
for (const [key, child] of Object.entries(object)) {
|
|
286
|
+
if (RESERVED_KEYS.has(normalizedKey(key))) {
|
|
287
|
+
throw requestError(
|
|
288
|
+
"RESERVED_REQUEST_FIELD",
|
|
289
|
+
`Agents24 reserved request field cannot be overridden: ${path}${key}`
|
|
290
|
+
);
|
|
291
|
+
}
|
|
292
|
+
assertNoReservedFields(child, `${path}${key}.`);
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
function allowedRecord(value, allowed, label) {
|
|
296
|
+
const input = record2(value);
|
|
297
|
+
if (!input) {
|
|
298
|
+
if (value === void 0) return {};
|
|
299
|
+
throw requestError("INVALID_REQUEST_OPTIONS", `Agents24 ${label} must be an object.`);
|
|
300
|
+
}
|
|
301
|
+
assertNoReservedFields(input, `${label}.`);
|
|
302
|
+
const output = {};
|
|
303
|
+
for (const [key, child] of Object.entries(input)) {
|
|
304
|
+
if (!allowed.has(key)) {
|
|
305
|
+
throw requestError(
|
|
306
|
+
"REQUEST_FIELD_NOT_ALLOWLISTED",
|
|
307
|
+
`Agents24 ${label} field is not allowlisted: ${key}`
|
|
308
|
+
);
|
|
309
|
+
}
|
|
310
|
+
output[key] = child;
|
|
311
|
+
}
|
|
312
|
+
return output;
|
|
313
|
+
}
|
|
314
|
+
function headerEntries(headers) {
|
|
315
|
+
if (!headers) return [];
|
|
316
|
+
if (typeof headers.forEach === "function") {
|
|
317
|
+
const output = [];
|
|
318
|
+
headers.forEach((value, key) => output.push([key, value]));
|
|
319
|
+
return output;
|
|
320
|
+
}
|
|
321
|
+
return Object.entries(headers);
|
|
322
|
+
}
|
|
323
|
+
function prepareAgents24Request(options, policy) {
|
|
324
|
+
const allowedBody = new Set(policy?.allowedBodyFields ?? ["attachmentIds", "requestedModelId", "toolInputs"]);
|
|
325
|
+
const allowedHeaders = new Set((policy?.allowedHeaders ?? []).map((name) => name.toLowerCase()));
|
|
326
|
+
const allowedMetadata = new Set(policy?.allowedMetadataFields ?? []);
|
|
327
|
+
const body = allowedRecord(options.body, allowedBody, "body");
|
|
328
|
+
const metadata = allowedRecord(options.metadata, allowedMetadata, "metadata");
|
|
329
|
+
const headers = {};
|
|
330
|
+
for (const [rawName, value] of headerEntries(options.headers)) {
|
|
331
|
+
const name = rawName.toLowerCase();
|
|
332
|
+
if (RESERVED_HEADERS.has(name)) {
|
|
333
|
+
throw requestError("RESERVED_REQUEST_HEADER", `Agents24 reserved header cannot be overridden: ${rawName}`);
|
|
334
|
+
}
|
|
335
|
+
if (!allowedHeaders.has(name)) {
|
|
336
|
+
throw requestError("REQUEST_HEADER_NOT_ALLOWLISTED", `Agents24 header is not allowlisted: ${rawName}`);
|
|
337
|
+
}
|
|
338
|
+
if (/[\r\n\0]/.test(value)) {
|
|
339
|
+
throw requestError("INVALID_REQUEST_HEADER", `Agents24 header contains invalid characters: ${rawName}`);
|
|
340
|
+
}
|
|
341
|
+
headers[name] = value;
|
|
342
|
+
}
|
|
343
|
+
const attachmentIds = body.attachmentIds === void 0 ? [] : Array.isArray(body.attachmentIds) && body.attachmentIds.every((item) => typeof item === "string" && item.length > 0) ? body.attachmentIds : (() => {
|
|
344
|
+
throw requestError("INVALID_ATTACHMENT_IDS", "Agents24 attachmentIds must be a string array.");
|
|
345
|
+
})();
|
|
346
|
+
const requestedModelId = body.requestedModelId === void 0 ? void 0 : typeof body.requestedModelId === "string" && body.requestedModelId.length > 0 ? body.requestedModelId : (() => {
|
|
347
|
+
throw requestError("INVALID_MODEL_ID", "Agents24 requestedModelId must be a non-empty string.");
|
|
348
|
+
})();
|
|
349
|
+
const toolInputs = body.toolInputs === void 0 ? {} : allowedRecord(body.toolInputs, new Set(Object.keys(record2(body.toolInputs) ?? {})), "toolInputs");
|
|
350
|
+
return {
|
|
351
|
+
attachmentIds,
|
|
352
|
+
headers,
|
|
353
|
+
metadata,
|
|
354
|
+
...requestedModelId ? { requestedModelId } : {},
|
|
355
|
+
toolInputs
|
|
356
|
+
};
|
|
357
|
+
}
|
|
358
|
+
function promptForRequest(messages) {
|
|
359
|
+
const message = messages.at(-1);
|
|
360
|
+
if (!message || message.role !== "user") {
|
|
361
|
+
throw requestError(
|
|
362
|
+
"UNSUPPORTED_SUBMIT_SHAPE",
|
|
363
|
+
"Agents24 submit requires the latest message to be a user message."
|
|
364
|
+
);
|
|
365
|
+
}
|
|
366
|
+
const unsupported = message.parts.find((part) => part.type !== "text");
|
|
367
|
+
if (unsupported) {
|
|
368
|
+
throw requestError(
|
|
369
|
+
"UNSUPPORTED_MESSAGE_PART",
|
|
370
|
+
`Agents24 does not accept AI SDK user part type: ${unsupported.type}`
|
|
371
|
+
);
|
|
372
|
+
}
|
|
373
|
+
const value = message.parts.map((part) => part.type === "text" ? part.text : "").join("\n").trim();
|
|
374
|
+
if (!value) {
|
|
375
|
+
throw requestError("EMPTY_USER_MESSAGE", "Agents24 requires a non-empty user text message.");
|
|
376
|
+
}
|
|
377
|
+
return value;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
// src/transport.ts
|
|
381
|
+
function defaultId() {
|
|
382
|
+
const crypto = globalThis.crypto;
|
|
383
|
+
if (!crypto?.randomUUID) {
|
|
384
|
+
throw new Agents24AiSdkError("A secure ID capability must be injected for this runtime.", {
|
|
385
|
+
code: "MISSING_ID_CAPABILITY",
|
|
386
|
+
kind: "capability"
|
|
387
|
+
});
|
|
388
|
+
}
|
|
389
|
+
return crypto.randomUUID();
|
|
390
|
+
}
|
|
391
|
+
function checkedId(createId) {
|
|
392
|
+
const value = createId();
|
|
393
|
+
if (!value || /[\r\n\0]/.test(value)) {
|
|
394
|
+
throw new Agents24AiSdkError("The ID provider returned an invalid identifier.", {
|
|
395
|
+
code: "INVALID_ID",
|
|
396
|
+
kind: "capability"
|
|
397
|
+
});
|
|
398
|
+
}
|
|
399
|
+
return value;
|
|
400
|
+
}
|
|
401
|
+
function safeStreamError(error) {
|
|
402
|
+
if (error instanceof Agents24ClientError || error instanceof Agents24AiSdkError) return error.message;
|
|
403
|
+
return "The Agents24 stream failed.";
|
|
404
|
+
}
|
|
405
|
+
function persistedState(messageId, metadata, status) {
|
|
406
|
+
return {
|
|
407
|
+
cursor: metadata.cursor ?? null,
|
|
408
|
+
messageId,
|
|
409
|
+
runId: metadata.runId ?? null,
|
|
410
|
+
status,
|
|
411
|
+
threadId: metadata.threadId ?? null
|
|
412
|
+
};
|
|
413
|
+
}
|
|
414
|
+
function terminalStatus(metadata, result) {
|
|
415
|
+
if (result.detached) return "detached";
|
|
416
|
+
if (metadata.status === "failed") return "failed";
|
|
417
|
+
if (metadata.status === "cancelled") return "cancelled";
|
|
418
|
+
return "completed";
|
|
419
|
+
}
|
|
420
|
+
function validState(value) {
|
|
421
|
+
return typeof value.messageId === "string" && value.messageId.length > 0 && (value.runId === null || typeof value.runId === "string") && (value.threadId === null || typeof value.threadId === "string") && (value.cursor === null || Number.isSafeInteger(value.cursor)) && ["active", "cancelled", "completed", "detached", "failed"].includes(value.status);
|
|
422
|
+
}
|
|
423
|
+
function createAgents24ChatTransport(options) {
|
|
424
|
+
const createId = options.createId ?? defaultId;
|
|
425
|
+
const stateStore = options.stateStore ?? createInMemoryAgents24ChatStateStore();
|
|
426
|
+
const emit = async (event) => {
|
|
427
|
+
try {
|
|
428
|
+
await options.telemetry?.emit(event);
|
|
429
|
+
} catch {
|
|
430
|
+
}
|
|
431
|
+
};
|
|
432
|
+
const stream = (input) => {
|
|
433
|
+
const mapper = new Agents24EventMapper(input.messageId, input.initialThreadId);
|
|
434
|
+
return new ReadableStream({
|
|
435
|
+
async start(controller) {
|
|
436
|
+
await emit({
|
|
437
|
+
chatId: input.chatId,
|
|
438
|
+
operation: input.operation,
|
|
439
|
+
status: "started",
|
|
440
|
+
...input.content ? { content: input.content } : {}
|
|
441
|
+
});
|
|
442
|
+
try {
|
|
443
|
+
await stateStore.save(
|
|
444
|
+
input.chatId,
|
|
445
|
+
persistedState(input.messageId, mapper.state, "active")
|
|
446
|
+
);
|
|
447
|
+
const result = await input.execute(async (event) => {
|
|
448
|
+
for (const chunk of mapper.map(event)) controller.enqueue(chunk);
|
|
449
|
+
await stateStore.save(
|
|
450
|
+
input.chatId,
|
|
451
|
+
persistedState(input.messageId, mapper.state, "active")
|
|
452
|
+
);
|
|
453
|
+
});
|
|
454
|
+
const status = terminalStatus(mapper.state, result);
|
|
455
|
+
for (const chunk of mapper.finalize({
|
|
456
|
+
aborted: input.abortSignal?.aborted,
|
|
457
|
+
detached: result.detached
|
|
458
|
+
})) controller.enqueue(chunk);
|
|
459
|
+
await stateStore.save(
|
|
460
|
+
input.chatId,
|
|
461
|
+
persistedState(input.messageId, mapper.state, status)
|
|
462
|
+
);
|
|
463
|
+
await emit({
|
|
464
|
+
chatId: input.chatId,
|
|
465
|
+
cursor: mapper.state.cursor,
|
|
466
|
+
operation: input.operation,
|
|
467
|
+
runId: mapper.state.runId,
|
|
468
|
+
status: "completed"
|
|
469
|
+
});
|
|
470
|
+
} catch (error) {
|
|
471
|
+
const aborted = input.abortSignal?.aborted ?? false;
|
|
472
|
+
for (const chunk of mapper.finalize({
|
|
473
|
+
aborted,
|
|
474
|
+
...aborted ? {} : { error: safeStreamError(error) }
|
|
475
|
+
})) controller.enqueue(chunk);
|
|
476
|
+
try {
|
|
477
|
+
await stateStore.save(
|
|
478
|
+
input.chatId,
|
|
479
|
+
persistedState(input.messageId, mapper.state, aborted ? "detached" : "failed")
|
|
480
|
+
);
|
|
481
|
+
} catch {
|
|
482
|
+
}
|
|
483
|
+
await emit({
|
|
484
|
+
chatId: input.chatId,
|
|
485
|
+
cursor: mapper.state.cursor,
|
|
486
|
+
operation: input.operation,
|
|
487
|
+
runId: mapper.state.runId,
|
|
488
|
+
status: aborted ? "completed" : "failed"
|
|
489
|
+
});
|
|
490
|
+
} finally {
|
|
491
|
+
controller.close();
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
});
|
|
495
|
+
};
|
|
496
|
+
return {
|
|
497
|
+
async sendMessages(input) {
|
|
498
|
+
if (input.trigger === "regenerate-message") {
|
|
499
|
+
throw new Agents24AiSdkError(
|
|
500
|
+
"Agents24 V0 does not support regenerate because the frozen client-runtime routes have no regenerate operation.",
|
|
501
|
+
{ code: "REGENERATE_UNSUPPORTED", kind: "unsupported" }
|
|
502
|
+
);
|
|
503
|
+
}
|
|
504
|
+
const prepared = prepareAgents24Request(input, options.requestPolicy);
|
|
505
|
+
const prompt = promptForRequest(input.messages);
|
|
506
|
+
const previous = await stateStore.load(input.chatId);
|
|
507
|
+
if (previous && !validState(previous)) {
|
|
508
|
+
throw new Agents24AiSdkError("Stored Agents24 chat state is invalid.", {
|
|
509
|
+
code: "INVALID_CHAT_STATE",
|
|
510
|
+
kind: "state"
|
|
511
|
+
});
|
|
512
|
+
}
|
|
513
|
+
if (!previous?.threadId && input.messages.length > 1) {
|
|
514
|
+
throw new Agents24AiSdkError(
|
|
515
|
+
"Conversation history requires persisted Agents24 thread state; client history is never replayed as forged runtime history.",
|
|
516
|
+
{ code: "CHAT_STATE_REQUIRED", kind: "state" }
|
|
517
|
+
);
|
|
518
|
+
}
|
|
519
|
+
const responseMessageId = checkedId(createId);
|
|
520
|
+
const content = options.requestPolicy?.includePromptAndToolContentInTelemetry ? { prompt, toolInputs: prepared.toolInputs } : void 0;
|
|
521
|
+
return stream({
|
|
522
|
+
chatId: input.chatId,
|
|
523
|
+
...previous?.threadId ? { initialThreadId: previous.threadId } : {},
|
|
524
|
+
messageId: responseMessageId,
|
|
525
|
+
operation: "submit",
|
|
526
|
+
...input.abortSignal ? { abortSignal: input.abortSignal } : {},
|
|
527
|
+
...content ? { content } : {},
|
|
528
|
+
execute: (onEvent) => options.client.chat.stream({
|
|
529
|
+
input: prompt,
|
|
530
|
+
attachmentIds: prepared.attachmentIds,
|
|
531
|
+
headers: prepared.headers,
|
|
532
|
+
idempotencyKey: checkedId(createId),
|
|
533
|
+
metadata: prepared.metadata,
|
|
534
|
+
...previous?.threadId ? { threadId: previous.threadId } : {},
|
|
535
|
+
...prepared.requestedModelId ? { requestedModelId: prepared.requestedModelId } : {},
|
|
536
|
+
toolInputs: prepared.toolInputs,
|
|
537
|
+
...input.abortSignal ? { signal: input.abortSignal } : {}
|
|
538
|
+
}, onEvent)
|
|
539
|
+
});
|
|
540
|
+
},
|
|
541
|
+
async reconnectToStream(input) {
|
|
542
|
+
const prepared = prepareAgents24Request(input, options.requestPolicy);
|
|
543
|
+
if (prepared.attachmentIds.length || Object.keys(prepared.metadata).length || prepared.requestedModelId || Object.keys(prepared.toolInputs).length) {
|
|
544
|
+
throw new Agents24AiSdkError(
|
|
545
|
+
"Reconnect accepts allowlisted headers only; run input is immutable after submission.",
|
|
546
|
+
{ code: "RECONNECT_OPTIONS_UNSUPPORTED", kind: "unsupported" }
|
|
547
|
+
);
|
|
548
|
+
}
|
|
549
|
+
const previous = await stateStore.load(input.chatId);
|
|
550
|
+
if (!previous) return null;
|
|
551
|
+
if (!validState(previous)) {
|
|
552
|
+
throw new Agents24AiSdkError("Stored Agents24 chat state is invalid.", {
|
|
553
|
+
code: "INVALID_CHAT_STATE",
|
|
554
|
+
kind: "state"
|
|
555
|
+
});
|
|
556
|
+
}
|
|
557
|
+
if (!previous.runId || previous.status === "completed" || previous.status === "failed" || previous.status === "cancelled") {
|
|
558
|
+
return null;
|
|
559
|
+
}
|
|
560
|
+
return stream({
|
|
561
|
+
chatId: input.chatId,
|
|
562
|
+
initialThreadId: previous.threadId,
|
|
563
|
+
messageId: previous.messageId,
|
|
564
|
+
operation: "reconnect",
|
|
565
|
+
execute: (onEvent) => options.client.runs.attach({
|
|
566
|
+
runId: previous.runId,
|
|
567
|
+
...previous.cursor === null ? {} : { cursor: previous.cursor },
|
|
568
|
+
headers: prepared.headers
|
|
569
|
+
}, onEvent)
|
|
570
|
+
});
|
|
571
|
+
}
|
|
572
|
+
};
|
|
573
|
+
}
|
|
574
|
+
export {
|
|
575
|
+
Agents24AiSdkError,
|
|
576
|
+
Agents24EventMapper,
|
|
577
|
+
createAgents24ChatTransport,
|
|
578
|
+
createInMemoryAgents24ChatStateStore
|
|
579
|
+
};
|
|
580
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/errors.ts","../src/event-mapper.ts","../src/state-store.ts","../src/transport.ts","../src/request-policy.ts"],"sourcesContent":["export type Agents24AiSdkErrorKind = \"capability\" | \"request\" | \"state\" | \"unsupported\";\n\nexport class Agents24AiSdkError extends Error {\n readonly code: string;\n readonly kind: Agents24AiSdkErrorKind;\n\n constructor(message: string, options: { code: string; kind: Agents24AiSdkErrorKind }) {\n super(message);\n this.name = \"Agents24AiSdkError\";\n this.code = options.code;\n this.kind = options.kind;\n }\n}\n\nexport function requestError(code: string, message: string): Agents24AiSdkError {\n return new Agents24AiSdkError(message, { code, kind: \"request\" });\n}\n","import type { RuntimeEvent } from \"@agents24/client\";\nimport type { UIMessageChunk } from \"ai\";\nimport type { Agents24MessageMetadata } from \"./types.js\";\n\nconst record = (value: unknown): Record<string, unknown> | null =>\n value && typeof value === \"object\" && !Array.isArray(value) ? value as Record<string, unknown> : null;\nconst text = (value: unknown): string | null => typeof value === \"string\" && value.length > 0 ? value : null;\n\nfunction safeWebUrl(value: unknown): string | null {\n if (typeof value !== \"string\") return null;\n try {\n const parsed = new URL(value);\n return parsed.protocol === \"https:\" || parsed.protocol === \"http:\" ? parsed.toString() : null;\n } catch {\n return null;\n }\n}\n\nfunction dataChunk(name: string, data: unknown, id?: string): UIMessageChunk {\n return {\n type: `data-agents24-${name}`,\n data,\n ...(id ? { id } : {}),\n } as UIMessageChunk;\n}\n\nexport class Agents24EventMapper {\n private cursor: number | null = null;\n private finished = false;\n private reasoningOpen = false;\n private runId: string | null = null;\n private started = false;\n private textOpen = false;\n private threadId: string | null;\n private readonly toolCalls = new Set<string>();\n private readonly toolOutputs = new Set<string>();\n private status: string | undefined;\n\n constructor(\n private readonly messageId: string,\n threadId?: string | null,\n ) {\n this.threadId = threadId ?? null;\n }\n\n get state(): Agents24MessageMetadata {\n return {\n cursor: this.cursor,\n runId: this.runId,\n threadId: this.threadId,\n ...(this.status ? { status: this.status } : {}),\n };\n }\n\n private ensureStarted(): UIMessageChunk[] {\n if (this.started) return [];\n this.started = true;\n return [\n { type: \"start\", messageId: this.messageId, messageMetadata: this.state },\n { type: \"start-step\" },\n ];\n }\n\n private text(value: string, id: string): UIMessageChunk[] {\n const chunks: UIMessageChunk[] = [];\n if (!this.textOpen) {\n this.textOpen = true;\n chunks.push({ type: \"text-start\", id });\n }\n if (value) chunks.push({ type: \"text-delta\", id, delta: value });\n return chunks;\n }\n\n private reasoning(value: string, id: string): UIMessageChunk[] {\n const chunks: UIMessageChunk[] = [];\n if (!this.reasoningOpen) {\n this.reasoningOpen = true;\n chunks.push({ type: \"reasoning-start\", id });\n }\n if (value) chunks.push({ type: \"reasoning-delta\", id, delta: value });\n return chunks;\n }\n\n private toolInput(block: Record<string, unknown>, fallbackId: string): UIMessageChunk[] {\n const tool = record(block.tool) || block;\n const toolCallId = text(tool.toolCallId) || text(tool.tool_call_id) || fallbackId;\n const toolName = text(tool.action) || text(tool.title) || text(block.display_name) || \"tool\";\n if (this.toolCalls.has(toolCallId)) return [];\n this.toolCalls.add(toolCallId);\n return [{\n type: \"tool-input-available\",\n toolCallId,\n toolName,\n input: tool.input ?? block.input ?? {},\n providerExecuted: true,\n dynamic: true,\n ...(text(tool.title) || text(block.display_name) ? { title: text(tool.title) || text(block.display_name) || undefined } : {}),\n }];\n }\n\n private toolOutput(block: Record<string, unknown>, fallbackId: string): UIMessageChunk[] {\n const tool = record(block.tool) || block;\n const toolCallId = text(tool.toolCallId) || text(tool.tool_call_id) || fallbackId;\n const chunks = this.toolInput(block, fallbackId);\n if (this.toolOutputs.has(toolCallId)) return chunks;\n this.toolOutputs.add(toolCallId);\n const failed = [\"failed\", \"error\"].includes(String(block.status || \"\").toLocaleLowerCase());\n chunks.push(failed\n ? { type: \"tool-output-error\", toolCallId, errorText: text(tool.error) || text(block.error) || \"Tool execution failed.\", providerExecuted: true, dynamic: true }\n : { type: \"tool-output-available\", toolCallId, output: tool.output ?? block.output ?? block, providerExecuted: true, dynamic: true });\n return chunks;\n }\n\n private mapBlock(block: Record<string, unknown>, fallbackId: string): UIMessageChunk[] {\n const kind = String(block.kind || \"unsupported\");\n const id = text(block.id) || fallbackId;\n const chunks: UIMessageChunk[] = [dataChunk(\"response-block\", block, id)];\n if (kind === \"assistant_text\" && !this.textOpen) {\n chunks.push(...this.text(text(block.text) || \"\", `${this.runId || \"run\"}-text`));\n } else if (kind === \"reasoning_note\" && !this.reasoningOpen) {\n chunks.push(...this.reasoning(text(block.description) || text(block.label) || \"\", `${this.runId || \"run\"}-reasoning`));\n } else if (kind === \"tool_call\") {\n chunks.push(...this.toolOutput(block, id));\n } else if (kind === \"source\") {\n const url = safeWebUrl(block.url);\n if (url) chunks.push({ type: \"source-url\", sourceId: id, url, ...(text(block.title) ? { title: text(block.title) || undefined } : {}) });\n } else if (kind === \"citation\") {\n chunks.push(dataChunk(\"citation\", block, id));\n } else if (kind === \"ui_blocks\") {\n chunks.push(dataChunk(\"ui-blocks\", block, id));\n } else if (kind === \"hitl_request\") {\n chunks.push(dataChunk(\"hitl\", block, id));\n } else if (kind === \"mcp_authorization\") {\n chunks.push(dataChunk(\"mcp\", block, id));\n } else if (kind === \"attachment\") {\n chunks.push(dataChunk(\"attachment\", block, id));\n } else if (kind === \"error\") {\n chunks.push({ type: \"error\", errorText: text(record(block.error)?.message) || text(block.text) || \"The run failed.\" });\n } else if (kind === \"user_message\") {\n chunks.push(dataChunk(\"unsupported\", { feature: \"terminal-user-message-block\", block }, id));\n }\n return chunks;\n }\n\n private terminal(finishReason: \"error\" | \"other\" | \"stop\", metadata: Agents24MessageMetadata): UIMessageChunk[] {\n if (this.finished) return [];\n this.finished = true;\n this.status = metadata.status;\n const chunks: UIMessageChunk[] = [];\n if (this.textOpen) chunks.push({ type: \"text-end\", id: `${this.runId || \"run\"}-text` });\n if (this.reasoningOpen) chunks.push({ type: \"reasoning-end\", id: `${this.runId || \"run\"}-reasoning` });\n chunks.push({ type: \"finish-step\" });\n chunks.push({ type: \"finish\", finishReason, messageMetadata: metadata });\n return chunks;\n }\n\n map(event: RuntimeEvent): UIMessageChunk[] {\n this.runId = event.run_id;\n this.cursor = event.seq;\n const payload = event.payload;\n this.threadId = text(payload.thread_id) || this.threadId;\n const chunks = this.ensureStarted();\n chunks.push(dataChunk(\"event\", event, `${event.run_id}:${event.seq}`));\n chunks.push({ type: \"message-metadata\", messageMetadata: this.state });\n\n if (event.event === \"assistant.delta\") {\n chunks.push(...this.text(text(payload.content) || \"\", `${event.run_id}-text`));\n } else if (event.event === \"reasoning.update\") {\n chunks.push(...this.reasoning(text(payload.delta) || text(payload.description) || text(payload.label) || \"\", `${event.run_id}-reasoning`));\n } else if (event.event === \"tool.started\") {\n chunks.push(...this.toolInput(payload, text(payload.tool_call_id) || `${event.run_id}:tool:${event.seq}`));\n } else if (event.event === \"tool.completed\" || event.event === \"tool.failed\" || event.event === \"tool.cancelled\") {\n chunks.push(...this.toolOutput({ ...payload, status: event.event.split(\".\")[1] }, text(payload.tool_call_id) || `${event.run_id}:tool:${event.seq}`));\n } else if (event.event === \"source.added\") {\n const source = record(payload.source) || payload;\n const sourceId = text(source.id) || `${event.run_id}:source:${event.seq}`;\n const url = safeWebUrl(source.url);\n if (url) chunks.push({ type: \"source-url\", sourceId, url, ...(text(source.title) ? { title: text(source.title) || undefined } : {}) });\n } else if (event.event === \"citation.added\") {\n chunks.push(dataChunk(\"citation\", record(payload.source) || payload, `${event.run_id}:citation:${event.seq}`));\n } else if (event.event === \"ui_blocks.updated\") {\n chunks.push(dataChunk(\"ui-blocks\", payload, `${event.run_id}:ui:${event.seq}`));\n } else if (event.event === \"context_window.updated\" || event.event === \"context.compression.updated\" || event.event === \"run_usage.updated\") {\n chunks.push(dataChunk(\"context\", payload, `${event.run_id}:context:${event.seq}`));\n } else if (event.event === \"hitl.requested\" || event.event === \"hitl.resolved\") {\n chunks.push(dataChunk(\"hitl\", payload, `${event.run_id}:hitl:${event.seq}`));\n } else if (event.event.startsWith(\"mcp.authorization.\")) {\n chunks.push(dataChunk(\"mcp\", payload, `${event.run_id}:mcp:${event.seq}`));\n } else if (event.event.startsWith(\"attachment.\")) {\n chunks.push(dataChunk(\"attachment\", payload, `${event.run_id}:attachment:${event.seq}`));\n } else if (event.event === \"runtime.error\") {\n chunks.push({ type: \"error\", errorText: text(record(payload.error)?.message) || \"The run failed.\" });\n }\n\n const blocks = Array.isArray(payload.response_blocks) ? payload.response_blocks : [];\n blocks.forEach((value, index) => {\n const block = record(value);\n if (block) chunks.push(...this.mapBlock(block, `${event.run_id}:block:${event.seq}:${index}`));\n });\n\n if (event.event === \"run.completed\") chunks.push(...this.terminal(\"stop\", { ...this.state, status: \"completed\" }));\n if (event.event === \"run.failed\") chunks.push(...this.terminal(\"error\", { ...this.state, status: \"failed\" }));\n if (event.event === \"run.cancelled\") chunks.push(...this.terminal(\"other\", { ...this.state, status: \"cancelled\" }));\n return chunks;\n }\n\n finalize(input: { aborted?: boolean; detached?: boolean; error?: string }): UIMessageChunk[] {\n const chunks = this.ensureStarted();\n if (input.aborted) {\n if (!this.finished) {\n this.finished = true;\n chunks.push({ type: \"abort\", reason: \"The local stream was stopped.\" });\n }\n return chunks;\n }\n if (input.error) {\n chunks.push({ type: \"error\", errorText: input.error });\n chunks.push(...this.terminal(\"error\", { ...this.state, status: \"failed\" }));\n return chunks;\n }\n chunks.push(...this.terminal(\"other\", { ...this.state, detached: Boolean(input.detached), status: input.detached ? \"detached\" : \"completed\" }));\n return chunks;\n }\n}\n","import type { Agents24ChatStateStore, Agents24PersistedChatState } from \"./types.js\";\n\nexport function createInMemoryAgents24ChatStateStore(): Agents24ChatStateStore {\n const states = new Map<string, Agents24PersistedChatState>();\n return {\n async load(chatId) {\n const state = states.get(chatId);\n return state ? { ...state } : null;\n },\n async save(chatId, state) {\n states.set(chatId, { ...state });\n },\n };\n}\n","import { Agents24ClientError } from \"@agents24/client\";\nimport type { StreamResult } from \"@agents24/client\";\nimport type { ChatRequestOptions, UIMessageChunk } from \"ai\";\nimport { Agents24AiSdkError } from \"./errors.js\";\nimport { Agents24EventMapper } from \"./event-mapper.js\";\nimport { prepareAgents24Request, promptForRequest } from \"./request-policy.js\";\nimport { createInMemoryAgents24ChatStateStore } from \"./state-store.js\";\nimport type {\n Agents24AdapterTelemetryEvent,\n Agents24ChatTransport,\n Agents24MessageMetadata,\n Agents24PersistedChatState,\n CreateAgents24ChatTransportOptions,\n} from \"./types.js\";\n\nfunction defaultId(): string {\n const crypto = (globalThis as unknown as { crypto?: { randomUUID?: () => string } }).crypto;\n if (!crypto?.randomUUID) {\n throw new Agents24AiSdkError(\"A secure ID capability must be injected for this runtime.\", {\n code: \"MISSING_ID_CAPABILITY\",\n kind: \"capability\",\n });\n }\n return crypto.randomUUID();\n}\n\nfunction checkedId(createId: () => string): string {\n const value = createId();\n if (!value || /[\\r\\n\\0]/.test(value)) {\n throw new Agents24AiSdkError(\"The ID provider returned an invalid identifier.\", {\n code: \"INVALID_ID\",\n kind: \"capability\",\n });\n }\n return value;\n}\n\nfunction safeStreamError(error: unknown): string {\n if (error instanceof Agents24ClientError || error instanceof Agents24AiSdkError) return error.message;\n return \"The Agents24 stream failed.\";\n}\n\nfunction persistedState(\n messageId: string,\n metadata: Agents24MessageMetadata,\n status: Agents24PersistedChatState[\"status\"],\n): Agents24PersistedChatState {\n return {\n cursor: metadata.cursor ?? null,\n messageId,\n runId: metadata.runId ?? null,\n status,\n threadId: metadata.threadId ?? null,\n };\n}\n\nfunction terminalStatus(\n metadata: Agents24MessageMetadata,\n result: StreamResult,\n): Agents24PersistedChatState[\"status\"] {\n if (result.detached) return \"detached\";\n if (metadata.status === \"failed\") return \"failed\";\n if (metadata.status === \"cancelled\") return \"cancelled\";\n return \"completed\";\n}\n\nfunction validState(value: Agents24PersistedChatState): boolean {\n return (\n typeof value.messageId === \"string\" &&\n value.messageId.length > 0 &&\n (value.runId === null || typeof value.runId === \"string\") &&\n (value.threadId === null || typeof value.threadId === \"string\") &&\n (value.cursor === null || Number.isSafeInteger(value.cursor)) &&\n [\"active\", \"cancelled\", \"completed\", \"detached\", \"failed\"].includes(value.status)\n );\n}\n\nexport function createAgents24ChatTransport(\n options: CreateAgents24ChatTransportOptions,\n): Agents24ChatTransport {\n const createId = options.createId ?? defaultId;\n const stateStore = options.stateStore ?? createInMemoryAgents24ChatStateStore();\n\n const emit = async (event: Agents24AdapterTelemetryEvent): Promise<void> => {\n try {\n await options.telemetry?.emit(event);\n } catch {\n // Adapter telemetry never receives credentials and cannot affect the stream.\n }\n };\n\n const stream = (input: {\n chatId: string;\n initialThreadId?: string | null;\n messageId: string;\n operation: \"reconnect\" | \"submit\";\n abortSignal?: AbortSignal;\n content?: Agents24AdapterTelemetryEvent[\"content\"];\n execute(onEvent: Parameters<CreateAgents24ChatTransportOptions[\"client\"][\"chat\"][\"stream\"]>[1]): Promise<StreamResult>;\n }): ReadableStream<UIMessageChunk> => {\n const mapper = new Agents24EventMapper(input.messageId, input.initialThreadId);\n return new ReadableStream<UIMessageChunk>({\n async start(controller) {\n await emit({\n chatId: input.chatId,\n operation: input.operation,\n status: \"started\",\n ...(input.content ? { content: input.content } : {}),\n });\n try {\n await stateStore.save(\n input.chatId,\n persistedState(input.messageId, mapper.state, \"active\"),\n );\n const result = await input.execute(async (event) => {\n for (const chunk of mapper.map(event)) controller.enqueue(chunk);\n await stateStore.save(\n input.chatId,\n persistedState(input.messageId, mapper.state, \"active\"),\n );\n });\n const status = terminalStatus(mapper.state, result);\n for (const chunk of mapper.finalize({\n aborted: input.abortSignal?.aborted,\n detached: result.detached,\n })) controller.enqueue(chunk);\n await stateStore.save(\n input.chatId,\n persistedState(input.messageId, mapper.state, status),\n );\n await emit({\n chatId: input.chatId,\n cursor: mapper.state.cursor,\n operation: input.operation,\n runId: mapper.state.runId,\n status: \"completed\",\n });\n } catch (error) {\n const aborted = input.abortSignal?.aborted ?? false;\n for (const chunk of mapper.finalize({\n aborted,\n ...(aborted ? {} : { error: safeStreamError(error) }),\n })) controller.enqueue(chunk);\n try {\n await stateStore.save(\n input.chatId,\n persistedState(input.messageId, mapper.state, aborted ? \"detached\" : \"failed\"),\n );\n } catch {\n // A failed state store is already represented by the safe stream error.\n }\n await emit({\n chatId: input.chatId,\n cursor: mapper.state.cursor,\n operation: input.operation,\n runId: mapper.state.runId,\n status: aborted ? \"completed\" : \"failed\",\n });\n } finally {\n controller.close();\n }\n },\n });\n };\n\n return {\n async sendMessages(input) {\n if (input.trigger === \"regenerate-message\") {\n throw new Agents24AiSdkError(\n \"Agents24 V0 does not support regenerate because the frozen client-runtime routes have no regenerate operation.\",\n { code: \"REGENERATE_UNSUPPORTED\", kind: \"unsupported\" },\n );\n }\n const prepared = prepareAgents24Request(input, options.requestPolicy);\n const prompt = promptForRequest(input.messages);\n const previous = await stateStore.load(input.chatId);\n if (previous && !validState(previous)) {\n throw new Agents24AiSdkError(\"Stored Agents24 chat state is invalid.\", {\n code: \"INVALID_CHAT_STATE\",\n kind: \"state\",\n });\n }\n if (!previous?.threadId && input.messages.length > 1) {\n throw new Agents24AiSdkError(\n \"Conversation history requires persisted Agents24 thread state; client history is never replayed as forged runtime history.\",\n { code: \"CHAT_STATE_REQUIRED\", kind: \"state\" },\n );\n }\n const responseMessageId = checkedId(createId);\n const content = options.requestPolicy?.includePromptAndToolContentInTelemetry\n ? { prompt, toolInputs: prepared.toolInputs }\n : undefined;\n return stream({\n chatId: input.chatId,\n ...(previous?.threadId ? { initialThreadId: previous.threadId } : {}),\n messageId: responseMessageId,\n operation: \"submit\",\n ...(input.abortSignal ? { abortSignal: input.abortSignal } : {}),\n ...(content ? { content } : {}),\n execute: (onEvent) => options.client.chat.stream({\n input: prompt,\n attachmentIds: prepared.attachmentIds,\n headers: prepared.headers,\n idempotencyKey: checkedId(createId),\n metadata: prepared.metadata,\n ...(previous?.threadId ? { threadId: previous.threadId } : {}),\n ...(prepared.requestedModelId ? { requestedModelId: prepared.requestedModelId } : {}),\n toolInputs: prepared.toolInputs,\n ...(input.abortSignal ? { signal: input.abortSignal } : {}),\n }, onEvent),\n });\n },\n\n async reconnectToStream(input) {\n const prepared = prepareAgents24Request(input, options.requestPolicy);\n if (\n prepared.attachmentIds.length ||\n Object.keys(prepared.metadata).length ||\n prepared.requestedModelId ||\n Object.keys(prepared.toolInputs).length\n ) {\n throw new Agents24AiSdkError(\n \"Reconnect accepts allowlisted headers only; run input is immutable after submission.\",\n { code: \"RECONNECT_OPTIONS_UNSUPPORTED\", kind: \"unsupported\" },\n );\n }\n const previous = await stateStore.load(input.chatId);\n if (!previous) return null;\n if (!validState(previous)) {\n throw new Agents24AiSdkError(\"Stored Agents24 chat state is invalid.\", {\n code: \"INVALID_CHAT_STATE\",\n kind: \"state\",\n });\n }\n if (!previous.runId || previous.status === \"completed\" || previous.status === \"failed\" || previous.status === \"cancelled\") {\n return null;\n }\n return stream({\n chatId: input.chatId,\n initialThreadId: previous.threadId,\n messageId: previous.messageId,\n operation: \"reconnect\",\n execute: (onEvent) => options.client.runs.attach({\n runId: previous.runId as string,\n ...(previous.cursor === null ? {} : { cursor: previous.cursor }),\n headers: prepared.headers,\n }, onEvent),\n });\n },\n };\n}\n","import type { ChatRequestOptions } from \"ai\";\nimport { requestError } from \"./errors.js\";\nimport type { Agents24RequestPolicy, Agents24UIMessage } from \"./types.js\";\n\nconst RESERVED_KEYS = new Set([\n \"agent\", \"agentid\", \"agentversion\", \"agentversionid\", \"authorization\", \"clientid\",\n \"cursor\", \"deployment\", \"deploymentid\", \"dpop\", \"identity\", \"origin\", \"refreshgrant\",\n \"runid\", \"session\", \"sessionid\", \"tenant\", \"tenantid\", \"token\", \"userid\", \"version\",\n]);\nconst RESERVED_HEADERS = new Set([\n \"authorization\", \"cookie\", \"dpop\", \"host\", \"origin\", \"proxy-authorization\",\n \"sec-fetch-site\", \"x-agent-id\", \"x-agent-version\", \"x-agents24-deployment-id\",\n \"x-client-id\", \"x-deployment-id\", \"x-forwarded-host\", \"x-refresh-grant\", \"x-run-id\", \"x-session-id\",\n]);\n\nfunction normalizedKey(value: string): string {\n return value.toLowerCase().replace(/[^a-z0-9]/g, \"\");\n}\n\nfunction record(value: unknown): Record<string, unknown> | null {\n return value && typeof value === \"object\" && !Array.isArray(value)\n ? value as Record<string, unknown>\n : null;\n}\n\nfunction assertNoReservedFields(value: unknown, path: string): void {\n const object = record(value);\n if (!object) return;\n for (const [key, child] of Object.entries(object)) {\n if (RESERVED_KEYS.has(normalizedKey(key))) {\n throw requestError(\n \"RESERVED_REQUEST_FIELD\",\n `Agents24 reserved request field cannot be overridden: ${path}${key}`,\n );\n }\n assertNoReservedFields(child, `${path}${key}.`);\n }\n}\n\nfunction allowedRecord(value: unknown, allowed: ReadonlySet<string>, label: string): Record<string, unknown> {\n const input = record(value);\n if (!input) {\n if (value === undefined) return {};\n throw requestError(\"INVALID_REQUEST_OPTIONS\", `Agents24 ${label} must be an object.`);\n }\n assertNoReservedFields(input, `${label}.`);\n const output: Record<string, unknown> = {};\n for (const [key, child] of Object.entries(input)) {\n if (!allowed.has(key)) {\n throw requestError(\n \"REQUEST_FIELD_NOT_ALLOWLISTED\",\n `Agents24 ${label} field is not allowlisted: ${key}`,\n );\n }\n output[key] = child;\n }\n return output;\n}\n\nfunction headerEntries(headers: ChatRequestOptions[\"headers\"]): Array<[string, string]> {\n if (!headers) return [];\n if (typeof (headers as Headers).forEach === \"function\") {\n const output: Array<[string, string]> = [];\n (headers as Headers).forEach((value, key) => output.push([key, value]));\n return output;\n }\n return Object.entries(headers as Record<string, string>);\n}\n\nexport type PreparedAgents24Request = {\n attachmentIds: string[];\n headers: Readonly<Record<string, string>>;\n metadata: Readonly<Record<string, unknown>>;\n requestedModelId?: string;\n toolInputs: Readonly<Record<string, Readonly<Record<string, unknown>>>>;\n};\n\nexport function prepareAgents24Request(\n options: ChatRequestOptions,\n policy: Agents24RequestPolicy | undefined,\n): PreparedAgents24Request {\n const allowedBody = new Set(policy?.allowedBodyFields ?? [\"attachmentIds\", \"requestedModelId\", \"toolInputs\"]);\n const allowedHeaders = new Set((policy?.allowedHeaders ?? []).map((name) => name.toLowerCase()));\n const allowedMetadata = new Set(policy?.allowedMetadataFields ?? []);\n const body = allowedRecord(options.body, allowedBody, \"body\");\n const metadata = allowedRecord(options.metadata, allowedMetadata, \"metadata\");\n const headers: Record<string, string> = {};\n for (const [rawName, value] of headerEntries(options.headers)) {\n const name = rawName.toLowerCase();\n if (RESERVED_HEADERS.has(name)) {\n throw requestError(\"RESERVED_REQUEST_HEADER\", `Agents24 reserved header cannot be overridden: ${rawName}`);\n }\n if (!allowedHeaders.has(name)) {\n throw requestError(\"REQUEST_HEADER_NOT_ALLOWLISTED\", `Agents24 header is not allowlisted: ${rawName}`);\n }\n if (/[\\r\\n\\0]/.test(value)) {\n throw requestError(\"INVALID_REQUEST_HEADER\", `Agents24 header contains invalid characters: ${rawName}`);\n }\n headers[name] = value;\n }\n const attachmentIds = body.attachmentIds === undefined\n ? []\n : Array.isArray(body.attachmentIds) && body.attachmentIds.every((item) => typeof item === \"string\" && item.length > 0)\n ? body.attachmentIds\n : (() => { throw requestError(\"INVALID_ATTACHMENT_IDS\", \"Agents24 attachmentIds must be a string array.\"); })();\n const requestedModelId = body.requestedModelId === undefined\n ? undefined\n : typeof body.requestedModelId === \"string\" && body.requestedModelId.length > 0\n ? body.requestedModelId\n : (() => { throw requestError(\"INVALID_MODEL_ID\", \"Agents24 requestedModelId must be a non-empty string.\"); })();\n const toolInputs = body.toolInputs === undefined\n ? {}\n : allowedRecord(body.toolInputs, new Set(Object.keys(record(body.toolInputs) ?? {})), \"toolInputs\");\n return {\n attachmentIds,\n headers,\n metadata,\n ...(requestedModelId ? { requestedModelId } : {}),\n toolInputs: toolInputs as Readonly<Record<string, Readonly<Record<string, unknown>>>>,\n };\n}\n\nexport function promptForRequest(messages: Agents24UIMessage[]): string {\n const message = messages.at(-1);\n if (!message || message.role !== \"user\") {\n throw requestError(\n \"UNSUPPORTED_SUBMIT_SHAPE\",\n \"Agents24 submit requires the latest message to be a user message.\",\n );\n }\n const unsupported = message.parts.find((part) => part.type !== \"text\");\n if (unsupported) {\n throw requestError(\n \"UNSUPPORTED_MESSAGE_PART\",\n `Agents24 does not accept AI SDK user part type: ${unsupported.type}`,\n );\n }\n const value = message.parts\n .map((part) => part.type === \"text\" ? part.text : \"\")\n .join(\"\\n\")\n .trim();\n if (!value) {\n throw requestError(\"EMPTY_USER_MESSAGE\", \"Agents24 requires a non-empty user text message.\");\n }\n return value;\n}\n"],"mappings":"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","names":["record"]}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ChatRequestOptions } from "ai";
|
|
2
|
+
import type { Agents24RequestPolicy, Agents24UIMessage } from "./types.js";
|
|
3
|
+
export type PreparedAgents24Request = {
|
|
4
|
+
attachmentIds: string[];
|
|
5
|
+
headers: Readonly<Record<string, string>>;
|
|
6
|
+
metadata: Readonly<Record<string, unknown>>;
|
|
7
|
+
requestedModelId?: string;
|
|
8
|
+
toolInputs: Readonly<Record<string, Readonly<Record<string, unknown>>>>;
|
|
9
|
+
};
|
|
10
|
+
export declare function prepareAgents24Request(options: ChatRequestOptions, policy: Agents24RequestPolicy | undefined): PreparedAgents24Request;
|
|
11
|
+
export declare function promptForRequest(messages: Agents24UIMessage[]): string;
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import type { AgentClient, RuntimeEvent } from "@agents24/client";
|
|
2
|
+
import type { ChatTransport, UIMessage } from "ai";
|
|
3
|
+
export type Agents24MessageMetadata = {
|
|
4
|
+
cursor?: number | null;
|
|
5
|
+
detached?: boolean;
|
|
6
|
+
runId?: string | null;
|
|
7
|
+
status?: string;
|
|
8
|
+
threadId?: string | null;
|
|
9
|
+
};
|
|
10
|
+
export type Agents24DataParts = {
|
|
11
|
+
"agents24-attachment": Record<string, unknown>;
|
|
12
|
+
"agents24-citation": Record<string, unknown>;
|
|
13
|
+
"agents24-context": Record<string, unknown>;
|
|
14
|
+
"agents24-event": RuntimeEvent;
|
|
15
|
+
"agents24-hitl": Record<string, unknown>;
|
|
16
|
+
"agents24-mcp": Record<string, unknown>;
|
|
17
|
+
"agents24-response-block": Record<string, unknown>;
|
|
18
|
+
"agents24-ui-blocks": Record<string, unknown>;
|
|
19
|
+
"agents24-unsupported": Record<string, unknown>;
|
|
20
|
+
};
|
|
21
|
+
export type Agents24UIMessage = UIMessage<Agents24MessageMetadata, Agents24DataParts>;
|
|
22
|
+
export type Agents24PersistedChatState = {
|
|
23
|
+
cursor: number | null;
|
|
24
|
+
messageId: string;
|
|
25
|
+
runId: string | null;
|
|
26
|
+
status: "active" | "cancelled" | "completed" | "detached" | "failed";
|
|
27
|
+
threadId: string | null;
|
|
28
|
+
};
|
|
29
|
+
export interface Agents24ChatStateStore {
|
|
30
|
+
load(chatId: string): Promise<Agents24PersistedChatState | null>;
|
|
31
|
+
save(chatId: string, state: Agents24PersistedChatState): Promise<void>;
|
|
32
|
+
}
|
|
33
|
+
export type Agents24RequestPolicy = {
|
|
34
|
+
allowedBodyFields?: readonly string[];
|
|
35
|
+
allowedHeaders?: readonly string[];
|
|
36
|
+
allowedMetadataFields?: readonly string[];
|
|
37
|
+
includePromptAndToolContentInTelemetry?: boolean;
|
|
38
|
+
};
|
|
39
|
+
export type Agents24AdapterTelemetryEvent = {
|
|
40
|
+
chatId: string;
|
|
41
|
+
cursor?: number | null;
|
|
42
|
+
operation: "reconnect" | "regenerate" | "submit";
|
|
43
|
+
runId?: string | null;
|
|
44
|
+
status: "completed" | "failed" | "started";
|
|
45
|
+
content?: {
|
|
46
|
+
prompt: string;
|
|
47
|
+
toolInputs: Readonly<Record<string, Readonly<Record<string, unknown>>>>;
|
|
48
|
+
};
|
|
49
|
+
};
|
|
50
|
+
export type Agents24AdapterTelemetry = {
|
|
51
|
+
emit(event: Agents24AdapterTelemetryEvent): Promise<void> | void;
|
|
52
|
+
};
|
|
53
|
+
export type CreateAgents24ChatTransportOptions = {
|
|
54
|
+
client: AgentClient;
|
|
55
|
+
createId?: () => string;
|
|
56
|
+
requestPolicy?: Agents24RequestPolicy;
|
|
57
|
+
stateStore?: Agents24ChatStateStore;
|
|
58
|
+
telemetry?: Agents24AdapterTelemetry;
|
|
59
|
+
};
|
|
60
|
+
export type Agents24ChatTransport = ChatTransport<Agents24UIMessage>;
|
package/package.json
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@agents24/ai-sdk",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Vercel AI SDK v7 ChatTransport adapter for Agents24 client runtimes.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"agents24",
|
|
7
|
+
"ai-sdk",
|
|
8
|
+
"chat-transport"
|
|
9
|
+
],
|
|
10
|
+
"license": "MIT",
|
|
11
|
+
"repository": {
|
|
12
|
+
"type": "git",
|
|
13
|
+
"url": "git+https://github.com/daniel5426/talmudpedia.git",
|
|
14
|
+
"directory": "packages/agents24-ai-sdk"
|
|
15
|
+
},
|
|
16
|
+
"type": "module",
|
|
17
|
+
"main": "./dist/index.js",
|
|
18
|
+
"module": "./dist/index.js",
|
|
19
|
+
"types": "./dist/index.d.ts",
|
|
20
|
+
"exports": {
|
|
21
|
+
".": {
|
|
22
|
+
"types": "./dist/index.d.ts",
|
|
23
|
+
"default": "./dist/index.js"
|
|
24
|
+
},
|
|
25
|
+
"./compatibility.json": "./compatibility.json"
|
|
26
|
+
},
|
|
27
|
+
"files": [
|
|
28
|
+
"dist",
|
|
29
|
+
"compatibility.json",
|
|
30
|
+
"README.md",
|
|
31
|
+
"LICENSE"
|
|
32
|
+
],
|
|
33
|
+
"sideEffects": false,
|
|
34
|
+
"publishConfig": {
|
|
35
|
+
"access": "public",
|
|
36
|
+
"provenance": false
|
|
37
|
+
},
|
|
38
|
+
"scripts": {
|
|
39
|
+
"sync:contract": "node scripts/sync-contract.mjs",
|
|
40
|
+
"check:contract": "node scripts/sync-contract.mjs --check",
|
|
41
|
+
"build": "pnpm run sync:contract && tsup && tsc -p tsconfig.build.json",
|
|
42
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
43
|
+
"test": "pnpm run build && tsx --test tests/*.test.ts",
|
|
44
|
+
"check:boundaries": "node tests/check-boundaries.mjs",
|
|
45
|
+
"check:pack": "node scripts/check-pack.mjs",
|
|
46
|
+
"prepack": "pnpm run build && pnpm run check:boundaries"
|
|
47
|
+
},
|
|
48
|
+
"dependencies": {
|
|
49
|
+
"@agents24/client": "0.1.0"
|
|
50
|
+
},
|
|
51
|
+
"peerDependencies": {
|
|
52
|
+
"ai": ">=7.0.0 <8.0.0"
|
|
53
|
+
},
|
|
54
|
+
"devDependencies": {
|
|
55
|
+
"ai": "7.0.0",
|
|
56
|
+
"tsup": "^8.5.1",
|
|
57
|
+
"tsx": "^4.20.6",
|
|
58
|
+
"typescript": "^5.9.3"
|
|
59
|
+
}
|
|
60
|
+
}
|