@hachej/boring-agent 0.1.95 → 0.1.96

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.
Files changed (45) hide show
  1. package/dist/DebugDrawer-2TO5SE2D.js +7 -0
  2. package/dist/{chunk-NITBKFG6.js → chunk-3OEDBRKY.js} +93 -58
  3. package/dist/{chunk-BOIV2I3N.js → chunk-46HJK2ES.js} +31 -16
  4. package/dist/{chunk-AQBXNPMD.js → chunk-4IQ4HHBG.js} +4 -0
  5. package/dist/{chunk-OFQ7J6SI.js → chunk-LSO2AO6Q.js} +57 -1
  6. package/dist/{chunk-2EMAKBVR.js → chunk-NSE2RHU3.js} +8967 -7740
  7. package/dist/{chunk-2GBHYJVC.js → chunk-VXF5DWS6.js} +34 -0
  8. package/dist/{chunk-2TMS2RU2.js → chunk-WC5KBGP2.js} +518 -165
  9. package/dist/chunk-YGRQ4Q5P.js +20 -0
  10. package/dist/core/index.d.ts +5 -5
  11. package/dist/core/index.js +604 -7
  12. package/dist/{createHarness-UCD74XXK.js → createHarness-PW3A2MRB.js} +3 -3
  13. package/dist/{errors-G6T6S7PQ.d.ts → errors-cNC4HMpV.d.ts} +14 -7
  14. package/dist/eval/index.d.ts +5 -3
  15. package/dist/eval/index.js +31 -23
  16. package/dist/file-search-QxnanNjO.d.ts +87 -0
  17. package/dist/front/index.d.ts +84 -16
  18. package/dist/front/index.js +832 -339
  19. package/dist/front/styles.css +1171 -2129
  20. package/dist/{harness-Cc48o6uS.d.ts → harness-DS8jLKIx.d.ts} +4 -2
  21. package/dist/{lease-CusB-uLg.d.ts → lease-D8WC6pQl.d.ts} +10 -89
  22. package/dist/{middleware-CzW8n7B7.d.ts → middleware-Cq_cYHjJ.d.ts} +1 -1
  23. package/dist/piChatEvent-B3ehh9V0.d.ts +384 -0
  24. package/dist/{piChatSessionService-C0KbcGw9.d.ts → piChatSessionService-xnv8rcdh.d.ts} +1 -1
  25. package/dist/{sandbox-DAD8cWQR.d.ts → sandbox-KQiEdz4W.d.ts} +12 -1
  26. package/dist/server/agent-host/testing/compositionRouteProof.d.ts +8 -0
  27. package/dist/server/agent-host/testing/compositionRouteProof.js +78 -0
  28. package/dist/server/agent-host/testing/gatewayConformance.d.ts +6 -6
  29. package/dist/server/agent-host/testing/gatewayConformance.js +17 -9
  30. package/dist/server/index.d.ts +569 -370
  31. package/dist/server/index.js +69 -17
  32. package/dist/server/worker/index.d.ts +2 -2
  33. package/dist/server/worker/index.js +9 -9
  34. package/dist/shared/index.d.ts +212 -56
  35. package/dist/shared/index.js +43 -7
  36. package/dist/{types-C-Eroi__.d.ts → types-D_SD-7_l.d.ts} +304 -87
  37. package/docs/AGENT_GATEWAY_V0.md +6 -3
  38. package/docs/AGENT_PACKAGES.md +80 -0
  39. package/docs/ERROR_CODES.md +58 -0
  40. package/docs/README.md +1 -0
  41. package/docs/runtime.md +19 -2
  42. package/package.json +34 -29
  43. package/dist/DebugDrawer-RYEBQ6CO.js +0 -6
  44. package/dist/chunk-EOMY2HDT.js +0 -619
  45. package/dist/piChatEvent-BsMp3MSo.d.ts +0 -368
@@ -1,4 +1,4 @@
1
- import { b as PiChatEvent, o as ChatModelSelection, K as ThinkingLevel, v as ChatAttachmentPayload, Q as QueuedUserMessage, n as PiChatSnapshot } from './piChatEvent-BsMp3MSo.js';
1
+ import { b as PiChatEvent, o as ChatModelSelection, L as ThinkingLevel, v as ChatAttachmentPayload, Q as QueuedUserMessage, n as PiChatSnapshot } from './piChatEvent-B3ehh9V0.js';
2
2
 
3
3
  /** Placement-independent event envelope. `seq` is the only replay cursor. */
4
4
  interface AgentSessionEvent {
@@ -43,6 +43,8 @@ interface AgentSummary {
43
43
  readonly agentTypeId: string;
44
44
  readonly label: string;
45
45
  readonly description?: string;
46
+ /** Runtime plugins explicitly bound to this Agent definition. */
47
+ readonly pluginIds?: readonly string[];
46
48
  readonly definition?: {
47
49
  readonly version: string;
48
50
  readonly digest: string;
@@ -64,6 +66,11 @@ interface AgentSessionSummary {
64
66
  readonly status: AgentSessionActivity;
65
67
  readonly createdAt: number;
66
68
  readonly updatedAt: number;
69
+ readonly turnCount?: number;
70
+ /** Present only for an explicitly allowed bare native Pi transcript. */
71
+ readonly nativeSessionId?: string;
72
+ /** Native transcript metadata used to gate rename until a reply exists. */
73
+ readonly hasAssistantReply?: boolean;
67
74
  }
68
75
  interface AgentSessionPage {
69
76
  readonly sessions: readonly AgentSessionSummary[];
@@ -74,6 +81,8 @@ interface CreateAgentSessionInput {
74
81
  readonly agentTypeId: string;
75
82
  readonly requestId: string;
76
83
  readonly title?: string;
84
+ /** Boot-only intent to resume this exact tab-owned empty session. */
85
+ readonly resumeSessionId?: string;
77
86
  }
78
87
  interface ConnectAgentSessionInput {
79
88
  readonly scope: AuthorizedAgentScope;
@@ -166,10 +175,6 @@ interface AgentGateway {
166
175
  close(): Promise<void>;
167
176
  }
168
177
 
169
- interface FileSearch {
170
- search(glob: string, limit?: number): Promise<string[]>;
171
- }
172
-
173
178
  declare const AgentGatewayErrorCode: {
174
179
  readonly AGENT_TYPE_UNKNOWN: "AGENT_TYPE_UNKNOWN";
175
180
  readonly AGENT_SESSION_NOT_FOUND: "AGENT_SESSION_NOT_FOUND";
@@ -179,14 +184,16 @@ declare const AgentGatewayErrorCode: {
179
184
  readonly AGENT_SESSION_CURSOR_EXPIRED: "AGENT_SESSION_CURSOR_EXPIRED";
180
185
  readonly AGENT_SESSION_CURSOR_INVALID: "AGENT_SESSION_CURSOR_INVALID";
181
186
  readonly AGENT_REQUEST_CONFLICT: "AGENT_REQUEST_CONFLICT";
187
+ readonly AGENT_REQUEST_IN_PROGRESS: "AGENT_REQUEST_IN_PROGRESS";
182
188
  readonly AGENT_REQUEST_OUTCOME_UNKNOWN: "AGENT_REQUEST_OUTCOME_UNKNOWN";
189
+ readonly AGENT_RUNTIME_RESTART_REQUIRED: "AGENT_RUNTIME_RESTART_REQUIRED";
183
190
  readonly AGENT_COMMAND_INVALID_STATE: "AGENT_COMMAND_INVALID_STATE";
184
191
  readonly AGENT_SESSION_RUNTIME_SCOPE_MISMATCH: "AGENT_SESSION_RUNTIME_SCOPE_MISMATCH";
185
192
  readonly AGENT_SHARED_ENVIRONMENT_UNAVAILABLE: "AGENT_SHARED_ENVIRONMENT_UNAVAILABLE";
186
193
  readonly AGENT_GATEWAY_CLOSED: "AGENT_GATEWAY_CLOSED";
187
194
  };
188
195
  type AgentGatewayErrorCode = (typeof AgentGatewayErrorCode)[keyof typeof AgentGatewayErrorCode];
189
- declare const AGENT_GATEWAY_ERROR_CODES: readonly ["AGENT_TYPE_UNKNOWN", "AGENT_SESSION_NOT_FOUND", "AGENT_SCOPE_DENIED", "AGENT_SESSION_REPLAY_GAP", "AGENT_SESSION_CURSOR_AHEAD", "AGENT_SESSION_CURSOR_EXPIRED", "AGENT_SESSION_CURSOR_INVALID", "AGENT_REQUEST_CONFLICT", "AGENT_REQUEST_OUTCOME_UNKNOWN", "AGENT_COMMAND_INVALID_STATE", "AGENT_SESSION_RUNTIME_SCOPE_MISMATCH", "AGENT_SHARED_ENVIRONMENT_UNAVAILABLE", "AGENT_GATEWAY_CLOSED"];
196
+ declare const AGENT_GATEWAY_ERROR_CODES: readonly ["AGENT_TYPE_UNKNOWN", "AGENT_SESSION_NOT_FOUND", "AGENT_SCOPE_DENIED", "AGENT_SESSION_REPLAY_GAP", "AGENT_SESSION_CURSOR_AHEAD", "AGENT_SESSION_CURSOR_EXPIRED", "AGENT_SESSION_CURSOR_INVALID", "AGENT_REQUEST_CONFLICT", "AGENT_REQUEST_IN_PROGRESS", "AGENT_REQUEST_OUTCOME_UNKNOWN", "AGENT_RUNTIME_RESTART_REQUIRED", "AGENT_COMMAND_INVALID_STATE", "AGENT_SESSION_RUNTIME_SCOPE_MISMATCH", "AGENT_SHARED_ENVIRONMENT_UNAVAILABLE", "AGENT_GATEWAY_CLOSED"];
190
197
  interface AgentGatewayErrorDTO {
191
198
  readonly code: AgentGatewayErrorCode;
192
199
  readonly message: string;
@@ -199,4 +206,4 @@ declare class AgentGatewayError extends Error {
199
206
  toJSON(): AgentGatewayErrorDTO;
200
207
  }
201
208
 
202
- export { type AgentGateway as A, type ConnectAgentSessionInput as C, type DeleteAgentSessionInput as D, type FileSearch as F, type IdempotentAgentControl as I, type JsonValue as J, type ListAgentsInput as L, type ReadAgentSessionStateInput as R, type VerifiedAgentScopeClaim as V, type WorkspaceScopeId as W, type AuthorizedAgentScope as a, type AgentSessionRef as b, type AgentSessionActivity as c, type AgentSessionSummary as d, type AgentSessionStateSnapshot as e, type AgentSessionConnection as f, type AgentGatewayErrorDTO as g, type AgentScopeVerifier as h, AGENT_GATEWAY_ERROR_CODES as i, type AgentFollowUpCommand as j, AgentGatewayError as k, AgentGatewayErrorCode as l, type AgentPromptCommand as m, type AgentSendReceipt as n, type AgentSessionEvent as o, type AgentSessionPage as p, type AgentSummary as q, type AuthSubjectId as r, type AuthorizedAgentSessionQuery as s, type CreateAgentSessionInput as t, type IdempotentAgentSend as u, type IdempotentQueueClear as v, type JsonPrimitive as w, type JsonSafe as x, type RenameAgentSessionInput as y };
209
+ export { type AgentSummary as A, type ConnectAgentSessionInput as C, type DeleteAgentSessionInput as D, type IdempotentAgentControl as I, type JsonValue as J, type ListAgentsInput as L, type ReadAgentSessionStateInput as R, type VerifiedAgentScopeClaim as V, type WorkspaceScopeId as W, AgentGatewayErrorCode as a, type AgentGateway as b, type AuthorizedAgentScope as c, type AgentSessionRef as d, type AgentSessionActivity as e, type AgentGatewayErrorDTO as f, type AgentSessionSummary as g, type AgentSessionStateSnapshot as h, type AgentSessionConnection as i, type AgentScopeVerifier as j, AGENT_GATEWAY_ERROR_CODES as k, type AgentFollowUpCommand as l, AgentGatewayError as m, type AgentPromptCommand as n, type AgentSendReceipt as o, type AgentSessionEvent as p, type AgentSessionPage as q, type AuthSubjectId as r, type AuthorizedAgentSessionQuery as s, type CreateAgentSessionInput as t, type IdempotentAgentSend as u, type IdempotentQueueClear as v, type JsonPrimitive as w, type JsonSafe as x, type RenameAgentSessionInput as y };
@@ -61,8 +61,10 @@ type EvalModelSelection = string | {
61
61
  id: string;
62
62
  };
63
63
  interface EvalPromptOptions {
64
- /** A FastifyInstance from createAgentApp / createWorkspaceAgentApp / etc. */
64
+ /** A FastifyInstance from createStandaloneAgentHostApp / createWorkspaceAgentApp / etc. */
65
65
  app: FastifyInstance;
66
+ /** Addressed Agent owner exercised by this eval. */
67
+ agentTypeId: string;
66
68
  /** User prompt sent to the agent. */
67
69
  prompt: string;
68
70
  /**
@@ -92,8 +94,6 @@ interface EvalPromptOptions {
92
94
  sessionId?: string;
93
95
  /** Optional headers sent to session/chat requests (e.g. workspace scoping). */
94
96
  headers?: Record<string, string>;
95
- /** Optional query params appended to session/chat requests (e.g. workspaceId). */
96
- query?: Record<string, string | number | boolean | undefined>;
97
97
  /** Per-call timeout in ms. Defaults to 30_000. */
98
98
  timeoutMs?: number;
99
99
  /** Per-prompt retry count. Default: 0. */
@@ -120,6 +120,8 @@ interface EvalResult {
120
120
  */
121
121
  interface SuiteOptions {
122
122
  app: FastifyInstance;
123
+ /** Addressed Agent owner exercised by every fixture. */
124
+ agentTypeId: string;
123
125
  /** Path to a YAML fixture file. See AGENT_EVAL_FRAMEWORK.md for format. */
124
126
  fixturesPath: string;
125
127
  /** Stop on first failure. Default: false. */
@@ -1,5 +1,5 @@
1
1
  // src/eval/evalPrompt.ts
2
- import { randomUUID } from "crypto";
2
+ import { randomUUID } from "node:crypto";
3
3
 
4
4
  // src/eval/types.ts
5
5
  var EvalAny = /* @__PURE__ */ Symbol.for("@hachej/boring-agent/eval/EvalAny");
@@ -202,13 +202,13 @@ async function evalAgentPrompt(opts) {
202
202
  let captured;
203
203
  try {
204
204
  captured = await runOnce(opts.app, {
205
+ agentTypeId: opts.agentTypeId,
205
206
  sessionId: `${sessionId}-attempt-${attempts}`,
206
207
  prompt: opts.prompt,
207
208
  systemPrompt: opts.systemPrompt,
208
209
  model,
209
210
  timeoutMs,
210
- headers: opts.headers,
211
- query: opts.query
211
+ headers: opts.headers
212
212
  });
213
213
  } catch (err) {
214
214
  lastResult = {
@@ -279,7 +279,18 @@ function matchExpectations(opts, actual) {
279
279
  return someCallMatches(opts.expect, actual);
280
280
  }
281
281
  async function runOnce(app, opts) {
282
- const querySuffix = formatQuerySuffix(opts.query);
282
+ const sessionsPath = `/api/v1/agents/${encodeURIComponent(opts.agentTypeId)}/sessions`;
283
+ const created = await app.inject({
284
+ method: "POST",
285
+ url: sessionsPath,
286
+ headers: opts.headers,
287
+ payload: { requestId: `eval-create-${opts.sessionId}`, title: opts.sessionId }
288
+ });
289
+ if (created.statusCode !== 201) {
290
+ throw new Error(`Agent session create returned ${created.statusCode}: ${created.body.slice(0, 256)}`);
291
+ }
292
+ const sessionId = created.json().sessionId;
293
+ if (typeof sessionId !== "string" || !sessionId) throw new Error("Agent session create did not return sessionId");
283
294
  const userMessage = opts.systemPrompt ? `[SYSTEM]
284
295
  ${opts.systemPrompt}
285
296
  [/SYSTEM]
@@ -289,10 +300,11 @@ ${opts.prompt}` : opts.prompt;
289
300
  const res = await withTimeout(
290
301
  app.inject({
291
302
  method: "POST",
292
- url: `/api/v1/agent/pi-chat/${encodeURIComponent(opts.sessionId)}/prompt${querySuffix}`,
303
+ url: `${sessionsPath}/${encodeURIComponent(sessionId)}/prompt`,
293
304
  headers: opts.headers,
294
305
  payload: {
295
- message: userMessage,
306
+ requestId: `eval-${sessionId}`,
307
+ content: userMessage,
296
308
  clientNonce: `eval-${opts.sessionId}`,
297
309
  model: opts.model
298
310
  }
@@ -306,7 +318,7 @@ ${opts.prompt}` : opts.prompt;
306
318
  );
307
319
  }
308
320
  const snapshot = await withTimeout(
309
- waitForSettledState(app, opts, querySuffix),
321
+ waitForSettledState(app, opts, sessionId),
310
322
  opts.timeoutMs,
311
323
  `chat turn did not settle within ${opts.timeoutMs}ms`
312
324
  );
@@ -314,25 +326,30 @@ ${opts.prompt}` : opts.prompt;
314
326
  } finally {
315
327
  void app.inject({
316
328
  method: "DELETE",
317
- url: `/api/v1/agent/pi-chat/sessions/${encodeURIComponent(opts.sessionId)}${querySuffix}`,
329
+ url: `${sessionsPath}/${encodeURIComponent(sessionId)}`,
318
330
  headers: opts.headers
319
331
  }).catch(() => {
320
332
  });
321
333
  }
322
334
  }
323
335
  var STATE_POLL_INTERVAL_MS = 250;
324
- async function waitForSettledState(app, opts, querySuffix) {
336
+ async function waitForSettledState(app, opts, sessionId) {
325
337
  for (; ; ) {
326
338
  const state = await app.inject({
327
339
  method: "GET",
328
- url: `/api/v1/agent/pi-chat/${encodeURIComponent(opts.sessionId)}/state${querySuffix}`,
340
+ url: `/api/v1/agents/${encodeURIComponent(opts.agentTypeId)}/sessions/${encodeURIComponent(sessionId)}/state`,
329
341
  headers: opts.headers
330
342
  });
331
343
  if (state.statusCode !== 200) {
332
344
  throw new Error(`Pi chat state returned ${state.statusCode}: ${state.body.slice(0, 256)}`);
333
345
  }
334
- const snapshot = JSON.parse(state.body);
335
- if (snapshot.status !== "streaming") return snapshot;
346
+ const envelope = JSON.parse(state.body);
347
+ const snapshot = envelope.state;
348
+ if (!snapshot || typeof snapshot !== "object" || Array.isArray(snapshot)) {
349
+ throw new Error("Pi chat state did not return an addressed state envelope");
350
+ }
351
+ const addressedState = snapshot;
352
+ if (addressedState.status !== "streaming") return addressedState;
336
353
  await new Promise((resolve) => setTimeout(resolve, STATE_POLL_INTERVAL_MS));
337
354
  }
338
355
  }
@@ -356,16 +373,6 @@ function capturePiChatSnapshot(snapshot) {
356
373
  }
357
374
  return { toolCalls, text: textParts.join(""), errorText };
358
375
  }
359
- function formatQuerySuffix(query) {
360
- if (!query) return "";
361
- const params = new URLSearchParams();
362
- for (const [key, value] of Object.entries(query)) {
363
- if (value === void 0) continue;
364
- params.set(key, String(value));
365
- }
366
- const encoded = params.toString();
367
- return encoded ? `?${encoded}` : "";
368
- }
369
376
  function withTimeout(p, ms, label) {
370
377
  return new Promise((resolve, reject) => {
371
378
  const timer = setTimeout(() => reject(new Error(label)), ms);
@@ -390,7 +397,7 @@ function parseModelString(input) {
390
397
  }
391
398
 
392
399
  // src/eval/runSuite.ts
393
- import { readFile } from "fs/promises";
400
+ import { readFile } from "node:fs/promises";
394
401
 
395
402
  // src/eval/yamlSchema.ts
396
403
  import { parse, Schema } from "yaml";
@@ -505,6 +512,7 @@ async function runOnePrompt(opts, fixture, p) {
505
512
  const timeoutMs = p.timeoutMs ?? fixture.defaults?.timeoutMs ?? DEFAULT_TIMEOUT_MS;
506
513
  return evalAgentPrompt({
507
514
  app: opts.app,
515
+ agentTypeId: opts.agentTypeId,
508
516
  prompt: p.prompt,
509
517
  expect: p.expect,
510
518
  expectFirst: p.expectFirst,
@@ -0,0 +1,87 @@
1
+ import { D as InterruptReceipt, j as StopReceipt } from './piChatEvent-B3ehh9V0.js';
2
+ import { p as AgentSendInput, j as AgentEvent } from './harness-DS8jLKIx.js';
3
+ import { b as Workspace } from './sandbox-KQiEdz4W.js';
4
+ import { d as AgentSessionRef, o as AgentSendReceipt, b as AgentGateway, c as AuthorizedAgentScope } from './errors-cNC4HMpV.js';
5
+
6
+ interface WorkspaceAgentDispatcherContext {
7
+ workspaceId: string;
8
+ userId: string;
9
+ }
10
+ type WorkspaceAgentDispatcherSendInput = Omit<AgentSendInput, 'ctx'>;
11
+ interface WorkspaceAgentDispatcherDispatchInput extends WorkspaceAgentDispatcherSendInput {
12
+ /** Optional user-visible presentation when content carries hidden instructions. */
13
+ displayMessage?: string;
14
+ /** Optional title for a newly created addressed session. */
15
+ title?: string;
16
+ /** Durable caller-owned idempotency key. */
17
+ requestId: string;
18
+ /** Defaults to requestId. */
19
+ clientNonce?: string;
20
+ /** Defaults to prompt; follow-up requires a non-negative clientSeq. */
21
+ kind?: 'prompt' | 'followup';
22
+ clientSeq?: number;
23
+ }
24
+ interface WorkspaceAgentDispatch {
25
+ ref: AgentSessionRef;
26
+ receipt: AgentSendReceipt;
27
+ events: AsyncIterable<AgentEvent>;
28
+ }
29
+ /**
30
+ * Callback-scoped direct Agent capability. The Workspace and operations are
31
+ * lease guarded by the Host and must not be retained after the callback.
32
+ */
33
+ interface LeaseBoundWorkspaceAgent {
34
+ readonly workspace: Workspace;
35
+ readonly signal: AbortSignal;
36
+ dispatch(input: WorkspaceAgentDispatcherDispatchInput, onEvent: (event: AgentEvent) => void | Promise<void>, onAccepted?: (accepted: {
37
+ readonly ref: AgentSessionRef;
38
+ readonly receipt: AgentSendReceipt;
39
+ }) => void | Promise<void>): Promise<{
40
+ readonly ref: AgentSessionRef;
41
+ readonly receipt: AgentSendReceipt;
42
+ }>;
43
+ interrupt(sessionId: string, requestId: string): Promise<InterruptReceipt>;
44
+ stop(sessionId: string, requestId: string): Promise<StopReceipt>;
45
+ }
46
+ interface WorkspaceAgentDirectRunInput {
47
+ readonly agentTypeId: string;
48
+ readonly context: WorkspaceAgentDispatcherContext;
49
+ readonly requestId: string;
50
+ }
51
+ type WorkspaceAgentDirectRunCallback = (binding: LeaseBoundWorkspaceAgent) => Promise<void>;
52
+ /** Addressed gateway binding minted by the trusted composition root. */
53
+ interface WorkspaceAgentGatewayBinding {
54
+ gateway: AgentGateway;
55
+ scope: AuthorizedAgentScope;
56
+ agentTypeId: string;
57
+ }
58
+ /**
59
+ * Compatibility-facing delegation surface. New durable callers use dispatch so
60
+ * the addressed ref and accepted Gateway receipt can be persisted before they
61
+ * consume events. send remains for callers that only need the legacy stream.
62
+ */
63
+ interface WorkspaceAgentDispatcher {
64
+ /** Optional only for source compatibility with pre-Gateway injected resolvers. */
65
+ dispatch?(input: WorkspaceAgentDispatcherDispatchInput): Promise<WorkspaceAgentDispatch>;
66
+ send(input: WorkspaceAgentDispatcherSendInput): AsyncIterable<AgentEvent>;
67
+ interrupt(sessionId: string): Promise<InterruptReceipt>;
68
+ stop(sessionId: string): Promise<StopReceipt>;
69
+ }
70
+
71
+ declare const AGENT_RESOURCES_FILESYSTEM_ID: "agent_resources";
72
+ /**
73
+ * Agent-scoped readonly filesystem carrying the knowledge/ folder shipped
74
+ * inside an agent definition package (gh-1107 slice 2). Generic id only —
75
+ * never tenant-named. The binding exists only for the owning agent.
76
+ */
77
+ declare const AGENT_KNOWLEDGE_FILESYSTEM_ID: "agent_knowledge";
78
+ interface AgentSkillResource {
79
+ readonly filesystem: 'user' | typeof AGENT_RESOURCES_FILESYSTEM_ID | (string & {});
80
+ readonly path: string;
81
+ }
82
+
83
+ interface FileSearch {
84
+ search(glob: string, limit?: number): Promise<string[]>;
85
+ }
86
+
87
+ export { type AgentSkillResource as A, type FileSearch as F, type LeaseBoundWorkspaceAgent as L, type WorkspaceAgentDirectRunInput as W, type WorkspaceAgentDirectRunCallback as a, type WorkspaceAgentDispatcherContext as b, type WorkspaceAgentDispatcher as c, type WorkspaceAgentGatewayBinding as d, AGENT_KNOWLEDGE_FILESYSTEM_ID as e, AGENT_RESOURCES_FILESYSTEM_ID as f, type WorkspaceAgentDispatch as g, type WorkspaceAgentDispatcherDispatchInput as h, type WorkspaceAgentDispatcherSendInput as i };
@@ -1,7 +1,8 @@
1
- import { T as ToolUiMetadata, B as BoringChatPart, a as BoringChatMessage, P as PiChatStatus, Q as QueuedUserMessage, C as ChatError, b as PiChatEvent, c as PromptPayload, d as PromptReceipt, F as FollowUpPayload, e as FollowUpReceipt, f as QueueClearPayload, g as QueueClearReceipt, I as InterruptPayload, h as CommandReceipt, i as StopPayload, j as StopReceipt, k as SessionSummary } from '../piChatEvent-BsMp3MSo.js';
1
+ import { T as ToolUiMetadata, B as BoringChatPart, a as BoringChatMessage, P as PiChatStatus, Q as QueuedUserMessage, C as ChatError, b as PiChatEvent, c as PromptPayload, d as PromptReceipt, F as FollowUpPayload, e as FollowUpReceipt, f as QueueClearPayload, g as QueueClearReceipt, I as InterruptPayload, h as CommandReceipt, i as StopPayload, j as StopReceipt, k as SessionSummary, E as ErrorCode } from '../piChatEvent-B3ehh9V0.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 { A as AgentSummary, a as AgentGatewayErrorCode, J as JsonValue } from '../errors-cNC4HMpV.js';
5
6
  import { InputGroupAddon, InputGroupButton, InputGroupTextarea, Button, Collapsible, CollapsibleContent, CollapsibleTrigger } from '@hachej/boring-ui-kit';
6
7
  import { Streamdown } from 'streamdown';
7
8
  import { StickToBottom } from 'use-stick-to-bottom';
@@ -199,7 +200,7 @@ interface SlashCommandContext {
199
200
  * Drives the PluginUpdateStatus banner above the composer. The `/reload`
200
201
  * builtin prefers this over the inline-text path: it calls
201
202
  * `pluginUpdate.run()` which (1) sets the banner to "running", (2)
202
- * hits /api/v1/agent/reload, (3) transitions to "success" or "error"
203
+ * hits the addressed Agent reload route, (3) transitions to "success" or "error"
203
204
  * with diagnostics. Returns a short string ack for the assistant
204
205
  * message bubble.
205
206
  */
@@ -241,7 +242,9 @@ interface ToolPart$1 {
241
242
  rendererResolution?: ToolRendererResolution;
242
243
  }
243
244
  type ToolRenderablePart = ToolPart$1 | BoringToolCallPart | unknown;
244
- type ToolRenderer = (part: ToolPart$1) => ReactNode;
245
+ type ToolRenderer = ((part: ToolPart$1) => ReactNode) & {
246
+ presentation?: "inline";
247
+ };
245
248
  type ToolRendererOverrides = Partial<Record<string, ToolRenderer>>;
246
249
  declare const defaultToolRenderers: Record<string, ToolRenderer>;
247
250
  declare function mergeToolRenderers(overrides?: ToolRendererOverrides): Record<string, ToolRenderer>;
@@ -280,7 +283,7 @@ interface OptimisticUserMessage extends BoringChatMessage {
280
283
  afterMessageId?: string;
281
284
  }
282
285
 
283
- type PiChatConnectionState = 'disconnected' | 'connecting' | 'connected' | 'reconnecting';
286
+ type PiChatConnectionState = 'disconnected' | 'connecting' | 'connected' | 'reconnecting' | 'suspended';
284
287
 
285
288
  interface PiChatRuntimeNotice {
286
289
  id: string;
@@ -346,8 +349,8 @@ interface RemotePiSessionHeaders {
346
349
  }
347
350
  interface RemotePiSessionOptions {
348
351
  sessionId: string;
349
- /** Selects the additive addressed AgentGateway transport. Omit for legacy wire. */
350
- agentTypeId?: string;
352
+ /** Addressed AgentGateway owner for this session. */
353
+ agentTypeId: string;
351
354
  workspaceId?: string;
352
355
  storageScope?: string;
353
356
  apiBaseUrl?: string;
@@ -400,6 +403,7 @@ interface RemotePiSessionDebugState {
400
403
  streamingMessageCount: 0 | 1;
401
404
  };
402
405
  disposed: boolean;
406
+ suspended: boolean;
403
407
  generation: number;
404
408
  streamRunId: number;
405
409
  reconnectAttempt: number;
@@ -419,6 +423,7 @@ declare class RemotePiSession {
419
423
  private streamRunId;
420
424
  private reconnectAttempt;
421
425
  private started;
426
+ private suspended;
422
427
  private disposed;
423
428
  private streamAbortController?;
424
429
  private reconnectTimer?;
@@ -436,6 +441,8 @@ declare class RemotePiSession {
436
441
  clearQueue(payload?: QueueClearPayload): Promise<QueueClearReceipt>;
437
442
  interrupt(payload?: InterruptPayload): Promise<CommandReceipt>;
438
443
  stop(payload?: StopPayload): Promise<StopReceipt>;
444
+ suspendStream(): void;
445
+ resumeStream(): void;
439
446
  dispose(): void;
440
447
  private hydrateAndConnect;
441
448
  private connectEvents;
@@ -458,6 +465,8 @@ declare class RemotePiSession {
458
465
  private clearReconnectTimer;
459
466
  private abortEventStream;
460
467
  private isGenerationActive;
468
+ private isStreamLifecycleActive;
469
+ private isHydrationActive;
461
470
  private isStreamActive;
462
471
  }
463
472
 
@@ -466,17 +475,27 @@ interface ActiveSessionStorageLike {
466
475
  setItem(key: string, value: string): void;
467
476
  removeItem(key: string): void;
468
477
  }
478
+ interface BootResumeSessionSource {
479
+ apiBaseUrl?: string;
480
+ sessionsApiPath: string;
481
+ /** Explicit normalized owner, including when sessionsApiPath is host-fixed. */
482
+ agentTypeId?: string;
483
+ workspaceId?: string;
484
+ storageScope?: string;
485
+ }
469
486
  interface ActiveSessionStorageOptions {
470
487
  storageScope?: string;
471
488
  storage?: ActiveSessionStorageLike;
489
+ bootResumeSource?: BootResumeSessionSource;
472
490
  }
473
491
  declare function activeSessionStorageKey(storageScope?: string): string;
474
492
  declare function readActiveSessionId(options?: ActiveSessionStorageOptions): string | undefined;
475
493
  declare function writeActiveSessionId(sessionId: string | undefined, options?: ActiveSessionStorageOptions): void;
476
- declare function clearActiveSessionId(options?: ActiveSessionStorageOptions): void;
477
494
 
478
495
  interface PiSessionCreateInit {
479
496
  title?: string;
497
+ /** Boot-only intent to resume this exact tab-owned empty session. */
498
+ resumeSessionId?: string;
480
499
  }
481
500
  interface PiSessionRefreshOptions {
482
501
  background?: boolean;
@@ -484,18 +503,24 @@ interface PiSessionRefreshOptions {
484
503
  throwOnError?: boolean;
485
504
  }
486
505
  interface UsePiSessionsOptions {
506
+ agentTypeId: string;
487
507
  apiBaseUrl?: string;
488
508
  sessionsApiPath?: string;
489
- /** Selects the additive addressed AgentGateway transport. Omit for legacy wire. */
490
- agentTypeId?: string;
491
509
  workspaceId?: string;
510
+ /** Stable caller identity echoed only after this source's rows are authoritative. */
511
+ sourceIdentity?: string;
512
+ /** Server-authorized workspace/storage scope used for HTTP requests. */
492
513
  storageScope?: string;
514
+ /** Browser-only active-session persistence scope; defaults to storageScope. */
515
+ activeSessionStorageScope?: string;
493
516
  requestHeaders?: Record<string, string | undefined>;
494
517
  enabled?: boolean;
495
518
  refreshKey?: unknown;
496
519
  initialActiveSessionId?: string;
497
520
  fetch?: typeof globalThis.fetch;
498
521
  storage?: ActiveSessionStorageLike;
522
+ /** Tab-owned unsent-session resume storage. Defaults to sessionStorage. */
523
+ bootResumeStorage?: ActiveSessionStorageLike;
499
524
  createRemoteSession?: (options: RemotePiSessionOptions) => RemotePiSession;
500
525
  remoteSessionOptions?: Omit<Partial<RemotePiSessionOptions>, 'sessionId' | 'agentTypeId' | 'workspaceId' | 'storageScope' | 'apiBaseUrl' | 'headers' | 'fetch'>;
501
526
  connectActiveSession?: boolean;
@@ -509,20 +534,25 @@ interface UsePiSessionsResult {
509
534
  sessions: SessionSummary[];
510
535
  activeSession: SessionSummary | undefined;
511
536
  activeSessionId: string | undefined;
537
+ /** Hidden boot candidate; never connected/rendered before create confirms it. */
538
+ resumeSessionId: string | undefined;
512
539
  activePiSession: RemotePiSession | undefined;
513
540
  dataStorageScope: string;
541
+ /** Attests that returned session data belongs to the caller's expected source. */
542
+ sourceIdentity: string | undefined;
514
543
  loading: boolean;
515
544
  loadingMore: boolean;
516
545
  hasMore: boolean;
517
546
  error: Error | undefined;
518
547
  refresh: (options?: PiSessionRefreshOptions) => Promise<void>;
519
548
  create: (init?: PiSessionCreateInit) => Promise<SessionSummary>;
549
+ rename: (id: string, title: string) => Promise<SessionSummary>;
520
550
  switch: (id: string) => void;
521
551
  delete: (id: string) => Promise<void>;
522
552
  loadMore: () => Promise<void>;
523
553
  reset: () => void;
524
554
  }
525
- declare function usePiSessions(options?: UsePiSessionsOptions): UsePiSessionsResult;
555
+ declare function usePiSessions(options: UsePiSessionsOptions): UsePiSessionsResult;
526
556
 
527
557
  interface SessionListProps {
528
558
  sessions: SessionSummary[];
@@ -619,8 +649,8 @@ interface AgentPluginReloadResult {
619
649
  interface PiChatPanelProps<TComposerBlocker extends ComposerBlocker = ComposerBlocker> {
620
650
  /** Optional externally selected Pi session id. When provided, session navigation is owned by the host. */
621
651
  sessionId?: string;
622
- /** Selects the additive addressed AgentGateway transport. Omit for legacy wire. */
623
- agentTypeId?: string;
652
+ /** Addressed AgentGateway owner for every chat/session request. */
653
+ agentTypeId: string;
624
654
  /** Alias kept for consumers that still pass the pre-cutover prop name. */
625
655
  extraCommands?: SlashCommand[];
626
656
  apiBaseUrl?: string;
@@ -690,7 +720,41 @@ interface PiChatPanelProps<TComposerBlocker extends ComposerBlocker = ComposerBl
690
720
  }
691
721
  declare function PiChatPanel<TComposerBlocker extends ComposerBlocker = ComposerBlocker>({ sessionId, agentTypeId, extraCommands, apiBaseUrl, workspaceId, storageScope, requestHeaders, storage, fetch, className, chrome, debug, showSessions, hotReloadEnabled, suggestions, emptyState, emptyPlacement, composerPlaceholder, initialDraft, autoSubmitInitialDraft, onDraftRestored, onAutoSubmitInitialDraftAccepted, onAutoSubmitInitialDraftSettled, model, defaultModel, availableModels, hideDefaultModelOption, hideComposerSettings, suppressPreSubmitCancelledWarning, thinkingLevel, thinkingControl, serverResourcesEnabled, mentionedFiles, commands, excludeBuiltinCommands, toolRenderers, createRemoteSession, remoteSessionOptions, hydrateMessages, allowPromptDuringInitialHydration, workspaceWarmupStatus, onSessionReset, onBeforeSubmit, onReloadAgentPlugins, onCommandResult, onComposerWarning, onMentionedFilesConsumed, onPromptSubmitStarted, onData, onOpenArtifact, composerBlockers, onComposerStop, onComposerBlockerAction, onTurnComplete, renderNoticeAction, }: PiChatPanelProps<TComposerBlocker>): react.JSX.Element;
692
722
 
723
+ type AddressedAgentOption = Pick<AgentSummary, 'agentTypeId' | 'label' | 'description' | 'pluginIds'>;
724
+ interface UseAddressedAgentSelectionOptions {
725
+ apiBaseUrl?: string;
726
+ requestHeaders?: Record<string, string | undefined>;
727
+ storageScope?: string;
728
+ fetch?: typeof globalThis.fetch;
729
+ enabled?: boolean;
730
+ }
731
+ interface UseAddressedAgentSelectionResult {
732
+ agents: AddressedAgentOption[];
733
+ selectedAgentTypeId: string | undefined;
734
+ loading: boolean;
735
+ error: Error | undefined;
736
+ selectAgentTypeId: (agentTypeId: string) => void;
737
+ }
738
+ declare function useAddressedAgentSelection({ apiBaseUrl, requestHeaders, storageScope, fetch, enabled, }?: UseAddressedAgentSelectionOptions): UseAddressedAgentSelectionResult;
739
+
740
+ declare const RUNTIME_SCOPE_MISMATCH_MESSAGE = "This chat belongs to a previous runtime configuration and can no longer be changed.";
741
+ type GatewayResponseErrorCode = AgentGatewayErrorCode | ErrorCode;
742
+ declare class GatewayResponseError extends Error {
743
+ readonly status: number;
744
+ readonly code?: GatewayResponseErrorCode | undefined;
745
+ readonly details?: JsonValue | undefined;
746
+ readonly body?: unknown | undefined;
747
+ readonly operation?: string | undefined;
748
+ readonly errorCode?: GatewayResponseErrorCode;
749
+ constructor(status: number, message: string, code?: GatewayResponseErrorCode | undefined, details?: JsonValue | undefined, body?: unknown | undefined, operation?: string | undefined);
750
+ }
751
+ declare function gatewayResponseError(response: Response, fallbackMessage: string, operation?: string): Promise<GatewayResponseError>;
752
+ declare function gatewayResponseErrorFromBody(status: number, body: unknown, fallbackMessage: string, operation?: string): GatewayResponseError;
753
+ declare function errorResponseCode(error: unknown): GatewayResponseErrorCode | undefined;
754
+ declare function isRuntimeScopeMismatchError(error: unknown): boolean;
755
+
693
756
  interface DebugDrawerProps {
757
+ agentTypeId: string;
694
758
  apiBaseUrl?: string;
695
759
  fetch?: typeof globalThis.fetch;
696
760
  sessionId: string;
@@ -700,7 +764,7 @@ interface DebugDrawerProps {
700
764
  width: number;
701
765
  onWidthChange: (w: number) => void;
702
766
  }
703
- declare function DebugDrawer({ apiBaseUrl, fetch, sessionId, messages, requestHeaders, storageScope, width, onWidthChange }: DebugDrawerProps): react.JSX.Element;
767
+ declare function DebugDrawer({ agentTypeId, apiBaseUrl, fetch, sessionId, messages, requestHeaders, storageScope, width, onWidthChange }: DebugDrawerProps): react.JSX.Element;
704
768
 
705
769
  interface OpenArtifactOptions {
706
770
  filesystem?: string;
@@ -733,7 +797,7 @@ declare function ModelPickerMenu({ value, onChange, options, disabled, hideDefau
733
797
  }): react.JSX.Element;
734
798
  /**
735
799
  * Model picker whose options are pi-coding-agent's actual available
736
- * models (fetched from /api/v1/agent/models). Groups by provider and
800
+ * models (fetched from the addressed Agent models route). Groups by provider and
737
801
  * shows a concise human-friendly label with the raw pi id as the
738
802
  * option's stored value, encoded as "{provider}:{id}" to keep
739
803
  * ids stable across providers.
@@ -834,7 +898,11 @@ type MessageActionProps = ComponentProps<typeof Button> & {
834
898
  };
835
899
  declare const MessageAction: ({ tooltip, children, label, variant, size, ...props }: MessageActionProps) => react.JSX.Element;
836
900
  type MessageResponseProps = ComponentProps<typeof Streamdown>;
837
- declare const MessageResponse: react.MemoExoticComponent<({ className, shikiTheme, components, ...props }: MessageResponseProps) => react.JSX.Element>;
901
+ type BoringMessageResponseProps = MessageResponseProps & {
902
+ /** Source path inferred from the preceding write/edit tool call, when known. */
903
+ codeFilename?: string;
904
+ };
905
+ declare const MessageResponse: react.MemoExoticComponent<({ className, shikiTheme, components, codeFilename, ...props }: BoringMessageResponseProps) => react.JSX.Element>;
838
906
 
839
907
  type ConversationProps = ComponentProps<typeof StickToBottom> & {
840
908
  onScrollToBottomReady?: (scrollToBottom: () => void) => void;
@@ -896,4 +964,4 @@ declare const ToolContent: ({ className, ...props }: ToolContentProps) => react.
896
964
 
897
965
  declare function cn(...inputs: ClassValue[]): string;
898
966
 
899
- export { type AgentCommandContribution, type AgentCommandOptions, type AgentPluginReloadResult, ArtifactOpenProvider, type AvailableModel, BoringChatMessage, ChatEmptyState, type ChatEmptyStateProps, type ChatMessageContribution, type ChatMessageContributionProps, ChatMessageContributionProvider, PiChatPanel as ChatPanel, type PiChatPanelProps as ChatPanelProps, type ChatSuggestion, CodeBlock, type CommandRegistry, type ComposerActionContributionProps, type ComposerBlocker, type ComposerBlockerAction, type ComposerContribution, ComposerContributionProvider, type ComposerDraftUpdate, Conversation, ConversationContent, ConversationScrollButton, DebugDrawer, type GroupedToolEntry, Message, MessageAction, MessageActions, MessageContent, MessageResponse, ModelPickerMenu, ModelSelect, ModelSelectTrigger, type ModelSelection, type OpenArtifactHandler, type ParsedCommand, PiChatPanel, type PiChatPanelProps, SessionBrowser as PiSessionBrowser, type PiSessionCreateInit, SessionList as PiSessionList, type PiSessionSearchItem, type PiSessionSearchOptions, type PiSessionSearchSortMode, PromptInput, PromptInputFooter, PromptInputSubmit, PromptInputTextarea, Reasoning, ReasoningContent, ReasoningTrigger, type SessionListProps, type SlashCommand, type SlashCommandContext, type ThinkingLevel, ThinkingSelect, Tool, ToolCallGroup, ToolContent, ToolHeader, type ToolPart$1 as ToolPart, type ToolRenderer, type ToolRendererOverrides, type UploadFileOptions, type UploadFileResult, type UsePiSessionsOptions, type UsePiSessionsResult, activeSessionStorageKey, builtinCommands, clearActiveSessionId, cn, createCommandRegistry, defaultChatSuggestions, defaultToolRenderers, getAgentCommands, matchPiSessionSearch, mergeShadcnToolRenderers, mergeToolRenderers, parsePiSessionSearchQuery, parseSlashCommand, readActiveSessionId, resolveToolRenderer, searchPiSessions, uploadFile, useOpenArtifact, usePiSessions, writeActiveSessionId };
967
+ export { type AddressedAgentOption, type AgentCommandContribution, type AgentCommandOptions, type AgentPluginReloadResult, ArtifactOpenProvider, type AvailableModel, BoringChatMessage, ChatEmptyState, type ChatEmptyStateProps, type ChatMessageContribution, type ChatMessageContributionProps, ChatMessageContributionProvider, PiChatPanel as ChatPanel, type PiChatPanelProps as ChatPanelProps, type ChatSuggestion, CodeBlock, type CommandRegistry, type ComposerActionContributionProps, type ComposerBlocker, type ComposerBlockerAction, type ComposerContribution, ComposerContributionProvider, type ComposerDraftUpdate, Conversation, ConversationContent, ConversationScrollButton, DebugDrawer, GatewayResponseError, type GatewayResponseErrorCode, type GroupedToolEntry, Message, MessageAction, MessageActions, MessageContent, MessageResponse, ModelPickerMenu, ModelSelect, ModelSelectTrigger, type ModelSelection, type OpenArtifactHandler, type ParsedCommand, PiChatPanel, type PiChatPanelProps, SessionBrowser as PiSessionBrowser, type PiSessionCreateInit, SessionList as PiSessionList, type PiSessionSearchItem, type PiSessionSearchOptions, type PiSessionSearchSortMode, PromptInput, PromptInputFooter, PromptInputSubmit, PromptInputTextarea, RUNTIME_SCOPE_MISMATCH_MESSAGE, Reasoning, ReasoningContent, ReasoningTrigger, type SessionListProps, type SlashCommand, type SlashCommandContext, type ThinkingLevel, ThinkingSelect, Tool, ToolCallGroup, ToolContent, ToolHeader, type ToolPart$1 as ToolPart, type ToolRenderer, type ToolRendererOverrides, type UploadFileOptions, type UploadFileResult, type UseAddressedAgentSelectionOptions, type UseAddressedAgentSelectionResult, type UsePiSessionsOptions, type UsePiSessionsResult, activeSessionStorageKey, builtinCommands, cn, createCommandRegistry, defaultChatSuggestions, defaultToolRenderers, errorResponseCode, gatewayResponseError, gatewayResponseErrorFromBody, getAgentCommands, isRuntimeScopeMismatchError, matchPiSessionSearch, mergeShadcnToolRenderers, mergeToolRenderers, parsePiSessionSearchQuery, parseSlashCommand, readActiveSessionId, resolveToolRenderer, searchPiSessions, uploadFile, useAddressedAgentSelection, useOpenArtifact, usePiSessions, writeActiveSessionId };