@hachej/boring-agent 0.1.94 → 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-N4AATPH7.js → chunk-NSE2RHU3.js} +8973 -7731
  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 +87 -17
  18. package/dist/front/index.js +1232 -690
  19. package/dist/front/styles.css +1228 -2167
  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 +570 -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';
@@ -137,11 +138,13 @@ interface ChatEmptyStateProps {
137
138
  * resolves this to `sendMessage` with the suggestion's prompt.
138
139
  */
139
140
  onSelect?: (suggestion: ChatSuggestion) => void;
141
+ /** Uses the concise empty-chat hierarchy. */
142
+ hero?: boolean;
140
143
  /** Optional content rendered below the suggestion grid. */
141
144
  footer?: ReactNode;
142
145
  className?: string;
143
146
  }
144
- declare function ChatEmptyState({ eyebrow, title, description, suggestions, onSelect, footer, className, }: ChatEmptyStateProps): react.JSX.Element;
147
+ declare function ChatEmptyState({ eyebrow, title, description, suggestions, onSelect, hero, footer, className, }: ChatEmptyStateProps): react.JSX.Element;
145
148
 
146
149
  interface ParsedCommand {
147
150
  name: string;
@@ -197,7 +200,7 @@ interface SlashCommandContext {
197
200
  * Drives the PluginUpdateStatus banner above the composer. The `/reload`
198
201
  * builtin prefers this over the inline-text path: it calls
199
202
  * `pluginUpdate.run()` which (1) sets the banner to "running", (2)
200
- * hits /api/v1/agent/reload, (3) transitions to "success" or "error"
203
+ * hits the addressed Agent reload route, (3) transitions to "success" or "error"
201
204
  * with diagnostics. Returns a short string ack for the assistant
202
205
  * message bubble.
203
206
  */
@@ -239,7 +242,9 @@ interface ToolPart$1 {
239
242
  rendererResolution?: ToolRendererResolution;
240
243
  }
241
244
  type ToolRenderablePart = ToolPart$1 | BoringToolCallPart | unknown;
242
- type ToolRenderer = (part: ToolPart$1) => ReactNode;
245
+ type ToolRenderer = ((part: ToolPart$1) => ReactNode) & {
246
+ presentation?: "inline";
247
+ };
243
248
  type ToolRendererOverrides = Partial<Record<string, ToolRenderer>>;
244
249
  declare const defaultToolRenderers: Record<string, ToolRenderer>;
245
250
  declare function mergeToolRenderers(overrides?: ToolRendererOverrides): Record<string, ToolRenderer>;
@@ -278,7 +283,7 @@ interface OptimisticUserMessage extends BoringChatMessage {
278
283
  afterMessageId?: string;
279
284
  }
280
285
 
281
- type PiChatConnectionState = 'disconnected' | 'connecting' | 'connected' | 'reconnecting';
286
+ type PiChatConnectionState = 'disconnected' | 'connecting' | 'connected' | 'reconnecting' | 'suspended';
282
287
 
283
288
  interface PiChatRuntimeNotice {
284
289
  id: string;
@@ -344,8 +349,8 @@ interface RemotePiSessionHeaders {
344
349
  }
345
350
  interface RemotePiSessionOptions {
346
351
  sessionId: string;
347
- /** Selects the additive addressed AgentGateway transport. Omit for legacy wire. */
348
- agentTypeId?: string;
352
+ /** Addressed AgentGateway owner for this session. */
353
+ agentTypeId: string;
349
354
  workspaceId?: string;
350
355
  storageScope?: string;
351
356
  apiBaseUrl?: string;
@@ -398,6 +403,7 @@ interface RemotePiSessionDebugState {
398
403
  streamingMessageCount: 0 | 1;
399
404
  };
400
405
  disposed: boolean;
406
+ suspended: boolean;
401
407
  generation: number;
402
408
  streamRunId: number;
403
409
  reconnectAttempt: number;
@@ -417,6 +423,7 @@ declare class RemotePiSession {
417
423
  private streamRunId;
418
424
  private reconnectAttempt;
419
425
  private started;
426
+ private suspended;
420
427
  private disposed;
421
428
  private streamAbortController?;
422
429
  private reconnectTimer?;
@@ -434,6 +441,8 @@ declare class RemotePiSession {
434
441
  clearQueue(payload?: QueueClearPayload): Promise<QueueClearReceipt>;
435
442
  interrupt(payload?: InterruptPayload): Promise<CommandReceipt>;
436
443
  stop(payload?: StopPayload): Promise<StopReceipt>;
444
+ suspendStream(): void;
445
+ resumeStream(): void;
437
446
  dispose(): void;
438
447
  private hydrateAndConnect;
439
448
  private connectEvents;
@@ -456,6 +465,8 @@ declare class RemotePiSession {
456
465
  private clearReconnectTimer;
457
466
  private abortEventStream;
458
467
  private isGenerationActive;
468
+ private isStreamLifecycleActive;
469
+ private isHydrationActive;
459
470
  private isStreamActive;
460
471
  }
461
472
 
@@ -464,17 +475,27 @@ interface ActiveSessionStorageLike {
464
475
  setItem(key: string, value: string): void;
465
476
  removeItem(key: string): void;
466
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
+ }
467
486
  interface ActiveSessionStorageOptions {
468
487
  storageScope?: string;
469
488
  storage?: ActiveSessionStorageLike;
489
+ bootResumeSource?: BootResumeSessionSource;
470
490
  }
471
491
  declare function activeSessionStorageKey(storageScope?: string): string;
472
492
  declare function readActiveSessionId(options?: ActiveSessionStorageOptions): string | undefined;
473
493
  declare function writeActiveSessionId(sessionId: string | undefined, options?: ActiveSessionStorageOptions): void;
474
- declare function clearActiveSessionId(options?: ActiveSessionStorageOptions): void;
475
494
 
476
495
  interface PiSessionCreateInit {
477
496
  title?: string;
497
+ /** Boot-only intent to resume this exact tab-owned empty session. */
498
+ resumeSessionId?: string;
478
499
  }
479
500
  interface PiSessionRefreshOptions {
480
501
  background?: boolean;
@@ -482,18 +503,24 @@ interface PiSessionRefreshOptions {
482
503
  throwOnError?: boolean;
483
504
  }
484
505
  interface UsePiSessionsOptions {
506
+ agentTypeId: string;
485
507
  apiBaseUrl?: string;
486
508
  sessionsApiPath?: string;
487
- /** Selects the additive addressed AgentGateway transport. Omit for legacy wire. */
488
- agentTypeId?: string;
489
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. */
490
513
  storageScope?: string;
514
+ /** Browser-only active-session persistence scope; defaults to storageScope. */
515
+ activeSessionStorageScope?: string;
491
516
  requestHeaders?: Record<string, string | undefined>;
492
517
  enabled?: boolean;
493
518
  refreshKey?: unknown;
494
519
  initialActiveSessionId?: string;
495
520
  fetch?: typeof globalThis.fetch;
496
521
  storage?: ActiveSessionStorageLike;
522
+ /** Tab-owned unsent-session resume storage. Defaults to sessionStorage. */
523
+ bootResumeStorage?: ActiveSessionStorageLike;
497
524
  createRemoteSession?: (options: RemotePiSessionOptions) => RemotePiSession;
498
525
  remoteSessionOptions?: Omit<Partial<RemotePiSessionOptions>, 'sessionId' | 'agentTypeId' | 'workspaceId' | 'storageScope' | 'apiBaseUrl' | 'headers' | 'fetch'>;
499
526
  connectActiveSession?: boolean;
@@ -507,20 +534,25 @@ interface UsePiSessionsResult {
507
534
  sessions: SessionSummary[];
508
535
  activeSession: SessionSummary | undefined;
509
536
  activeSessionId: string | undefined;
537
+ /** Hidden boot candidate; never connected/rendered before create confirms it. */
538
+ resumeSessionId: string | undefined;
510
539
  activePiSession: RemotePiSession | undefined;
511
540
  dataStorageScope: string;
541
+ /** Attests that returned session data belongs to the caller's expected source. */
542
+ sourceIdentity: string | undefined;
512
543
  loading: boolean;
513
544
  loadingMore: boolean;
514
545
  hasMore: boolean;
515
546
  error: Error | undefined;
516
547
  refresh: (options?: PiSessionRefreshOptions) => Promise<void>;
517
548
  create: (init?: PiSessionCreateInit) => Promise<SessionSummary>;
549
+ rename: (id: string, title: string) => Promise<SessionSummary>;
518
550
  switch: (id: string) => void;
519
551
  delete: (id: string) => Promise<void>;
520
552
  loadMore: () => Promise<void>;
521
553
  reset: () => void;
522
554
  }
523
- declare function usePiSessions(options?: UsePiSessionsOptions): UsePiSessionsResult;
555
+ declare function usePiSessions(options: UsePiSessionsOptions): UsePiSessionsResult;
524
556
 
525
557
  interface SessionListProps {
526
558
  sessions: SessionSummary[];
@@ -617,8 +649,8 @@ interface AgentPluginReloadResult {
617
649
  interface PiChatPanelProps<TComposerBlocker extends ComposerBlocker = ComposerBlocker> {
618
650
  /** Optional externally selected Pi session id. When provided, session navigation is owned by the host. */
619
651
  sessionId?: string;
620
- /** Selects the additive addressed AgentGateway transport. Omit for legacy wire. */
621
- agentTypeId?: string;
652
+ /** Addressed AgentGateway owner for every chat/session request. */
653
+ agentTypeId: string;
622
654
  /** Alias kept for consumers that still pass the pre-cutover prop name. */
623
655
  extraCommands?: SlashCommand[];
624
656
  apiBaseUrl?: string;
@@ -688,7 +720,41 @@ interface PiChatPanelProps<TComposerBlocker extends ComposerBlocker = ComposerBl
688
720
  }
689
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;
690
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
+
691
756
  interface DebugDrawerProps {
757
+ agentTypeId: string;
692
758
  apiBaseUrl?: string;
693
759
  fetch?: typeof globalThis.fetch;
694
760
  sessionId: string;
@@ -698,7 +764,7 @@ interface DebugDrawerProps {
698
764
  width: number;
699
765
  onWidthChange: (w: number) => void;
700
766
  }
701
- 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;
702
768
 
703
769
  interface OpenArtifactOptions {
704
770
  filesystem?: string;
@@ -731,7 +797,7 @@ declare function ModelPickerMenu({ value, onChange, options, disabled, hideDefau
731
797
  }): react.JSX.Element;
732
798
  /**
733
799
  * Model picker whose options are pi-coding-agent's actual available
734
- * models (fetched from /api/v1/agent/models). Groups by provider and
800
+ * models (fetched from the addressed Agent models route). Groups by provider and
735
801
  * shows a concise human-friendly label with the raw pi id as the
736
802
  * option's stored value, encoded as "{provider}:{id}" to keep
737
803
  * ids stable across providers.
@@ -832,7 +898,11 @@ type MessageActionProps = ComponentProps<typeof Button> & {
832
898
  };
833
899
  declare const MessageAction: ({ tooltip, children, label, variant, size, ...props }: MessageActionProps) => react.JSX.Element;
834
900
  type MessageResponseProps = ComponentProps<typeof Streamdown>;
835
- 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>;
836
906
 
837
907
  type ConversationProps = ComponentProps<typeof StickToBottom> & {
838
908
  onScrollToBottomReady?: (scrollToBottom: () => void) => void;
@@ -894,4 +964,4 @@ declare const ToolContent: ({ className, ...props }: ToolContentProps) => react.
894
964
 
895
965
  declare function cn(...inputs: ClassValue[]): string;
896
966
 
897
- 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 };