@hachej/boring-agent 0.1.41 → 0.1.43

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 (43) hide show
  1. package/README.md +31 -252
  2. package/dist/{DebugDrawer-2PUDZ2RL.js → DebugDrawer-RYEBQ6CO.js} +1 -1
  3. package/dist/{agentPluginEvents-CKrZLW3g.d.ts → agentPluginEvents-DP-vLNCs.d.ts} +36 -3
  4. package/dist/{session-BRovhe0D.d.ts → chatSubmitPayload-gC61O4Ni.d.ts} +20 -1
  5. package/dist/{chunk-IUJ22EFB.js → chunk-BOIV2I3N.js} +2 -10
  6. package/dist/{chunk-VQ7VSSSX.js → chunk-YUDMSYAO.js} +6 -1
  7. package/dist/front/index.d.ts +22 -5
  8. package/dist/front/index.js +155 -103
  9. package/dist/front/styles.css +0 -6
  10. package/dist/piChatEvent-DR9a-FVz.d.ts +306 -0
  11. package/dist/server/index.d.ts +363 -94
  12. package/dist/server/index.js +1611 -414
  13. package/dist/shared/index.d.ts +29 -23
  14. package/dist/shared/index.js +1 -1
  15. package/docs/ACCESSIBILITY.md +11 -13
  16. package/docs/API.md +86 -59
  17. package/docs/CSP.md +10 -9
  18. package/docs/ERROR_CODES.md +5 -1
  19. package/docs/KNOWN_LIMITATIONS.md +3 -3
  20. package/docs/MIGRATION.md +16 -16
  21. package/docs/PERFORMANCE.md +1 -1
  22. package/docs/PLUGINS.md +42 -12
  23. package/docs/README.md +89 -12
  24. package/docs/RISKS-MULTI-TAB.md +1 -1
  25. package/docs/STYLING.md +6 -4
  26. package/docs/UI-SHADCN.md +7 -7
  27. package/docs/runtime-provisioning.md +7 -3
  28. package/docs/runtime.md +68 -13
  29. package/docs/tools.md +37 -14
  30. package/package.json +2 -2
  31. package/dist/piChatEvent-Ck1BAE_m.d.ts +0 -323
  32. /package/docs/plans/{AGENT_EVAL_FRAMEWORK.md → archive/AGENT_EVAL_FRAMEWORK.md} +0 -0
  33. /package/docs/plans/{agent-package-spec.md → archive/agent-package-spec.md} +0 -0
  34. /package/docs/plans/{harness-followup-capabilities.md → archive/harness-followup-capabilities.md} +0 -0
  35. /package/docs/plans/{harness-tool-ui-capabilities.md → archive/harness-tool-ui-capabilities.md} +0 -0
  36. /package/docs/plans/{pi-followup-history-projection.md → archive/pi-followup-history-projection.md} +0 -0
  37. /package/docs/plans/{pi-tools-migration.md → archive/pi-tools-migration.md} +0 -0
  38. /package/docs/plans/{reviews → archive/reviews}/pi-followup-history-codex-review.md +0 -0
  39. /package/docs/plans/{reviews → archive/reviews}/pi-followup-history-gpt-review.md +0 -0
  40. /package/docs/plans/{reviews → archive/reviews}/pi-followup-history-opus-review.md +0 -0
  41. /package/docs/plans/{reviews → archive/reviews}/pi-followup-history-xai-review.md +0 -0
  42. /package/docs/plans/{vercel-base-snapshot-template-plan.md → archive/vercel-base-snapshot-template-plan.md} +0 -0
  43. /package/docs/plans/{vercel-persistent-sandbox-adapter.md → archive/vercel-persistent-sandbox-adapter.md} +0 -0
@@ -1,18 +1,28 @@
1
- import { o as WorkspaceRuntimeContext, S as Sandbox, g as SandboxHandleStore, f as SandboxHandleRecord, W as Workspace, j as TelemetrySink, F as FileSearch, P as PluginRestartWarning, A as AgentTool, q as AgentHarnessFactory } from '../agentPluginEvents-CKrZLW3g.js';
2
- export { r as AgentHarnessFactoryInput } from '../agentPluginEvents-CKrZLW3g.js';
1
+ import { o as WorkspaceRuntimeContext, S as Sandbox, g as SandboxHandleStore, f as SandboxHandleRecord, W as Workspace, j as TelemetrySink, F as FileSearch, i as Stat, E as Entry, c as ExecResult, q as WorkspaceChangeEvent, b as ExecOptions, P as PluginRestartWarning, A as AgentTool, r as AgentHarnessFactory } from '../agentPluginEvents-DP-vLNCs.js';
2
+ export { t as AgentHarnessFactoryInput } from '../agentPluginEvents-DP-vLNCs.js';
3
3
  import { Sandbox as Sandbox$1 } from '@vercel/sandbox';
4
4
  import { FastifyInstance, FastifyRequest, FastifyPluginAsync } from 'fastify';
5
5
  import { PackageSource, ExtensionFactory, SettingsManager } from '@mariozechner/pi-coding-agent';
6
- import '../session-BRovhe0D.js';
6
+ import { a as ChatModelSelection } from '../chatSubmitPayload-gC61O4Ni.js';
7
7
 
8
8
  interface CreateDirectSandboxOptions {
9
9
  runtimeContext?: WorkspaceRuntimeContext;
10
10
  }
11
11
  declare function createDirectSandbox(opts?: CreateDirectSandboxOptions): Sandbox;
12
12
 
13
+ interface BwrapResourceLimits {
14
+ cpuSeconds?: number;
15
+ fileSizeBlocks?: number;
16
+ maxProcesses?: number;
17
+ openFiles?: number;
18
+ virtualMemoryKb?: number;
19
+ }
13
20
  interface CreateBwrapSandboxOptions {
14
21
  hostWorkspaceRoot?: string;
15
22
  runtimeContext?: WorkspaceRuntimeContext;
23
+ network?: 'shared' | 'isolated';
24
+ dropAllCapabilities?: boolean;
25
+ resourceLimits?: BwrapResourceLimits;
16
26
  }
17
27
  declare function createBwrapSandbox(opts?: CreateBwrapSandboxOptions): Sandbox;
18
28
 
@@ -189,53 +199,6 @@ interface CreateNodeWorkspaceOptions {
189
199
  }
190
200
  declare function createNodeWorkspace(root: string, opts?: CreateNodeWorkspaceOptions): Workspace;
191
201
 
192
- declare function fileRoutes(app: FastifyInstance, opts: {
193
- workspace?: Workspace;
194
- getWorkspace?: (request: FastifyRequest) => Workspace | Promise<Workspace>;
195
- }, done: (err?: Error) => void): void;
196
-
197
- interface RuntimeTemplateContribution$1 {
198
- id: string;
199
- path: string | URL;
200
- target?: string;
201
- }
202
- interface RuntimePythonSpec$1 {
203
- id: string;
204
- /** uv-compatible pyproject.toml. Console scripts declared here are exposed to the agent. */
205
- projectFile: string | URL;
206
- /** Extra workspace libraries to install into the same environment. */
207
- extraLibs?: string[];
208
- /** Env vars exported by command shims, e.g. plugin builtin paths. */
209
- env?: Record<string, string | URL>;
210
- }
211
- interface RuntimeNodePackageSpec$1 {
212
- id: string;
213
- /** Package name materialized under workspaceRoot/node_modules, e.g. @boring/workspace. */
214
- packageName: string;
215
- /** Source package root. The provisioner copies the built package payload into node_modules. */
216
- packageRoot: string | URL;
217
- }
218
- interface RuntimeProvisioningContribution$1 {
219
- templateDirs?: RuntimeTemplateContribution$1[];
220
- python?: RuntimePythonSpec$1[];
221
- nodePackages?: RuntimeNodePackageSpec$1[];
222
- }
223
- interface ProvisionRuntimeWorkspaceOptions {
224
- workspaceRoot: string;
225
- contributions?: Array<{
226
- id: string;
227
- provisioning?: RuntimeProvisioningContribution$1;
228
- }>;
229
- force?: boolean;
230
- }
231
- interface RuntimeWorkspaceProvisioningResult {
232
- fingerprint: string;
233
- changed: boolean;
234
- env: Record<string, string>;
235
- binDir: string;
236
- }
237
- declare function provisionRuntimeWorkspace({ workspaceRoot, contributions, force, }: ProvisionRuntimeWorkspaceOptions): Promise<RuntimeWorkspaceProvisioningResult>;
238
-
239
202
  interface BoringAgentRuntimePaths {
240
203
  /** Runtime-visible workspace root. This is BORING_AGENT_WORKSPACE_ROOT. */
241
204
  workspaceRoot: string;
@@ -260,15 +223,6 @@ declare function getBoringAgentRuntimePaths(runtimeWorkspaceRoot: string): Borin
260
223
  declare function getBoringAgentPathEntries(paths: BoringAgentRuntimePaths): string[];
261
224
  declare function getBoringAgentRuntimeEnv(paths: BoringAgentRuntimePaths, adapterCacheRoot?: string): Record<string, string>;
262
225
 
263
- declare const VERCEL_SANDBOX_WORKSPACE_ROOT = "/workspace";
264
- interface VercelSandboxWorkspace extends Workspace {
265
- invalidateMetadataCache(): void;
266
- }
267
- interface VercelSandboxWorkspaceOptions {
268
- onMutation?: () => void;
269
- }
270
- declare function createVercelSandboxWorkspace(sandbox: Sandbox$1, workspaceOpts?: VercelSandboxWorkspaceOptions): VercelSandboxWorkspace;
271
-
272
226
  interface ProvisioningLogger {
273
227
  info?(message: string, fields?: Record<string, unknown>): void;
274
228
  warn?(message: string, fields?: Record<string, unknown>): void;
@@ -279,12 +233,12 @@ interface PluginSkillSource {
279
233
  name: string;
280
234
  source: string | URL;
281
235
  }
282
- interface RuntimeTemplateContribution {
236
+ interface RuntimeTemplateContribution$1 {
283
237
  id: string;
284
238
  path: string | URL;
285
239
  target?: string;
286
240
  }
287
- interface RuntimePythonSpec {
241
+ interface RuntimePythonSpec$1 {
288
242
  id: string;
289
243
  projectFile: string | URL;
290
244
  packageName?: string;
@@ -294,17 +248,17 @@ interface RuntimePythonSpec {
294
248
  env?: Record<string, string | URL>;
295
249
  expectedBins?: string[];
296
250
  }
297
- interface RuntimeNodePackageSpec {
251
+ interface RuntimeNodePackageSpec$1 {
298
252
  id: string;
299
253
  packageName: string;
300
254
  packageRoot?: string | URL;
301
255
  version?: string;
302
256
  expectedBins?: string[];
303
257
  }
304
- interface RuntimeProvisioningContribution {
305
- templateDirs?: RuntimeTemplateContribution[];
306
- python?: RuntimePythonSpec[];
307
- nodePackages?: RuntimeNodePackageSpec[];
258
+ interface RuntimeProvisioningContribution$1 {
259
+ templateDirs?: RuntimeTemplateContribution$1[];
260
+ python?: RuntimePythonSpec$1[];
261
+ nodePackages?: RuntimeNodePackageSpec$1[];
308
262
  }
309
263
  interface WorkspaceProvisioningResult {
310
264
  changed: boolean;
@@ -352,7 +306,7 @@ interface ProvisionWorkspaceRuntimeOptions {
352
306
  plugins: Array<{
353
307
  id: string;
354
308
  skills?: PluginSkillSource[];
355
- provisioning?: RuntimeProvisioningContribution;
309
+ provisioning?: RuntimeProvisioningContribution$1;
356
310
  }>;
357
311
  adapter: WorkspaceProvisioningAdapter;
358
312
  runtimeLayout: BoringAgentRuntimePaths;
@@ -363,32 +317,6 @@ interface ProvisionWorkspaceRuntimeOptions {
363
317
 
364
318
  declare function provisionWorkspaceRuntime(opts: ProvisionWorkspaceRuntimeOptions): Promise<WorkspaceProvisioningResult>;
365
319
 
366
- type ProvisioningArtifactKind = 'node' | 'python';
367
- /** What a per-mode packer receives to produce one artifact. `id`/`fingerprint`
368
- * are passed through (not used by the default packer, but part of the public
369
- * `prepareArtifact` contract — consumers key their own artifact paths off them). */
370
- interface ProvisioningArtifactRequest {
371
- kind: ProvisioningArtifactKind;
372
- id: string;
373
- fingerprint: string;
374
- source: string | URL;
375
- outputPath: string;
376
- }
377
-
378
- declare const VERCEL_PROVISIONING_CACHE_ROOT = "/tmp/boring-agent-cache";
379
- interface CreateVercelProvisioningAdapterOptions {
380
- runtimeLayout: BoringAgentRuntimePaths;
381
- workspaceFs: WorkspaceProvisioningAdapter['workspaceFs'];
382
- exec(command: string, args: string[], opts?: {
383
- cwd?: string;
384
- env?: Record<string, string>;
385
- timeoutMs?: number;
386
- }): Promise<WorkspaceProvisioningExecResult | void>;
387
- prepareArtifact(request: ProvisioningArtifactRequest): Promise<void>;
388
- cacheRoot?: string;
389
- }
390
- declare function createVercelProvisioningAdapter(options: CreateVercelProvisioningAdapterOptions): WorkspaceProvisioningAdapter;
391
-
392
320
  type BuiltinRuntimeModeId = 'direct' | 'local' | 'vercel-sandbox';
393
321
  type RuntimeModeId = BuiltinRuntimeModeId | (string & {});
394
322
  interface RuntimeModeAdapter {
@@ -424,6 +352,230 @@ interface RuntimeBundle {
424
352
  fileSearch: FileSearch;
425
353
  }
426
354
 
355
+ declare const REMOTE_WORKER_RUNTIME_CWD = "/workspace";
356
+ declare const REMOTE_WORKER_PROVIDER = "remote-worker";
357
+ declare const WORKER_INTERNAL_TOKEN_HEADER = "x-boring-internal-token";
358
+ declare const WORKER_WORKSPACE_ID_HEADER = "x-boring-workspace-id";
359
+ declare const WORKER_REQUEST_ID_HEADER = "x-boring-request-id";
360
+ type RemoteWorkerWorkspaceOp = {
361
+ op: 'readFile';
362
+ path: string;
363
+ } | {
364
+ op: 'readBinaryFile';
365
+ path: string;
366
+ } | {
367
+ op: 'writeFile';
368
+ path: string;
369
+ data: string;
370
+ } | {
371
+ op: 'writeBinaryFile';
372
+ path: string;
373
+ dataBase64: string;
374
+ } | {
375
+ op: 'readFileWithStat';
376
+ path: string;
377
+ } | {
378
+ op: 'writeFileWithStat';
379
+ path: string;
380
+ data: string;
381
+ } | {
382
+ op: 'writeBinaryFileWithStat';
383
+ path: string;
384
+ dataBase64: string;
385
+ } | {
386
+ op: 'unlink';
387
+ path: string;
388
+ } | {
389
+ op: 'readdir';
390
+ path: string;
391
+ } | {
392
+ op: 'stat';
393
+ path: string;
394
+ } | {
395
+ op: 'mkdir';
396
+ path: string;
397
+ recursive?: boolean;
398
+ } | {
399
+ op: 'rename';
400
+ from: string;
401
+ to: string;
402
+ };
403
+ type RemoteWorkerWorkspaceResult = {
404
+ content: string;
405
+ } | {
406
+ dataBase64: string;
407
+ } | {
408
+ stat: Stat;
409
+ } | {
410
+ content: string;
411
+ stat: Stat;
412
+ } | {
413
+ entries: Entry[];
414
+ } | {
415
+ ok: true;
416
+ };
417
+ interface RemoteWorkerExecRequest {
418
+ cmd: string;
419
+ cwd?: string;
420
+ env?: Record<string, string>;
421
+ timeoutMs?: number;
422
+ maxOutputBytes?: number;
423
+ }
424
+ interface RemoteWorkerExecResponse extends Omit<ExecResult, 'stdout' | 'stderr'> {
425
+ stdoutBase64: string;
426
+ stderrBase64: string;
427
+ }
428
+ interface RemoteWorkerErrorPayload {
429
+ error: {
430
+ code: string;
431
+ message: string;
432
+ statusCode?: number;
433
+ details?: unknown;
434
+ };
435
+ }
436
+ interface RemoteWorkerFsEventEnvelope {
437
+ event: WorkspaceChangeEvent;
438
+ }
439
+
440
+ interface RemoteWorkerClientOptions {
441
+ baseUrl: string;
442
+ token: string;
443
+ workspaceId: string;
444
+ requestId?: string;
445
+ fetchImpl?: typeof fetch;
446
+ requestTimeoutMs?: number;
447
+ execTimeoutMs?: number;
448
+ execRequestGraceMs?: number;
449
+ }
450
+ declare class RemoteWorkerClientError extends Error {
451
+ readonly statusCode: number;
452
+ readonly code: string;
453
+ readonly details?: unknown;
454
+ constructor(message: string, opts: {
455
+ statusCode: number;
456
+ code?: string;
457
+ details?: unknown;
458
+ });
459
+ }
460
+ declare class RemoteWorkerClient {
461
+ private readonly baseUrl;
462
+ private readonly token;
463
+ private readonly workspaceId;
464
+ private readonly requestId?;
465
+ private readonly fetchImpl;
466
+ private readonly requestTimeoutMs;
467
+ private readonly execTimeoutMs;
468
+ private readonly execRequestGraceMs;
469
+ constructor(opts: RemoteWorkerClientOptions);
470
+ private timeoutError;
471
+ private abortedError;
472
+ private fetchWithTimeout;
473
+ health(): Promise<void>;
474
+ workspace(op: RemoteWorkerWorkspaceOp): Promise<RemoteWorkerWorkspaceResult>;
475
+ exec(input: RemoteWorkerExecRequest, opts?: Pick<ExecOptions, 'signal'>): Promise<ExecResult>;
476
+ watch(onEvent: (event: WorkspaceChangeEvent) => void, onError?: (error: Error) => void): {
477
+ close(): void;
478
+ };
479
+ private consumeEvents;
480
+ private handleSseFrame;
481
+ }
482
+ declare function encodeBytesForWorker(bytes: Uint8Array): string;
483
+ declare function decodeBytesFromWorker(value: string): Uint8Array;
484
+ declare function constantTimeTokenEqual(a: string, b: string): boolean;
485
+
486
+ interface RemoteWorkerModeAdapterOptions {
487
+ baseUrl?: string;
488
+ token?: string;
489
+ fetchImpl?: RemoteWorkerClientOptions['fetchImpl'];
490
+ }
491
+ declare function createRemoteWorkerModeAdapter(opts?: RemoteWorkerModeAdapterOptions): RuntimeModeAdapter;
492
+
493
+ declare function createRemoteWorkerWorkspace(client: RemoteWorkerClient): Workspace;
494
+
495
+ declare function createRemoteWorkerSandbox(client: RemoteWorkerClient): Sandbox;
496
+
497
+ declare function fileRoutes(app: FastifyInstance, opts: {
498
+ workspace?: Workspace;
499
+ getWorkspace?: (request: FastifyRequest) => Workspace | Promise<Workspace>;
500
+ }, done: (err?: Error) => void): void;
501
+
502
+ interface RuntimeTemplateContribution {
503
+ id: string;
504
+ path: string | URL;
505
+ target?: string;
506
+ }
507
+ interface RuntimePythonSpec {
508
+ id: string;
509
+ /** uv-compatible pyproject.toml. Console scripts declared here are exposed to the agent. */
510
+ projectFile: string | URL;
511
+ /** Extra workspace libraries to install into the same environment. */
512
+ extraLibs?: string[];
513
+ /** Env vars exported by command shims, e.g. plugin builtin paths. */
514
+ env?: Record<string, string | URL>;
515
+ }
516
+ interface RuntimeNodePackageSpec {
517
+ id: string;
518
+ /** Package name materialized under workspaceRoot/node_modules, e.g. @boring/workspace. */
519
+ packageName: string;
520
+ /** Source package root. The provisioner copies the built package payload into node_modules. */
521
+ packageRoot: string | URL;
522
+ }
523
+ interface RuntimeProvisioningContribution {
524
+ templateDirs?: RuntimeTemplateContribution[];
525
+ python?: RuntimePythonSpec[];
526
+ nodePackages?: RuntimeNodePackageSpec[];
527
+ }
528
+ interface ProvisionRuntimeWorkspaceOptions {
529
+ workspaceRoot: string;
530
+ contributions?: Array<{
531
+ id: string;
532
+ provisioning?: RuntimeProvisioningContribution;
533
+ }>;
534
+ force?: boolean;
535
+ }
536
+ interface RuntimeWorkspaceProvisioningResult {
537
+ fingerprint: string;
538
+ changed: boolean;
539
+ env: Record<string, string>;
540
+ binDir: string;
541
+ }
542
+ declare function provisionRuntimeWorkspace({ workspaceRoot, contributions, force, }: ProvisionRuntimeWorkspaceOptions): Promise<RuntimeWorkspaceProvisioningResult>;
543
+
544
+ declare const VERCEL_SANDBOX_WORKSPACE_ROOT = "/workspace";
545
+ interface VercelSandboxWorkspace extends Workspace {
546
+ invalidateMetadataCache(): void;
547
+ }
548
+ interface VercelSandboxWorkspaceOptions {
549
+ onMutation?: () => void;
550
+ }
551
+ declare function createVercelSandboxWorkspace(sandbox: Sandbox$1, workspaceOpts?: VercelSandboxWorkspaceOptions): VercelSandboxWorkspace;
552
+
553
+ type ProvisioningArtifactKind = 'node' | 'python';
554
+ /** What a per-mode packer receives to produce one artifact. `id`/`fingerprint`
555
+ * are passed through (not used by the default packer, but part of the public
556
+ * `prepareArtifact` contract — consumers key their own artifact paths off them). */
557
+ interface ProvisioningArtifactRequest {
558
+ kind: ProvisioningArtifactKind;
559
+ id: string;
560
+ fingerprint: string;
561
+ source: string | URL;
562
+ outputPath: string;
563
+ }
564
+
565
+ declare const VERCEL_PROVISIONING_CACHE_ROOT = "/tmp/boring-agent-cache";
566
+ interface CreateVercelProvisioningAdapterOptions {
567
+ runtimeLayout: BoringAgentRuntimePaths;
568
+ workspaceFs: WorkspaceProvisioningAdapter['workspaceFs'];
569
+ exec(command: string, args: string[], opts?: {
570
+ cwd?: string;
571
+ env?: Record<string, string>;
572
+ timeoutMs?: number;
573
+ }): Promise<WorkspaceProvisioningExecResult | void>;
574
+ prepareArtifact(request: ProvisioningArtifactRequest): Promise<void>;
575
+ cacheRoot?: string;
576
+ }
577
+ declare function createVercelProvisioningAdapter(options: CreateVercelProvisioningAdapterOptions): WorkspaceProvisioningAdapter;
578
+
427
579
  declare function hasBwrap(): boolean;
428
580
  declare function autoDetectMode(): RuntimeModeId;
429
581
  declare function resolveMode(mode?: RuntimeModeId): RuntimeModeAdapter;
@@ -486,6 +638,102 @@ interface HotReloadablePiResources {
486
638
  type PiExtensionFactory = ExtensionFactory;
487
639
  declare function createResourceSettingsManager(cwd: string, agentDir: string, piPackages: PiPackageSource[]): SettingsManager;
488
640
 
641
+ /**
642
+ * Generic metering seam for hosts that bill native Pi usage.
643
+ *
644
+ * The agent package owns lifecycle correctness (when to reserve, record,
645
+ * settle, release based on native Pi events); the host-provided sink owns
646
+ * persistence and product policy (credits, pricing, currencies, hard stops).
647
+ *
648
+ * Lifecycle per accepted prompt/follow-up ("run", identified by `runId`):
649
+ *
650
+ * reserveRun before execution starts; throwing rejects the request
651
+ * (fail closed) so hosts can enforce hard stops.
652
+ * recordUsage once per native assistant message carrying usage.
653
+ * `usageId` is a stable idempotency key.
654
+ * settleRun when the run reaches a native terminal state and usage
655
+ * was recorded (or it finished ok).
656
+ * releaseRun when the run never produced billable usage: rejected
657
+ * execution, cleared queue, cancel/abort, or error before
658
+ * any usage arrived.
659
+ *
660
+ * Every run terminates with exactly one settle or release from the
661
+ * coordinator; sinks should still treat all four methods as idempotent
662
+ * because process restarts and client retries can replay transitions.
663
+ */
664
+ interface AgentMeteringSink {
665
+ reserveRun(input: MeteringReserveInput): Promise<MeteringReservationResult>;
666
+ /** Records the usage and returns the credit micros it was actually billed. The
667
+ * coordinator counts a usage as billable from this charged amount (not raw provider
668
+ * fields), so a row that prices to 0 (e.g. cost-only usage when provider cost isn't
669
+ * trusted) doesn't make a free run settle. */
670
+ recordUsage(input: MeteringUsageInput): Promise<MeteringUsageResult>;
671
+ settleRun(input: MeteringSettleInput): Promise<void>;
672
+ releaseRun(input: MeteringReleaseInput): Promise<void>;
673
+ }
674
+ interface MeteringUsageResult {
675
+ /** Credit micros this usage row was billed (0 = no real debit). */
676
+ billedMicros: number;
677
+ }
678
+ interface MeteringRunScope {
679
+ workspaceId: string;
680
+ userId?: string;
681
+ sessionId: string;
682
+ /** Stable id for one accepted prompt/follow-up run. */
683
+ runId: string;
684
+ source: 'pi-chat';
685
+ }
686
+ type MeteringRunKind = 'prompt' | 'followup';
687
+ interface MeteringReserveInput extends MeteringRunScope {
688
+ kind: MeteringRunKind;
689
+ message: string;
690
+ model?: ChatModelSelection;
691
+ }
692
+ /** Sinks without reservation rows can return an empty object. */
693
+ interface MeteringReservationResult {
694
+ reservationId?: string;
695
+ }
696
+ interface MeteringUsage {
697
+ input: number;
698
+ output: number;
699
+ cacheRead: number;
700
+ cacheWrite: number;
701
+ cost: {
702
+ input: number;
703
+ output: number;
704
+ cacheRead: number;
705
+ cacheWrite: number;
706
+ total: number;
707
+ };
708
+ }
709
+ interface MeteringUsageInput extends MeteringRunScope {
710
+ reservationId?: string;
711
+ /** Stable idempotency key for this usage row. */
712
+ usageId: string;
713
+ messageId?: string;
714
+ model?: {
715
+ provider?: string;
716
+ id?: string;
717
+ };
718
+ usage: MeteringUsage;
719
+ stopReason?: string;
720
+ }
721
+ type MeteringRunStatus = 'ok' | 'error' | 'aborted';
722
+ interface MeteringSettleInput extends MeteringRunScope {
723
+ reservationId?: string;
724
+ status: MeteringRunStatus;
725
+ }
726
+ type MeteringReleaseReason = 'run-rejected' | 'queue-cleared' | 'cancelled' | 'error-before-usage' | 'usage-write-failed' | 'fallback-hold-charge';
727
+ interface MeteringReleaseInput extends MeteringRunScope {
728
+ reservationId?: string;
729
+ reason: MeteringReleaseReason;
730
+ }
731
+ type MeteringErrorLogger = (message: string, error: unknown) => void;
732
+ /** Native Pi usage objects always carry token + cost breakdowns; normalize
733
+ * defensively (zero-filling gaps and clamping negatives) so a partial object
734
+ * from an unexpected provider still meters as zeros instead of NaN. */
735
+ declare function normalizeMeteringUsage(value: unknown): MeteringUsage | undefined;
736
+
489
737
  interface CreateAgentAppOptions {
490
738
  workspaceRoot?: string;
491
739
  sessionId?: string;
@@ -518,8 +766,16 @@ interface CreateAgentAppOptions {
518
766
  sessionNamespace?: string;
519
767
  /** Optional best-effort telemetry sink supplied by an embedding host. */
520
768
  telemetry?: TelemetrySink;
769
+ /** Optional billing sink for native Pi usage (see AgentMeteringSink). */
770
+ metering?: AgentMeteringSink;
521
771
  /** Optional explicit file-backed session directory. Mostly for tests/hosts. */
522
772
  sessionDir?: string;
773
+ /**
774
+ * Enable user/global Pi extension auto-discovery from .pi/ and ~/.pi.
775
+ * App/internal plugins should be passed through extraTools/pi instead.
776
+ * Defaults to true for standalone agent compatibility.
777
+ */
778
+ externalPlugins?: boolean;
523
779
  /**
524
780
  * Called BEFORE the harness reloads its session. May return a
525
781
  * `ReloadHookResult` (with `restart_warnings` and/or diagnostics) —
@@ -595,6 +851,19 @@ interface RegisterAgentRoutesOptions {
595
851
  sessionNamespace?: string;
596
852
  /** Optional best-effort telemetry sink supplied by an embedding host. */
597
853
  telemetry?: TelemetrySink;
854
+ /**
855
+ * Optional billing sink for native Pi usage. Reserve happens before
856
+ * accepted prompt/follow-up execution (fail closed), usage is recorded from
857
+ * native assistant message_end events, and runs settle/release from native
858
+ * terminal lifecycle. See AgentMeteringSink.
859
+ */
860
+ metering?: AgentMeteringSink;
861
+ /**
862
+ * Enable user/global Pi extension auto-discovery from .pi/ and ~/.pi.
863
+ * App/internal plugins should be passed through extraTools/pi instead.
864
+ * Defaults to true for standalone agent compatibility.
865
+ */
866
+ externalPlugins?: boolean;
598
867
  getSessionNamespace?: (ctx: {
599
868
  workspaceId: string;
600
869
  workspaceRoot: string;
@@ -658,4 +927,4 @@ interface Logger {
658
927
  }
659
928
  declare function createLogger(prefix: string): Logger;
660
929
 
661
- export { AgentHarnessFactory, type BoringAgentRuntimePaths, type BuiltinRuntimeModeId, type CreateAgentAppOptions, type CreateVercelProvisioningAdapterOptions, type DeploymentSnapshotProvider, type DeploymentSnapshotRecipe, type DeploymentSnapshotResult, type DeploymentSnapshotStatus, FileHandleStore, type LogFields, type Logger, type ModeContext, PI_PACKAGE_RESOURCE_FILTERS, type PiExtensionFactory, type PiHarnessOptions, type PiPackageSource, type PluginSkillSource, type ProvisionRuntimeWorkspaceOptions, type ProvisionWorkspaceRuntimeOptions, type ProvisioningArtifactRequest, type RegisterAgentRoutesOptions, type RuntimeBundle, type RuntimeModeAdapter, type RuntimeModeId, type RuntimeNodePackageSpec, type RuntimeProvisioningContribution, type RuntimePythonSpec, type RuntimeTemplateContribution, type RuntimeWorkspaceProvisioningResult, type SnapshotBakeOptions, type SnapshotBakeResult, UV_SETUP_COMMANDS, VERCEL_PROVISIONING_CACHE_ROOT, VERCEL_SANDBOX_WORKSPACE_ROOT, UV_SETUP_COMMANDS as VERCEL_UV_SETUP_COMMANDS, type VercelBakeClient, type VercelBakeSandbox, type VercelDeploymentSnapshotOptions, type WorkspaceProvisioningAdapter, type WorkspaceProvisioningExecResult, type WorkspaceProvisioningResult, applyCspHeaders, autoDetectMode, bakeSnapshotIfNeeded, buildDeploymentSnapshotRecipe, buildPackageHash, buildSnapshotRecipeHash, compactPiPackages, createAgentApp, createBwrapSandbox, createDirectSandbox, createLogger, createNodeWorkspace, createResourceSettingsManager, createVercelDeploymentSnapshotProvider, createVercelProvisioningAdapter, createVercelSandboxWorkspace, fileRoutes, getBoringAgentPathEntries, getBoringAgentRuntimeEnv, getBoringAgentRuntimePaths, hasBwrap, mergePiPackageSources, piPackageSourceKey, prepareDeploymentSnapshot, prepareVercelDeploymentSnapshot, provisionRuntimeWorkspace, provisionWorkspaceRuntime, registerAgentRoutes, resolveMode, resolveSandboxHandle };
930
+ export { AgentHarnessFactory, type AgentMeteringSink, type BoringAgentRuntimePaths, type BuiltinRuntimeModeId, type BwrapResourceLimits, type CreateAgentAppOptions, type CreateBwrapSandboxOptions, type CreateVercelProvisioningAdapterOptions, type DeploymentSnapshotProvider, type DeploymentSnapshotRecipe, type DeploymentSnapshotResult, type DeploymentSnapshotStatus, FileHandleStore, type LogFields, type Logger, type MeteringErrorLogger, type MeteringReleaseInput, type MeteringReleaseReason, type MeteringReservationResult, type MeteringReserveInput, type MeteringRunKind, type MeteringRunScope, type MeteringRunStatus, type MeteringSettleInput, type MeteringUsage, type MeteringUsageInput, type ModeContext, PI_PACKAGE_RESOURCE_FILTERS, type PiExtensionFactory, type PiHarnessOptions, type PiPackageSource, type PluginSkillSource, type ProvisionRuntimeWorkspaceOptions, type ProvisionWorkspaceRuntimeOptions, type ProvisioningArtifactRequest, REMOTE_WORKER_PROVIDER, REMOTE_WORKER_RUNTIME_CWD, type RegisterAgentRoutesOptions, RemoteWorkerClient, RemoteWorkerClientError, type RemoteWorkerClientOptions, type RemoteWorkerErrorPayload, type RemoteWorkerExecRequest, type RemoteWorkerExecResponse, type RemoteWorkerFsEventEnvelope, type RemoteWorkerModeAdapterOptions, type RemoteWorkerWorkspaceOp, type RemoteWorkerWorkspaceResult, type RuntimeBundle, type RuntimeModeAdapter, type RuntimeModeId, type RuntimeNodePackageSpec$1 as RuntimeNodePackageSpec, type RuntimeProvisioningContribution$1 as RuntimeProvisioningContribution, type RuntimePythonSpec$1 as RuntimePythonSpec, type RuntimeTemplateContribution$1 as RuntimeTemplateContribution, type RuntimeWorkspaceProvisioningResult, type SnapshotBakeOptions, type SnapshotBakeResult, UV_SETUP_COMMANDS, VERCEL_PROVISIONING_CACHE_ROOT, VERCEL_SANDBOX_WORKSPACE_ROOT, UV_SETUP_COMMANDS as VERCEL_UV_SETUP_COMMANDS, type VercelBakeClient, type VercelBakeSandbox, type VercelDeploymentSnapshotOptions, WORKER_INTERNAL_TOKEN_HEADER, WORKER_REQUEST_ID_HEADER, WORKER_WORKSPACE_ID_HEADER, type WorkspaceProvisioningAdapter, type WorkspaceProvisioningExecResult, type WorkspaceProvisioningResult, applyCspHeaders, autoDetectMode, bakeSnapshotIfNeeded, buildDeploymentSnapshotRecipe, buildPackageHash, buildSnapshotRecipeHash, compactPiPackages, constantTimeTokenEqual, createAgentApp, createBwrapSandbox, createDirectSandbox, createLogger, createNodeWorkspace, createRemoteWorkerModeAdapter, createRemoteWorkerSandbox, createRemoteWorkerWorkspace, createResourceSettingsManager, createVercelDeploymentSnapshotProvider, createVercelProvisioningAdapter, createVercelSandboxWorkspace, decodeBytesFromWorker, encodeBytesForWorker, fileRoutes, getBoringAgentPathEntries, getBoringAgentRuntimeEnv, getBoringAgentRuntimePaths, hasBwrap, mergePiPackageSources, normalizeMeteringUsage, piPackageSourceKey, prepareDeploymentSnapshot, prepareVercelDeploymentSnapshot, provisionRuntimeWorkspace, provisionWorkspaceRuntime, registerAgentRoutes, resolveMode, resolveSandboxHandle };