@hachej/boring-agent 0.1.34 → 0.1.35
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/{DebugDrawer-PX2PHXJH.js → DebugDrawer-2PUDZ2RL.js} +1 -1
- package/dist/{agentPluginEvents-CF0BGY4D.d.ts → agentPluginEvents-CAMp363h.d.ts} +99 -1
- package/dist/{chunk-UTUXVT2K.js → chunk-IUJ22EFB.js} +24 -8
- package/dist/chunk-NZN2PRET.js +6 -0
- package/dist/chunk-VQ7VSSSX.js +369 -0
- package/dist/eval/index.js +50 -73
- package/dist/front/index.d.ts +432 -254
- package/dist/front/index.js +8461 -5902
- package/dist/front/styles.css +405 -255
- package/dist/piChatEvent-Ck1BAE_m.d.ts +323 -0
- package/dist/server/index.d.ts +3 -4
- package/dist/server/index.js +2656 -2446
- package/dist/session-BRovhe0D.d.ts +27 -0
- package/dist/shared/index.d.ts +1375 -48
- package/dist/shared/index.js +64 -8
- package/package.json +7 -4
- package/dist/chunk-B5JECXMG.js +0 -36
- package/dist/chunk-IDRC4SFU.js +0 -85
- package/dist/chunk-Q7ZLUJQW.js +0 -88
- package/dist/harness-dYuMzxmp.d.ts +0 -153
- package/dist/tool-ui-DIFNGwYd.d.ts +0 -20
package/README.md
CHANGED
|
@@ -285,7 +285,7 @@ A: Yes. Use the `CatalogDeps` pattern to build tools that bind to `Workspace` an
|
|
|
285
285
|
A: It lets the agent programmatically open files, panels, and surfaces in the workbench. The agent calls `exec_ui({ kind: "openFile", params: { path: "src/index.ts" } })` and the panel opens. It's a typed pubsub bus between backend and frontend.
|
|
286
286
|
|
|
287
287
|
**Q: How does stream resumption work?**
|
|
288
|
-
A: The server wraps the harness's event stream in a per-turn ring buffer. Disconnected clients reconnect via `GET /api/v1/agent/chat/:sessionId
|
|
288
|
+
A: The server wraps the harness's event stream in a per-turn ring buffer. Disconnected clients reconnect via `GET /api/v1/agent/pi-chat/:sessionId/events?from=<seq>`; the replay buffer serves missed events.
|
|
289
289
|
|
|
290
290
|
---
|
|
291
291
|
|
|
@@ -1,3 +1,101 @@
|
|
|
1
|
+
import { b as SessionStore } from './session-BRovhe0D.js';
|
|
2
|
+
|
|
3
|
+
interface TelemetrySink {
|
|
4
|
+
capture(event: TelemetryEvent): void | Promise<void>;
|
|
5
|
+
flush?(): void | Promise<void>;
|
|
6
|
+
}
|
|
7
|
+
interface TelemetryEvent {
|
|
8
|
+
name: string;
|
|
9
|
+
distinctId?: string;
|
|
10
|
+
properties?: Record<string, unknown>;
|
|
11
|
+
}
|
|
12
|
+
declare const noopTelemetry: TelemetrySink;
|
|
13
|
+
declare function safeCapture(telemetry: TelemetrySink, event: TelemetryEvent): void;
|
|
14
|
+
|
|
15
|
+
type JSONSchema = Record<string, unknown>;
|
|
16
|
+
type ToolReadinessRequirement = 'workspace-fs' | 'sandbox-exec' | 'ui-bridge' | 'runtime-dependencies' | `runtime:${string}`;
|
|
17
|
+
interface AgentTool {
|
|
18
|
+
name: string;
|
|
19
|
+
description: string;
|
|
20
|
+
/** Optional one-line prompt entry. Pi-built tools should preserve pi's snippet verbatim. */
|
|
21
|
+
promptSnippet?: string;
|
|
22
|
+
readinessRequirements?: ToolReadinessRequirement[];
|
|
23
|
+
parameters: JSONSchema;
|
|
24
|
+
execute(params: Record<string, unknown>, ctx: ToolExecContext): Promise<ToolResult>;
|
|
25
|
+
}
|
|
26
|
+
interface ToolExecContext {
|
|
27
|
+
abortSignal: AbortSignal;
|
|
28
|
+
toolCallId: string;
|
|
29
|
+
onUpdate?: (partial: string) => void;
|
|
30
|
+
/** Agent chat/session id executing this tool, when known. */
|
|
31
|
+
sessionId?: string;
|
|
32
|
+
}
|
|
33
|
+
interface ToolResult {
|
|
34
|
+
content: Array<{
|
|
35
|
+
type: 'text';
|
|
36
|
+
text: string;
|
|
37
|
+
}>;
|
|
38
|
+
isError?: boolean;
|
|
39
|
+
details?: unknown;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
interface AgentHarnessFactoryInput {
|
|
43
|
+
tools: AgentTool[];
|
|
44
|
+
/** Host/storage cwd used for harness-owned filesystem resources. */
|
|
45
|
+
cwd: string;
|
|
46
|
+
/** Agent-visible cwd used by Pi/system prompt/session metadata. */
|
|
47
|
+
runtimeCwd?: string;
|
|
48
|
+
systemPromptAppend?: string;
|
|
49
|
+
sessionNamespace?: string;
|
|
50
|
+
sessionDir?: string;
|
|
51
|
+
/**
|
|
52
|
+
* Optional dynamic system-prompt source. Harness calls it whenever it
|
|
53
|
+
* builds or rebuilds a session prompt and appends the returned string.
|
|
54
|
+
* Workspace plugin layer wires this so live-reloaded plugins can contribute
|
|
55
|
+
* prompt context without a workspace-injected harness extension.
|
|
56
|
+
*/
|
|
57
|
+
systemPromptDynamic?: () => string | undefined | Promise<string | undefined>;
|
|
58
|
+
/** Host-provided telemetry sink. Optional and best-effort; harnesses may ignore it. */
|
|
59
|
+
telemetry?: TelemetrySink;
|
|
60
|
+
}
|
|
61
|
+
type AgentHarnessFactory = (input: AgentHarnessFactoryInput) => AgentHarness | Promise<AgentHarness>;
|
|
62
|
+
interface AgentHarness {
|
|
63
|
+
readonly id: string;
|
|
64
|
+
readonly placement: 'server' | 'browser';
|
|
65
|
+
/** Session lifecycle; may delegate to an underlying runtime (e.g. pi's JSONL). */
|
|
66
|
+
sessions: SessionStore;
|
|
67
|
+
/**
|
|
68
|
+
* Resolved system prompt currently in effect for `sessionId`. Returns
|
|
69
|
+
* `undefined` when the underlying runtime hasn't yet instantiated a
|
|
70
|
+
* session (typical pre-first-turn state — pi creates lazily on the first
|
|
71
|
+
* prompt). Optional so non-pi harnesses can opt out cleanly.
|
|
72
|
+
*/
|
|
73
|
+
getSystemPrompt?: (sessionId: string) => string | undefined;
|
|
74
|
+
/** Reload native agent resources/extensions for an existing session. */
|
|
75
|
+
reloadSession?: (sessionId: string) => Promise<boolean>;
|
|
76
|
+
}
|
|
77
|
+
interface MessageAttachment {
|
|
78
|
+
filename?: string;
|
|
79
|
+
mediaType?: string;
|
|
80
|
+
/** data: URL (base64) or remote URL */
|
|
81
|
+
url: string;
|
|
82
|
+
}
|
|
83
|
+
interface SendMessageInput {
|
|
84
|
+
sessionId: string;
|
|
85
|
+
message: string;
|
|
86
|
+
thinkingLevel?: 'off' | 'low' | 'medium' | 'high';
|
|
87
|
+
model?: {
|
|
88
|
+
provider: string;
|
|
89
|
+
id: string;
|
|
90
|
+
};
|
|
91
|
+
attachments?: MessageAttachment[];
|
|
92
|
+
}
|
|
93
|
+
interface RunContext {
|
|
94
|
+
abortSignal: AbortSignal;
|
|
95
|
+
workdir: string;
|
|
96
|
+
userId?: string;
|
|
97
|
+
}
|
|
98
|
+
|
|
1
99
|
interface WorkspaceRuntimeContext {
|
|
2
100
|
/** Agent-visible working directory shared by file-tree and shell execution. */
|
|
3
101
|
readonly runtimeCwd: string;
|
|
@@ -297,4 +395,4 @@ interface PluginRestartWarning {
|
|
|
297
395
|
message: string;
|
|
298
396
|
}
|
|
299
397
|
|
|
300
|
-
export { type Entry as E, type FileSearch as F, type IsolatedCodeInput as I, type PluginRestartWarning as P, type Sandbox as S, type Workspace as W, type
|
|
398
|
+
export { type AgentTool as A, type Entry as E, type FileSearch as F, type IsolatedCodeInput as I, type JSONSchema as J, type PluginRestartWarning as P, type RunContext as R, type Sandbox as S, type TelemetryEvent as T, type Workspace as W, type AgentHarness as a, type ExecOptions as b, type ExecResult as c, type IsolatedCodeOutput as d, type SandboxCapability as e, type SandboxHandleRecord as f, type SandboxHandleStore as g, type SendMessageInput as h, type Stat as i, type TelemetrySink as j, type ToolExecContext as k, type ToolResult as l, WORKSPACE_AGENT_PLUGINS_RELOADED_EVENT as m, type WorkspaceRuntimeContext as n, noopTelemetry as o, type AgentHarnessFactory as p, type AgentHarnessFactoryInput as q, safeCapture as s };
|
|
@@ -74,7 +74,7 @@ function CopyButton({ value, label }) {
|
|
|
74
74
|
function DebugValue({ label, value }) {
|
|
75
75
|
return /* @__PURE__ */ jsxs("div", { className: "rounded-md border border-border/40 bg-muted/20 p-2", children: [
|
|
76
76
|
/* @__PURE__ */ jsxs("div", { className: "mb-1 flex items-center justify-between gap-2", children: [
|
|
77
|
-
/* @__PURE__ */ jsx("span", { className: "text-[10px] font-medium uppercase tracking-[0.16em] text-muted-foreground
|
|
77
|
+
/* @__PURE__ */ jsx("span", { className: "text-[10px] font-medium uppercase tracking-[0.16em] text-muted-foreground", children: label }),
|
|
78
78
|
/* @__PURE__ */ jsx(CopyButton, { value, label: `Copy ${label}` })
|
|
79
79
|
] }),
|
|
80
80
|
/* @__PURE__ */ jsx("code", { className: "block break-all font-mono text-[11px] leading-relaxed text-foreground dark:text-zinc-100", children: value })
|
|
@@ -86,7 +86,7 @@ function SessionTab({ sessionId }) {
|
|
|
86
86
|
/* @__PURE__ */ jsx("p", { className: "text-muted-foreground dark:text-zinc-300", children: "This web chat is backed by a pi session. Use the id below from the workspace root to resume the same conversation in a terminal." }),
|
|
87
87
|
/* @__PURE__ */ jsx(DebugValue, { label: "Pi session id", value: sessionId }),
|
|
88
88
|
/* @__PURE__ */ jsx(DebugValue, { label: "Resume command", value: resumeCommand }),
|
|
89
|
-
/* @__PURE__ */ jsxs("p", { className: "rounded-md border border-border/30 bg-muted/10 p-2 text-[10px] leading-relaxed text-muted-foreground
|
|
89
|
+
/* @__PURE__ */ jsxs("p", { className: "rounded-md border border-border/30 bg-muted/10 p-2 text-[10px] leading-relaxed text-muted-foreground dark:text-zinc-300", children: [
|
|
90
90
|
"Tip: ",
|
|
91
91
|
/* @__PURE__ */ jsx("code", { className: "font-mono text-foreground/80", children: "pi --continue" }),
|
|
92
92
|
" ",
|
|
@@ -97,8 +97,11 @@ function SessionTab({ sessionId }) {
|
|
|
97
97
|
var RETRY_DELAY_MS = 2500;
|
|
98
98
|
var MAX_RETRIES = 20;
|
|
99
99
|
function SystemPromptTab({
|
|
100
|
+
apiBaseUrl,
|
|
101
|
+
fetch: fetchImpl,
|
|
100
102
|
sessionId,
|
|
101
|
-
requestHeaders
|
|
103
|
+
requestHeaders,
|
|
104
|
+
storageScope
|
|
102
105
|
}) {
|
|
103
106
|
const [state, setState] = useState({ kind: "loading" });
|
|
104
107
|
const [retryKey, setRetryKey] = useState(0);
|
|
@@ -111,8 +114,10 @@ function SystemPromptTab({
|
|
|
111
114
|
let aborted = false;
|
|
112
115
|
let retryTimer = null;
|
|
113
116
|
setState({ kind: "loading" });
|
|
114
|
-
const
|
|
115
|
-
|
|
117
|
+
const nextFetch = fetchImpl ?? globalThis.fetch.bind(globalThis);
|
|
118
|
+
nextFetch(agentResourceUrl(apiBaseUrl, `/api/v1/agent/sessions/${encodeURIComponent(sessionId)}/system-prompt`), {
|
|
119
|
+
headers: scopedHeaders(requestHeaders, storageScope)
|
|
120
|
+
}).then(async (res) => {
|
|
116
121
|
if (aborted) return;
|
|
117
122
|
if (res.ok) {
|
|
118
123
|
const payload2 = await res.json();
|
|
@@ -142,7 +147,7 @@ function SystemPromptTab({
|
|
|
142
147
|
aborted = true;
|
|
143
148
|
if (retryTimer) clearTimeout(retryTimer);
|
|
144
149
|
};
|
|
145
|
-
}, [sessionId, requestHeaders, retryKey]);
|
|
150
|
+
}, [apiBaseUrl, fetchImpl, sessionId, requestHeaders, retryKey, storageScope]);
|
|
146
151
|
return /* @__PURE__ */ jsxs("div", { className: "flex flex-col h-full min-h-0", children: [
|
|
147
152
|
/* @__PURE__ */ jsxs("div", { className: "shrink-0 flex items-center justify-between px-3 pt-2 pb-1 border-b border-border/40", children: [
|
|
148
153
|
/* @__PURE__ */ jsx("span", { className: "text-[10px] text-muted-foreground/80 font-mono", children: state.kind === "ok" ? `${state.text.length.toLocaleString()} chars` : state.kind === "loading" ? "loading\u2026" : state.kind === "empty" ? `waiting for session \xB7 retry ${retryCount.current}/${MAX_RETRIES}` : "error" }),
|
|
@@ -265,7 +270,7 @@ var TABS = [
|
|
|
265
270
|
];
|
|
266
271
|
var MIN_WIDTH = 280;
|
|
267
272
|
var MAX_WIDTH = 800;
|
|
268
|
-
function DebugDrawer({ sessionId, messages, requestHeaders, width, onWidthChange }) {
|
|
273
|
+
function DebugDrawer({ apiBaseUrl, fetch, sessionId, messages, requestHeaders, storageScope, width, onWidthChange }) {
|
|
269
274
|
const [tab, setTab] = useState("session");
|
|
270
275
|
const onDragStart = useCallback((e) => {
|
|
271
276
|
e.preventDefault();
|
|
@@ -310,13 +315,24 @@ function DebugDrawer({ sessionId, messages, requestHeaders, width, onWidthChange
|
|
|
310
315
|
id
|
|
311
316
|
)) }) }),
|
|
312
317
|
/* @__PURE__ */ jsx(TabsContent, { value: "session", forceMount: true, className: "flex flex-col flex-1 min-h-0 overflow-hidden data-[state=inactive]:hidden", children: /* @__PURE__ */ jsx(SessionTab, { sessionId }) }),
|
|
313
|
-
/* @__PURE__ */ jsx(TabsContent, { value: "prompt", forceMount: true, className: "flex flex-col flex-1 min-h-0 overflow-hidden data-[state=inactive]:hidden", children: /* @__PURE__ */ jsx(SystemPromptTab, { sessionId, requestHeaders }) }),
|
|
318
|
+
/* @__PURE__ */ jsx(TabsContent, { value: "prompt", forceMount: true, className: "flex flex-col flex-1 min-h-0 overflow-hidden data-[state=inactive]:hidden", children: /* @__PURE__ */ jsx(SystemPromptTab, { apiBaseUrl, fetch, sessionId, requestHeaders, storageScope }) }),
|
|
314
319
|
/* @__PURE__ */ jsx(TabsContent, { value: "messages", forceMount: true, className: "flex flex-col flex-1 min-h-0 overflow-hidden data-[state=inactive]:hidden", children: /* @__PURE__ */ jsx(MessagesTab, { messages }) })
|
|
315
320
|
] })
|
|
316
321
|
}
|
|
317
322
|
)
|
|
318
323
|
] });
|
|
319
324
|
}
|
|
325
|
+
function agentResourceUrl(apiBaseUrl, path) {
|
|
326
|
+
const base = apiBaseUrl?.replace(/\/$/, "") ?? "";
|
|
327
|
+
return `${base}${path}`;
|
|
328
|
+
}
|
|
329
|
+
function scopedHeaders(headers, storageScope) {
|
|
330
|
+
if (!headers && !storageScope) return void 0;
|
|
331
|
+
const result = { ...headers ?? {} };
|
|
332
|
+
const hasStorageScope = Object.keys(result).some((key) => key.toLowerCase() === "x-boring-storage-scope");
|
|
333
|
+
if (storageScope && !hasStorageScope) result["x-boring-storage-scope"] = storageScope;
|
|
334
|
+
return result;
|
|
335
|
+
}
|
|
320
336
|
|
|
321
337
|
export {
|
|
322
338
|
cn,
|
|
@@ -0,0 +1,369 @@
|
|
|
1
|
+
// src/shared/tool-ui.ts
|
|
2
|
+
function isRecord(value) {
|
|
3
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
4
|
+
}
|
|
5
|
+
function isToolUiMetadata(value) {
|
|
6
|
+
if (!isRecord(value)) return false;
|
|
7
|
+
return (value.rendererId === void 0 || typeof value.rendererId === "string") && (value.displayGroup === void 0 || typeof value.displayGroup === "string") && (value.icon === void 0 || typeof value.icon === "string");
|
|
8
|
+
}
|
|
9
|
+
function sanitizeToolUiMetadata(value) {
|
|
10
|
+
if (!isToolUiMetadata(value)) return void 0;
|
|
11
|
+
const rendererId = value.rendererId?.trim();
|
|
12
|
+
const displayGroup = value.displayGroup?.trim();
|
|
13
|
+
const icon = value.icon?.trim();
|
|
14
|
+
return {
|
|
15
|
+
...rendererId ? { rendererId } : {},
|
|
16
|
+
...displayGroup ? { displayGroup } : {},
|
|
17
|
+
...icon ? { icon } : {},
|
|
18
|
+
...value.details !== void 0 ? { details: value.details } : {}
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
function extractToolUiMetadata(output) {
|
|
22
|
+
if (!isRecord(output)) return void 0;
|
|
23
|
+
const details = output.details;
|
|
24
|
+
if (!isRecord(details)) return void 0;
|
|
25
|
+
return sanitizeToolUiMetadata(details.ui);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// src/shared/error-codes.ts
|
|
29
|
+
import { z } from "zod";
|
|
30
|
+
var ErrorCode = z.enum([
|
|
31
|
+
// Auth / config
|
|
32
|
+
"MISSING_API_KEY",
|
|
33
|
+
"INVALID_API_KEY",
|
|
34
|
+
"OIDC_REFRESH_FAILED",
|
|
35
|
+
"VERCEL_AUTH_FAILED",
|
|
36
|
+
"CONFIG_INVALID",
|
|
37
|
+
// Workspace / path
|
|
38
|
+
"PATH_ESCAPE",
|
|
39
|
+
"PATH_ABSOLUTE",
|
|
40
|
+
"PATH_NULL_BYTE",
|
|
41
|
+
"PATH_SYMLINK_ESCAPE",
|
|
42
|
+
"PATH_NOT_FOUND",
|
|
43
|
+
"PATH_NOT_WRITABLE",
|
|
44
|
+
"WORKSPACE_UNINITIALIZED",
|
|
45
|
+
"WORKSPACE_NOT_READY",
|
|
46
|
+
// Agent runtime / provisioning
|
|
47
|
+
"AGENT_RUNTIME_NOT_READY",
|
|
48
|
+
"RUNTIME_PROVISIONING_FAILED",
|
|
49
|
+
"RUNTIME_PROVISIONING_LOCKED",
|
|
50
|
+
// Sandbox / exec
|
|
51
|
+
"BWRAP_UNAVAILABLE",
|
|
52
|
+
"BWRAP_TIMEOUT",
|
|
53
|
+
"OUTPUT_TRUNCATED",
|
|
54
|
+
"SANDBOX_NOT_READY",
|
|
55
|
+
"SANDBOX_EXPIRED",
|
|
56
|
+
"VERCEL_API_ERROR",
|
|
57
|
+
"CIRCUIT_OPEN",
|
|
58
|
+
"ABORTED",
|
|
59
|
+
// Session / bridge
|
|
60
|
+
"SESSION_NOT_FOUND",
|
|
61
|
+
"SESSION_LOCKED",
|
|
62
|
+
"STREAM_BUFFER_EVICTED",
|
|
63
|
+
"CURSOR_OUT_OF_RANGE",
|
|
64
|
+
"BRIDGE_COMMAND_INVALID",
|
|
65
|
+
// Tool
|
|
66
|
+
"TOOL_NOT_FOUND",
|
|
67
|
+
"TOOL_INVALID_INPUT",
|
|
68
|
+
"TOOL_EXECUTION_ERROR",
|
|
69
|
+
// Plugin
|
|
70
|
+
"PLUGIN_LOAD_FAILED",
|
|
71
|
+
"PLUGIN_NAME_COLLISION",
|
|
72
|
+
"PLUGIN_RUNTIME_REVISION_MISMATCH",
|
|
73
|
+
"PLUGIN_RUNTIME_PRIVATE_FILE",
|
|
74
|
+
"PLUGIN_RUNTIME_UNSAFE_IMPORT",
|
|
75
|
+
"PLUGIN_RUNTIME_TRANSFORM_FAILED",
|
|
76
|
+
"RUNTIME_PLUGIN_NOT_FOUND",
|
|
77
|
+
"RUNTIME_PLUGIN_ROUTE_NOT_FOUND",
|
|
78
|
+
"RUNTIME_PLUGIN_HANDLER_FAILED",
|
|
79
|
+
"RUNTIME_PLUGIN_LOAD_FAILED",
|
|
80
|
+
"RUNTIME_PLUGIN_RESPONSE_UNSUPPORTED",
|
|
81
|
+
// Runtime provisioning
|
|
82
|
+
"PROVISIONING_LAYOUT_FAILED",
|
|
83
|
+
"PROVISIONING_SKILLS_FAILED",
|
|
84
|
+
"PROVISIONING_TEMPLATES_FAILED",
|
|
85
|
+
"PROVISIONING_NODE_PREFLIGHT_FAILED",
|
|
86
|
+
"PROVISIONING_NPM_INSTALL_FAILED",
|
|
87
|
+
"PROVISIONING_UV_BOOTSTRAP_FAILED",
|
|
88
|
+
"PROVISIONING_UV_INSTALL_FAILED",
|
|
89
|
+
"PROVISIONING_ARTIFACT_FAILED",
|
|
90
|
+
// Internal
|
|
91
|
+
"INTERNAL_ERROR"
|
|
92
|
+
]);
|
|
93
|
+
var ERROR_CODES = ErrorCode.options;
|
|
94
|
+
var ApiErrorPayloadSchema = z.object({
|
|
95
|
+
code: ErrorCode,
|
|
96
|
+
message: z.string().min(1),
|
|
97
|
+
details: z.record(z.unknown()).optional()
|
|
98
|
+
});
|
|
99
|
+
var ApiErrorResponseSchema = z.object({
|
|
100
|
+
error: ApiErrorPayloadSchema
|
|
101
|
+
});
|
|
102
|
+
var ErrorLogFieldsSchema = z.object({
|
|
103
|
+
level: z.enum(["warn", "error"]),
|
|
104
|
+
code: ErrorCode,
|
|
105
|
+
prefix: z.string().min(1),
|
|
106
|
+
msg: z.string().min(1)
|
|
107
|
+
}).catchall(z.unknown());
|
|
108
|
+
|
|
109
|
+
// src/shared/chat/piChatSchemas.ts
|
|
110
|
+
import { z as z2 } from "zod";
|
|
111
|
+
var nonEmptyString = z2.string().min(1);
|
|
112
|
+
var seqNumber = z2.number().int().nonnegative();
|
|
113
|
+
var ShallowPayloadSchema = z2.union([
|
|
114
|
+
z2.string(),
|
|
115
|
+
z2.number(),
|
|
116
|
+
z2.boolean(),
|
|
117
|
+
z2.null(),
|
|
118
|
+
z2.array(z2.unknown()),
|
|
119
|
+
z2.record(z2.unknown())
|
|
120
|
+
]);
|
|
121
|
+
function isRecord2(value) {
|
|
122
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
123
|
+
}
|
|
124
|
+
var ToolUiMetadataSchema = z2.object({
|
|
125
|
+
rendererId: z2.string().optional(),
|
|
126
|
+
displayGroup: z2.string().optional(),
|
|
127
|
+
icon: z2.string().optional(),
|
|
128
|
+
details: z2.unknown().optional()
|
|
129
|
+
});
|
|
130
|
+
function sanitizeToolUiMetadata2(value) {
|
|
131
|
+
if (!isRecord2(value)) return void 0;
|
|
132
|
+
const parsed = ToolUiMetadataSchema.safeParse(value);
|
|
133
|
+
return parsed.success ? parsed.data : void 0;
|
|
134
|
+
}
|
|
135
|
+
var OptionalToolUiMetadataSchema = z2.preprocess(
|
|
136
|
+
(value) => sanitizeToolUiMetadata2(value),
|
|
137
|
+
ToolUiMetadataSchema.optional()
|
|
138
|
+
);
|
|
139
|
+
var ChatErrorSchema = z2.object({
|
|
140
|
+
code: ErrorCode,
|
|
141
|
+
message: nonEmptyString,
|
|
142
|
+
retryable: z2.boolean().optional(),
|
|
143
|
+
details: z2.unknown().optional()
|
|
144
|
+
});
|
|
145
|
+
var BoringChatPartSchema = z2.discriminatedUnion("type", [
|
|
146
|
+
z2.object({ type: z2.literal("text"), id: z2.string().optional(), text: z2.string() }),
|
|
147
|
+
z2.object({
|
|
148
|
+
type: z2.literal("reasoning"),
|
|
149
|
+
id: nonEmptyString,
|
|
150
|
+
text: z2.string(),
|
|
151
|
+
state: z2.enum(["streaming", "done"]).optional()
|
|
152
|
+
}),
|
|
153
|
+
z2.object({
|
|
154
|
+
type: z2.literal("tool-call"),
|
|
155
|
+
id: nonEmptyString,
|
|
156
|
+
toolName: nonEmptyString,
|
|
157
|
+
input: z2.unknown().optional(),
|
|
158
|
+
state: z2.enum(["input-streaming", "input-available", "output-available", "output-error", "aborted"]),
|
|
159
|
+
output: z2.unknown().optional(),
|
|
160
|
+
errorText: z2.string().optional(),
|
|
161
|
+
ui: OptionalToolUiMetadataSchema
|
|
162
|
+
}),
|
|
163
|
+
z2.object({
|
|
164
|
+
type: z2.literal("file"),
|
|
165
|
+
id: z2.string().optional(),
|
|
166
|
+
filename: z2.string().optional(),
|
|
167
|
+
mediaType: z2.string().optional(),
|
|
168
|
+
url: z2.string().optional()
|
|
169
|
+
}),
|
|
170
|
+
z2.object({
|
|
171
|
+
type: z2.literal("notice"),
|
|
172
|
+
id: z2.string().optional(),
|
|
173
|
+
level: z2.enum(["info", "warning", "error"]),
|
|
174
|
+
text: z2.string()
|
|
175
|
+
})
|
|
176
|
+
]);
|
|
177
|
+
var BoringChatMessageSchema = z2.object({
|
|
178
|
+
id: nonEmptyString,
|
|
179
|
+
role: z2.enum(["user", "assistant", "system"]),
|
|
180
|
+
status: z2.enum(["pending", "streaming", "done", "aborted", "error"]).optional(),
|
|
181
|
+
parts: z2.array(BoringChatPartSchema),
|
|
182
|
+
createdAt: z2.string().optional(),
|
|
183
|
+
clientNonce: z2.string().optional(),
|
|
184
|
+
clientSeq: z2.number().int().nonnegative().optional(),
|
|
185
|
+
piEntryId: z2.string().optional(),
|
|
186
|
+
turnId: z2.string().optional()
|
|
187
|
+
});
|
|
188
|
+
var QueuedUserMessageSchema = z2.object({
|
|
189
|
+
id: nonEmptyString,
|
|
190
|
+
kind: z2.literal("followup"),
|
|
191
|
+
clientNonce: z2.string().optional(),
|
|
192
|
+
clientSeq: z2.number().int().nonnegative().optional(),
|
|
193
|
+
displayText: z2.string(),
|
|
194
|
+
createdAt: z2.string().optional()
|
|
195
|
+
});
|
|
196
|
+
var PiChatStatusSchema = z2.enum(["idle", "hydrating", "submitted", "streaming", "aborting", "error"]);
|
|
197
|
+
var PiChatSnapshotSchema = z2.object({
|
|
198
|
+
protocolVersion: z2.literal(1),
|
|
199
|
+
sessionId: nonEmptyString,
|
|
200
|
+
seq: seqNumber,
|
|
201
|
+
status: PiChatStatusSchema,
|
|
202
|
+
activeTurnId: z2.string().optional(),
|
|
203
|
+
messages: z2.array(BoringChatMessageSchema),
|
|
204
|
+
queue: z2.object({ followUps: z2.array(QueuedUserMessageSchema) }),
|
|
205
|
+
followUpMode: z2.literal("one-at-a-time"),
|
|
206
|
+
error: ChatErrorSchema.optional()
|
|
207
|
+
});
|
|
208
|
+
var baseEvent = z2.object({ seq: seqNumber });
|
|
209
|
+
var PiChatEventSchema = z2.discriminatedUnion("type", [
|
|
210
|
+
baseEvent.extend({ type: z2.literal("agent-start"), turnId: nonEmptyString }),
|
|
211
|
+
baseEvent.extend({ type: z2.literal("agent-end"), turnId: nonEmptyString, status: z2.enum(["ok", "aborted", "error"]) }),
|
|
212
|
+
baseEvent.extend({
|
|
213
|
+
type: z2.literal("message-start"),
|
|
214
|
+
messageId: nonEmptyString,
|
|
215
|
+
role: z2.enum(["user", "assistant"]),
|
|
216
|
+
clientNonce: z2.string().optional(),
|
|
217
|
+
clientSeq: z2.number().int().nonnegative().optional(),
|
|
218
|
+
createdAt: z2.string().optional(),
|
|
219
|
+
text: z2.string().optional(),
|
|
220
|
+
files: z2.array(BoringChatPartSchema).optional()
|
|
221
|
+
}),
|
|
222
|
+
baseEvent.extend({
|
|
223
|
+
type: z2.literal("message-delta"),
|
|
224
|
+
messageId: nonEmptyString,
|
|
225
|
+
partId: nonEmptyString,
|
|
226
|
+
kind: z2.enum(["text", "reasoning"]),
|
|
227
|
+
delta: z2.string()
|
|
228
|
+
}),
|
|
229
|
+
baseEvent.extend({
|
|
230
|
+
type: z2.literal("message-part-end"),
|
|
231
|
+
messageId: nonEmptyString,
|
|
232
|
+
partId: nonEmptyString,
|
|
233
|
+
kind: z2.enum(["text", "reasoning"]),
|
|
234
|
+
text: z2.string()
|
|
235
|
+
}),
|
|
236
|
+
baseEvent.extend({ type: z2.literal("message-end"), messageId: nonEmptyString, final: BoringChatMessageSchema }),
|
|
237
|
+
baseEvent.extend({
|
|
238
|
+
type: z2.literal("tool-call"),
|
|
239
|
+
messageId: nonEmptyString,
|
|
240
|
+
toolCallId: nonEmptyString,
|
|
241
|
+
toolName: nonEmptyString,
|
|
242
|
+
input: ShallowPayloadSchema,
|
|
243
|
+
ui: OptionalToolUiMetadataSchema
|
|
244
|
+
}),
|
|
245
|
+
baseEvent.extend({
|
|
246
|
+
type: z2.literal("tool-result"),
|
|
247
|
+
messageId: nonEmptyString,
|
|
248
|
+
toolCallId: nonEmptyString,
|
|
249
|
+
output: ShallowPayloadSchema,
|
|
250
|
+
isError: z2.boolean().optional(),
|
|
251
|
+
errorText: z2.string().optional(),
|
|
252
|
+
ui: OptionalToolUiMetadataSchema
|
|
253
|
+
}),
|
|
254
|
+
baseEvent.extend({ type: z2.literal("queue-updated"), queue: z2.object({ followUps: z2.array(QueuedUserMessageSchema) }) }),
|
|
255
|
+
baseEvent.extend({
|
|
256
|
+
type: z2.literal("followup-consumed"),
|
|
257
|
+
clientNonce: z2.string().optional(),
|
|
258
|
+
clientSeq: z2.number().int().nonnegative().optional(),
|
|
259
|
+
messageId: nonEmptyString
|
|
260
|
+
}),
|
|
261
|
+
baseEvent.extend({ type: z2.literal("file-changed"), path: nonEmptyString, changeType: nonEmptyString }),
|
|
262
|
+
baseEvent.extend({ type: z2.literal("ui-command"), command: ShallowPayloadSchema, displayOnly: z2.literal(true) }),
|
|
263
|
+
baseEvent.extend({ type: z2.literal("usage"), usage: ShallowPayloadSchema }),
|
|
264
|
+
baseEvent.extend({
|
|
265
|
+
type: z2.literal("auto-retry-start"),
|
|
266
|
+
attempt: z2.number().int().nonnegative(),
|
|
267
|
+
maxAttempts: z2.number().int().nonnegative(),
|
|
268
|
+
delayMs: z2.number().int().nonnegative(),
|
|
269
|
+
errorMessage: z2.string()
|
|
270
|
+
}),
|
|
271
|
+
baseEvent.extend({
|
|
272
|
+
type: z2.literal("auto-retry-end"),
|
|
273
|
+
success: z2.boolean(),
|
|
274
|
+
attempt: z2.number().int().nonnegative(),
|
|
275
|
+
finalError: z2.string().optional()
|
|
276
|
+
}),
|
|
277
|
+
baseEvent.extend({ type: z2.literal("error"), turnId: z2.string().optional(), retryable: z2.boolean().optional(), error: ChatErrorSchema })
|
|
278
|
+
]);
|
|
279
|
+
var PiChatHeartbeatFrameSchema = z2.object({ type: z2.literal("heartbeat"), now: z2.string() });
|
|
280
|
+
var PiChatStreamFrameSchema = z2.union([PiChatEventSchema, PiChatHeartbeatFrameSchema]);
|
|
281
|
+
var ChatModelSelectionSchema = z2.object({
|
|
282
|
+
provider: nonEmptyString,
|
|
283
|
+
id: nonEmptyString
|
|
284
|
+
});
|
|
285
|
+
var ThinkingLevelSchema = z2.enum(["off", "low", "medium", "high"]);
|
|
286
|
+
var ChatAttachmentPayloadSchema = z2.object({
|
|
287
|
+
filename: z2.string().optional(),
|
|
288
|
+
mediaType: z2.string().optional(),
|
|
289
|
+
url: nonEmptyString
|
|
290
|
+
});
|
|
291
|
+
var PromptPayloadSchema = z2.object({
|
|
292
|
+
message: z2.string().min(1).max(1e6),
|
|
293
|
+
displayMessage: z2.string().min(1).max(1e6).optional(),
|
|
294
|
+
clientNonce: nonEmptyString.max(128),
|
|
295
|
+
model: ChatModelSelectionSchema.optional(),
|
|
296
|
+
thinkingLevel: ThinkingLevelSchema.optional(),
|
|
297
|
+
attachments: z2.array(ChatAttachmentPayloadSchema).max(20).optional()
|
|
298
|
+
});
|
|
299
|
+
var FollowUpPayloadSchema = z2.object({
|
|
300
|
+
message: z2.string().min(1).max(1e6),
|
|
301
|
+
displayMessage: z2.string().min(1).max(1e6).optional(),
|
|
302
|
+
clientNonce: nonEmptyString.max(128),
|
|
303
|
+
clientSeq: z2.number().int().nonnegative()
|
|
304
|
+
});
|
|
305
|
+
var QueueClearPayloadSchema = z2.preprocess(
|
|
306
|
+
(value) => value ?? {},
|
|
307
|
+
z2.object({
|
|
308
|
+
clientNonce: nonEmptyString.max(128).optional(),
|
|
309
|
+
clientSeq: z2.number().int().nonnegative().optional()
|
|
310
|
+
}).strict()
|
|
311
|
+
);
|
|
312
|
+
var InterruptPayloadSchema = z2.object({}).strict();
|
|
313
|
+
var StopPayloadSchema = z2.object({}).strict();
|
|
314
|
+
var CommandReceiptSchema = z2.object({
|
|
315
|
+
accepted: z2.literal(true),
|
|
316
|
+
cursor: seqNumber
|
|
317
|
+
});
|
|
318
|
+
var PromptReceiptSchema = CommandReceiptSchema.extend({
|
|
319
|
+
clientNonce: nonEmptyString,
|
|
320
|
+
duplicate: z2.boolean().optional()
|
|
321
|
+
});
|
|
322
|
+
var FollowUpReceiptSchema = CommandReceiptSchema.extend({
|
|
323
|
+
clientNonce: nonEmptyString,
|
|
324
|
+
clientSeq: z2.number().int().nonnegative(),
|
|
325
|
+
queued: z2.literal(true),
|
|
326
|
+
duplicate: z2.boolean().optional()
|
|
327
|
+
});
|
|
328
|
+
var QueueClearReceiptSchema = CommandReceiptSchema.extend({
|
|
329
|
+
cleared: z2.number().int().nonnegative()
|
|
330
|
+
});
|
|
331
|
+
var StopReceiptSchema = CommandReceiptSchema.extend({
|
|
332
|
+
stopped: z2.boolean(),
|
|
333
|
+
clearedQueue: z2.array(QueuedUserMessageSchema)
|
|
334
|
+
});
|
|
335
|
+
|
|
336
|
+
export {
|
|
337
|
+
isToolUiMetadata,
|
|
338
|
+
sanitizeToolUiMetadata,
|
|
339
|
+
extractToolUiMetadata,
|
|
340
|
+
ErrorCode,
|
|
341
|
+
ERROR_CODES,
|
|
342
|
+
ApiErrorPayloadSchema,
|
|
343
|
+
ApiErrorResponseSchema,
|
|
344
|
+
ErrorLogFieldsSchema,
|
|
345
|
+
ToolUiMetadataSchema,
|
|
346
|
+
sanitizeToolUiMetadata2,
|
|
347
|
+
ChatErrorSchema,
|
|
348
|
+
BoringChatPartSchema,
|
|
349
|
+
BoringChatMessageSchema,
|
|
350
|
+
QueuedUserMessageSchema,
|
|
351
|
+
PiChatStatusSchema,
|
|
352
|
+
PiChatSnapshotSchema,
|
|
353
|
+
PiChatEventSchema,
|
|
354
|
+
PiChatHeartbeatFrameSchema,
|
|
355
|
+
PiChatStreamFrameSchema,
|
|
356
|
+
ChatModelSelectionSchema,
|
|
357
|
+
ThinkingLevelSchema,
|
|
358
|
+
ChatAttachmentPayloadSchema,
|
|
359
|
+
PromptPayloadSchema,
|
|
360
|
+
FollowUpPayloadSchema,
|
|
361
|
+
QueueClearPayloadSchema,
|
|
362
|
+
InterruptPayloadSchema,
|
|
363
|
+
StopPayloadSchema,
|
|
364
|
+
CommandReceiptSchema,
|
|
365
|
+
PromptReceiptSchema,
|
|
366
|
+
FollowUpReceiptSchema,
|
|
367
|
+
QueueClearReceiptSchema,
|
|
368
|
+
StopReceiptSchema
|
|
369
|
+
};
|