@hachej/boring-agent 0.1.103 → 0.1.104

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.
@@ -174,12 +174,17 @@ var QueuedUserMessageSchema = z.object({
174
174
  createdAt: z.string().optional()
175
175
  });
176
176
  var PiChatStatusSchema = z.enum(["idle", "hydrating", "submitted", "streaming", "aborting", "error"]);
177
+ var ChatModelSelectionSchema = z.object({
178
+ provider: nonEmptyString,
179
+ id: nonEmptyString
180
+ });
177
181
  var PiChatSnapshotSchema = z.object({
178
182
  protocolVersion: z.literal(1),
179
183
  sessionId: nonEmptyString,
180
184
  seq: seqNumber,
181
185
  status: PiChatStatusSchema,
182
186
  activeTurnId: z.string().optional(),
187
+ currentModel: ChatModelSelectionSchema.optional(),
183
188
  messages: z.array(BoringChatMessageSchema),
184
189
  queue: z.object({ followUps: z.array(QueuedUserMessageSchema) }),
185
190
  followUpMode: z.literal("one-at-a-time"),
@@ -188,6 +193,7 @@ var PiChatSnapshotSchema = z.object({
188
193
  var baseEvent = z.object({ seq: seqNumber });
189
194
  var PiChatEventSchema = z.discriminatedUnion("type", [
190
195
  baseEvent.extend({ type: z.literal("agent-start"), turnId: nonEmptyString }),
196
+ baseEvent.extend({ type: z.literal("model-changed"), currentModel: ChatModelSelectionSchema }),
191
197
  baseEvent.extend({ type: z.literal("agent-end"), turnId: nonEmptyString, status: z.enum(["ok", "aborted", "error"]), willRetry: z.boolean().optional() }),
192
198
  baseEvent.extend({
193
199
  type: z.literal("message-start"),
@@ -258,10 +264,6 @@ var PiChatEventSchema = z.discriminatedUnion("type", [
258
264
  ]);
259
265
  var PiChatHeartbeatFrameSchema = z.object({ type: z.literal("heartbeat"), now: z.string() });
260
266
  var PiChatStreamFrameSchema = z.union([PiChatEventSchema, PiChatHeartbeatFrameSchema]);
261
- var ChatModelSelectionSchema = z.object({
262
- provider: nonEmptyString,
263
- id: nonEmptyString
264
- });
265
267
  var ThinkingLevelSchema = z.enum(["off", "low", "medium", "high"]);
266
268
  var ChatAttachmentPayloadSchema = z.object({
267
269
  filename: z.string().optional(),
@@ -330,11 +332,11 @@ export {
330
332
  BoringChatMessageSchema,
331
333
  QueuedUserMessageSchema,
332
334
  PiChatStatusSchema,
335
+ ChatModelSelectionSchema,
333
336
  PiChatSnapshotSchema,
334
337
  PiChatEventSchema,
335
338
  PiChatHeartbeatFrameSchema,
336
339
  PiChatStreamFrameSchema,
337
- ChatModelSelectionSchema,
338
340
  ThinkingLevelSchema,
339
341
  ChatAttachmentPayloadSchema,
340
342
  PromptPayloadSchema,
@@ -7,7 +7,7 @@ import {
7
7
  readConfiguredDefaultModel,
8
8
  registerConfiguredModelProviders,
9
9
  withPiHarnessDefaults
10
- } from "./chunk-TW7G33QH.js";
10
+ } from "./chunk-I7KFNGB4.js";
11
11
  import {
12
12
  AGENT_KNOWLEDGE_FILESYSTEM_ID,
13
13
  AgentDefinitionValidationError,
@@ -41,7 +41,7 @@ import {
41
41
  AgentGatewayErrorCode,
42
42
  extractToolUiMetadata,
43
43
  sanitizeToolUiMetadata2 as sanitizeToolUiMetadata
44
- } from "./chunk-7QM22DU7.js";
44
+ } from "./chunk-6DRHERVK.js";
45
45
  import {
46
46
  AgentDefinitionErrorCode,
47
47
  AgentDeploymentErrorCode,
@@ -2212,6 +2212,28 @@ var agentSandboxRuntimeHostOperations = {
2212
2212
  withWorkspacePythonEnv
2213
2213
  };
2214
2214
  var sandboxRuntimeHostOperations = agentSandboxRuntimeHostOperations;
2215
+ function resolveBwrapPolicy(options) {
2216
+ const sandbox = options?.sandbox;
2217
+ const namespaceProfile = sandbox?.namespaceProfile ?? "full";
2218
+ return {
2219
+ namespaceProfile,
2220
+ network: sandbox?.network ?? "shared",
2221
+ // Docker mode runs outside a nested user namespace. Never allow the outer
2222
+ // container's SYS_ADMIN capability to reach any local execution path.
2223
+ dropAllCapabilities: namespaceProfile === "docker" || sandbox?.dropAllCapabilities === true
2224
+ };
2225
+ }
2226
+ function withBwrapPolicy(runtimeHost, policy) {
2227
+ return {
2228
+ ...runtimeHost,
2229
+ buildBwrapArgs(workspaceRoot, executionOptions) {
2230
+ return runtimeHost.buildBwrapArgs(workspaceRoot, {
2231
+ ...executionOptions,
2232
+ ...policy
2233
+ });
2234
+ }
2235
+ };
2236
+ }
2215
2237
  function resolveBuiltinRuntimeLayoutRoot(mode, workspaceRoot) {
2216
2238
  return mode === "blaxel" ? BLAXEL_WORKSPACE_ROOT : mode === "vercel-sandbox" ? VERCEL_SANDBOX_WORKSPACE_ROOT : workspaceRoot;
2217
2239
  }
@@ -2222,11 +2244,20 @@ function createSandboxRuntimeModeAdapter(mode, options = {}) {
2222
2244
  provider: createDirectSandboxProvider(),
2223
2245
  runtimeHost: agentSandboxRuntimeHostOperations
2224
2246
  });
2225
- case "local":
2247
+ case "local": {
2248
+ const policy = resolveBwrapPolicy(options.bwrap);
2249
+ const runtimeHost = withBwrapPolicy(agentSandboxRuntimeHostOperations, policy);
2226
2250
  return createLocalModeAdapter({
2227
- provider: createBwrapSandboxProvider(),
2228
- runtimeHost: agentSandboxRuntimeHostOperations
2251
+ provider: createBwrapSandboxProvider({
2252
+ ...options.bwrap,
2253
+ sandbox: {
2254
+ ...options.bwrap?.sandbox,
2255
+ ...policy
2256
+ }
2257
+ }),
2258
+ runtimeHost
2229
2259
  });
2260
+ }
2230
2261
  case "vercel-sandbox":
2231
2262
  return createVercelSandboxModeAdapter({
2232
2263
  provider: createVercelSandboxProvider({
@@ -4889,6 +4920,7 @@ function buildPiChatSnapshot(adapter, options) {
4889
4920
  seq: options.seq,
4890
4921
  status,
4891
4922
  activeTurnId: options.activeTurnId,
4923
+ currentModel: adapter.currentModel?.(),
4892
4924
  messages: buildPiChatHistory(piSnapshot.messages, {
4893
4925
  sessionId,
4894
4926
  messageTurnIds: options.messageTurnIds,
@@ -6357,6 +6389,9 @@ function codedError(message, code, statusCode, extra) {
6357
6389
  // src/server/pi-chat/harnessPiChatService.ts
6358
6390
  var MAX_PROMPT_IMAGE_BYTES = 10 * 1024 * 1024;
6359
6391
  var PROMPT_IMAGE_EXTENSIONS = /* @__PURE__ */ new Set([".avif", ".gif", ".jpg", ".jpeg", ".png", ".webp"]);
6392
+ function sameModelSelection(left, right) {
6393
+ return left?.provider === right.provider && left.id === right.id;
6394
+ }
6360
6395
  var HarnessPiChatService = class {
6361
6396
  harness;
6362
6397
  sessionStore;
@@ -6612,12 +6647,13 @@ var HarnessPiChatService = class {
6612
6647
  async readPersistedState(ctx, sessionId) {
6613
6648
  if (!this.sessionStore.loadEntries) return null;
6614
6649
  try {
6615
- const { id, messages } = await this.sessionStore.loadEntries(toSessionCtx(ctx), sessionId);
6650
+ const { id, messages, currentModel } = await this.sessionStore.loadEntries(toSessionCtx(ctx), sessionId);
6616
6651
  return {
6617
6652
  protocolVersion: 1,
6618
6653
  sessionId: id,
6619
6654
  seq: await this.readDurableLatestPiChatSeq(sessionStreamPath(this.sessionKey(ctx, id))),
6620
6655
  status: "idle",
6656
+ currentModel,
6621
6657
  messages: buildPiChatHistory(messages, {
6622
6658
  sessionId: id,
6623
6659
  attachmentUrl: this.attachmentUrlFor(id)
@@ -6666,6 +6702,13 @@ var HarnessPiChatService = class {
6666
6702
  };
6667
6703
  }
6668
6704
  if (outcome === "cancelled") throw promptCancelledError();
6705
+ const currentModel = adapter.currentModel?.();
6706
+ if (currentModel && !sameModelSelection(channel.advertisedModel, currentModel)) {
6707
+ channel.advertisedModel = currentModel;
6708
+ this.publishChannelEvents(sessionId, channel, [
6709
+ channel.mapper.mapSynthetic({ type: "model-changed", currentModel })
6710
+ ]);
6711
+ }
6669
6712
  this.messageMetadata.recordPrompt(sessionKey, payload);
6670
6713
  const receiptCursor = nextPromptReceiptCursor(channel);
6671
6714
  try {
@@ -7112,7 +7155,8 @@ var HarnessPiChatService = class {
7112
7155
  closed: closed.promise,
7113
7156
  resolveClosed: () => closed.resolve(),
7114
7157
  rejectClosed: closed.reject,
7115
- messageTurnIds: /* @__PURE__ */ new Map()
7158
+ messageTurnIds: /* @__PURE__ */ new Map(),
7159
+ advertisedModel: adapter.currentModel?.()
7116
7160
  };
7117
7161
  const unsubscribe = adapter.subscribe((event) => {
7118
7162
  const mappedEvents = mapper.map(event);
@@ -7941,7 +7985,7 @@ async function buildAgentComposition(input) {
7941
7985
  sessionNamespace: configuredNamespace,
7942
7986
  sessionDir: runtimeScope.sessionDir ?? factoryInput.sessionDir
7943
7987
  }) : async (factoryInput) => {
7944
- const { createPiCodingAgentHarness } = await import("./createHarness-4Q6DQBRT.js");
7988
+ const { createPiCodingAgentHarness } = await import("./createHarness-POZ4AXCZ.js");
7945
7989
  return createPiCodingAgentHarness({
7946
7990
  ...factoryInput,
7947
7991
  pi,
@@ -567,6 +567,28 @@ async function summarizeNativeTranscript(filepath) {
567
567
  }
568
568
 
569
569
  // src/server/harness/pi-coding-agent/sessions.ts
570
+ function legacyAssistantModel(entry) {
571
+ const message = entry.message;
572
+ if (message.role !== "assistant") return void 0;
573
+ if (typeof message.provider === "string" && typeof message.model === "string") {
574
+ return { provider: message.provider, id: message.model };
575
+ }
576
+ if (typeof message.model !== "object" || message.model === null) return void 0;
577
+ const model = message.model;
578
+ return typeof model.provider === "string" && typeof model.id === "string" ? { provider: model.provider, id: model.id } : void 0;
579
+ }
580
+ function currentModelFromTranscript(entries) {
581
+ for (let index = entries.length - 1; index >= 0; index -= 1) {
582
+ const entry = entries[index];
583
+ if (!entry) continue;
584
+ if (entry.type === "model_change") return { provider: entry.provider, id: entry.modelId };
585
+ if (entry.type === "message") {
586
+ const model = legacyAssistantModel(entry);
587
+ if (model) return model;
588
+ }
589
+ }
590
+ return void 0;
591
+ }
570
592
  function sessionBaseDir(explicitRoot) {
571
593
  const explicit = explicitRoot?.trim();
572
594
  if (explicit) return resolve(explicit);
@@ -745,7 +767,11 @@ var PiSessionStore = class {
745
767
  async loadEntries(ctx, sessionId) {
746
768
  const resolved = await this.resolveSessionTranscript(ctx, sessionId);
747
769
  const messages = resolved.transcriptEntries.filter((entry) => entry.type === "message").map((entry) => withStableMessageId(entry.message, entry.id));
748
- return { id: resolved.resolvedSessionId, messages };
770
+ return {
771
+ id: resolved.resolvedSessionId,
772
+ messages,
773
+ currentModel: currentModelFromTranscript(resolved.transcriptEntries)
774
+ };
749
775
  }
750
776
  async loadAttachment(ctx, sessionId, messageId, index) {
751
777
  const resolved = await this.resolveSessionTranscript(ctx, sessionId);
@@ -1,8 +1,8 @@
1
- import { A as AgentHarness, a as AgentReadiness, b as Agent } from '../harness-erpL2SER.js';
2
- export { c as AGENT_NOT_IMPLEMENTED_UNTIL_T1, d as AgentActor, e as AgentCoreHarness, f as AgentCoreHarnessFactory, g as AgentCorePromptInput, h as AgentCoreSessionAdapter, i as AgentCoreSessionSnapshot, j as AgentEvent, k as AgentMessageContent, l as AgentMessagePart, m as AgentNotImplementedError, n as AgentReadinessStatus, o as AgentResolveInputResponse, p as AgentSendInput, q as AgentStartReceipt, r as AgentStreamOptions } from '../harness-erpL2SER.js';
3
- import { S as SessionStore } from '../piChatEvent-g1nIBh44.js';
4
- import { A as AgentCoreSessionService, a as AgentEffectAdmission } from '../piChatSessionService-DugeRHzb.js';
5
- export { b as AGENT_EFFECT_METHODS, c as AgentEffectAdmissionError, P as PiChatEventStreamResult, d as PiChatEventStreamSubscription, e as PiChatEventSubscriber, f as PiChatReplayRangeError, g as PiChatSessionService, h as PiSessionCreateInit, i as PiSessionRequestContext, w as withAgentEffectAdmission } from '../piChatSessionService-DugeRHzb.js';
1
+ import { A as AgentHarness, a as AgentReadiness, b as Agent } from '../harness-Dcd08yKr.js';
2
+ export { c as AGENT_NOT_IMPLEMENTED_UNTIL_T1, d as AgentActor, e as AgentCoreHarness, f as AgentCoreHarnessFactory, g as AgentCorePromptInput, h as AgentCoreSessionAdapter, i as AgentCoreSessionSnapshot, j as AgentEvent, k as AgentMessageContent, l as AgentMessagePart, m as AgentNotImplementedError, n as AgentReadinessStatus, o as AgentResolveInputResponse, p as AgentSendInput, q as AgentStartReceipt, r as AgentStreamOptions } from '../harness-Dcd08yKr.js';
3
+ import { S as SessionStore } from '../piChatEvent-iNSXiFQq.js';
4
+ import { A as AgentCoreSessionService, a as AgentEffectAdmission } from '../piChatSessionService-DQSQ_kWZ.js';
5
+ export { b as AGENT_EFFECT_METHODS, c as AgentEffectAdmissionError, P as PiChatEventStreamResult, d as PiChatEventStreamSubscription, e as PiChatEventSubscriber, f as PiChatReplayRangeError, g as PiChatSessionService, h as PiSessionCreateInit, i as PiSessionRequestContext, w as withAgentEffectAdmission } from '../piChatSessionService-DQSQ_kWZ.js';
6
6
  import '@mariozechner/pi-coding-agent';
7
7
  import 'zod';
8
8
 
@@ -5,7 +5,7 @@ import {
5
5
  mergePiPackageSources,
6
6
  projectSkillResourceLocations,
7
7
  withPiHarnessDefaults
8
- } from "./chunk-TW7G33QH.js";
8
+ } from "./chunk-I7KFNGB4.js";
9
9
  import "./chunk-4IQ4HHBG.js";
10
10
  import "./chunk-K25PK5EC.js";
11
11
  export {
@@ -1,4 +1,4 @@
1
- import { c as PiChatEvent, C as ChatModelSelection, T as ThinkingLevel, l as ChatAttachmentPayload, m as QueuedUserMessage, P as PiChatSnapshot } from './piChatEvent-g1nIBh44.js';
1
+ import { c as PiChatEvent, C as ChatModelSelection, T as ThinkingLevel, l as ChatAttachmentPayload, m as QueuedUserMessage, P as PiChatSnapshot } from './piChatEvent-iNSXiFQq.js';
2
2
 
3
3
  /** Placement-independent event envelope. `seq` is the only replay cursor. */
4
4
  interface AgentSessionEvent {
@@ -1,7 +1,7 @@
1
- import { k as InterruptReceipt, j as StopReceipt } from './piChatEvent-g1nIBh44.js';
2
- import { p as AgentSendInput, j as AgentEvent } from './harness-erpL2SER.js';
1
+ import { k as InterruptReceipt, j as StopReceipt } from './piChatEvent-iNSXiFQq.js';
2
+ import { p as AgentSendInput, j as AgentEvent } from './harness-Dcd08yKr.js';
3
3
  import { b as Workspace } from './sandbox-BMhut3kh.js';
4
- import { b as AgentSessionRef, d as AgentSendReceipt, A as AgentGateway, a as AuthorizedAgentScope } from './errors-szpcDUFQ.js';
4
+ import { b as AgentSessionRef, d as AgentSendReceipt, A as AgentGateway, a as AuthorizedAgentScope } from './errors-DH7C01Pm.js';
5
5
 
6
6
  interface WorkspaceAgentDispatcherContext {
7
7
  workspaceId: string;
@@ -1,8 +1,8 @@
1
- import { p as ToolUiMetadata, B as BoringChatPart, v as BoringChatMessage, H as PiChatStatus, m as QueuedUserMessage, w as ChatError, c as PiChatEvent, d as PromptPayload, e as PromptReceipt, F as FollowUpPayload, f as FollowUpReceipt, Q as QueueClearPayload, g as QueueClearReceipt, I as InterruptPayload, h as CommandReceipt, i as StopPayload, j as StopReceipt, b as SessionSummary, y as ErrorCode } from '../piChatEvent-g1nIBh44.js';
1
+ import { p as ToolUiMetadata, B as BoringChatPart, v as BoringChatMessage, H as PiChatStatus, P as PiChatSnapshot, m as QueuedUserMessage, w as ChatError, c as PiChatEvent, d as PromptPayload, e as PromptReceipt, F as FollowUpPayload, f as FollowUpReceipt, Q as QueueClearPayload, g as QueueClearReceipt, I as InterruptPayload, h as CommandReceipt, i as StopPayload, j as StopReceipt, b as SessionSummary, y as ErrorCode } from '../piChatEvent-iNSXiFQq.js';
2
2
  import * as react from 'react';
3
3
  import { ComponentProps, HTMLAttributes, FormEvent, ReactNode, ComponentType } from 'react';
4
4
  import { FileUIPart, ChatStatus, UIMessage } from 'ai';
5
- import { q as AgentSummary, h as AgentGatewayErrorCode, x as JsonValue } from '../errors-szpcDUFQ.js';
5
+ import { q as AgentSummary, h as AgentGatewayErrorCode, x as JsonValue } from '../errors-DH7C01Pm.js';
6
6
  export { Artifact, ArtifactAction, ArtifactActions, ArtifactDescription, ArtifactHeader, ArtifactOpenProvider, ArtifactTitle, OpenArtifactHandler, useOpenArtifact } from './artifacts.js';
7
7
  import { InputGroupAddon, InputGroupButton, InputGroupTextarea, Button, Collapsible, CollapsibleContent, CollapsibleTrigger } from '@hachej/boring-ui-kit';
8
8
  import { Streamdown } from 'streamdown';
@@ -318,6 +318,7 @@ interface PiChatState {
318
318
  workspaceId?: string;
319
319
  storageScope: string;
320
320
  status: PiChatStatus;
321
+ currentModel?: PiChatSnapshot['currentModel'];
321
322
  turnId?: string;
322
323
  lastSeq: number;
323
324
  committedMessages: BoringChatMessage[];
@@ -772,6 +773,8 @@ type SelectorTrigger = 'button' | 'slash';
772
773
  declare const ModelSelectTrigger: react.ForwardRefExoticComponent<Omit<Omit<react.DetailedHTMLProps<react.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, "ref">, "value"> & {
773
774
  value: ModelSelection | null;
774
775
  options: AvailableModel[];
776
+ sessionModel?: ModelSelection;
777
+ isOverride?: boolean;
775
778
  disabled?: boolean;
776
779
  trigger?: SelectorTrigger;
777
780
  open?: boolean;