@mariozechner/pi-agent-core 0.9.1
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/dist/agent.d.ts +47 -0
- package/dist/agent.d.ts.map +1 -0
- package/dist/agent.js +311 -0
- package/dist/agent.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -0
- package/dist/transports/AppTransport.d.ts +24 -0
- package/dist/transports/AppTransport.d.ts.map +1 -0
- package/dist/transports/AppTransport.js +312 -0
- package/dist/transports/AppTransport.js.map +1 -0
- package/dist/transports/ProviderTransport.d.ts +25 -0
- package/dist/transports/ProviderTransport.d.ts.map +1 -0
- package/dist/transports/ProviderTransport.js +46 -0
- package/dist/transports/ProviderTransport.js.map +1 -0
- package/dist/transports/index.d.ts +5 -0
- package/dist/transports/index.d.ts.map +1 -0
- package/dist/transports/index.js +3 -0
- package/dist/transports/index.js.map +1 -0
- package/dist/transports/proxy-types.d.ts +53 -0
- package/dist/transports/proxy-types.d.ts.map +1 -0
- package/dist/transports/proxy-types.js +2 -0
- package/dist/transports/proxy-types.js.map +1 -0
- package/dist/transports/types.d.ts +22 -0
- package/dist/transports/types.d.ts.map +1 -0
- package/dist/transports/types.js +2 -0
- package/dist/transports/types.js.map +1 -0
- package/dist/types.d.ts +99 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +46 -0
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
import { agentLoop } from "@mariozechner/pi-ai";
|
|
2
|
+
import { AssistantMessageEventStream } from "@mariozechner/pi-ai/dist/utils/event-stream.js";
|
|
3
|
+
import { parseStreamingJson } from "@mariozechner/pi-ai/dist/utils/json-parse.js";
|
|
4
|
+
/**
|
|
5
|
+
* Stream function that proxies through a server instead of calling providers directly.
|
|
6
|
+
* The server strips the partial field from delta events to reduce bandwidth.
|
|
7
|
+
* We reconstruct the partial message client-side.
|
|
8
|
+
*/
|
|
9
|
+
function streamSimpleProxy(model, context, options, proxyUrl) {
|
|
10
|
+
const stream = new AssistantMessageEventStream();
|
|
11
|
+
(async () => {
|
|
12
|
+
// Initialize the partial message that we'll build up from events
|
|
13
|
+
const partial = {
|
|
14
|
+
role: "assistant",
|
|
15
|
+
stopReason: "stop",
|
|
16
|
+
content: [],
|
|
17
|
+
api: model.api,
|
|
18
|
+
provider: model.provider,
|
|
19
|
+
model: model.id,
|
|
20
|
+
usage: {
|
|
21
|
+
input: 0,
|
|
22
|
+
output: 0,
|
|
23
|
+
cacheRead: 0,
|
|
24
|
+
cacheWrite: 0,
|
|
25
|
+
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },
|
|
26
|
+
},
|
|
27
|
+
timestamp: Date.now(),
|
|
28
|
+
};
|
|
29
|
+
let reader;
|
|
30
|
+
// Set up abort handler to cancel the reader
|
|
31
|
+
const abortHandler = () => {
|
|
32
|
+
if (reader) {
|
|
33
|
+
reader.cancel("Request aborted by user").catch(() => { });
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
if (options.signal) {
|
|
37
|
+
options.signal.addEventListener("abort", abortHandler);
|
|
38
|
+
}
|
|
39
|
+
try {
|
|
40
|
+
const response = await fetch(`${proxyUrl}/api/stream`, {
|
|
41
|
+
method: "POST",
|
|
42
|
+
headers: {
|
|
43
|
+
Authorization: `Bearer ${options.authToken}`,
|
|
44
|
+
"Content-Type": "application/json",
|
|
45
|
+
},
|
|
46
|
+
body: JSON.stringify({
|
|
47
|
+
model,
|
|
48
|
+
context,
|
|
49
|
+
options: {
|
|
50
|
+
temperature: options.temperature,
|
|
51
|
+
maxTokens: options.maxTokens,
|
|
52
|
+
reasoning: options.reasoning,
|
|
53
|
+
// Don't send apiKey or signal - those are added server-side
|
|
54
|
+
},
|
|
55
|
+
}),
|
|
56
|
+
signal: options.signal,
|
|
57
|
+
});
|
|
58
|
+
if (!response.ok) {
|
|
59
|
+
let errorMessage = `Proxy error: ${response.status} ${response.statusText}`;
|
|
60
|
+
try {
|
|
61
|
+
const errorData = (await response.json());
|
|
62
|
+
if (errorData.error) {
|
|
63
|
+
errorMessage = `Proxy error: ${errorData.error}`;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
catch {
|
|
67
|
+
// Couldn't parse error response, use default message
|
|
68
|
+
}
|
|
69
|
+
throw new Error(errorMessage);
|
|
70
|
+
}
|
|
71
|
+
// Parse SSE stream
|
|
72
|
+
reader = response.body.getReader();
|
|
73
|
+
const decoder = new TextDecoder();
|
|
74
|
+
let buffer = "";
|
|
75
|
+
while (true) {
|
|
76
|
+
const { done, value } = await reader.read();
|
|
77
|
+
if (done)
|
|
78
|
+
break;
|
|
79
|
+
// Check if aborted after reading
|
|
80
|
+
if (options.signal?.aborted) {
|
|
81
|
+
throw new Error("Request aborted by user");
|
|
82
|
+
}
|
|
83
|
+
buffer += decoder.decode(value, { stream: true });
|
|
84
|
+
const lines = buffer.split("\n");
|
|
85
|
+
buffer = lines.pop() || "";
|
|
86
|
+
for (const line of lines) {
|
|
87
|
+
if (line.startsWith("data: ")) {
|
|
88
|
+
const data = line.slice(6).trim();
|
|
89
|
+
if (data) {
|
|
90
|
+
const proxyEvent = JSON.parse(data);
|
|
91
|
+
let event;
|
|
92
|
+
// Handle different event types
|
|
93
|
+
// Server sends events with partial for non-delta events,
|
|
94
|
+
// and without partial for delta events
|
|
95
|
+
switch (proxyEvent.type) {
|
|
96
|
+
case "start":
|
|
97
|
+
event = { type: "start", partial };
|
|
98
|
+
break;
|
|
99
|
+
case "text_start":
|
|
100
|
+
partial.content[proxyEvent.contentIndex] = {
|
|
101
|
+
type: "text",
|
|
102
|
+
text: "",
|
|
103
|
+
};
|
|
104
|
+
event = { type: "text_start", contentIndex: proxyEvent.contentIndex, partial };
|
|
105
|
+
break;
|
|
106
|
+
case "text_delta": {
|
|
107
|
+
const content = partial.content[proxyEvent.contentIndex];
|
|
108
|
+
if (content?.type === "text") {
|
|
109
|
+
content.text += proxyEvent.delta;
|
|
110
|
+
event = {
|
|
111
|
+
type: "text_delta",
|
|
112
|
+
contentIndex: proxyEvent.contentIndex,
|
|
113
|
+
delta: proxyEvent.delta,
|
|
114
|
+
partial,
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
throw new Error("Received text_delta for non-text content");
|
|
119
|
+
}
|
|
120
|
+
break;
|
|
121
|
+
}
|
|
122
|
+
case "text_end": {
|
|
123
|
+
const content = partial.content[proxyEvent.contentIndex];
|
|
124
|
+
if (content?.type === "text") {
|
|
125
|
+
content.textSignature = proxyEvent.contentSignature;
|
|
126
|
+
event = {
|
|
127
|
+
type: "text_end",
|
|
128
|
+
contentIndex: proxyEvent.contentIndex,
|
|
129
|
+
content: content.text,
|
|
130
|
+
partial,
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
else {
|
|
134
|
+
throw new Error("Received text_end for non-text content");
|
|
135
|
+
}
|
|
136
|
+
break;
|
|
137
|
+
}
|
|
138
|
+
case "thinking_start":
|
|
139
|
+
partial.content[proxyEvent.contentIndex] = {
|
|
140
|
+
type: "thinking",
|
|
141
|
+
thinking: "",
|
|
142
|
+
};
|
|
143
|
+
event = { type: "thinking_start", contentIndex: proxyEvent.contentIndex, partial };
|
|
144
|
+
break;
|
|
145
|
+
case "thinking_delta": {
|
|
146
|
+
const content = partial.content[proxyEvent.contentIndex];
|
|
147
|
+
if (content?.type === "thinking") {
|
|
148
|
+
content.thinking += proxyEvent.delta;
|
|
149
|
+
event = {
|
|
150
|
+
type: "thinking_delta",
|
|
151
|
+
contentIndex: proxyEvent.contentIndex,
|
|
152
|
+
delta: proxyEvent.delta,
|
|
153
|
+
partial,
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
else {
|
|
157
|
+
throw new Error("Received thinking_delta for non-thinking content");
|
|
158
|
+
}
|
|
159
|
+
break;
|
|
160
|
+
}
|
|
161
|
+
case "thinking_end": {
|
|
162
|
+
const content = partial.content[proxyEvent.contentIndex];
|
|
163
|
+
if (content?.type === "thinking") {
|
|
164
|
+
content.thinkingSignature = proxyEvent.contentSignature;
|
|
165
|
+
event = {
|
|
166
|
+
type: "thinking_end",
|
|
167
|
+
contentIndex: proxyEvent.contentIndex,
|
|
168
|
+
content: content.thinking,
|
|
169
|
+
partial,
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
else {
|
|
173
|
+
throw new Error("Received thinking_end for non-thinking content");
|
|
174
|
+
}
|
|
175
|
+
break;
|
|
176
|
+
}
|
|
177
|
+
case "toolcall_start":
|
|
178
|
+
partial.content[proxyEvent.contentIndex] = {
|
|
179
|
+
type: "toolCall",
|
|
180
|
+
id: proxyEvent.id,
|
|
181
|
+
name: proxyEvent.toolName,
|
|
182
|
+
arguments: {},
|
|
183
|
+
partialJson: "",
|
|
184
|
+
};
|
|
185
|
+
event = { type: "toolcall_start", contentIndex: proxyEvent.contentIndex, partial };
|
|
186
|
+
break;
|
|
187
|
+
case "toolcall_delta": {
|
|
188
|
+
const content = partial.content[proxyEvent.contentIndex];
|
|
189
|
+
if (content?.type === "toolCall") {
|
|
190
|
+
content.partialJson += proxyEvent.delta;
|
|
191
|
+
content.arguments = parseStreamingJson(content.partialJson) || {};
|
|
192
|
+
event = {
|
|
193
|
+
type: "toolcall_delta",
|
|
194
|
+
contentIndex: proxyEvent.contentIndex,
|
|
195
|
+
delta: proxyEvent.delta,
|
|
196
|
+
partial,
|
|
197
|
+
};
|
|
198
|
+
partial.content[proxyEvent.contentIndex] = { ...content }; // Trigger reactivity
|
|
199
|
+
}
|
|
200
|
+
else {
|
|
201
|
+
throw new Error("Received toolcall_delta for non-toolCall content");
|
|
202
|
+
}
|
|
203
|
+
break;
|
|
204
|
+
}
|
|
205
|
+
case "toolcall_end": {
|
|
206
|
+
const content = partial.content[proxyEvent.contentIndex];
|
|
207
|
+
if (content?.type === "toolCall") {
|
|
208
|
+
delete content.partialJson;
|
|
209
|
+
event = {
|
|
210
|
+
type: "toolcall_end",
|
|
211
|
+
contentIndex: proxyEvent.contentIndex,
|
|
212
|
+
toolCall: content,
|
|
213
|
+
partial,
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
break;
|
|
217
|
+
}
|
|
218
|
+
case "done":
|
|
219
|
+
partial.stopReason = proxyEvent.reason;
|
|
220
|
+
partial.usage = proxyEvent.usage;
|
|
221
|
+
event = { type: "done", reason: proxyEvent.reason, message: partial };
|
|
222
|
+
break;
|
|
223
|
+
case "error":
|
|
224
|
+
partial.stopReason = proxyEvent.reason;
|
|
225
|
+
partial.errorMessage = proxyEvent.errorMessage;
|
|
226
|
+
partial.usage = proxyEvent.usage;
|
|
227
|
+
event = { type: "error", reason: proxyEvent.reason, error: partial };
|
|
228
|
+
break;
|
|
229
|
+
default: {
|
|
230
|
+
// Exhaustive check
|
|
231
|
+
const _exhaustiveCheck = proxyEvent;
|
|
232
|
+
console.warn(`Unhandled event type: ${proxyEvent.type}`);
|
|
233
|
+
break;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
// Push the event to stream
|
|
237
|
+
if (event) {
|
|
238
|
+
stream.push(event);
|
|
239
|
+
}
|
|
240
|
+
else {
|
|
241
|
+
throw new Error("Failed to create event from proxy event");
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
// Check if aborted after reading
|
|
248
|
+
if (options.signal?.aborted) {
|
|
249
|
+
throw new Error("Request aborted by user");
|
|
250
|
+
}
|
|
251
|
+
stream.end();
|
|
252
|
+
}
|
|
253
|
+
catch (error) {
|
|
254
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
255
|
+
partial.stopReason = options.signal?.aborted ? "aborted" : "error";
|
|
256
|
+
partial.errorMessage = errorMessage;
|
|
257
|
+
stream.push({
|
|
258
|
+
type: "error",
|
|
259
|
+
reason: partial.stopReason,
|
|
260
|
+
error: partial,
|
|
261
|
+
});
|
|
262
|
+
stream.end();
|
|
263
|
+
}
|
|
264
|
+
finally {
|
|
265
|
+
// Clean up abort handler
|
|
266
|
+
if (options.signal) {
|
|
267
|
+
options.signal.removeEventListener("abort", abortHandler);
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
})();
|
|
271
|
+
return stream;
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* Transport that uses an app server with user authentication tokens.
|
|
275
|
+
* The server manages user accounts and proxies requests to LLM providers.
|
|
276
|
+
*/
|
|
277
|
+
export class AppTransport {
|
|
278
|
+
options;
|
|
279
|
+
constructor(options) {
|
|
280
|
+
this.options = options;
|
|
281
|
+
}
|
|
282
|
+
async *run(messages, userMessage, cfg, signal) {
|
|
283
|
+
const authToken = await this.options.getAuthToken();
|
|
284
|
+
if (!authToken) {
|
|
285
|
+
throw new Error("Auth token is required for AppTransport");
|
|
286
|
+
}
|
|
287
|
+
// Use proxy - no local API key needed
|
|
288
|
+
const streamFn = (model, context, options) => {
|
|
289
|
+
return streamSimpleProxy(model, context, {
|
|
290
|
+
...options,
|
|
291
|
+
authToken,
|
|
292
|
+
}, this.options.proxyUrl);
|
|
293
|
+
};
|
|
294
|
+
// Messages are already LLM-compatible (filtered by Agent)
|
|
295
|
+
const context = {
|
|
296
|
+
systemPrompt: cfg.systemPrompt,
|
|
297
|
+
messages,
|
|
298
|
+
tools: cfg.tools,
|
|
299
|
+
};
|
|
300
|
+
const pc = {
|
|
301
|
+
model: cfg.model,
|
|
302
|
+
reasoning: cfg.reasoning,
|
|
303
|
+
getQueuedMessages: cfg.getQueuedMessages,
|
|
304
|
+
};
|
|
305
|
+
// Yield events from the upstream agentLoop iterator
|
|
306
|
+
// Pass streamFn as the 5th parameter to use proxy
|
|
307
|
+
for await (const ev of agentLoop(userMessage, context, pc, signal, streamFn)) {
|
|
308
|
+
yield ev;
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
//# sourceMappingURL=AppTransport.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AppTransport.js","sourceRoot":"","sources":["../../src/transports/AppTransport.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n\tAgentContext,\n\tAgentLoopConfig,\n\tApi,\n\tAssistantMessage,\n\tAssistantMessageEvent,\n\tContext,\n\tMessage,\n\tModel,\n\tSimpleStreamOptions,\n\tToolCall,\n\tUserMessage,\n} from \"@mariozechner/pi-ai\";\nimport { agentLoop } from \"@mariozechner/pi-ai\";\nimport { AssistantMessageEventStream } from \"@mariozechner/pi-ai/dist/utils/event-stream.js\";\nimport { parseStreamingJson } from \"@mariozechner/pi-ai/dist/utils/json-parse.js\";\nimport type { ProxyAssistantMessageEvent } from \"./proxy-types.js\";\nimport type { AgentRunConfig, AgentTransport } from \"./types.js\";\n\n/**\n * Stream function that proxies through a server instead of calling providers directly.\n * The server strips the partial field from delta events to reduce bandwidth.\n * We reconstruct the partial message client-side.\n */\nfunction streamSimpleProxy(\n\tmodel: Model<any>,\n\tcontext: Context,\n\toptions: SimpleStreamOptions & { authToken: string },\n\tproxyUrl: string,\n): AssistantMessageEventStream {\n\tconst stream = new AssistantMessageEventStream();\n\n\t(async () => {\n\t\t// Initialize the partial message that we'll build up from events\n\t\tconst partial: AssistantMessage = {\n\t\t\trole: \"assistant\",\n\t\t\tstopReason: \"stop\",\n\t\t\tcontent: [],\n\t\t\tapi: model.api,\n\t\t\tprovider: model.provider,\n\t\t\tmodel: model.id,\n\t\t\tusage: {\n\t\t\t\tinput: 0,\n\t\t\t\toutput: 0,\n\t\t\t\tcacheRead: 0,\n\t\t\t\tcacheWrite: 0,\n\t\t\t\tcost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },\n\t\t\t},\n\t\t\ttimestamp: Date.now(),\n\t\t};\n\n\t\tlet reader: ReadableStreamDefaultReader<Uint8Array> | undefined;\n\n\t\t// Set up abort handler to cancel the reader\n\t\tconst abortHandler = () => {\n\t\t\tif (reader) {\n\t\t\t\treader.cancel(\"Request aborted by user\").catch(() => {});\n\t\t\t}\n\t\t};\n\n\t\tif (options.signal) {\n\t\t\toptions.signal.addEventListener(\"abort\", abortHandler);\n\t\t}\n\n\t\ttry {\n\t\t\tconst response = await fetch(`${proxyUrl}/api/stream`, {\n\t\t\t\tmethod: \"POST\",\n\t\t\t\theaders: {\n\t\t\t\t\tAuthorization: `Bearer ${options.authToken}`,\n\t\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\t},\n\t\t\t\tbody: JSON.stringify({\n\t\t\t\t\tmodel,\n\t\t\t\t\tcontext,\n\t\t\t\t\toptions: {\n\t\t\t\t\t\ttemperature: options.temperature,\n\t\t\t\t\t\tmaxTokens: options.maxTokens,\n\t\t\t\t\t\treasoning: options.reasoning,\n\t\t\t\t\t\t// Don't send apiKey or signal - those are added server-side\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t\tsignal: options.signal,\n\t\t\t});\n\n\t\t\tif (!response.ok) {\n\t\t\t\tlet errorMessage = `Proxy error: ${response.status} ${response.statusText}`;\n\t\t\t\ttry {\n\t\t\t\t\tconst errorData = (await response.json()) as { error?: string };\n\t\t\t\t\tif (errorData.error) {\n\t\t\t\t\t\terrorMessage = `Proxy error: ${errorData.error}`;\n\t\t\t\t\t}\n\t\t\t\t} catch {\n\t\t\t\t\t// Couldn't parse error response, use default message\n\t\t\t\t}\n\t\t\t\tthrow new Error(errorMessage);\n\t\t\t}\n\n\t\t\t// Parse SSE stream\n\t\t\treader = response.body!.getReader();\n\t\t\tconst decoder = new TextDecoder();\n\t\t\tlet buffer = \"\";\n\n\t\t\twhile (true) {\n\t\t\t\tconst { done, value } = await reader.read();\n\t\t\t\tif (done) break;\n\n\t\t\t\t// Check if aborted after reading\n\t\t\t\tif (options.signal?.aborted) {\n\t\t\t\t\tthrow new Error(\"Request aborted by user\");\n\t\t\t\t}\n\n\t\t\t\tbuffer += decoder.decode(value, { stream: true });\n\t\t\t\tconst lines = buffer.split(\"\\n\");\n\t\t\t\tbuffer = lines.pop() || \"\";\n\n\t\t\t\tfor (const line of lines) {\n\t\t\t\t\tif (line.startsWith(\"data: \")) {\n\t\t\t\t\t\tconst data = line.slice(6).trim();\n\t\t\t\t\t\tif (data) {\n\t\t\t\t\t\t\tconst proxyEvent = JSON.parse(data) as ProxyAssistantMessageEvent;\n\t\t\t\t\t\t\tlet event: AssistantMessageEvent | undefined;\n\n\t\t\t\t\t\t\t// Handle different event types\n\t\t\t\t\t\t\t// Server sends events with partial for non-delta events,\n\t\t\t\t\t\t\t// and without partial for delta events\n\t\t\t\t\t\t\tswitch (proxyEvent.type) {\n\t\t\t\t\t\t\t\tcase \"start\":\n\t\t\t\t\t\t\t\t\tevent = { type: \"start\", partial };\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase \"text_start\":\n\t\t\t\t\t\t\t\t\tpartial.content[proxyEvent.contentIndex] = {\n\t\t\t\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\t\t\t\ttext: \"\",\n\t\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t\t\tevent = { type: \"text_start\", contentIndex: proxyEvent.contentIndex, partial };\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase \"text_delta\": {\n\t\t\t\t\t\t\t\t\tconst content = partial.content[proxyEvent.contentIndex];\n\t\t\t\t\t\t\t\t\tif (content?.type === \"text\") {\n\t\t\t\t\t\t\t\t\t\tcontent.text += proxyEvent.delta;\n\t\t\t\t\t\t\t\t\t\tevent = {\n\t\t\t\t\t\t\t\t\t\t\ttype: \"text_delta\",\n\t\t\t\t\t\t\t\t\t\t\tcontentIndex: proxyEvent.contentIndex,\n\t\t\t\t\t\t\t\t\t\t\tdelta: proxyEvent.delta,\n\t\t\t\t\t\t\t\t\t\t\tpartial,\n\t\t\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\tthrow new Error(\"Received text_delta for non-text content\");\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tcase \"text_end\": {\n\t\t\t\t\t\t\t\t\tconst content = partial.content[proxyEvent.contentIndex];\n\t\t\t\t\t\t\t\t\tif (content?.type === \"text\") {\n\t\t\t\t\t\t\t\t\t\tcontent.textSignature = proxyEvent.contentSignature;\n\t\t\t\t\t\t\t\t\t\tevent = {\n\t\t\t\t\t\t\t\t\t\t\ttype: \"text_end\",\n\t\t\t\t\t\t\t\t\t\t\tcontentIndex: proxyEvent.contentIndex,\n\t\t\t\t\t\t\t\t\t\t\tcontent: content.text,\n\t\t\t\t\t\t\t\t\t\t\tpartial,\n\t\t\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\tthrow new Error(\"Received text_end for non-text content\");\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tcase \"thinking_start\":\n\t\t\t\t\t\t\t\t\tpartial.content[proxyEvent.contentIndex] = {\n\t\t\t\t\t\t\t\t\t\ttype: \"thinking\",\n\t\t\t\t\t\t\t\t\t\tthinking: \"\",\n\t\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t\t\tevent = { type: \"thinking_start\", contentIndex: proxyEvent.contentIndex, partial };\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase \"thinking_delta\": {\n\t\t\t\t\t\t\t\t\tconst content = partial.content[proxyEvent.contentIndex];\n\t\t\t\t\t\t\t\t\tif (content?.type === \"thinking\") {\n\t\t\t\t\t\t\t\t\t\tcontent.thinking += proxyEvent.delta;\n\t\t\t\t\t\t\t\t\t\tevent = {\n\t\t\t\t\t\t\t\t\t\t\ttype: \"thinking_delta\",\n\t\t\t\t\t\t\t\t\t\t\tcontentIndex: proxyEvent.contentIndex,\n\t\t\t\t\t\t\t\t\t\t\tdelta: proxyEvent.delta,\n\t\t\t\t\t\t\t\t\t\t\tpartial,\n\t\t\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\tthrow new Error(\"Received thinking_delta for non-thinking content\");\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tcase \"thinking_end\": {\n\t\t\t\t\t\t\t\t\tconst content = partial.content[proxyEvent.contentIndex];\n\t\t\t\t\t\t\t\t\tif (content?.type === \"thinking\") {\n\t\t\t\t\t\t\t\t\t\tcontent.thinkingSignature = proxyEvent.contentSignature;\n\t\t\t\t\t\t\t\t\t\tevent = {\n\t\t\t\t\t\t\t\t\t\t\ttype: \"thinking_end\",\n\t\t\t\t\t\t\t\t\t\t\tcontentIndex: proxyEvent.contentIndex,\n\t\t\t\t\t\t\t\t\t\t\tcontent: content.thinking,\n\t\t\t\t\t\t\t\t\t\t\tpartial,\n\t\t\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\tthrow new Error(\"Received thinking_end for non-thinking content\");\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tcase \"toolcall_start\":\n\t\t\t\t\t\t\t\t\tpartial.content[proxyEvent.contentIndex] = {\n\t\t\t\t\t\t\t\t\t\ttype: \"toolCall\",\n\t\t\t\t\t\t\t\t\t\tid: proxyEvent.id,\n\t\t\t\t\t\t\t\t\t\tname: proxyEvent.toolName,\n\t\t\t\t\t\t\t\t\t\targuments: {},\n\t\t\t\t\t\t\t\t\t\tpartialJson: \"\",\n\t\t\t\t\t\t\t\t\t} satisfies ToolCall & { partialJson: string } as ToolCall;\n\t\t\t\t\t\t\t\t\tevent = { type: \"toolcall_start\", contentIndex: proxyEvent.contentIndex, partial };\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase \"toolcall_delta\": {\n\t\t\t\t\t\t\t\t\tconst content = partial.content[proxyEvent.contentIndex];\n\t\t\t\t\t\t\t\t\tif (content?.type === \"toolCall\") {\n\t\t\t\t\t\t\t\t\t\t(content as any).partialJson += proxyEvent.delta;\n\t\t\t\t\t\t\t\t\t\tcontent.arguments = parseStreamingJson((content as any).partialJson) || {};\n\t\t\t\t\t\t\t\t\t\tevent = {\n\t\t\t\t\t\t\t\t\t\t\ttype: \"toolcall_delta\",\n\t\t\t\t\t\t\t\t\t\t\tcontentIndex: proxyEvent.contentIndex,\n\t\t\t\t\t\t\t\t\t\t\tdelta: proxyEvent.delta,\n\t\t\t\t\t\t\t\t\t\t\tpartial,\n\t\t\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t\t\t\tpartial.content[proxyEvent.contentIndex] = { ...content }; // Trigger reactivity\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\tthrow new Error(\"Received toolcall_delta for non-toolCall content\");\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tcase \"toolcall_end\": {\n\t\t\t\t\t\t\t\t\tconst content = partial.content[proxyEvent.contentIndex];\n\t\t\t\t\t\t\t\t\tif (content?.type === \"toolCall\") {\n\t\t\t\t\t\t\t\t\t\tdelete (content as any).partialJson;\n\t\t\t\t\t\t\t\t\t\tevent = {\n\t\t\t\t\t\t\t\t\t\t\ttype: \"toolcall_end\",\n\t\t\t\t\t\t\t\t\t\t\tcontentIndex: proxyEvent.contentIndex,\n\t\t\t\t\t\t\t\t\t\t\ttoolCall: content,\n\t\t\t\t\t\t\t\t\t\t\tpartial,\n\t\t\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tcase \"done\":\n\t\t\t\t\t\t\t\t\tpartial.stopReason = proxyEvent.reason;\n\t\t\t\t\t\t\t\t\tpartial.usage = proxyEvent.usage;\n\t\t\t\t\t\t\t\t\tevent = { type: \"done\", reason: proxyEvent.reason, message: partial };\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase \"error\":\n\t\t\t\t\t\t\t\t\tpartial.stopReason = proxyEvent.reason;\n\t\t\t\t\t\t\t\t\tpartial.errorMessage = proxyEvent.errorMessage;\n\t\t\t\t\t\t\t\t\tpartial.usage = proxyEvent.usage;\n\t\t\t\t\t\t\t\t\tevent = { type: \"error\", reason: proxyEvent.reason, error: partial };\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tdefault: {\n\t\t\t\t\t\t\t\t\t// Exhaustive check\n\t\t\t\t\t\t\t\t\tconst _exhaustiveCheck: never = proxyEvent;\n\t\t\t\t\t\t\t\t\tconsole.warn(`Unhandled event type: ${(proxyEvent as any).type}`);\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// Push the event to stream\n\t\t\t\t\t\t\tif (event) {\n\t\t\t\t\t\t\t\tstream.push(event);\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tthrow new Error(\"Failed to create event from proxy event\");\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Check if aborted after reading\n\t\t\tif (options.signal?.aborted) {\n\t\t\t\tthrow new Error(\"Request aborted by user\");\n\t\t\t}\n\n\t\t\tstream.end();\n\t\t} catch (error) {\n\t\t\tconst errorMessage = error instanceof Error ? error.message : String(error);\n\t\t\tpartial.stopReason = options.signal?.aborted ? \"aborted\" : \"error\";\n\t\t\tpartial.errorMessage = errorMessage;\n\t\t\tstream.push({\n\t\t\t\ttype: \"error\",\n\t\t\t\treason: partial.stopReason,\n\t\t\t\terror: partial,\n\t\t\t} satisfies AssistantMessageEvent);\n\t\t\tstream.end();\n\t\t} finally {\n\t\t\t// Clean up abort handler\n\t\t\tif (options.signal) {\n\t\t\t\toptions.signal.removeEventListener(\"abort\", abortHandler);\n\t\t\t}\n\t\t}\n\t})();\n\n\treturn stream;\n}\n\nexport interface AppTransportOptions {\n\t/**\n\t * Proxy server URL. The server manages user accounts and proxies requests to LLM providers.\n\t * Example: \"https://genai.mariozechner.at\"\n\t */\n\tproxyUrl: string;\n\n\t/**\n\t * Function to retrieve auth token for the proxy server.\n\t * The token is used for user authentication and authorization.\n\t */\n\tgetAuthToken: () => Promise<string> | string;\n}\n\n/**\n * Transport that uses an app server with user authentication tokens.\n * The server manages user accounts and proxies requests to LLM providers.\n */\nexport class AppTransport implements AgentTransport {\n\tprivate options: AppTransportOptions;\n\n\tconstructor(options: AppTransportOptions) {\n\t\tthis.options = options;\n\t}\n\n\tasync *run(messages: Message[], userMessage: Message, cfg: AgentRunConfig, signal?: AbortSignal) {\n\t\tconst authToken = await this.options.getAuthToken();\n\t\tif (!authToken) {\n\t\t\tthrow new Error(\"Auth token is required for AppTransport\");\n\t\t}\n\n\t\t// Use proxy - no local API key needed\n\t\tconst streamFn = <TApi extends Api>(model: Model<TApi>, context: Context, options?: SimpleStreamOptions) => {\n\t\t\treturn streamSimpleProxy(\n\t\t\t\tmodel,\n\t\t\t\tcontext,\n\t\t\t\t{\n\t\t\t\t\t...options,\n\t\t\t\t\tauthToken,\n\t\t\t\t},\n\t\t\t\tthis.options.proxyUrl,\n\t\t\t);\n\t\t};\n\n\t\t// Messages are already LLM-compatible (filtered by Agent)\n\t\tconst context: AgentContext = {\n\t\t\tsystemPrompt: cfg.systemPrompt,\n\t\t\tmessages,\n\t\t\ttools: cfg.tools,\n\t\t};\n\n\t\tconst pc: AgentLoopConfig = {\n\t\t\tmodel: cfg.model,\n\t\t\treasoning: cfg.reasoning,\n\t\t\tgetQueuedMessages: cfg.getQueuedMessages,\n\t\t};\n\n\t\t// Yield events from the upstream agentLoop iterator\n\t\t// Pass streamFn as the 5th parameter to use proxy\n\t\tfor await (const ev of agentLoop(userMessage as unknown as UserMessage, context, pc, signal, streamFn as any)) {\n\t\t\tyield ev;\n\t\t}\n\t}\n}\n"]}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { type Message } from "@mariozechner/pi-ai";
|
|
2
|
+
import type { AgentRunConfig, AgentTransport } from "./types.js";
|
|
3
|
+
export interface ProviderTransportOptions {
|
|
4
|
+
/**
|
|
5
|
+
* Function to retrieve API key for a given provider.
|
|
6
|
+
* If not provided, transport will try to use environment variables.
|
|
7
|
+
*/
|
|
8
|
+
getApiKey?: (provider: string) => Promise<string | undefined> | string | undefined;
|
|
9
|
+
/**
|
|
10
|
+
* Optional CORS proxy URL for browser environments.
|
|
11
|
+
* If provided, all requests will be routed through this proxy.
|
|
12
|
+
* Format: "https://proxy.example.com"
|
|
13
|
+
*/
|
|
14
|
+
corsProxyUrl?: string;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Transport that calls LLM providers directly.
|
|
18
|
+
* Optionally routes calls through a CORS proxy if configured.
|
|
19
|
+
*/
|
|
20
|
+
export declare class ProviderTransport implements AgentTransport {
|
|
21
|
+
private options;
|
|
22
|
+
constructor(options?: ProviderTransportOptions);
|
|
23
|
+
run(messages: Message[], userMessage: Message, cfg: AgentRunConfig, signal?: AbortSignal): AsyncGenerator<import("@mariozechner/pi-ai").AgentEvent, void, unknown>;
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=ProviderTransport.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ProviderTransport.d.ts","sourceRoot":"","sources":["../../src/transports/ProviderTransport.ts"],"names":[],"mappings":"AAAA,OAAO,EAIN,KAAK,OAAO,EAEZ,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjE,MAAM,WAAW,wBAAwB;IACxC;;;OAGG;IACH,SAAS,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,GAAG,MAAM,GAAG,SAAS,CAAC;IAEnF;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;GAGG;AACH,qBAAa,iBAAkB,YAAW,cAAc;IACvD,OAAO,CAAC,OAAO,CAA2B;IAE1C,YAAY,OAAO,GAAE,wBAA6B,EAEjD;IAEM,GAAG,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,WAAW,EAAE,OAAO,EAAE,GAAG,EAAE,cAAc,EAAE,MAAM,CAAC,EAAE,WAAW,2EAsC9F;CACD","sourcesContent":["import {\n\ttype AgentContext,\n\ttype AgentLoopConfig,\n\tagentLoop,\n\ttype Message,\n\ttype UserMessage,\n} from \"@mariozechner/pi-ai\";\nimport type { AgentRunConfig, AgentTransport } from \"./types.js\";\n\nexport interface ProviderTransportOptions {\n\t/**\n\t * Function to retrieve API key for a given provider.\n\t * If not provided, transport will try to use environment variables.\n\t */\n\tgetApiKey?: (provider: string) => Promise<string | undefined> | string | undefined;\n\n\t/**\n\t * Optional CORS proxy URL for browser environments.\n\t * If provided, all requests will be routed through this proxy.\n\t * Format: \"https://proxy.example.com\"\n\t */\n\tcorsProxyUrl?: string;\n}\n\n/**\n * Transport that calls LLM providers directly.\n * Optionally routes calls through a CORS proxy if configured.\n */\nexport class ProviderTransport implements AgentTransport {\n\tprivate options: ProviderTransportOptions;\n\n\tconstructor(options: ProviderTransportOptions = {}) {\n\t\tthis.options = options;\n\t}\n\n\tasync *run(messages: Message[], userMessage: Message, cfg: AgentRunConfig, signal?: AbortSignal) {\n\t\t// Get API key\n\t\tlet apiKey: string | undefined;\n\t\tif (this.options.getApiKey) {\n\t\t\tapiKey = await this.options.getApiKey(cfg.model.provider);\n\t\t}\n\n\t\tif (!apiKey) {\n\t\t\tthrow new Error(`No API key found for provider: ${cfg.model.provider}`);\n\t\t}\n\n\t\t// Clone model and modify baseUrl if CORS proxy is enabled\n\t\tlet model = cfg.model;\n\t\tif (this.options.corsProxyUrl && cfg.model.baseUrl) {\n\t\t\tmodel = {\n\t\t\t\t...cfg.model,\n\t\t\t\tbaseUrl: `${this.options.corsProxyUrl}/?url=${encodeURIComponent(cfg.model.baseUrl)}`,\n\t\t\t};\n\t\t}\n\n\t\t// Messages are already LLM-compatible (filtered by Agent)\n\t\tconst context: AgentContext = {\n\t\t\tsystemPrompt: cfg.systemPrompt,\n\t\t\tmessages,\n\t\t\ttools: cfg.tools,\n\t\t};\n\n\t\tconst pc: AgentLoopConfig = {\n\t\t\tmodel,\n\t\t\treasoning: cfg.reasoning,\n\t\t\tapiKey,\n\t\t\tgetQueuedMessages: cfg.getQueuedMessages,\n\t\t};\n\n\t\t// Yield events from agentLoop\n\t\tfor await (const ev of agentLoop(userMessage as unknown as UserMessage, context, pc, signal)) {\n\t\t\tyield ev;\n\t\t}\n\t}\n}\n"]}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { agentLoop, } from "@mariozechner/pi-ai";
|
|
2
|
+
/**
|
|
3
|
+
* Transport that calls LLM providers directly.
|
|
4
|
+
* Optionally routes calls through a CORS proxy if configured.
|
|
5
|
+
*/
|
|
6
|
+
export class ProviderTransport {
|
|
7
|
+
options;
|
|
8
|
+
constructor(options = {}) {
|
|
9
|
+
this.options = options;
|
|
10
|
+
}
|
|
11
|
+
async *run(messages, userMessage, cfg, signal) {
|
|
12
|
+
// Get API key
|
|
13
|
+
let apiKey;
|
|
14
|
+
if (this.options.getApiKey) {
|
|
15
|
+
apiKey = await this.options.getApiKey(cfg.model.provider);
|
|
16
|
+
}
|
|
17
|
+
if (!apiKey) {
|
|
18
|
+
throw new Error(`No API key found for provider: ${cfg.model.provider}`);
|
|
19
|
+
}
|
|
20
|
+
// Clone model and modify baseUrl if CORS proxy is enabled
|
|
21
|
+
let model = cfg.model;
|
|
22
|
+
if (this.options.corsProxyUrl && cfg.model.baseUrl) {
|
|
23
|
+
model = {
|
|
24
|
+
...cfg.model,
|
|
25
|
+
baseUrl: `${this.options.corsProxyUrl}/?url=${encodeURIComponent(cfg.model.baseUrl)}`,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
// Messages are already LLM-compatible (filtered by Agent)
|
|
29
|
+
const context = {
|
|
30
|
+
systemPrompt: cfg.systemPrompt,
|
|
31
|
+
messages,
|
|
32
|
+
tools: cfg.tools,
|
|
33
|
+
};
|
|
34
|
+
const pc = {
|
|
35
|
+
model,
|
|
36
|
+
reasoning: cfg.reasoning,
|
|
37
|
+
apiKey,
|
|
38
|
+
getQueuedMessages: cfg.getQueuedMessages,
|
|
39
|
+
};
|
|
40
|
+
// Yield events from agentLoop
|
|
41
|
+
for await (const ev of agentLoop(userMessage, context, pc, signal)) {
|
|
42
|
+
yield ev;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=ProviderTransport.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ProviderTransport.js","sourceRoot":"","sources":["../../src/transports/ProviderTransport.ts"],"names":[],"mappings":"AAAA,OAAO,EAGN,SAAS,GAGT,MAAM,qBAAqB,CAAC;AAkB7B;;;GAGG;AACH,MAAM,OAAO,iBAAiB;IACrB,OAAO,CAA2B;IAE1C,YAAY,OAAO,GAA6B,EAAE,EAAE;QACnD,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IAAA,CACvB;IAED,KAAK,CAAC,CAAC,GAAG,CAAC,QAAmB,EAAE,WAAoB,EAAE,GAAmB,EAAE,MAAoB,EAAE;QAChG,cAAc;QACd,IAAI,MAA0B,CAAC;QAC/B,IAAI,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC;YAC5B,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QAC3D,CAAC;QAED,IAAI,CAAC,MAAM,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CAAC,kCAAkC,GAAG,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;QACzE,CAAC;QAED,0DAA0D;QAC1D,IAAI,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC;QACtB,IAAI,IAAI,CAAC,OAAO,CAAC,YAAY,IAAI,GAAG,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;YACpD,KAAK,GAAG;gBACP,GAAG,GAAG,CAAC,KAAK;gBACZ,OAAO,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,SAAS,kBAAkB,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE;aACrF,CAAC;QACH,CAAC;QAED,0DAA0D;QAC1D,MAAM,OAAO,GAAiB;YAC7B,YAAY,EAAE,GAAG,CAAC,YAAY;YAC9B,QAAQ;YACR,KAAK,EAAE,GAAG,CAAC,KAAK;SAChB,CAAC;QAEF,MAAM,EAAE,GAAoB;YAC3B,KAAK;YACL,SAAS,EAAE,GAAG,CAAC,SAAS;YACxB,MAAM;YACN,iBAAiB,EAAE,GAAG,CAAC,iBAAiB;SACxC,CAAC;QAEF,8BAA8B;QAC9B,IAAI,KAAK,EAAE,MAAM,EAAE,IAAI,SAAS,CAAC,WAAqC,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,CAAC;YAC9F,MAAM,EAAE,CAAC;QACV,CAAC;IAAA,CACD;CACD","sourcesContent":["import {\n\ttype AgentContext,\n\ttype AgentLoopConfig,\n\tagentLoop,\n\ttype Message,\n\ttype UserMessage,\n} from \"@mariozechner/pi-ai\";\nimport type { AgentRunConfig, AgentTransport } from \"./types.js\";\n\nexport interface ProviderTransportOptions {\n\t/**\n\t * Function to retrieve API key for a given provider.\n\t * If not provided, transport will try to use environment variables.\n\t */\n\tgetApiKey?: (provider: string) => Promise<string | undefined> | string | undefined;\n\n\t/**\n\t * Optional CORS proxy URL for browser environments.\n\t * If provided, all requests will be routed through this proxy.\n\t * Format: \"https://proxy.example.com\"\n\t */\n\tcorsProxyUrl?: string;\n}\n\n/**\n * Transport that calls LLM providers directly.\n * Optionally routes calls through a CORS proxy if configured.\n */\nexport class ProviderTransport implements AgentTransport {\n\tprivate options: ProviderTransportOptions;\n\n\tconstructor(options: ProviderTransportOptions = {}) {\n\t\tthis.options = options;\n\t}\n\n\tasync *run(messages: Message[], userMessage: Message, cfg: AgentRunConfig, signal?: AbortSignal) {\n\t\t// Get API key\n\t\tlet apiKey: string | undefined;\n\t\tif (this.options.getApiKey) {\n\t\t\tapiKey = await this.options.getApiKey(cfg.model.provider);\n\t\t}\n\n\t\tif (!apiKey) {\n\t\t\tthrow new Error(`No API key found for provider: ${cfg.model.provider}`);\n\t\t}\n\n\t\t// Clone model and modify baseUrl if CORS proxy is enabled\n\t\tlet model = cfg.model;\n\t\tif (this.options.corsProxyUrl && cfg.model.baseUrl) {\n\t\t\tmodel = {\n\t\t\t\t...cfg.model,\n\t\t\t\tbaseUrl: `${this.options.corsProxyUrl}/?url=${encodeURIComponent(cfg.model.baseUrl)}`,\n\t\t\t};\n\t\t}\n\n\t\t// Messages are already LLM-compatible (filtered by Agent)\n\t\tconst context: AgentContext = {\n\t\t\tsystemPrompt: cfg.systemPrompt,\n\t\t\tmessages,\n\t\t\ttools: cfg.tools,\n\t\t};\n\n\t\tconst pc: AgentLoopConfig = {\n\t\t\tmodel,\n\t\t\treasoning: cfg.reasoning,\n\t\t\tapiKey,\n\t\t\tgetQueuedMessages: cfg.getQueuedMessages,\n\t\t};\n\n\t\t// Yield events from agentLoop\n\t\tfor await (const ev of agentLoop(userMessage as unknown as UserMessage, context, pc, signal)) {\n\t\t\tyield ev;\n\t\t}\n\t}\n}\n"]}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { AppTransport, type AppTransportOptions } from "./AppTransport.js";
|
|
2
|
+
export { ProviderTransport, type ProviderTransportOptions } from "./ProviderTransport.js";
|
|
3
|
+
export type { ProxyAssistantMessageEvent } from "./proxy-types.js";
|
|
4
|
+
export type { AgentRunConfig, AgentTransport } from "./types.js";
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/transports/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,KAAK,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAC3E,OAAO,EAAE,iBAAiB,EAAE,KAAK,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAC1F,YAAY,EAAE,0BAA0B,EAAE,MAAM,kBAAkB,CAAC;AACnE,YAAY,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC","sourcesContent":["export { AppTransport, type AppTransportOptions } from \"./AppTransport.js\";\nexport { ProviderTransport, type ProviderTransportOptions } from \"./ProviderTransport.js\";\nexport type { ProxyAssistantMessageEvent } from \"./proxy-types.js\";\nexport type { AgentRunConfig, AgentTransport } from \"./types.js\";\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/transports/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAA4B,MAAM,mBAAmB,CAAC;AAC3E,OAAO,EAAE,iBAAiB,EAAiC,MAAM,wBAAwB,CAAC","sourcesContent":["export { AppTransport, type AppTransportOptions } from \"./AppTransport.js\";\nexport { ProviderTransport, type ProviderTransportOptions } from \"./ProviderTransport.js\";\nexport type { ProxyAssistantMessageEvent } from \"./proxy-types.js\";\nexport type { AgentRunConfig, AgentTransport } from \"./types.js\";\n"]}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import type { StopReason, Usage } from "@mariozechner/pi-ai";
|
|
2
|
+
/**
|
|
3
|
+
* Event types emitted by the proxy server.
|
|
4
|
+
* The server strips the `partial` field from delta events to reduce bandwidth.
|
|
5
|
+
* Clients reconstruct the partial message from these events.
|
|
6
|
+
*/
|
|
7
|
+
export type ProxyAssistantMessageEvent = {
|
|
8
|
+
type: "start";
|
|
9
|
+
} | {
|
|
10
|
+
type: "text_start";
|
|
11
|
+
contentIndex: number;
|
|
12
|
+
} | {
|
|
13
|
+
type: "text_delta";
|
|
14
|
+
contentIndex: number;
|
|
15
|
+
delta: string;
|
|
16
|
+
} | {
|
|
17
|
+
type: "text_end";
|
|
18
|
+
contentIndex: number;
|
|
19
|
+
contentSignature?: string;
|
|
20
|
+
} | {
|
|
21
|
+
type: "thinking_start";
|
|
22
|
+
contentIndex: number;
|
|
23
|
+
} | {
|
|
24
|
+
type: "thinking_delta";
|
|
25
|
+
contentIndex: number;
|
|
26
|
+
delta: string;
|
|
27
|
+
} | {
|
|
28
|
+
type: "thinking_end";
|
|
29
|
+
contentIndex: number;
|
|
30
|
+
contentSignature?: string;
|
|
31
|
+
} | {
|
|
32
|
+
type: "toolcall_start";
|
|
33
|
+
contentIndex: number;
|
|
34
|
+
id: string;
|
|
35
|
+
toolName: string;
|
|
36
|
+
} | {
|
|
37
|
+
type: "toolcall_delta";
|
|
38
|
+
contentIndex: number;
|
|
39
|
+
delta: string;
|
|
40
|
+
} | {
|
|
41
|
+
type: "toolcall_end";
|
|
42
|
+
contentIndex: number;
|
|
43
|
+
} | {
|
|
44
|
+
type: "done";
|
|
45
|
+
reason: Extract<StopReason, "stop" | "length" | "toolUse">;
|
|
46
|
+
usage: Usage;
|
|
47
|
+
} | {
|
|
48
|
+
type: "error";
|
|
49
|
+
reason: Extract<StopReason, "aborted" | "error">;
|
|
50
|
+
errorMessage: string;
|
|
51
|
+
usage: Usage;
|
|
52
|
+
};
|
|
53
|
+
//# sourceMappingURL=proxy-types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proxy-types.d.ts","sourceRoot":"","sources":["../../src/transports/proxy-types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAE7D;;;;GAIG;AACH,MAAM,MAAM,0BAA0B,GACnC;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,GACjB;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,GAC5C;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAC3D;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,gBAAgB,CAAC,EAAE,MAAM,CAAA;CAAE,GACrE;IAAE,IAAI,EAAE,gBAAgB,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,GAChD;IAAE,IAAI,EAAE,gBAAgB,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAC/D;IAAE,IAAI,EAAE,cAAc,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,gBAAgB,CAAC,EAAE,MAAM,CAAA;CAAE,GACzE;IAAE,IAAI,EAAE,gBAAgB,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAC9E;IAAE,IAAI,EAAE,gBAAgB,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAC/D;IAAE,IAAI,EAAE,cAAc,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,GAC9C;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,OAAO,CAAC,UAAU,EAAE,MAAM,GAAG,QAAQ,GAAG,SAAS,CAAC,CAAC;IAAC,KAAK,EAAE,KAAK,CAAA;CAAE,GAC1F;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,OAAO,CAAC,UAAU,EAAE,SAAS,GAAG,OAAO,CAAC,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,KAAK,CAAA;CAAE,CAAC","sourcesContent":["import type { StopReason, Usage } from \"@mariozechner/pi-ai\";\n\n/**\n * Event types emitted by the proxy server.\n * The server strips the `partial` field from delta events to reduce bandwidth.\n * Clients reconstruct the partial message from these events.\n */\nexport type ProxyAssistantMessageEvent =\n\t| { type: \"start\" }\n\t| { type: \"text_start\"; contentIndex: number }\n\t| { type: \"text_delta\"; contentIndex: number; delta: string }\n\t| { type: \"text_end\"; contentIndex: number; contentSignature?: string }\n\t| { type: \"thinking_start\"; contentIndex: number }\n\t| { type: \"thinking_delta\"; contentIndex: number; delta: string }\n\t| { type: \"thinking_end\"; contentIndex: number; contentSignature?: string }\n\t| { type: \"toolcall_start\"; contentIndex: number; id: string; toolName: string }\n\t| { type: \"toolcall_delta\"; contentIndex: number; delta: string }\n\t| { type: \"toolcall_end\"; contentIndex: number }\n\t| { type: \"done\"; reason: Extract<StopReason, \"stop\" | \"length\" | \"toolUse\">; usage: Usage }\n\t| { type: \"error\"; reason: Extract<StopReason, \"aborted\" | \"error\">; errorMessage: string; usage: Usage };\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proxy-types.js","sourceRoot":"","sources":["../../src/transports/proxy-types.ts"],"names":[],"mappings":"","sourcesContent":["import type { StopReason, Usage } from \"@mariozechner/pi-ai\";\n\n/**\n * Event types emitted by the proxy server.\n * The server strips the `partial` field from delta events to reduce bandwidth.\n * Clients reconstruct the partial message from these events.\n */\nexport type ProxyAssistantMessageEvent =\n\t| { type: \"start\" }\n\t| { type: \"text_start\"; contentIndex: number }\n\t| { type: \"text_delta\"; contentIndex: number; delta: string }\n\t| { type: \"text_end\"; contentIndex: number; contentSignature?: string }\n\t| { type: \"thinking_start\"; contentIndex: number }\n\t| { type: \"thinking_delta\"; contentIndex: number; delta: string }\n\t| { type: \"thinking_end\"; contentIndex: number; contentSignature?: string }\n\t| { type: \"toolcall_start\"; contentIndex: number; id: string; toolName: string }\n\t| { type: \"toolcall_delta\"; contentIndex: number; delta: string }\n\t| { type: \"toolcall_end\"; contentIndex: number }\n\t| { type: \"done\"; reason: Extract<StopReason, \"stop\" | \"length\" | \"toolUse\">; usage: Usage }\n\t| { type: \"error\"; reason: Extract<StopReason, \"aborted\" | \"error\">; errorMessage: string; usage: Usage };\n"]}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { AgentEvent, AgentTool, Message, Model, QueuedMessage } from "@mariozechner/pi-ai";
|
|
2
|
+
/**
|
|
3
|
+
* The minimal configuration needed to run an agent turn.
|
|
4
|
+
*/
|
|
5
|
+
export interface AgentRunConfig {
|
|
6
|
+
systemPrompt: string;
|
|
7
|
+
tools: AgentTool<any>[];
|
|
8
|
+
model: Model<any>;
|
|
9
|
+
reasoning?: "low" | "medium" | "high";
|
|
10
|
+
getQueuedMessages?: <T>() => Promise<QueuedMessage<T>[]>;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Transport interface for executing agent turns.
|
|
14
|
+
* Transports handle the communication with LLM providers,
|
|
15
|
+
* abstracting away the details of API calls, proxies, etc.
|
|
16
|
+
*
|
|
17
|
+
* Events yielded must match the @mariozechner/pi-ai AgentEvent types.
|
|
18
|
+
*/
|
|
19
|
+
export interface AgentTransport {
|
|
20
|
+
run(messages: Message[], userMessage: Message, config: AgentRunConfig, signal?: AbortSignal): AsyncIterable<AgentEvent>;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/transports/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEhG;;GAEG;AACH,MAAM,WAAW,cAAc;IAC9B,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC;IACxB,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;IAClB,SAAS,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;IACtC,iBAAiB,CAAC,EAAE,CAAC,CAAC,OAAO,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;CACzD;AAED;;;;;;GAMG;AACH,MAAM,WAAW,cAAc;IAC9B,GAAG,CACF,QAAQ,EAAE,OAAO,EAAE,EACnB,WAAW,EAAE,OAAO,EACpB,MAAM,EAAE,cAAc,EACtB,MAAM,CAAC,EAAE,WAAW,GAClB,aAAa,CAAC,UAAU,CAAC,CAAC;CAC7B","sourcesContent":["import type { AgentEvent, AgentTool, Message, Model, QueuedMessage } from \"@mariozechner/pi-ai\";\n\n/**\n * The minimal configuration needed to run an agent turn.\n */\nexport interface AgentRunConfig {\n\tsystemPrompt: string;\n\ttools: AgentTool<any>[];\n\tmodel: Model<any>;\n\treasoning?: \"low\" | \"medium\" | \"high\";\n\tgetQueuedMessages?: <T>() => Promise<QueuedMessage<T>[]>;\n}\n\n/**\n * Transport interface for executing agent turns.\n * Transports handle the communication with LLM providers,\n * abstracting away the details of API calls, proxies, etc.\n *\n * Events yielded must match the @mariozechner/pi-ai AgentEvent types.\n */\nexport interface AgentTransport {\n\trun(\n\t\tmessages: Message[],\n\t\tuserMessage: Message,\n\t\tconfig: AgentRunConfig,\n\t\tsignal?: AbortSignal,\n\t): AsyncIterable<AgentEvent>;\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/transports/types.ts"],"names":[],"mappings":"","sourcesContent":["import type { AgentEvent, AgentTool, Message, Model, QueuedMessage } from \"@mariozechner/pi-ai\";\n\n/**\n * The minimal configuration needed to run an agent turn.\n */\nexport interface AgentRunConfig {\n\tsystemPrompt: string;\n\ttools: AgentTool<any>[];\n\tmodel: Model<any>;\n\treasoning?: \"low\" | \"medium\" | \"high\";\n\tgetQueuedMessages?: <T>() => Promise<QueuedMessage<T>[]>;\n}\n\n/**\n * Transport interface for executing agent turns.\n * Transports handle the communication with LLM providers,\n * abstracting away the details of API calls, proxies, etc.\n *\n * Events yielded must match the @mariozechner/pi-ai AgentEvent types.\n */\nexport interface AgentTransport {\n\trun(\n\t\tmessages: Message[],\n\t\tuserMessage: Message,\n\t\tconfig: AgentRunConfig,\n\t\tsignal?: AbortSignal,\n\t): AsyncIterable<AgentEvent>;\n}\n"]}
|