@hachej/boring-agent 0.1.43 → 0.1.44
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/{agentPluginEvents-DP-vLNCs.d.ts → agentPluginEvents-Dgm57gEU.d.ts} +1 -1
- package/dist/{chatSubmitPayload-gC61O4Ni.d.ts → chatSubmitPayload-DHqQL2wD.d.ts} +2 -0
- package/dist/{chunk-YUDMSYAO.js → chunk-HEEJSOFF.js} +2 -1
- package/dist/front/index.d.ts +5 -2
- package/dist/front/index.js +80 -16
- package/dist/{piChatEvent-DR9a-FVz.d.ts → piChatEvent-DNKo77Xw.d.ts} +1 -1
- package/dist/server/index.d.ts +3 -3
- package/dist/server/index.js +55 -17
- package/dist/shared/index.d.ts +13 -5
- package/dist/shared/index.js +1 -1
- package/package.json +2 -2
|
@@ -33,6 +33,8 @@ interface ChatAttachmentPayload {
|
|
|
33
33
|
filename?: string;
|
|
34
34
|
mediaType?: string;
|
|
35
35
|
url: string;
|
|
36
|
+
/** Workspace-relative path when the browser upload endpoint persisted the attachment. */
|
|
37
|
+
path?: string;
|
|
36
38
|
}
|
|
37
39
|
interface ChatSubmitPayload {
|
|
38
40
|
message: string;
|
|
@@ -291,7 +291,8 @@ var ThinkingLevelSchema = z2.enum(["off", "low", "medium", "high"]);
|
|
|
291
291
|
var ChatAttachmentPayloadSchema = z2.object({
|
|
292
292
|
filename: z2.string().optional(),
|
|
293
293
|
mediaType: z2.string().optional(),
|
|
294
|
-
url: nonEmptyString
|
|
294
|
+
url: nonEmptyString,
|
|
295
|
+
path: z2.string().optional()
|
|
295
296
|
});
|
|
296
297
|
var PromptPayloadSchema = z2.object({
|
|
297
298
|
message: z2.string().min(1).max(1e6),
|
package/dist/front/index.d.ts
CHANGED
|
@@ -2,8 +2,8 @@ import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
|
2
2
|
import * as react from 'react';
|
|
3
3
|
import { ComponentType, ReactNode, HTMLAttributes, ComponentProps, FormEvent } from 'react';
|
|
4
4
|
import { FileUIPart, UIMessage, ChatStatus } from 'ai';
|
|
5
|
-
import { T as ToolUiMetadata, B as BoringChatPart, d as BoringChatMessage, m as PiChatStatus, r as QueuedUserMessage, C as ChatError, P as PiChatEvent, o as PromptPayload, p as PromptReceipt, F as FollowUpPayload, i as FollowUpReceipt, Q as QueueClearPayload, q as QueueClearReceipt, I as InterruptPayload, e as CommandReceipt, S as StopPayload, s as StopReceipt } from '../piChatEvent-
|
|
6
|
-
import { e as SessionSummary } from '../chatSubmitPayload-
|
|
5
|
+
import { T as ToolUiMetadata, B as BoringChatPart, d as BoringChatMessage, m as PiChatStatus, r as QueuedUserMessage, C as ChatError, P as PiChatEvent, o as PromptPayload, p as PromptReceipt, F as FollowUpPayload, i as FollowUpReceipt, Q as QueueClearPayload, q as QueueClearReceipt, I as InterruptPayload, e as CommandReceipt, S as StopPayload, s as StopReceipt } from '../piChatEvent-DNKo77Xw.js';
|
|
6
|
+
import { e as SessionSummary } from '../chatSubmitPayload-DHqQL2wD.js';
|
|
7
7
|
import { Button, Collapsible, CollapsibleContent, CollapsibleTrigger, InputGroupAddon, InputGroupButton, InputGroupTextarea } from '@hachej/boring-ui-kit';
|
|
8
8
|
import { Streamdown } from 'streamdown';
|
|
9
9
|
import { StickToBottom } from 'use-stick-to-bottom';
|
|
@@ -15,6 +15,7 @@ interface UploadFileOptions {
|
|
|
15
15
|
workspaceRequestId?: string | null;
|
|
16
16
|
directory?: string;
|
|
17
17
|
sourcePath?: string;
|
|
18
|
+
fetch?: typeof globalThis.fetch;
|
|
18
19
|
}
|
|
19
20
|
interface UploadFileResult {
|
|
20
21
|
url: string;
|
|
@@ -390,6 +391,7 @@ declare class RemotePiSession {
|
|
|
390
391
|
private connectEvents;
|
|
391
392
|
private runEventStream;
|
|
392
393
|
private rehydrateAfterStreamReset;
|
|
394
|
+
private ensureReconnectScheduled;
|
|
393
395
|
private scheduleReconnect;
|
|
394
396
|
private postCommand;
|
|
395
397
|
private rollbackOptimisticMessage;
|
|
@@ -695,6 +697,7 @@ type PromptInputProps = Omit<HTMLAttributes<HTMLFormElement>, "onSubmit" | "onEr
|
|
|
695
697
|
* attachment URL is replaced with the stable server path before submit. */
|
|
696
698
|
onUploadFile?: (file: File) => Promise<{
|
|
697
699
|
url: string;
|
|
700
|
+
path?: string;
|
|
698
701
|
}>;
|
|
699
702
|
};
|
|
700
703
|
declare const PromptInput: ({ className, accept, multiple, globalDrop, syncHiddenInput, maxFiles, maxFileSize, onError, onSubmit, onUploadFile, children, ...props }: PromptInputProps) => react_jsx_runtime.JSX.Element;
|
package/dist/front/index.js
CHANGED
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
StopReceiptSchema,
|
|
14
14
|
extractToolUiMetadata,
|
|
15
15
|
sanitizeToolUiMetadata
|
|
16
|
-
} from "../chunk-
|
|
16
|
+
} from "../chunk-HEEJSOFF.js";
|
|
17
17
|
import {
|
|
18
18
|
DebugDrawer,
|
|
19
19
|
cn,
|
|
@@ -30,14 +30,14 @@ function readAsDataUrl(file) {
|
|
|
30
30
|
});
|
|
31
31
|
}
|
|
32
32
|
async function uploadFile(file, opts = {}) {
|
|
33
|
-
const { apiBaseUrl = "", workspaceRequestId, directory, sourcePath } = opts;
|
|
33
|
+
const { apiBaseUrl = "", workspaceRequestId, directory, sourcePath, fetch: fetchImpl = globalThis.fetch } = opts;
|
|
34
34
|
const dataUrl = await readAsDataUrl(file);
|
|
35
35
|
const comma = dataUrl.indexOf(",");
|
|
36
36
|
const contentBase64 = comma >= 0 ? dataUrl.slice(comma + 1) : "";
|
|
37
37
|
const headers = { "Content-Type": "application/json" };
|
|
38
38
|
if (workspaceRequestId) headers["x-boring-workspace-id"] = workspaceRequestId;
|
|
39
39
|
const base = apiBaseUrl.replace(/\/$/, "");
|
|
40
|
-
const res = await
|
|
40
|
+
const res = await fetchImpl(`${base}/api/v1/files/upload`, {
|
|
41
41
|
method: "POST",
|
|
42
42
|
headers,
|
|
43
43
|
credentials: "include",
|
|
@@ -2230,7 +2230,8 @@ async function resolveAttachmentUrls(files) {
|
|
|
2230
2230
|
return Promise.all(files.map(async (file) => ({
|
|
2231
2231
|
filename: file.filename,
|
|
2232
2232
|
mediaType: file.mediaType,
|
|
2233
|
-
url: file.url.startsWith("blob:") ? await convertBlobUrlToDataUrl(file.url) ?? file.url : file.url
|
|
2233
|
+
url: file.url.startsWith("blob:") ? await convertBlobUrlToDataUrl(file.url) ?? file.url : file.url,
|
|
2234
|
+
...typeof file.path === "string" ? { path: file.path } : {}
|
|
2234
2235
|
})));
|
|
2235
2236
|
}
|
|
2236
2237
|
async function readFileAsText(file) {
|
|
@@ -2255,14 +2256,18 @@ async function createEnrichedSubmitPayload({
|
|
|
2255
2256
|
for (const file of files ?? []) {
|
|
2256
2257
|
const label = file.filename ?? "attachment";
|
|
2257
2258
|
const mime = file.mediaType ?? "application/octet-stream";
|
|
2259
|
+
const workspacePath = typeof file.path === "string" ? file.path : void 0;
|
|
2260
|
+
const pathNote = workspacePath ? `
|
|
2261
|
+
Saved in workspace at: ${workspacePath}
|
|
2262
|
+
Use the workspace file/read tools with this path if you need to inspect it.` : "";
|
|
2258
2263
|
const content = await readFileAsText(file);
|
|
2259
2264
|
if (content !== null) {
|
|
2260
|
-
attachmentSummaries.push(`[attached: ${label} (${mime})]
|
|
2265
|
+
attachmentSummaries.push(`[attached: ${label} (${mime})${pathNote}]
|
|
2261
2266
|
\`\`\`
|
|
2262
2267
|
${content}
|
|
2263
2268
|
\`\`\``);
|
|
2264
2269
|
} else {
|
|
2265
|
-
attachmentSummaries.push(`[attached: ${label} (${mime}, not inlined \u2014 binary)]`);
|
|
2270
|
+
attachmentSummaries.push(`[attached: ${label} (${mime}, not inlined \u2014 binary)${pathNote}]`);
|
|
2266
2271
|
}
|
|
2267
2272
|
}
|
|
2268
2273
|
const mentionNote = mentionedFiles.length > 0 ? `@files: ${mentionedFiles.join(", ")}` : null;
|
|
@@ -3246,7 +3251,7 @@ function selectQueuePreview(state) {
|
|
|
3246
3251
|
}
|
|
3247
3252
|
function selectRuntimeNotices(state) {
|
|
3248
3253
|
const notices = [...state.notices];
|
|
3249
|
-
if (state.connection.state === "reconnecting") {
|
|
3254
|
+
if (state.connection.state === "reconnecting" && hasVisibleReconnectWork(state)) {
|
|
3250
3255
|
notices.push({ id: "connection-reconnecting", level: "warning", text: "Reconnecting to the agent session\u2026" });
|
|
3251
3256
|
}
|
|
3252
3257
|
if (state.retryNotice) {
|
|
@@ -3261,6 +3266,9 @@ function selectRuntimeNotices(state) {
|
|
|
3261
3266
|
}
|
|
3262
3267
|
return notices;
|
|
3263
3268
|
}
|
|
3269
|
+
function hasVisibleReconnectWork(state) {
|
|
3270
|
+
return state.status !== "idle" || state.queue.followUps.length > 0 || Object.keys(state.optimisticOutbox).length > 0 || state.pendingToolCallIds.size > 0;
|
|
3271
|
+
}
|
|
3264
3272
|
function optimisticText(message) {
|
|
3265
3273
|
const text = message.parts.filter((part) => part.type === "text").map((part) => part.text).join("\n\n");
|
|
3266
3274
|
return text;
|
|
@@ -3703,10 +3711,18 @@ function piChatReducer(state, action) {
|
|
|
3703
3711
|
queue: { followUps: clearQueuedFollowUps(state.queue.followUps, action) },
|
|
3704
3712
|
optimisticOutbox: clearOptimisticFollowUps(state.optimisticOutbox, action)
|
|
3705
3713
|
};
|
|
3706
|
-
case "connection-state":
|
|
3707
|
-
|
|
3714
|
+
case "connection-state": {
|
|
3715
|
+
const nextState = {
|
|
3716
|
+
...state,
|
|
3717
|
+
connection: { ...state.connection, state: action.state }
|
|
3718
|
+
};
|
|
3719
|
+
return action.state === "connected" ? clearProtocolError(nextState) : nextState;
|
|
3720
|
+
}
|
|
3708
3721
|
case "heartbeat":
|
|
3709
|
-
return {
|
|
3722
|
+
return clearProtocolError({
|
|
3723
|
+
...state,
|
|
3724
|
+
connection: { ...state.connection, lastHeartbeatAt: action.now ?? Date.now() }
|
|
3725
|
+
});
|
|
3710
3726
|
case "protocol-error":
|
|
3711
3727
|
return {
|
|
3712
3728
|
...state,
|
|
@@ -3723,6 +3739,14 @@ function piChatReducer(state, action) {
|
|
|
3723
3739
|
return { ...state, notices: state.notices.filter((notice) => notice.id !== action.id) };
|
|
3724
3740
|
}
|
|
3725
3741
|
}
|
|
3742
|
+
function clearProtocolError(state) {
|
|
3743
|
+
if (!state.notices.some((notice) => notice.id === "protocol-error")) return state;
|
|
3744
|
+
return {
|
|
3745
|
+
...state,
|
|
3746
|
+
error: void 0,
|
|
3747
|
+
notices: state.notices.filter((notice) => notice.id !== "protocol-error")
|
|
3748
|
+
};
|
|
3749
|
+
}
|
|
3726
3750
|
function syncCursor(state, cursor) {
|
|
3727
3751
|
if (cursor <= state.lastSeq) return { ...state, hydrated: true, needsResync: void 0 };
|
|
3728
3752
|
return { ...state, lastSeq: cursor, hydrated: true, needsResync: void 0 };
|
|
@@ -3730,7 +3754,9 @@ function syncCursor(state, cursor) {
|
|
|
3730
3754
|
function hydrateFromSnapshot(state, snapshot, options = {}) {
|
|
3731
3755
|
if (snapshot.seq < state.lastSeq && !options.allowSeqRewind) return state;
|
|
3732
3756
|
const queue = { followUps: enrichQueueWithKnownMetadata(snapshot.queue.followUps, state.optimisticOutbox, state.queue.followUps) };
|
|
3733
|
-
const
|
|
3757
|
+
const snapshotMessages = normalizeSnapshotMessages(snapshot.messages);
|
|
3758
|
+
const preserveLocalHistory = shouldPreserveLocalCommittedHistory(state, snapshot, snapshotMessages, options);
|
|
3759
|
+
const committedMessages = preserveLocalHistory ? mergeSnapshotMessagesIntoLocal(state.committedMessages, snapshotMessages) : snapshotMessages;
|
|
3734
3760
|
const serverNonces = /* @__PURE__ */ new Set();
|
|
3735
3761
|
for (const message of committedMessages) {
|
|
3736
3762
|
if (message.clientNonce) serverNonces.add(message.clientNonce);
|
|
@@ -3739,7 +3765,12 @@ function hydrateFromSnapshot(state, snapshot, options = {}) {
|
|
|
3739
3765
|
if (followUp.clientNonce) serverNonces.add(followUp.clientNonce);
|
|
3740
3766
|
}
|
|
3741
3767
|
const nextOutbox = {};
|
|
3742
|
-
|
|
3768
|
+
if (preserveLocalHistory) {
|
|
3769
|
+
for (const message of Object.values(state.optimisticOutbox)) {
|
|
3770
|
+
if (!serverNonces.has(message.clientNonce)) nextOutbox[message.clientNonce] = message;
|
|
3771
|
+
}
|
|
3772
|
+
}
|
|
3773
|
+
const staleOutbox = preserveLocalHistory ? [] : Object.values(state.optimisticOutbox).filter((message) => !serverNonces.has(message.clientNonce));
|
|
3743
3774
|
const notices = staleOutbox.length > 0 ? upsertNotice(state.notices, {
|
|
3744
3775
|
id: "stale-outbox-cleared",
|
|
3745
3776
|
level: "warning",
|
|
@@ -3766,6 +3797,22 @@ function hydrateFromSnapshot(state, snapshot, options = {}) {
|
|
|
3766
3797
|
needsResync: void 0
|
|
3767
3798
|
};
|
|
3768
3799
|
}
|
|
3800
|
+
function shouldPreserveLocalCommittedHistory(state, snapshot, snapshotMessages, options) {
|
|
3801
|
+
if (options.allowSeqRewind) return false;
|
|
3802
|
+
if (!state.hydrated) return false;
|
|
3803
|
+
if (state.sessionId !== snapshot.sessionId) return false;
|
|
3804
|
+
if (state.committedMessages.length === 0) return false;
|
|
3805
|
+
if (snapshotMessages.length < state.committedMessages.length) return true;
|
|
3806
|
+
for (let index = 0; index < state.committedMessages.length; index += 1) {
|
|
3807
|
+
if (snapshotMessages[index]?.id !== state.committedMessages[index]?.id) return true;
|
|
3808
|
+
}
|
|
3809
|
+
return false;
|
|
3810
|
+
}
|
|
3811
|
+
function mergeSnapshotMessagesIntoLocal(currentMessages, snapshotMessages) {
|
|
3812
|
+
let merged = currentMessages;
|
|
3813
|
+
for (const message of snapshotMessages) merged = replaceOrAppendMessage(merged, message);
|
|
3814
|
+
return merged;
|
|
3815
|
+
}
|
|
3769
3816
|
function applySequencedEvent(state, event) {
|
|
3770
3817
|
if (event.seq <= state.lastSeq) return state;
|
|
3771
3818
|
const expectedSeq = state.lastSeq + 1;
|
|
@@ -4494,6 +4541,7 @@ var RemotePiSession = class {
|
|
|
4494
4541
|
this.store.dispatch({ type: "optimistic-user-message", message: toOptimisticUserMessage(payload) }, { flush: true });
|
|
4495
4542
|
}
|
|
4496
4543
|
if (!this.started) await this.start(this.store.getState().lastSeq);
|
|
4544
|
+
else this.ensureReconnectScheduled();
|
|
4497
4545
|
try {
|
|
4498
4546
|
const receipt = await this.postCommand("/prompt", payload, PromptReceiptSchema);
|
|
4499
4547
|
return receipt;
|
|
@@ -4507,6 +4555,7 @@ var RemotePiSession = class {
|
|
|
4507
4555
|
this.store.dispatch({ type: "optimistic-user-message", message: toOptimisticUserMessage(payload) }, { flush: true });
|
|
4508
4556
|
}
|
|
4509
4557
|
if (!this.started) await this.start(this.store.getState().lastSeq);
|
|
4558
|
+
else this.ensureReconnectScheduled();
|
|
4510
4559
|
try {
|
|
4511
4560
|
const receipt = await this.postCommand("/followup", payload, FollowUpReceiptSchema);
|
|
4512
4561
|
return receipt;
|
|
@@ -4675,7 +4724,9 @@ var RemotePiSession = class {
|
|
|
4675
4724
|
markOpen();
|
|
4676
4725
|
if (!this.isStreamActive(generation, runId)) return;
|
|
4677
4726
|
if (!connectTimedOut && shouldIgnoreStreamClose(error, controller)) return;
|
|
4678
|
-
|
|
4727
|
+
if (!connectTimedOut) {
|
|
4728
|
+
this.dispatchProtocolError(errorMessage(error, "Pi chat event stream disconnected."));
|
|
4729
|
+
}
|
|
4679
4730
|
this.scheduleReconnect(generation);
|
|
4680
4731
|
} finally {
|
|
4681
4732
|
clearConnectTimer();
|
|
@@ -4687,6 +4738,13 @@ var RemotePiSession = class {
|
|
|
4687
4738
|
this.abortEventStream();
|
|
4688
4739
|
void this.hydrateAndConnect(generation, options);
|
|
4689
4740
|
}
|
|
4741
|
+
ensureReconnectScheduled() {
|
|
4742
|
+
if (!this.isGenerationActive(this.generation)) return;
|
|
4743
|
+
const state = this.store.getState();
|
|
4744
|
+
if (state.connection.state === "connected" || state.connection.state === "connecting") return;
|
|
4745
|
+
if (this.reconnectTimer !== void 0) return;
|
|
4746
|
+
void this.hydrateAndConnect(this.generation);
|
|
4747
|
+
}
|
|
4690
4748
|
scheduleReconnect(generation) {
|
|
4691
4749
|
if (!this.isGenerationActive(generation)) return;
|
|
4692
4750
|
this.clearReconnectTimer();
|
|
@@ -7988,11 +8046,11 @@ var PromptInput = ({
|
|
|
7988
8046
|
const inputRef = useRef14(null);
|
|
7989
8047
|
const formRef = useRef14(null);
|
|
7990
8048
|
const [items, setItems] = useState17([]);
|
|
7991
|
-
const setFileUrlLocal = useCallback15((id, url, status) => {
|
|
8049
|
+
const setFileUrlLocal = useCallback15((id, url, status, path) => {
|
|
7992
8050
|
setItems((prev) => prev.map((f) => {
|
|
7993
8051
|
if (f.id !== id) return f;
|
|
7994
8052
|
if (f.url !== url && f.url.startsWith("blob:")) URL.revokeObjectURL(f.url);
|
|
7995
|
-
return { ...f, url, status };
|
|
8053
|
+
return { ...f, url, status, ...path ? { path } : {} };
|
|
7996
8054
|
}));
|
|
7997
8055
|
}, []);
|
|
7998
8056
|
const files = usingProvider ? controller.attachments.files : items;
|
|
@@ -8061,7 +8119,7 @@ var PromptInput = ({
|
|
|
8061
8119
|
for (let i = 0; i < entries.length; i++) {
|
|
8062
8120
|
const entry = entries[i];
|
|
8063
8121
|
const file = capped[i];
|
|
8064
|
-
onUploadFile(file).then(({ url }) => setFileUrlLocal(entry.id, url, "ready")).catch(() => setFileUrlLocal(entry.id, entry.url, "error"));
|
|
8122
|
+
onUploadFile(file).then(({ url, path }) => setFileUrlLocal(entry.id, url, "ready", path)).catch(() => setFileUrlLocal(entry.id, entry.url, "error"));
|
|
8065
8123
|
}
|
|
8066
8124
|
}
|
|
8067
8125
|
},
|
|
@@ -8744,6 +8802,11 @@ function PiChatComposerSurface({
|
|
|
8744
8802
|
onSubmitMessage,
|
|
8745
8803
|
onStop
|
|
8746
8804
|
}) {
|
|
8805
|
+
const uploadAttachment = useCallback16((file) => uploadFile(file, {
|
|
8806
|
+
apiBaseUrl,
|
|
8807
|
+
workspaceRequestId: requestHeaders?.["x-boring-workspace-id"],
|
|
8808
|
+
fetch: fetch2
|
|
8809
|
+
}), [apiBaseUrl, fetch2, requestHeaders]);
|
|
8747
8810
|
const resizeTextarea = useCallback16((node) => {
|
|
8748
8811
|
if (!node) return;
|
|
8749
8812
|
node.style.height = "auto";
|
|
@@ -8903,6 +8966,7 @@ function PiChatComposerSurface({
|
|
|
8903
8966
|
{
|
|
8904
8967
|
"data-boring-state": status,
|
|
8905
8968
|
onSubmit: (message) => onSubmitMessage({ text: message.text, files: message.files }),
|
|
8969
|
+
onUploadFile: uploadAttachment,
|
|
8906
8970
|
multiple: true,
|
|
8907
8971
|
maxFiles: disabled || isStreaming ? 0 : MAX_PROMPT_ATTACHMENTS,
|
|
8908
8972
|
maxFileSize: MAX_PROMPT_ATTACHMENT_BYTES,
|
package/dist/server/index.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { o as WorkspaceRuntimeContext, S as Sandbox, g as SandboxHandleStore, f as SandboxHandleRecord, W as Workspace, j as TelemetrySink, F as FileSearch, i as Stat, E as Entry, c as ExecResult, q as WorkspaceChangeEvent, b as ExecOptions, P as PluginRestartWarning, A as AgentTool, r as AgentHarnessFactory } from '../agentPluginEvents-
|
|
2
|
-
export { t as AgentHarnessFactoryInput } from '../agentPluginEvents-
|
|
1
|
+
import { o as WorkspaceRuntimeContext, S as Sandbox, g as SandboxHandleStore, f as SandboxHandleRecord, W as Workspace, j as TelemetrySink, F as FileSearch, i as Stat, E as Entry, c as ExecResult, q as WorkspaceChangeEvent, b as ExecOptions, P as PluginRestartWarning, A as AgentTool, r as AgentHarnessFactory } from '../agentPluginEvents-Dgm57gEU.js';
|
|
2
|
+
export { t as AgentHarnessFactoryInput } from '../agentPluginEvents-Dgm57gEU.js';
|
|
3
3
|
import { Sandbox as Sandbox$1 } from '@vercel/sandbox';
|
|
4
4
|
import { FastifyInstance, FastifyRequest, FastifyPluginAsync } from 'fastify';
|
|
5
5
|
import { PackageSource, ExtensionFactory, SettingsManager } from '@mariozechner/pi-coding-agent';
|
|
6
|
-
import { a as ChatModelSelection } from '../chatSubmitPayload-
|
|
6
|
+
import { a as ChatModelSelection } from '../chatSubmitPayload-DHqQL2wD.js';
|
|
7
7
|
|
|
8
8
|
interface CreateDirectSandboxOptions {
|
|
9
9
|
runtimeContext?: WorkspaceRuntimeContext;
|
package/dist/server/index.js
CHANGED
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
StopPayloadSchema,
|
|
14
14
|
extractToolUiMetadata,
|
|
15
15
|
sanitizeToolUiMetadata2 as sanitizeToolUiMetadata
|
|
16
|
-
} from "../chunk-
|
|
16
|
+
} from "../chunk-HEEJSOFF.js";
|
|
17
17
|
|
|
18
18
|
// src/server/sandbox/direct/createDirectSandbox.ts
|
|
19
19
|
import { spawn } from "child_process";
|
|
@@ -1795,13 +1795,15 @@ async function bakeSnapshotIfNeeded(opts) {
|
|
|
1795
1795
|
}
|
|
1796
1796
|
|
|
1797
1797
|
// src/server/sandbox/snapshots/deploymentSnapshot.ts
|
|
1798
|
-
var
|
|
1798
|
+
var VERCEL_UV_BIN_DIR = "/workspace/.boring-agent/sdk/uv/bin";
|
|
1799
|
+
var VERCEL_UV_BIN = `${VERCEL_UV_BIN_DIR}/uv`;
|
|
1799
1800
|
var UV_SETUP_COMMANDS = [
|
|
1800
1801
|
"command -v uv >/dev/null 2>&1 || python3 -m pip install --upgrade uv",
|
|
1801
1802
|
"uv --version"
|
|
1802
1803
|
];
|
|
1803
1804
|
var NODE_UV_SETUP_COMMANDS = [
|
|
1804
|
-
`
|
|
1805
|
+
`mkdir -p ${VERCEL_UV_BIN_DIR}`,
|
|
1806
|
+
`[ -x ${VERCEL_UV_BIN} ] || curl -LsSf https://astral.sh/uv/install.sh | UV_INSTALL_DIR=${VERCEL_UV_BIN_DIR} sh`,
|
|
1805
1807
|
`${VERCEL_UV_BIN} --version`
|
|
1806
1808
|
];
|
|
1807
1809
|
function isNodeFamilyRuntime(runtime) {
|
|
@@ -8723,19 +8725,25 @@ import { AuthStorage as AuthStorage2, ModelRegistry as ModelRegistry2 } from "@m
|
|
|
8723
8725
|
function modelsRoutes(app, _opts, done) {
|
|
8724
8726
|
const authStorage = AuthStorage2.create();
|
|
8725
8727
|
const registry = ModelRegistry2.create(authStorage);
|
|
8726
|
-
registerConfiguredModelProviders(registry);
|
|
8728
|
+
const configuredModels = registerConfiguredModelProviders(registry);
|
|
8729
|
+
const configuredModelSet = new Set(
|
|
8730
|
+
configuredModels.map((model) => `${model.provider}:${model.id}`)
|
|
8731
|
+
);
|
|
8727
8732
|
app.get("/api/v1/agent/models", async (_request, reply) => {
|
|
8728
8733
|
const availableModels = registry.getAvailable();
|
|
8729
8734
|
const availableSet = new Set(
|
|
8730
8735
|
availableModels.map((m) => `${m.provider}:${m.id}`)
|
|
8731
8736
|
);
|
|
8732
|
-
const
|
|
8737
|
+
const allModels = configuredModelSet.size > 0 ? registry.getAll().filter((m) => configuredModelSet.has(`${m.provider}:${m.id}`)) : registry.getAll();
|
|
8738
|
+
const models = allModels.map((m) => ({
|
|
8733
8739
|
provider: m.provider,
|
|
8734
8740
|
id: m.id,
|
|
8735
8741
|
label: m.label ?? m.id,
|
|
8736
8742
|
// Keep this endpoint cheap: it is fetched on chat mount, so it must never
|
|
8737
8743
|
// block workspace load on deep provider auth resolution. ModelRegistry's
|
|
8738
|
-
// available set is already derived from configured auth sources.
|
|
8744
|
+
// available set is already derived from configured auth sources. When
|
|
8745
|
+
// hosts configure launch/custom providers, those configured models are an
|
|
8746
|
+
// allowlist: do not leak the built-in registry's unavailable catalog.
|
|
8739
8747
|
available: availableSet.has(`${m.provider}:${m.id}`)
|
|
8740
8748
|
}));
|
|
8741
8749
|
models.sort((a, b) => {
|
|
@@ -9210,7 +9218,7 @@ function statusCodeFromError(err) {
|
|
|
9210
9218
|
|
|
9211
9219
|
// src/server/http/routes/systemPrompt.ts
|
|
9212
9220
|
function systemPromptRoutes(app, opts, done) {
|
|
9213
|
-
async function
|
|
9221
|
+
async function resolveHarness2(request) {
|
|
9214
9222
|
if (opts.getHarness) return await opts.getHarness(request);
|
|
9215
9223
|
if (opts.harness) return opts.harness;
|
|
9216
9224
|
throw new Error("system prompt route requires harness or getHarness");
|
|
@@ -9229,7 +9237,7 @@ function systemPromptRoutes(app, opts, done) {
|
|
|
9229
9237
|
}
|
|
9230
9238
|
});
|
|
9231
9239
|
}
|
|
9232
|
-
const harness = await
|
|
9240
|
+
const harness = await resolveHarness2(request);
|
|
9233
9241
|
if (typeof harness.getSystemPrompt !== "function") {
|
|
9234
9242
|
return reply.code(501).send({
|
|
9235
9243
|
error: {
|
|
@@ -9387,14 +9395,24 @@ function normalizeSessionId(value, fallback) {
|
|
|
9387
9395
|
const trimmed = value.trim();
|
|
9388
9396
|
return trimmed.length > 0 ? trimmed : fallback;
|
|
9389
9397
|
}
|
|
9398
|
+
function resolveHarness(opts, request) {
|
|
9399
|
+
return "getHarness" in opts ? opts.getHarness(request) : opts.harness;
|
|
9400
|
+
}
|
|
9401
|
+
function resolveWorkdir(opts, request) {
|
|
9402
|
+
return "getWorkdir" in opts ? opts.getWorkdir(request) : opts.workdir;
|
|
9403
|
+
}
|
|
9390
9404
|
function commandsRoutes(app, opts, done) {
|
|
9391
9405
|
app.get("/api/v1/agent/commands", async (request, reply) => {
|
|
9392
9406
|
try {
|
|
9393
9407
|
const query = request.query;
|
|
9394
9408
|
const sessionId = normalizeSessionId(query.sessionId, opts.defaultSessionId);
|
|
9395
|
-
const
|
|
9409
|
+
const [harness, workdir] = await Promise.all([
|
|
9410
|
+
resolveHarness(opts, request),
|
|
9411
|
+
resolveWorkdir(opts, request)
|
|
9412
|
+
]);
|
|
9413
|
+
const commands = await harness.getSlashCommands?.(sessionId, {
|
|
9396
9414
|
abortSignal: new AbortController().signal,
|
|
9397
|
-
workdir
|
|
9415
|
+
workdir
|
|
9398
9416
|
}) ?? [];
|
|
9399
9417
|
return reply.code(200).send({ commands });
|
|
9400
9418
|
} catch (error) {
|
|
@@ -9403,19 +9421,23 @@ function commandsRoutes(app, opts, done) {
|
|
|
9403
9421
|
}
|
|
9404
9422
|
});
|
|
9405
9423
|
app.post("/api/v1/agent/commands/execute", async (request, reply) => {
|
|
9406
|
-
if (!opts.harness.executeSlashCommand) {
|
|
9407
|
-
return reply.code(501).send({ error: "Command execution not supported by this harness." });
|
|
9408
|
-
}
|
|
9409
9424
|
try {
|
|
9425
|
+
const [harness, workdir] = await Promise.all([
|
|
9426
|
+
resolveHarness(opts, request),
|
|
9427
|
+
resolveWorkdir(opts, request)
|
|
9428
|
+
]);
|
|
9429
|
+
if (!harness.executeSlashCommand) {
|
|
9430
|
+
return reply.code(501).send({ error: "Command execution not supported by this harness." });
|
|
9431
|
+
}
|
|
9410
9432
|
const query = request.query;
|
|
9411
9433
|
const body = request.body && typeof request.body === "object" ? request.body : {};
|
|
9412
9434
|
const sessionId = normalizeSessionId(query.sessionId, opts.defaultSessionId);
|
|
9413
9435
|
const name = typeof body.name === "string" ? body.name.trim() : "";
|
|
9414
9436
|
const args = typeof body.args === "string" ? body.args : "";
|
|
9415
9437
|
if (!name) return reply.code(400).send({ error: "name body field is required" });
|
|
9416
|
-
await
|
|
9438
|
+
await harness.executeSlashCommand(sessionId, name, args, {
|
|
9417
9439
|
abortSignal: new AbortController().signal,
|
|
9418
|
-
workdir
|
|
9440
|
+
workdir
|
|
9419
9441
|
});
|
|
9420
9442
|
return reply.code(200).send({ ok: true });
|
|
9421
9443
|
} catch (error) {
|
|
@@ -12032,9 +12054,13 @@ function pluginNameFromPath(path4) {
|
|
|
12032
12054
|
function getAvailableModelProviders() {
|
|
12033
12055
|
const authStorage = AuthStorage3.create();
|
|
12034
12056
|
const registry = ModelRegistry3.create(authStorage);
|
|
12035
|
-
registerConfiguredModelProviders(registry);
|
|
12057
|
+
const configuredModels = registerConfiguredModelProviders(registry);
|
|
12058
|
+
const configuredModelSet = new Set(
|
|
12059
|
+
configuredModels.map((model) => `${model.provider}:${model.id}`)
|
|
12060
|
+
);
|
|
12061
|
+
const availableModels = configuredModelSet.size > 0 ? registry.getAvailable().filter((model) => configuredModelSet.has(`${model.provider}:${model.id}`)) : registry.getAvailable();
|
|
12036
12062
|
return Array.from(
|
|
12037
|
-
new Set(
|
|
12063
|
+
new Set(availableModels.map((model) => model.provider))
|
|
12038
12064
|
).sort((a, b) => a.localeCompare(b));
|
|
12039
12065
|
}
|
|
12040
12066
|
function selectRuntimeModeAdapter(mode, sandboxHandleStore) {
|
|
@@ -12682,6 +12708,18 @@ var registerAgentRoutes = async (app, opts) => {
|
|
|
12682
12708
|
catalogRoutes,
|
|
12683
12709
|
staticBinding ? { tools: staticBinding.tools } : { getTools: async (request) => (await getBindingForRequest(request)).tools }
|
|
12684
12710
|
);
|
|
12711
|
+
await app.register(
|
|
12712
|
+
commandsRoutes,
|
|
12713
|
+
staticBinding ? {
|
|
12714
|
+
harness: staticBinding.harness,
|
|
12715
|
+
defaultSessionId: sessionId,
|
|
12716
|
+
workdir: staticBinding.runtimeBundle.workspace.root
|
|
12717
|
+
} : {
|
|
12718
|
+
defaultSessionId: sessionId,
|
|
12719
|
+
getHarness: async (request) => (await getBindingForRequest(request)).harness,
|
|
12720
|
+
getWorkdir: async (request) => (await getBindingForRequest(request)).runtimeBundle.workspace.root
|
|
12721
|
+
}
|
|
12722
|
+
);
|
|
12685
12723
|
await app.register(
|
|
12686
12724
|
readyStatusRoutes,
|
|
12687
12725
|
staticBinding ? { tracker: staticBinding.readyTracker } : { getTracker: async (request) => (await getBindingForRequest(request)).readyTracker }
|
package/dist/shared/index.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { W as Workspace, S as Sandbox, F as FileSearch, A as AgentTool } from '../agentPluginEvents-
|
|
2
|
-
export { a as AgentHarness, C as CommandNotifyPayload, E as Entry, b as ExecOptions, c as ExecResult, I as IsolatedCodeInput, d as IsolatedCodeOutput, J as JSONSchema, R as RunContext, e as SandboxCapability, f as SandboxHandleRecord, g as SandboxHandleStore, h as SendMessageInput, i as Stat, T as TelemetryEvent, j as TelemetrySink, k as ToolExecContext, l as ToolResult, m as WORKSPACE_AGENT_PLUGINS_RELOADED_EVENT, n as WORKSPACE_COMMAND_NOTIFY_EVENT, o as WorkspaceRuntimeContext, p as noopTelemetry, s as safeCapture } from '../agentPluginEvents-
|
|
3
|
-
import { B as BoringChatPart, T as ToolUiMetadata } from '../piChatEvent-
|
|
4
|
-
export { A as ApiErrorPayload, a as ApiErrorPayloadSchema, b as ApiErrorResponse, c as ApiErrorResponseSchema, d as BoringChatMessage, C as ChatError, e as CommandReceipt, E as ERROR_CODES, f as ErrorCode, g as ErrorLogFields, h as ErrorLogFieldsSchema, F as FollowUpPayload, i as FollowUpReceipt, I as InterruptPayload, j as InterruptReceipt, P as PiChatEvent, k as PiChatHeartbeatFrame, l as PiChatSnapshot, m as PiChatStatus, n as PiChatStreamFrame, o as PromptPayload, p as PromptReceipt, Q as QueueClearPayload, q as QueueClearReceipt, r as QueuedUserMessage, S as StopPayload, s as StopReceipt, t as extractToolUiMetadata, u as isToolUiMetadata } from '../piChatEvent-
|
|
5
|
-
export { C as ChatAttachmentPayload, a as ChatModelSelection, b as ChatSubmitPayload, S as SessionCtx, c as SessionDetail, d as SessionStore, e as SessionSummary, T as ThinkingLevel } from '../chatSubmitPayload-
|
|
1
|
+
import { W as Workspace, S as Sandbox, F as FileSearch, A as AgentTool } from '../agentPluginEvents-Dgm57gEU.js';
|
|
2
|
+
export { a as AgentHarness, C as CommandNotifyPayload, E as Entry, b as ExecOptions, c as ExecResult, I as IsolatedCodeInput, d as IsolatedCodeOutput, J as JSONSchema, R as RunContext, e as SandboxCapability, f as SandboxHandleRecord, g as SandboxHandleStore, h as SendMessageInput, i as Stat, T as TelemetryEvent, j as TelemetrySink, k as ToolExecContext, l as ToolResult, m as WORKSPACE_AGENT_PLUGINS_RELOADED_EVENT, n as WORKSPACE_COMMAND_NOTIFY_EVENT, o as WorkspaceRuntimeContext, p as noopTelemetry, s as safeCapture } from '../agentPluginEvents-Dgm57gEU.js';
|
|
3
|
+
import { B as BoringChatPart, T as ToolUiMetadata } from '../piChatEvent-DNKo77Xw.js';
|
|
4
|
+
export { A as ApiErrorPayload, a as ApiErrorPayloadSchema, b as ApiErrorResponse, c as ApiErrorResponseSchema, d as BoringChatMessage, C as ChatError, e as CommandReceipt, E as ERROR_CODES, f as ErrorCode, g as ErrorLogFields, h as ErrorLogFieldsSchema, F as FollowUpPayload, i as FollowUpReceipt, I as InterruptPayload, j as InterruptReceipt, P as PiChatEvent, k as PiChatHeartbeatFrame, l as PiChatSnapshot, m as PiChatStatus, n as PiChatStreamFrame, o as PromptPayload, p as PromptReceipt, Q as QueueClearPayload, q as QueueClearReceipt, r as QueuedUserMessage, S as StopPayload, s as StopReceipt, t as extractToolUiMetadata, u as isToolUiMetadata } from '../piChatEvent-DNKo77Xw.js';
|
|
5
|
+
export { C as ChatAttachmentPayload, a as ChatModelSelection, b as ChatSubmitPayload, S as SessionCtx, c as SessionDetail, d as SessionStore, e as SessionSummary, T as ThinkingLevel } from '../chatSubmitPayload-DHqQL2wD.js';
|
|
6
6
|
import { z } from 'zod';
|
|
7
7
|
|
|
8
8
|
interface CatalogDeps {
|
|
@@ -1347,12 +1347,15 @@ declare const ChatAttachmentPayloadSchema: z.ZodObject<{
|
|
|
1347
1347
|
filename: z.ZodOptional<z.ZodString>;
|
|
1348
1348
|
mediaType: z.ZodOptional<z.ZodString>;
|
|
1349
1349
|
url: z.ZodString;
|
|
1350
|
+
path: z.ZodOptional<z.ZodString>;
|
|
1350
1351
|
}, "strip", z.ZodTypeAny, {
|
|
1351
1352
|
url: string;
|
|
1353
|
+
path?: string | undefined;
|
|
1352
1354
|
filename?: string | undefined;
|
|
1353
1355
|
mediaType?: string | undefined;
|
|
1354
1356
|
}, {
|
|
1355
1357
|
url: string;
|
|
1358
|
+
path?: string | undefined;
|
|
1356
1359
|
filename?: string | undefined;
|
|
1357
1360
|
mediaType?: string | undefined;
|
|
1358
1361
|
}>;
|
|
@@ -1375,12 +1378,15 @@ declare const PromptPayloadSchema: z.ZodObject<{
|
|
|
1375
1378
|
filename: z.ZodOptional<z.ZodString>;
|
|
1376
1379
|
mediaType: z.ZodOptional<z.ZodString>;
|
|
1377
1380
|
url: z.ZodString;
|
|
1381
|
+
path: z.ZodOptional<z.ZodString>;
|
|
1378
1382
|
}, "strip", z.ZodTypeAny, {
|
|
1379
1383
|
url: string;
|
|
1384
|
+
path?: string | undefined;
|
|
1380
1385
|
filename?: string | undefined;
|
|
1381
1386
|
mediaType?: string | undefined;
|
|
1382
1387
|
}, {
|
|
1383
1388
|
url: string;
|
|
1389
|
+
path?: string | undefined;
|
|
1384
1390
|
filename?: string | undefined;
|
|
1385
1391
|
mediaType?: string | undefined;
|
|
1386
1392
|
}>, "many">>;
|
|
@@ -1395,6 +1401,7 @@ declare const PromptPayloadSchema: z.ZodObject<{
|
|
|
1395
1401
|
thinkingLevel?: "off" | "low" | "medium" | "high" | undefined;
|
|
1396
1402
|
attachments?: {
|
|
1397
1403
|
url: string;
|
|
1404
|
+
path?: string | undefined;
|
|
1398
1405
|
filename?: string | undefined;
|
|
1399
1406
|
mediaType?: string | undefined;
|
|
1400
1407
|
}[] | undefined;
|
|
@@ -1409,6 +1416,7 @@ declare const PromptPayloadSchema: z.ZodObject<{
|
|
|
1409
1416
|
thinkingLevel?: "off" | "low" | "medium" | "high" | undefined;
|
|
1410
1417
|
attachments?: {
|
|
1411
1418
|
url: string;
|
|
1419
|
+
path?: string | undefined;
|
|
1412
1420
|
filename?: string | undefined;
|
|
1413
1421
|
mediaType?: string | undefined;
|
|
1414
1422
|
}[] | undefined;
|
package/dist/shared/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hachej/boring-agent",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.44",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"description": "Pane-embeddable coding agent. Ships direct/local/vercel-sandbox execution modes behind one interface.",
|
|
@@ -74,7 +74,7 @@
|
|
|
74
74
|
"use-stick-to-bottom": "^1.1.3",
|
|
75
75
|
"yaml": "^2.8.3",
|
|
76
76
|
"zod": "^3.25.76",
|
|
77
|
-
"@hachej/boring-ui-kit": "0.1.
|
|
77
|
+
"@hachej/boring-ui-kit": "0.1.44"
|
|
78
78
|
},
|
|
79
79
|
"devDependencies": {
|
|
80
80
|
"@antithesishq/bombadil": "0.5.0",
|