@mariozechner/pi-web-ui 0.30.1 → 0.31.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/CHANGELOG.md +88 -0
- package/README.md +420 -150
- package/dist/ChatPanel.d.ts +1 -2
- package/dist/ChatPanel.d.ts.map +1 -1
- package/dist/ChatPanel.js +22 -45
- package/dist/ChatPanel.js.map +1 -1
- package/dist/components/AgentInterface.d.ts +1 -1
- package/dist/components/AgentInterface.d.ts.map +1 -1
- package/dist/components/AgentInterface.js +113 -91
- package/dist/components/AgentInterface.js.map +1 -1
- package/dist/components/AttachmentTile.d.ts.map +1 -1
- package/dist/components/AttachmentTile.js +12 -28
- package/dist/components/AttachmentTile.js.map +1 -1
- package/dist/components/ConsoleBlock.d.ts.map +1 -1
- package/dist/components/ConsoleBlock.js +6 -21
- package/dist/components/ConsoleBlock.js.map +1 -1
- package/dist/components/CustomProviderCard.d.ts.map +1 -1
- package/dist/components/CustomProviderCard.js +15 -34
- package/dist/components/CustomProviderCard.js.map +1 -1
- package/dist/components/ExpandableSection.d.ts.map +1 -1
- package/dist/components/ExpandableSection.js +10 -27
- package/dist/components/ExpandableSection.js.map +1 -1
- package/dist/components/Input.js.map +1 -1
- package/dist/components/MessageEditor.d.ts +2 -1
- package/dist/components/MessageEditor.d.ts.map +1 -1
- package/dist/components/MessageEditor.js +147 -190
- package/dist/components/MessageEditor.js.map +1 -1
- package/dist/components/MessageList.d.ts +2 -3
- package/dist/components/MessageList.d.ts.map +1 -1
- package/dist/components/MessageList.js +11 -28
- package/dist/components/MessageList.js.map +1 -1
- package/dist/components/Messages.d.ts +37 -7
- package/dist/components/Messages.d.ts.map +1 -1
- package/dist/components/Messages.js +127 -103
- package/dist/components/Messages.js.map +1 -1
- package/dist/components/ProviderKeyInput.d.ts.map +1 -1
- package/dist/components/ProviderKeyInput.js +15 -39
- package/dist/components/ProviderKeyInput.js.map +1 -1
- package/dist/components/SandboxedIframe.d.ts.map +1 -1
- package/dist/components/SandboxedIframe.js +11 -15
- package/dist/components/SandboxedIframe.js.map +1 -1
- package/dist/components/StreamingMessageContainer.d.ts +3 -2
- package/dist/components/StreamingMessageContainer.d.ts.map +1 -1
- package/dist/components/StreamingMessageContainer.js +16 -34
- package/dist/components/StreamingMessageContainer.js.map +1 -1
- package/dist/components/ThinkingBlock.d.ts.map +1 -1
- package/dist/components/ThinkingBlock.js +9 -26
- package/dist/components/ThinkingBlock.js.map +1 -1
- package/dist/components/message-renderer-registry.d.ts +5 -5
- package/dist/components/message-renderer-registry.d.ts.map +1 -1
- package/dist/components/message-renderer-registry.js.map +1 -1
- package/dist/components/sandbox/ArtifactsRuntimeProvider.d.ts.map +1 -1
- package/dist/components/sandbox/ArtifactsRuntimeProvider.js +3 -0
- package/dist/components/sandbox/ArtifactsRuntimeProvider.js.map +1 -1
- package/dist/components/sandbox/AttachmentsRuntimeProvider.d.ts.map +1 -1
- package/dist/components/sandbox/AttachmentsRuntimeProvider.js +1 -0
- package/dist/components/sandbox/AttachmentsRuntimeProvider.js.map +1 -1
- package/dist/components/sandbox/ConsoleRuntimeProvider.d.ts.map +1 -1
- package/dist/components/sandbox/ConsoleRuntimeProvider.js +3 -5
- package/dist/components/sandbox/ConsoleRuntimeProvider.js.map +1 -1
- package/dist/components/sandbox/FileDownloadRuntimeProvider.d.ts.map +1 -1
- package/dist/components/sandbox/FileDownloadRuntimeProvider.js +1 -3
- package/dist/components/sandbox/FileDownloadRuntimeProvider.js.map +1 -1
- package/dist/components/sandbox/RuntimeMessageBridge.d.ts.map +1 -1
- package/dist/components/sandbox/RuntimeMessageBridge.js.map +1 -1
- package/dist/components/sandbox/RuntimeMessageRouter.d.ts.map +1 -1
- package/dist/components/sandbox/RuntimeMessageRouter.js +3 -5
- package/dist/components/sandbox/RuntimeMessageRouter.js.map +1 -1
- package/dist/dialogs/ApiKeyPromptDialog.d.ts.map +1 -1
- package/dist/dialogs/ApiKeyPromptDialog.js +10 -23
- package/dist/dialogs/ApiKeyPromptDialog.js.map +1 -1
- package/dist/dialogs/AttachmentOverlay.d.ts.map +1 -1
- package/dist/dialogs/AttachmentOverlay.js +34 -46
- package/dist/dialogs/AttachmentOverlay.js.map +1 -1
- package/dist/dialogs/CustomProviderDialog.d.ts.map +1 -1
- package/dist/dialogs/CustomProviderDialog.js +19 -39
- package/dist/dialogs/CustomProviderDialog.js.map +1 -1
- package/dist/dialogs/ModelSelector.d.ts.map +1 -1
- package/dist/dialogs/ModelSelector.js +25 -53
- package/dist/dialogs/ModelSelector.js.map +1 -1
- package/dist/dialogs/PersistentStorageDialog.d.ts.map +1 -1
- package/dist/dialogs/PersistentStorageDialog.js +9 -23
- package/dist/dialogs/PersistentStorageDialog.js.map +1 -1
- package/dist/dialogs/ProvidersModelsTab.d.ts.map +1 -1
- package/dist/dialogs/ProvidersModelsTab.js +7 -23
- package/dist/dialogs/ProvidersModelsTab.js.map +1 -1
- package/dist/dialogs/SessionListDialog.d.ts.map +1 -1
- package/dist/dialogs/SessionListDialog.js +14 -29
- package/dist/dialogs/SessionListDialog.js.map +1 -1
- package/dist/dialogs/SettingsDialog.d.ts.map +1 -1
- package/dist/dialogs/SettingsDialog.js +20 -52
- package/dist/dialogs/SettingsDialog.js.map +1 -1
- package/dist/index.d.ts +5 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -6
- package/dist/index.js.map +1 -1
- package/dist/prompts/prompts.d.ts.map +1 -1
- package/dist/storage/app-storage.d.ts.map +1 -1
- package/dist/storage/app-storage.js +5 -0
- package/dist/storage/app-storage.js.map +1 -1
- package/dist/storage/backends/indexeddb-storage-backend.d.ts.map +1 -1
- package/dist/storage/backends/indexeddb-storage-backend.js +2 -1
- package/dist/storage/backends/indexeddb-storage-backend.js.map +1 -1
- package/dist/storage/store.d.ts.map +1 -1
- package/dist/storage/store.js +1 -3
- package/dist/storage/store.js.map +1 -1
- package/dist/storage/stores/custom-providers-store.d.ts.map +1 -1
- package/dist/storage/stores/custom-providers-store.js.map +1 -1
- package/dist/storage/stores/provider-keys-store.d.ts.map +1 -1
- package/dist/storage/stores/provider-keys-store.js.map +1 -1
- package/dist/storage/stores/sessions-store.d.ts +1 -1
- package/dist/storage/stores/sessions-store.d.ts.map +1 -1
- package/dist/storage/stores/sessions-store.js.map +1 -1
- package/dist/storage/stores/settings-store.d.ts.map +1 -1
- package/dist/storage/stores/settings-store.js.map +1 -1
- package/dist/storage/types.d.ts +2 -3
- package/dist/storage/types.d.ts.map +1 -1
- package/dist/tools/artifacts/ArtifactElement.d.ts.map +1 -1
- package/dist/tools/artifacts/ArtifactElement.js +1 -4
- package/dist/tools/artifacts/ArtifactElement.js.map +1 -1
- package/dist/tools/artifacts/ArtifactPill.js.map +1 -1
- package/dist/tools/artifacts/Console.d.ts.map +1 -1
- package/dist/tools/artifacts/Console.js +10 -28
- package/dist/tools/artifacts/Console.js.map +1 -1
- package/dist/tools/artifacts/DocxArtifact.d.ts.map +1 -1
- package/dist/tools/artifacts/DocxArtifact.js +7 -23
- package/dist/tools/artifacts/DocxArtifact.js.map +1 -1
- package/dist/tools/artifacts/ExcelArtifact.d.ts.map +1 -1
- package/dist/tools/artifacts/ExcelArtifact.js +7 -23
- package/dist/tools/artifacts/ExcelArtifact.js.map +1 -1
- package/dist/tools/artifacts/GenericArtifact.d.ts.map +1 -1
- package/dist/tools/artifacts/GenericArtifact.js +5 -19
- package/dist/tools/artifacts/GenericArtifact.js.map +1 -1
- package/dist/tools/artifacts/HtmlArtifact.d.ts.map +1 -1
- package/dist/tools/artifacts/HtmlArtifact.js +16 -35
- package/dist/tools/artifacts/HtmlArtifact.js.map +1 -1
- package/dist/tools/artifacts/ImageArtifact.d.ts.map +1 -1
- package/dist/tools/artifacts/ImageArtifact.js +5 -19
- package/dist/tools/artifacts/ImageArtifact.js.map +1 -1
- package/dist/tools/artifacts/MarkdownArtifact.d.ts.map +1 -1
- package/dist/tools/artifacts/MarkdownArtifact.js +8 -24
- package/dist/tools/artifacts/MarkdownArtifact.js.map +1 -1
- package/dist/tools/artifacts/PdfArtifact.d.ts.map +1 -1
- package/dist/tools/artifacts/PdfArtifact.js +8 -24
- package/dist/tools/artifacts/PdfArtifact.js.map +1 -1
- package/dist/tools/artifacts/SvgArtifact.d.ts.map +1 -1
- package/dist/tools/artifacts/SvgArtifact.js +8 -24
- package/dist/tools/artifacts/SvgArtifact.js.map +1 -1
- package/dist/tools/artifacts/TextArtifact.d.ts.map +1 -1
- package/dist/tools/artifacts/TextArtifact.js +6 -20
- package/dist/tools/artifacts/TextArtifact.js.map +1 -1
- package/dist/tools/artifacts/artifacts-tool-renderer.d.ts.map +1 -1
- package/dist/tools/artifacts/artifacts-tool-renderer.js +1 -0
- package/dist/tools/artifacts/artifacts-tool-renderer.js.map +1 -1
- package/dist/tools/artifacts/artifacts.d.ts +2 -3
- package/dist/tools/artifacts/artifacts.d.ts.map +1 -1
- package/dist/tools/artifacts/artifacts.js +30 -52
- package/dist/tools/artifacts/artifacts.js.map +1 -1
- package/dist/tools/extract-document.d.ts +2 -2
- package/dist/tools/extract-document.d.ts.map +1 -1
- package/dist/tools/extract-document.js.map +1 -1
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/javascript-repl.d.ts +3 -3
- package/dist/tools/javascript-repl.d.ts.map +1 -1
- package/dist/tools/javascript-repl.js.map +1 -1
- package/dist/tools/renderer-registry.js.map +1 -1
- package/dist/tools/renderers/BashRenderer.d.ts.map +1 -1
- package/dist/tools/renderers/BashRenderer.js.map +1 -1
- package/dist/tools/renderers/CalculateRenderer.d.ts.map +1 -1
- package/dist/tools/renderers/CalculateRenderer.js.map +1 -1
- package/dist/tools/renderers/DefaultRenderer.d.ts.map +1 -1
- package/dist/tools/renderers/DefaultRenderer.js.map +1 -1
- package/dist/tools/renderers/GetCurrentTimeRenderer.d.ts.map +1 -1
- package/dist/tools/renderers/GetCurrentTimeRenderer.js.map +1 -1
- package/dist/utils/attachment-utils.js.map +1 -1
- package/dist/utils/auth-token.js.map +1 -1
- package/dist/utils/format.js.map +1 -1
- package/dist/utils/i18n.d.ts +14 -14
- package/dist/utils/i18n.d.ts.map +1 -1
- package/dist/utils/i18n.js.map +1 -1
- package/dist/utils/model-discovery.js.map +1 -1
- package/dist/utils/proxy-utils.d.ts +9 -1
- package/dist/utils/proxy-utils.d.ts.map +1 -1
- package/dist/utils/proxy-utils.js +19 -0
- package/dist/utils/proxy-utils.js.map +1 -1
- package/dist/utils/test-sessions.d.ts +47 -47
- package/dist/utils/test-sessions.js.map +1 -1
- package/example/package.json +1 -1
- package/example/src/custom-messages.ts +26 -36
- package/example/src/main.ts +11 -20
- package/example/tsconfig.json +1 -0
- package/package.json +4 -4
- package/src/ChatPanel.ts +2 -3
- package/src/components/AgentInterface.ts +57 -13
- package/src/components/MessageEditor.ts +2 -1
- package/src/components/MessageList.ts +3 -4
- package/src/components/Messages.ts +108 -19
- package/src/components/StreamingMessageContainer.ts +6 -5
- package/src/components/message-renderer-registry.ts +5 -5
- package/src/index.ts +13 -10
- package/src/storage/stores/sessions-store.ts +1 -1
- package/src/storage/types.ts +2 -3
- package/src/tools/artifacts/artifacts.ts +4 -4
- package/src/tools/extract-document.ts +2 -1
- package/src/tools/javascript-repl.ts +2 -1
- package/src/utils/proxy-utils.ts +23 -1
- package/dist/agent/agent.d.ts +0 -62
- package/dist/agent/agent.d.ts.map +0 -1
- package/dist/agent/agent.js +0 -274
- package/dist/agent/agent.js.map +0 -1
- package/dist/agent/transports/AppTransport.d.ts +0 -15
- package/dist/agent/transports/AppTransport.d.ts.map +0 -1
- package/dist/agent/transports/AppTransport.js +0 -327
- package/dist/agent/transports/AppTransport.js.map +0 -1
- package/dist/agent/transports/ProviderTransport.d.ts +0 -14
- package/dist/agent/transports/ProviderTransport.d.ts.map +0 -1
- package/dist/agent/transports/ProviderTransport.js +0 -55
- package/dist/agent/transports/ProviderTransport.js.map +0 -1
- package/dist/agent/transports/index.d.ts +0 -4
- package/dist/agent/transports/index.d.ts.map +0 -1
- package/dist/agent/transports/index.js +0 -4
- package/dist/agent/transports/index.js.map +0 -1
- package/dist/agent/transports/proxy-types.d.ts +0 -48
- package/dist/agent/transports/proxy-types.d.ts.map +0 -1
- package/dist/agent/transports/proxy-types.js +0 -2
- package/dist/agent/transports/proxy-types.js.map +0 -1
- package/dist/agent/transports/types.d.ts +0 -15
- package/dist/agent/transports/types.d.ts.map +0 -1
- package/dist/agent/transports/types.js +0 -2
- package/dist/agent/transports/types.js.map +0 -1
- package/dist/agent/types.d.ts +0 -15
- package/dist/agent/types.d.ts.map +0 -1
- package/dist/agent/types.js +0 -2
- package/dist/agent/types.js.map +0 -1
- package/example/src/test-sessions.ts +0 -104
- package/src/agent/agent.ts +0 -341
- package/src/agent/transports/AppTransport.ts +0 -371
- package/src/agent/transports/ProviderTransport.ts +0 -71
- package/src/agent/transports/index.ts +0 -3
- package/src/agent/transports/proxy-types.ts +0 -15
- package/src/agent/transports/types.ts +0 -26
- package/src/agent/types.ts +0 -11
|
@@ -1,371 +0,0 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
AgentContext,
|
|
3
|
-
AgentLoopConfig,
|
|
4
|
-
Api,
|
|
5
|
-
AssistantMessage,
|
|
6
|
-
AssistantMessageEvent,
|
|
7
|
-
Context,
|
|
8
|
-
Message,
|
|
9
|
-
Model,
|
|
10
|
-
SimpleStreamOptions,
|
|
11
|
-
ToolCall,
|
|
12
|
-
UserMessage,
|
|
13
|
-
} from "@mariozechner/pi-ai";
|
|
14
|
-
import { agentLoop, agentLoopContinue } from "@mariozechner/pi-ai";
|
|
15
|
-
import { AssistantMessageEventStream } from "@mariozechner/pi-ai/dist/utils/event-stream.js";
|
|
16
|
-
import { parseStreamingJson } from "@mariozechner/pi-ai/dist/utils/json-parse.js";
|
|
17
|
-
import { clearAuthToken, getAuthToken } from "../../utils/auth-token.js";
|
|
18
|
-
import { i18n } from "../../utils/i18n.js";
|
|
19
|
-
import type { ProxyAssistantMessageEvent } from "./proxy-types.js";
|
|
20
|
-
import type { AgentRunConfig, AgentTransport } from "./types.js";
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Stream function that proxies through a server instead of calling providers directly.
|
|
24
|
-
* The server strips the partial field from delta events to reduce bandwidth.
|
|
25
|
-
* We reconstruct the partial message client-side.
|
|
26
|
-
*/
|
|
27
|
-
function streamSimpleProxy(
|
|
28
|
-
model: Model<any>,
|
|
29
|
-
context: Context,
|
|
30
|
-
options: SimpleStreamOptions & { authToken: string },
|
|
31
|
-
proxyUrl: string,
|
|
32
|
-
): AssistantMessageEventStream {
|
|
33
|
-
const stream = new AssistantMessageEventStream();
|
|
34
|
-
|
|
35
|
-
(async () => {
|
|
36
|
-
// Initialize the partial message that we'll build up from events
|
|
37
|
-
const partial: AssistantMessage = {
|
|
38
|
-
role: "assistant",
|
|
39
|
-
stopReason: "stop",
|
|
40
|
-
content: [],
|
|
41
|
-
api: model.api,
|
|
42
|
-
provider: model.provider,
|
|
43
|
-
model: model.id,
|
|
44
|
-
usage: {
|
|
45
|
-
input: 0,
|
|
46
|
-
output: 0,
|
|
47
|
-
cacheRead: 0,
|
|
48
|
-
cacheWrite: 0,
|
|
49
|
-
totalTokens: 0,
|
|
50
|
-
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },
|
|
51
|
-
},
|
|
52
|
-
timestamp: Date.now(),
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
let reader: ReadableStreamDefaultReader<Uint8Array> | undefined;
|
|
56
|
-
|
|
57
|
-
// Set up abort handler to cancel the reader
|
|
58
|
-
const abortHandler = () => {
|
|
59
|
-
if (reader) {
|
|
60
|
-
reader.cancel("Request aborted by user").catch(() => {});
|
|
61
|
-
}
|
|
62
|
-
};
|
|
63
|
-
|
|
64
|
-
if (options.signal) {
|
|
65
|
-
options.signal.addEventListener("abort", abortHandler);
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
try {
|
|
69
|
-
const response = await fetch(`${proxyUrl}/api/stream`, {
|
|
70
|
-
method: "POST",
|
|
71
|
-
headers: {
|
|
72
|
-
Authorization: `Bearer ${options.authToken}`,
|
|
73
|
-
"Content-Type": "application/json",
|
|
74
|
-
},
|
|
75
|
-
body: JSON.stringify({
|
|
76
|
-
model,
|
|
77
|
-
context,
|
|
78
|
-
options: {
|
|
79
|
-
temperature: options.temperature,
|
|
80
|
-
maxTokens: options.maxTokens,
|
|
81
|
-
reasoning: options.reasoning,
|
|
82
|
-
// Don't send apiKey or signal - those are added server-side
|
|
83
|
-
},
|
|
84
|
-
}),
|
|
85
|
-
signal: options.signal,
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
if (!response.ok) {
|
|
89
|
-
let errorMessage = `Proxy error: ${response.status} ${response.statusText}`;
|
|
90
|
-
try {
|
|
91
|
-
const errorData = await response.json();
|
|
92
|
-
if (errorData.error) {
|
|
93
|
-
errorMessage = `Proxy error: ${errorData.error}`;
|
|
94
|
-
}
|
|
95
|
-
} catch {
|
|
96
|
-
// Couldn't parse error response, use default message
|
|
97
|
-
}
|
|
98
|
-
throw new Error(errorMessage);
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
// Parse SSE stream
|
|
102
|
-
reader = response.body!.getReader();
|
|
103
|
-
const decoder = new TextDecoder();
|
|
104
|
-
let buffer = "";
|
|
105
|
-
|
|
106
|
-
while (true) {
|
|
107
|
-
const { done, value } = await reader.read();
|
|
108
|
-
if (done) break;
|
|
109
|
-
|
|
110
|
-
// Check if aborted after reading
|
|
111
|
-
if (options.signal?.aborted) {
|
|
112
|
-
throw new Error("Request aborted by user");
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
buffer += decoder.decode(value, { stream: true });
|
|
116
|
-
const lines = buffer.split("\n");
|
|
117
|
-
buffer = lines.pop() || "";
|
|
118
|
-
|
|
119
|
-
for (const line of lines) {
|
|
120
|
-
if (line.startsWith("data: ")) {
|
|
121
|
-
const data = line.slice(6).trim();
|
|
122
|
-
if (data) {
|
|
123
|
-
const proxyEvent = JSON.parse(data) as ProxyAssistantMessageEvent;
|
|
124
|
-
let event: AssistantMessageEvent | undefined;
|
|
125
|
-
|
|
126
|
-
// Handle different event types
|
|
127
|
-
// Server sends events with partial for non-delta events,
|
|
128
|
-
// and without partial for delta events
|
|
129
|
-
switch (proxyEvent.type) {
|
|
130
|
-
case "start":
|
|
131
|
-
event = { type: "start", partial };
|
|
132
|
-
break;
|
|
133
|
-
|
|
134
|
-
case "text_start":
|
|
135
|
-
partial.content[proxyEvent.contentIndex] = {
|
|
136
|
-
type: "text",
|
|
137
|
-
text: "",
|
|
138
|
-
};
|
|
139
|
-
event = { type: "text_start", contentIndex: proxyEvent.contentIndex, partial };
|
|
140
|
-
break;
|
|
141
|
-
|
|
142
|
-
case "text_delta": {
|
|
143
|
-
const content = partial.content[proxyEvent.contentIndex];
|
|
144
|
-
if (content?.type === "text") {
|
|
145
|
-
content.text += proxyEvent.delta;
|
|
146
|
-
event = {
|
|
147
|
-
type: "text_delta",
|
|
148
|
-
contentIndex: proxyEvent.contentIndex,
|
|
149
|
-
delta: proxyEvent.delta,
|
|
150
|
-
partial,
|
|
151
|
-
};
|
|
152
|
-
} else {
|
|
153
|
-
throw new Error("Received text_delta for non-text content");
|
|
154
|
-
}
|
|
155
|
-
break;
|
|
156
|
-
}
|
|
157
|
-
case "text_end": {
|
|
158
|
-
const content = partial.content[proxyEvent.contentIndex];
|
|
159
|
-
if (content?.type === "text") {
|
|
160
|
-
content.textSignature = proxyEvent.contentSignature;
|
|
161
|
-
event = {
|
|
162
|
-
type: "text_end",
|
|
163
|
-
contentIndex: proxyEvent.contentIndex,
|
|
164
|
-
content: content.text,
|
|
165
|
-
partial,
|
|
166
|
-
};
|
|
167
|
-
} else {
|
|
168
|
-
throw new Error("Received text_end for non-text content");
|
|
169
|
-
}
|
|
170
|
-
break;
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
case "thinking_start":
|
|
174
|
-
partial.content[proxyEvent.contentIndex] = {
|
|
175
|
-
type: "thinking",
|
|
176
|
-
thinking: "",
|
|
177
|
-
};
|
|
178
|
-
event = { type: "thinking_start", contentIndex: proxyEvent.contentIndex, partial };
|
|
179
|
-
break;
|
|
180
|
-
|
|
181
|
-
case "thinking_delta": {
|
|
182
|
-
const content = partial.content[proxyEvent.contentIndex];
|
|
183
|
-
if (content?.type === "thinking") {
|
|
184
|
-
content.thinking += proxyEvent.delta;
|
|
185
|
-
event = {
|
|
186
|
-
type: "thinking_delta",
|
|
187
|
-
contentIndex: proxyEvent.contentIndex,
|
|
188
|
-
delta: proxyEvent.delta,
|
|
189
|
-
partial,
|
|
190
|
-
};
|
|
191
|
-
} else {
|
|
192
|
-
throw new Error("Received thinking_delta for non-thinking content");
|
|
193
|
-
}
|
|
194
|
-
break;
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
case "thinking_end": {
|
|
198
|
-
const content = partial.content[proxyEvent.contentIndex];
|
|
199
|
-
if (content?.type === "thinking") {
|
|
200
|
-
content.thinkingSignature = proxyEvent.contentSignature;
|
|
201
|
-
event = {
|
|
202
|
-
type: "thinking_end",
|
|
203
|
-
contentIndex: proxyEvent.contentIndex,
|
|
204
|
-
content: content.thinking,
|
|
205
|
-
partial,
|
|
206
|
-
};
|
|
207
|
-
} else {
|
|
208
|
-
throw new Error("Received thinking_end for non-thinking content");
|
|
209
|
-
}
|
|
210
|
-
break;
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
case "toolcall_start":
|
|
214
|
-
partial.content[proxyEvent.contentIndex] = {
|
|
215
|
-
type: "toolCall",
|
|
216
|
-
id: proxyEvent.id,
|
|
217
|
-
name: proxyEvent.toolName,
|
|
218
|
-
arguments: {},
|
|
219
|
-
partialJson: "",
|
|
220
|
-
} satisfies ToolCall & { partialJson: string } as ToolCall;
|
|
221
|
-
event = { type: "toolcall_start", contentIndex: proxyEvent.contentIndex, partial };
|
|
222
|
-
break;
|
|
223
|
-
|
|
224
|
-
case "toolcall_delta": {
|
|
225
|
-
const content = partial.content[proxyEvent.contentIndex];
|
|
226
|
-
if (content?.type === "toolCall") {
|
|
227
|
-
(content as any).partialJson += proxyEvent.delta;
|
|
228
|
-
content.arguments = parseStreamingJson((content as any).partialJson) || {};
|
|
229
|
-
event = {
|
|
230
|
-
type: "toolcall_delta",
|
|
231
|
-
contentIndex: proxyEvent.contentIndex,
|
|
232
|
-
delta: proxyEvent.delta,
|
|
233
|
-
partial,
|
|
234
|
-
};
|
|
235
|
-
partial.content[proxyEvent.contentIndex] = { ...content }; // Trigger reactivity
|
|
236
|
-
} else {
|
|
237
|
-
throw new Error("Received toolcall_delta for non-toolCall content");
|
|
238
|
-
}
|
|
239
|
-
break;
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
case "toolcall_end": {
|
|
243
|
-
const content = partial.content[proxyEvent.contentIndex];
|
|
244
|
-
if (content?.type === "toolCall") {
|
|
245
|
-
delete (content as any).partialJson;
|
|
246
|
-
event = {
|
|
247
|
-
type: "toolcall_end",
|
|
248
|
-
contentIndex: proxyEvent.contentIndex,
|
|
249
|
-
toolCall: content,
|
|
250
|
-
partial,
|
|
251
|
-
};
|
|
252
|
-
}
|
|
253
|
-
break;
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
case "done":
|
|
257
|
-
partial.stopReason = proxyEvent.reason;
|
|
258
|
-
partial.usage = proxyEvent.usage;
|
|
259
|
-
event = { type: "done", reason: proxyEvent.reason, message: partial };
|
|
260
|
-
break;
|
|
261
|
-
|
|
262
|
-
case "error":
|
|
263
|
-
partial.stopReason = proxyEvent.reason;
|
|
264
|
-
partial.errorMessage = proxyEvent.errorMessage;
|
|
265
|
-
partial.usage = proxyEvent.usage;
|
|
266
|
-
event = { type: "error", reason: proxyEvent.reason, error: partial };
|
|
267
|
-
break;
|
|
268
|
-
|
|
269
|
-
default: {
|
|
270
|
-
// Exhaustive check
|
|
271
|
-
const _exhaustiveCheck: never = proxyEvent;
|
|
272
|
-
console.warn(`Unhandled event type: ${(proxyEvent as any).type}`);
|
|
273
|
-
break;
|
|
274
|
-
}
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
// Push the event to stream
|
|
278
|
-
if (event) {
|
|
279
|
-
stream.push(event);
|
|
280
|
-
} else {
|
|
281
|
-
throw new Error("Failed to create event from proxy event");
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
// Check if aborted after reading
|
|
289
|
-
if (options.signal?.aborted) {
|
|
290
|
-
throw new Error("Request aborted by user");
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
stream.end();
|
|
294
|
-
} catch (error) {
|
|
295
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
296
|
-
if (errorMessage.toLowerCase().includes("proxy") && errorMessage.includes("Unauthorized")) {
|
|
297
|
-
clearAuthToken();
|
|
298
|
-
}
|
|
299
|
-
partial.stopReason = options.signal?.aborted ? "aborted" : "error";
|
|
300
|
-
partial.errorMessage = errorMessage;
|
|
301
|
-
stream.push({
|
|
302
|
-
type: "error",
|
|
303
|
-
reason: partial.stopReason,
|
|
304
|
-
error: partial,
|
|
305
|
-
} satisfies AssistantMessageEvent);
|
|
306
|
-
stream.end();
|
|
307
|
-
} finally {
|
|
308
|
-
// Clean up abort handler
|
|
309
|
-
if (options.signal) {
|
|
310
|
-
options.signal.removeEventListener("abort", abortHandler);
|
|
311
|
-
}
|
|
312
|
-
}
|
|
313
|
-
})();
|
|
314
|
-
|
|
315
|
-
return stream;
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
/**
|
|
319
|
-
* Transport that uses an app server with user authentication tokens.
|
|
320
|
-
* The server manages user accounts and proxies requests to LLM providers.
|
|
321
|
-
*/
|
|
322
|
-
export class AppTransport implements AgentTransport {
|
|
323
|
-
private readonly proxyUrl = "https://genai.mariozechner.at";
|
|
324
|
-
|
|
325
|
-
private async getStreamFn() {
|
|
326
|
-
const authToken = await getAuthToken();
|
|
327
|
-
if (!authToken) {
|
|
328
|
-
throw new Error(i18n("Auth token is required for proxy transport"));
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
return <TApi extends Api>(model: Model<TApi>, context: Context, options?: SimpleStreamOptions) => {
|
|
332
|
-
return streamSimpleProxy(model, context, { ...options, authToken }, this.proxyUrl);
|
|
333
|
-
};
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
private buildContext(messages: Message[], cfg: AgentRunConfig): AgentContext {
|
|
337
|
-
return {
|
|
338
|
-
systemPrompt: cfg.systemPrompt,
|
|
339
|
-
messages,
|
|
340
|
-
tools: cfg.tools,
|
|
341
|
-
};
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
private buildLoopConfig(cfg: AgentRunConfig): AgentLoopConfig {
|
|
345
|
-
return {
|
|
346
|
-
model: cfg.model,
|
|
347
|
-
reasoning: cfg.reasoning,
|
|
348
|
-
getQueuedMessages: cfg.getQueuedMessages,
|
|
349
|
-
};
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
async *run(messages: Message[], userMessage: Message, cfg: AgentRunConfig, signal?: AbortSignal) {
|
|
353
|
-
const streamFn = await this.getStreamFn();
|
|
354
|
-
const context = this.buildContext(messages, cfg);
|
|
355
|
-
const pc = this.buildLoopConfig(cfg);
|
|
356
|
-
|
|
357
|
-
for await (const ev of agentLoop(userMessage as unknown as UserMessage, context, pc, signal, streamFn as any)) {
|
|
358
|
-
yield ev;
|
|
359
|
-
}
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
async *continue(messages: Message[], cfg: AgentRunConfig, signal?: AbortSignal) {
|
|
363
|
-
const streamFn = await this.getStreamFn();
|
|
364
|
-
const context = this.buildContext(messages, cfg);
|
|
365
|
-
const pc = this.buildLoopConfig(cfg);
|
|
366
|
-
|
|
367
|
-
for await (const ev of agentLoopContinue(context, pc, signal, streamFn as any)) {
|
|
368
|
-
yield ev;
|
|
369
|
-
}
|
|
370
|
-
}
|
|
371
|
-
}
|
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
type AgentContext,
|
|
3
|
-
type AgentLoopConfig,
|
|
4
|
-
agentLoop,
|
|
5
|
-
agentLoopContinue,
|
|
6
|
-
type Message,
|
|
7
|
-
type UserMessage,
|
|
8
|
-
} from "@mariozechner/pi-ai";
|
|
9
|
-
import { getAppStorage } from "../../storage/app-storage.js";
|
|
10
|
-
import { applyProxyIfNeeded } from "../../utils/proxy-utils.js";
|
|
11
|
-
import type { AgentRunConfig, AgentTransport } from "./types.js";
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Transport that calls LLM providers directly.
|
|
15
|
-
* Uses CORS proxy only for providers that require it (Anthropic OAuth, Z-AI).
|
|
16
|
-
*/
|
|
17
|
-
export class ProviderTransport implements AgentTransport {
|
|
18
|
-
private async getModel(cfg: AgentRunConfig) {
|
|
19
|
-
const apiKey = await getAppStorage().providerKeys.get(cfg.model.provider);
|
|
20
|
-
if (!apiKey) {
|
|
21
|
-
throw new Error("no-api-key");
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
const proxyEnabled = await getAppStorage().settings.get<boolean>("proxy.enabled");
|
|
25
|
-
const proxyUrl = await getAppStorage().settings.get<string>("proxy.url");
|
|
26
|
-
const model = applyProxyIfNeeded(cfg.model, apiKey, proxyEnabled ? proxyUrl || undefined : undefined);
|
|
27
|
-
|
|
28
|
-
return model;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
private buildContext(messages: Message[], cfg: AgentRunConfig): AgentContext {
|
|
32
|
-
return {
|
|
33
|
-
systemPrompt: cfg.systemPrompt,
|
|
34
|
-
messages,
|
|
35
|
-
tools: cfg.tools,
|
|
36
|
-
};
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
private buildLoopConfig(model: AgentRunConfig["model"], cfg: AgentRunConfig): AgentLoopConfig {
|
|
40
|
-
return {
|
|
41
|
-
model,
|
|
42
|
-
reasoning: cfg.reasoning,
|
|
43
|
-
// Resolve API key per assistant response (important for expiring OAuth tokens)
|
|
44
|
-
getApiKey: async (provider: string) => {
|
|
45
|
-
const key = await getAppStorage().providerKeys.get(provider);
|
|
46
|
-
return key ?? undefined; // Convert null to undefined for type compatibility
|
|
47
|
-
},
|
|
48
|
-
getQueuedMessages: cfg.getQueuedMessages,
|
|
49
|
-
};
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
async *run(messages: Message[], userMessage: Message, cfg: AgentRunConfig, signal?: AbortSignal) {
|
|
53
|
-
const model = await this.getModel(cfg);
|
|
54
|
-
const context = this.buildContext(messages, cfg);
|
|
55
|
-
const pc = this.buildLoopConfig(model, cfg);
|
|
56
|
-
|
|
57
|
-
for await (const ev of agentLoop(userMessage as unknown as UserMessage, context, pc, signal)) {
|
|
58
|
-
yield ev;
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
async *continue(messages: Message[], cfg: AgentRunConfig, signal?: AbortSignal) {
|
|
63
|
-
const model = await this.getModel(cfg);
|
|
64
|
-
const context = this.buildContext(messages, cfg);
|
|
65
|
-
const pc = this.buildLoopConfig(model, cfg);
|
|
66
|
-
|
|
67
|
-
for await (const ev of agentLoopContinue(context, pc, signal)) {
|
|
68
|
-
yield ev;
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import type { StopReason, Usage } from "@mariozechner/pi-ai";
|
|
2
|
-
|
|
3
|
-
export type ProxyAssistantMessageEvent =
|
|
4
|
-
| { type: "start" }
|
|
5
|
-
| { type: "text_start"; contentIndex: number }
|
|
6
|
-
| { type: "text_delta"; contentIndex: number; delta: string }
|
|
7
|
-
| { type: "text_end"; contentIndex: number; contentSignature?: string }
|
|
8
|
-
| { type: "thinking_start"; contentIndex: number }
|
|
9
|
-
| { type: "thinking_delta"; contentIndex: number; delta: string }
|
|
10
|
-
| { type: "thinking_end"; contentIndex: number; contentSignature?: string }
|
|
11
|
-
| { type: "toolcall_start"; contentIndex: number; id: string; toolName: string }
|
|
12
|
-
| { type: "toolcall_delta"; contentIndex: number; delta: string }
|
|
13
|
-
| { type: "toolcall_end"; contentIndex: number }
|
|
14
|
-
| { type: "done"; reason: Extract<StopReason, "stop" | "length" | "toolUse">; usage: Usage }
|
|
15
|
-
| { type: "error"; reason: Extract<StopReason, "aborted" | "error">; errorMessage: string; usage: Usage };
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import type { AgentEvent, AgentTool, Message, Model, QueuedMessage } from "@mariozechner/pi-ai";
|
|
2
|
-
|
|
3
|
-
// The minimal configuration needed to run a turn.
|
|
4
|
-
export interface AgentRunConfig {
|
|
5
|
-
systemPrompt: string;
|
|
6
|
-
tools: AgentTool<any>[];
|
|
7
|
-
model: Model<any>;
|
|
8
|
-
reasoning?: "low" | "medium" | "high";
|
|
9
|
-
getQueuedMessages?: <T>() => Promise<QueuedMessage<T>[]>;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
// Events yielded by transports must match the @mariozechner/pi-ai prompt() events.
|
|
13
|
-
// We re-export the Message type above; consumers should use the upstream AgentEvent type.
|
|
14
|
-
|
|
15
|
-
export interface AgentTransport {
|
|
16
|
-
/** Run with a new user message */
|
|
17
|
-
run(
|
|
18
|
-
messages: Message[],
|
|
19
|
-
userMessage: Message,
|
|
20
|
-
config: AgentRunConfig,
|
|
21
|
-
signal?: AbortSignal,
|
|
22
|
-
): AsyncIterable<AgentEvent>;
|
|
23
|
-
|
|
24
|
-
/** Continue from current context (no new user message) */
|
|
25
|
-
continue(messages: Message[], config: AgentRunConfig, signal?: AbortSignal): AsyncIterable<AgentEvent>;
|
|
26
|
-
}
|
package/src/agent/types.ts
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import type { AssistantMessage, Context } from "@mariozechner/pi-ai";
|
|
2
|
-
|
|
3
|
-
export interface DebugLogEntry {
|
|
4
|
-
timestamp: string;
|
|
5
|
-
request: { provider: string; model: string; context: Context };
|
|
6
|
-
response?: AssistantMessage;
|
|
7
|
-
error?: unknown;
|
|
8
|
-
sseEvents: string[];
|
|
9
|
-
ttft?: number;
|
|
10
|
-
totalTime?: number;
|
|
11
|
-
}
|