@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.
- package/dist/DebugDrawer-2TO5SE2D.js +7 -0
- package/dist/{chunk-NITBKFG6.js → chunk-3OEDBRKY.js} +93 -58
- package/dist/{chunk-BOIV2I3N.js → chunk-46HJK2ES.js} +31 -16
- package/dist/{chunk-AQBXNPMD.js → chunk-4IQ4HHBG.js} +4 -0
- package/dist/{chunk-OFQ7J6SI.js → chunk-LSO2AO6Q.js} +57 -1
- package/dist/{chunk-N4AATPH7.js → chunk-NSE2RHU3.js} +8973 -7731
- package/dist/{chunk-2GBHYJVC.js → chunk-VXF5DWS6.js} +34 -0
- package/dist/{chunk-2TMS2RU2.js → chunk-WC5KBGP2.js} +518 -165
- package/dist/chunk-YGRQ4Q5P.js +20 -0
- package/dist/core/index.d.ts +5 -5
- package/dist/core/index.js +604 -7
- package/dist/{createHarness-UCD74XXK.js → createHarness-PW3A2MRB.js} +3 -3
- package/dist/{errors-G6T6S7PQ.d.ts → errors-cNC4HMpV.d.ts} +14 -7
- package/dist/eval/index.d.ts +5 -3
- package/dist/eval/index.js +31 -23
- package/dist/file-search-QxnanNjO.d.ts +87 -0
- package/dist/front/index.d.ts +87 -17
- package/dist/front/index.js +1232 -690
- package/dist/front/styles.css +1228 -2167
- package/dist/{harness-Cc48o6uS.d.ts → harness-DS8jLKIx.d.ts} +4 -2
- package/dist/{lease-CusB-uLg.d.ts → lease-D8WC6pQl.d.ts} +10 -89
- package/dist/{middleware-CzW8n7B7.d.ts → middleware-Cq_cYHjJ.d.ts} +1 -1
- package/dist/piChatEvent-B3ehh9V0.d.ts +384 -0
- package/dist/{piChatSessionService-C0KbcGw9.d.ts → piChatSessionService-xnv8rcdh.d.ts} +1 -1
- package/dist/{sandbox-DAD8cWQR.d.ts → sandbox-KQiEdz4W.d.ts} +12 -1
- package/dist/server/agent-host/testing/compositionRouteProof.d.ts +8 -0
- package/dist/server/agent-host/testing/compositionRouteProof.js +78 -0
- package/dist/server/agent-host/testing/gatewayConformance.d.ts +6 -6
- package/dist/server/agent-host/testing/gatewayConformance.js +17 -9
- package/dist/server/index.d.ts +570 -370
- package/dist/server/index.js +69 -17
- package/dist/server/worker/index.d.ts +2 -2
- package/dist/server/worker/index.js +9 -9
- package/dist/shared/index.d.ts +212 -56
- package/dist/shared/index.js +43 -7
- package/dist/{types-C-Eroi__.d.ts → types-D_SD-7_l.d.ts} +304 -87
- package/docs/AGENT_GATEWAY_V0.md +6 -3
- package/docs/AGENT_PACKAGES.md +80 -0
- package/docs/ERROR_CODES.md +58 -0
- package/docs/README.md +1 -0
- package/docs/runtime.md +19 -2
- package/package.json +34 -29
- package/dist/DebugDrawer-RYEBQ6CO.js +0 -6
- package/dist/chunk-EOMY2HDT.js +0 -619
- package/dist/piChatEvent-BsMp3MSo.d.ts +0 -368
|
@@ -1,13 +1,77 @@
|
|
|
1
|
-
import * as fastify from 'fastify';
|
|
2
1
|
import { FastifyRequest, FastifyPluginAsync } from 'fastify';
|
|
3
|
-
import { w as ToolReadinessRequirement, T as TelemetrySink,
|
|
4
|
-
import { F as FileSearch,
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
2
|
+
import { w as ToolReadinessRequirement, T as TelemetrySink, s as AgentTool, t as AgentHarnessFactory } from './harness-DS8jLKIx.js';
|
|
3
|
+
import { F as FileSearch, A as AgentSkillResource, W as WorkspaceAgentDirectRunInput, L as LeaseBoundWorkspaceAgent } from './file-search-QxnanNjO.js';
|
|
4
|
+
import { b as Workspace, R as RuntimeFilesystemCapability, c as WorkspaceRuntimeContext, S as Sandbox } from './sandbox-KQiEdz4W.js';
|
|
5
|
+
import { d as AgentSessionRef, V as VerifiedAgentScopeClaim, f as AgentGatewayErrorDTO, J as JsonValue, c as AuthorizedAgentScope, b as AgentGateway, j as AgentScopeVerifier } from './errors-cNC4HMpV.js';
|
|
6
|
+
import { o as ChatModelSelection } from './piChatEvent-B3ehh9V0.js';
|
|
7
|
+
import { RuntimeHostOperations, RuntimeFilesystemBinding as RuntimeFilesystemBinding$1 } from '@hachej/boring-bash/agent';
|
|
8
8
|
import { CreateNodeWorkspaceOptions, BoringAgentRuntimePaths } from '@hachej/boring-sandbox/providers/node-workspace';
|
|
9
|
-
import { PackageSource, ExtensionFactory
|
|
10
|
-
|
|
9
|
+
import { PackageSource, ExtensionFactory } from '@mariozechner/pi-coding-agent';
|
|
10
|
+
|
|
11
|
+
type SessionFileChangeOp = 'write' | 'edit' | 'unlink' | 'rename' | 'mkdir';
|
|
12
|
+
interface SessionFileChange {
|
|
13
|
+
op: SessionFileChangeOp;
|
|
14
|
+
path: string;
|
|
15
|
+
oldPath?: string;
|
|
16
|
+
size?: number;
|
|
17
|
+
timestamp: string;
|
|
18
|
+
}
|
|
19
|
+
interface SessionChangesTracker {
|
|
20
|
+
record(scope: SessionChangesScope | string, change: SessionFileChange): void;
|
|
21
|
+
list(scope: SessionChangesScope | string): SessionFileChange[];
|
|
22
|
+
clear(scope: SessionChangesScope | string): void;
|
|
23
|
+
}
|
|
24
|
+
interface SessionChangesScope {
|
|
25
|
+
readonly workspaceScopeId?: string;
|
|
26
|
+
readonly agentTypeId?: string;
|
|
27
|
+
readonly sessionId: string;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
interface AgentModelSelection {
|
|
31
|
+
provider: string;
|
|
32
|
+
id: string;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* GET /api/v1/agents/:agentTypeId/models
|
|
37
|
+
*
|
|
38
|
+
* Returns the list of models pi-coding-agent has auth for (i.e. where
|
|
39
|
+
* the corresponding provider API key is present in the environment or
|
|
40
|
+
* `~/.pi/agent/auth.json`). Consumers — including the shadcn example
|
|
41
|
+
* ChatPanel — fetch this endpoint to populate the model-selector dropdown
|
|
42
|
+
* instead of hardcoding a short alias list.
|
|
43
|
+
*
|
|
44
|
+
* Shape:
|
|
45
|
+
* {
|
|
46
|
+
* models: [
|
|
47
|
+
* { provider: "anthropic", id: "claude-sonnet-4-6", label: "Claude Sonnet 4.6", available: true },
|
|
48
|
+
* ...
|
|
49
|
+
* ]
|
|
50
|
+
* }
|
|
51
|
+
*
|
|
52
|
+
* Safe to call unauthenticated — we only report {provider, id, label,
|
|
53
|
+
* available}, never any key material.
|
|
54
|
+
*/
|
|
55
|
+
|
|
56
|
+
interface ModelSummary {
|
|
57
|
+
provider: string;
|
|
58
|
+
id: string;
|
|
59
|
+
label: string;
|
|
60
|
+
available: boolean;
|
|
61
|
+
}
|
|
62
|
+
interface ModelFilterContext {
|
|
63
|
+
request: FastifyRequest;
|
|
64
|
+
workspaceId?: string;
|
|
65
|
+
}
|
|
66
|
+
type ModelFilterResult = {
|
|
67
|
+
models: readonly ModelSummary[];
|
|
68
|
+
defaultModel?: AgentModelSelection;
|
|
69
|
+
};
|
|
70
|
+
interface ModelsRoutesOptions {
|
|
71
|
+
path?: string;
|
|
72
|
+
authorizeRequest?: (request: FastifyRequest) => void | Promise<void>;
|
|
73
|
+
filterModels?: (ctx: ModelFilterContext, models: readonly ModelSummary[], defaultModel: AgentModelSelection | undefined) => ModelFilterResult | Promise<ModelFilterResult>;
|
|
74
|
+
}
|
|
11
75
|
|
|
12
76
|
/**
|
|
13
77
|
* Generic metering seam for hosts that bill native Pi usage.
|
|
@@ -187,7 +251,13 @@ interface AgentRuntimeHostOperations extends RuntimeHostOperations {
|
|
|
187
251
|
}>;
|
|
188
252
|
validatePath(root: string, requestedPath: string): string;
|
|
189
253
|
assertRealPathWithinWorkspace(root: string, targetPath: string): Promise<void>;
|
|
254
|
+
resolveRealWorkspacePath(root: string, targetPath: string): Promise<string>;
|
|
190
255
|
isIgnoredDirName(name: string): boolean;
|
|
256
|
+
/** Host-owned confined projection for package resources outside the workspace. */
|
|
257
|
+
createAgentResourceFilesystemBinding(filesystem: string, mounts: readonly {
|
|
258
|
+
readonly logicalRoot: string;
|
|
259
|
+
readonly sourceRoot: string;
|
|
260
|
+
}[]): Promise<RuntimeFilesystemBinding$1>;
|
|
191
261
|
}
|
|
192
262
|
|
|
193
263
|
interface ProvisioningLogger {
|
|
@@ -243,7 +313,7 @@ interface ResolveInstallSourceOpts {
|
|
|
243
313
|
fingerprint: string;
|
|
244
314
|
}
|
|
245
315
|
interface WorkspaceProvisioningAdapter {
|
|
246
|
-
mode: 'direct' | 'local' | 'vercel-sandbox';
|
|
316
|
+
mode: 'direct' | 'local' | 'blaxel' | 'vercel-sandbox';
|
|
247
317
|
exec(command: string, args: string[], opts?: {
|
|
248
318
|
cwd?: string;
|
|
249
319
|
env?: Record<string, string>;
|
|
@@ -283,7 +353,7 @@ interface ProvisionWorkspaceRuntimeOptions {
|
|
|
283
353
|
telemetryContext?: ProvisioningTelemetryContext;
|
|
284
354
|
}
|
|
285
355
|
|
|
286
|
-
type BuiltinRuntimeModeId = 'direct' | 'local' | 'vercel-sandbox';
|
|
356
|
+
type BuiltinRuntimeModeId = 'direct' | 'local' | 'blaxel' | 'vercel-sandbox';
|
|
287
357
|
type RuntimeModeId = BuiltinRuntimeModeId | (string & {});
|
|
288
358
|
interface RuntimeModeReadinessHooks {
|
|
289
359
|
initialSandboxReady?: boolean;
|
|
@@ -352,6 +422,12 @@ interface ModeContext {
|
|
|
352
422
|
requestId?: string;
|
|
353
423
|
telemetry?: TelemetrySink;
|
|
354
424
|
}
|
|
425
|
+
interface RuntimeFilesystemAccessDecision {
|
|
426
|
+
readonly filesystem: string;
|
|
427
|
+
readonly normalizedPath: string;
|
|
428
|
+
readonly access: 'readonly' | 'readwrite';
|
|
429
|
+
readonly capabilities: Readonly<Record<RuntimeFilesystemCapability, boolean>>;
|
|
430
|
+
}
|
|
355
431
|
interface RuntimeFilesystemBindingOperations {
|
|
356
432
|
read(descriptor: {
|
|
357
433
|
filesystem: string;
|
|
@@ -408,6 +484,14 @@ interface RuntimeFilesystemBindingOperations {
|
|
|
408
484
|
mtimeMs?: number;
|
|
409
485
|
metadata?: unknown;
|
|
410
486
|
}>;
|
|
487
|
+
writeBinary?(descriptor: {
|
|
488
|
+
filesystem: string;
|
|
489
|
+
path: string;
|
|
490
|
+
content: Uint8Array;
|
|
491
|
+
}): Promise<{
|
|
492
|
+
mtimeMs?: number;
|
|
493
|
+
metadata?: unknown;
|
|
494
|
+
}>;
|
|
411
495
|
delete?(descriptor: {
|
|
412
496
|
filesystem: string;
|
|
413
497
|
path: string;
|
|
@@ -428,6 +512,10 @@ interface RuntimeFilesystemBindingOperations {
|
|
|
428
512
|
}): Promise<{
|
|
429
513
|
metadata?: unknown;
|
|
430
514
|
}>;
|
|
515
|
+
resolveAccess?(descriptor: {
|
|
516
|
+
filesystem: string;
|
|
517
|
+
path: string;
|
|
518
|
+
}): Promise<RuntimeFilesystemAccessDecision>;
|
|
431
519
|
rejectMutation(operation: string, descriptor: {
|
|
432
520
|
filesystem: string;
|
|
433
521
|
path: string;
|
|
@@ -459,6 +547,12 @@ interface RuntimeBundle {
|
|
|
459
547
|
filesystem?: RuntimeFilesystemStrategy;
|
|
460
548
|
/** Optional filesystem bindings prepared for this runtime/session. */
|
|
461
549
|
filesystemBindings?: RuntimeFilesystemBinding[];
|
|
550
|
+
/**
|
|
551
|
+
* Workspace-relative prefixes the host protects from mutation. Carried on the
|
|
552
|
+
* bundle so shell/provisioning enforcement uses the same policy as the
|
|
553
|
+
* Operations bindings instead of re-deriving it.
|
|
554
|
+
*/
|
|
555
|
+
readonlyWorkspacePaths?: readonly string[];
|
|
462
556
|
/** Provisioning operations derived from this bundle's acquired Workspace + Sandbox pair. */
|
|
463
557
|
provisioningAdapter?: WorkspaceProvisioningAdapter;
|
|
464
558
|
/** Idempotently releases the acquired Workspace + Sandbox pair. */
|
|
@@ -474,6 +568,8 @@ declare function mergePiPackageSources(base?: PiPackageSource[], additional?: Pi
|
|
|
474
568
|
interface PiHarnessOptions {
|
|
475
569
|
noContextFiles?: boolean;
|
|
476
570
|
noSkills?: boolean;
|
|
571
|
+
/** Disable ambient Pi extensions (required when tools execute in a remote runtime). */
|
|
572
|
+
noExtensions?: boolean;
|
|
477
573
|
additionalSkillPaths?: string[];
|
|
478
574
|
defaultModel?: {
|
|
479
575
|
provider: string;
|
|
@@ -510,9 +606,36 @@ interface HotReloadablePiResources {
|
|
|
510
606
|
extensionPaths?: string[];
|
|
511
607
|
}
|
|
512
608
|
type PiExtensionFactory = ExtensionFactory;
|
|
513
|
-
declare function createResourceSettingsManager(cwd: string, agentDir: string, piPackages: PiPackageSource[]): SettingsManager;
|
|
514
609
|
|
|
515
|
-
|
|
610
|
+
/**
|
|
611
|
+
* GET /api/v1/agents/:agentTypeId/skills
|
|
612
|
+
*
|
|
613
|
+
* Returns the list of PI skills discovered for the current workspace —
|
|
614
|
+
* global skills (~/.pi/agent/skills) plus any project-local SKILL.md files.
|
|
615
|
+
* The front-end uses this to populate the slash-command picker without
|
|
616
|
+
* host apps having to hardcode skill names in extraCommands.
|
|
617
|
+
*
|
|
618
|
+
* Shape:
|
|
619
|
+
* { skills: [{ name: string, description: string }] }
|
|
620
|
+
*/
|
|
621
|
+
|
|
622
|
+
interface SkillSummary {
|
|
623
|
+
name: string;
|
|
624
|
+
description: string;
|
|
625
|
+
/** Browser-safe locator for opening a supported skill source. */
|
|
626
|
+
resource?: AgentSkillResource;
|
|
627
|
+
/** False for management-only rows that Pi did not retain as invocable. */
|
|
628
|
+
invocable?: boolean;
|
|
629
|
+
/** Human-readable source/scope label for diagnostics and disabled rows. */
|
|
630
|
+
source?: string;
|
|
631
|
+
}
|
|
632
|
+
interface AgentSkillResourceSnapshot {
|
|
633
|
+
readonly generation: string;
|
|
634
|
+
readonly managedSkills: readonly SkillSummary[];
|
|
635
|
+
locateSkill(filePath: string): AgentSkillResource | undefined;
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
type AgentGatewayEffect = 'session.create' | 'session.rename' | 'session.delete' | 'session.prompt' | 'session.followup' | 'session.interrupt' | 'session.stop' | 'session.queue.clear' | 'agent.reload' | 'session.command.execute';
|
|
516
639
|
type AgentRequestTarget = {
|
|
517
640
|
readonly kind: 'agent';
|
|
518
641
|
readonly agentTypeId: string;
|
|
@@ -527,25 +650,20 @@ interface AgentRequestKey {
|
|
|
527
650
|
readonly target: AgentRequestTarget;
|
|
528
651
|
readonly requestId: string;
|
|
529
652
|
}
|
|
653
|
+
interface AgentStableServiceErrorDTO {
|
|
654
|
+
readonly statusCode: number;
|
|
655
|
+
readonly error: {
|
|
656
|
+
readonly code: string;
|
|
657
|
+
readonly message: string;
|
|
658
|
+
readonly retryable?: boolean;
|
|
659
|
+
};
|
|
660
|
+
}
|
|
530
661
|
type AgentRequestFailure = {
|
|
531
662
|
readonly kind: 'gateway';
|
|
532
663
|
readonly error: AgentGatewayErrorDTO;
|
|
533
664
|
} | {
|
|
534
|
-
|
|
535
|
-
readonly
|
|
536
|
-
readonly code: string;
|
|
537
|
-
readonly statusCode: 500;
|
|
538
|
-
readonly message: string;
|
|
539
|
-
readonly details?: JsonValue;
|
|
540
|
-
} | {
|
|
541
|
-
/** Server-only observed legacy service failure; never returned by AgentGateway. */
|
|
542
|
-
readonly kind: 'legacy-service';
|
|
543
|
-
readonly name: string;
|
|
544
|
-
readonly message: string;
|
|
545
|
-
readonly code?: string;
|
|
546
|
-
readonly statusCode?: number;
|
|
547
|
-
readonly retryable?: boolean;
|
|
548
|
-
readonly details?: JsonValue;
|
|
665
|
+
readonly kind: 'service';
|
|
666
|
+
readonly error: AgentStableServiceErrorDTO;
|
|
549
667
|
};
|
|
550
668
|
interface AgentRequestLedgerRecordBase {
|
|
551
669
|
readonly key: AgentRequestKey;
|
|
@@ -570,13 +688,22 @@ type AgentRequestLedgerRecord = (AgentRequestLedgerRecordBase & {
|
|
|
570
688
|
readonly error: AgentGatewayErrorDTO;
|
|
571
689
|
});
|
|
572
690
|
interface AgentRequestLedger {
|
|
573
|
-
|
|
691
|
+
/** Direct production projections require transactional durable ownership. */
|
|
692
|
+
readonly durability: 'durable-transactional' | 'in-memory';
|
|
693
|
+
/** Atomic compare-and-create across every process sharing the durable store. */
|
|
694
|
+
prepare(key: AgentRequestKey, digest: string): Promise<AgentRequestLedgerPrepareResult>;
|
|
695
|
+
/** All transitions are compare-and-swap against the exact allowed prior state. */
|
|
574
696
|
acceptAdmission(key: AgentRequestKey, admissionReceipt: string): Promise<void>;
|
|
575
697
|
beginEffect(key: AgentRequestKey): Promise<void>;
|
|
576
698
|
reject(key: AgentRequestKey, failure: AgentRequestFailure): Promise<void>;
|
|
577
699
|
complete(key: AgentRequestKey, receipt: JsonValue): Promise<void>;
|
|
578
700
|
markOutcomeUnknown(key: AgentRequestKey, error: AgentGatewayErrorDTO): Promise<void>;
|
|
579
701
|
read(key: AgentRequestKey): Promise<AgentRequestLedgerRecord | undefined>;
|
|
702
|
+
close?(): void | Promise<void>;
|
|
703
|
+
}
|
|
704
|
+
interface AgentRequestLedgerPrepareResult {
|
|
705
|
+
readonly ownership: 'created' | 'existing';
|
|
706
|
+
readonly record: AgentRequestLedgerRecord;
|
|
580
707
|
}
|
|
581
708
|
type AgentEffectAdmissionResult = {
|
|
582
709
|
readonly type: 'accepted';
|
|
@@ -598,13 +725,45 @@ interface AgentEffectAdmission {
|
|
|
598
725
|
readonly target: AgentRequestTarget;
|
|
599
726
|
}): Promise<AgentEffectAdmissionResult>;
|
|
600
727
|
}
|
|
728
|
+
/**
|
|
729
|
+
* An authored file that contributes to this agent's instructions, addressed
|
|
730
|
+
* exactly like every other openable resource (`{filesystem, path}`) so the
|
|
731
|
+
* client can route it through the same safety guard as skills.
|
|
732
|
+
*
|
|
733
|
+
* The Host knows these locations from fleet configuration; clients must never
|
|
734
|
+
* re-derive them from the agent id (seat and agentTypeId are unrelated
|
|
735
|
+
* fleet.yaml fields). `role` is a DISCRIMINATOR, not a display string — the
|
|
736
|
+
* words shown to the user are the client's business.
|
|
737
|
+
*/
|
|
738
|
+
interface AgentInstructionFileRef {
|
|
739
|
+
readonly filesystem: string;
|
|
740
|
+
/** Workspace-relative path, e.g. `.agents/personas/concierge/instructions.md`. */
|
|
741
|
+
readonly path: string;
|
|
742
|
+
readonly role: 'persona';
|
|
743
|
+
}
|
|
601
744
|
interface ConfiguredAgentHostAgentSpec {
|
|
602
745
|
readonly agentTypeId: string;
|
|
603
746
|
readonly definition: {
|
|
604
747
|
readonly instructions: string;
|
|
605
748
|
readonly label: string;
|
|
606
749
|
readonly version?: string;
|
|
750
|
+
/**
|
|
751
|
+
* Computed identity of the compiled definition (instructions + knowledge
|
|
752
|
+
* bytes). The digest, not the version string, is the definition identity.
|
|
753
|
+
*/
|
|
754
|
+
readonly digest?: string;
|
|
607
755
|
};
|
|
756
|
+
/**
|
|
757
|
+
* Optional agent-carried knowledge shipped inside the definition package.
|
|
758
|
+
* Composition mounts it as a readonly, agent-scoped filesystem binding;
|
|
759
|
+
* absent = no binding.
|
|
760
|
+
*/
|
|
761
|
+
readonly knowledge?: {
|
|
762
|
+
/** Host path of the package's `knowledge/` folder. */
|
|
763
|
+
readonly rootDir: string;
|
|
764
|
+
};
|
|
765
|
+
/** Authored instruction sources behind `definition.instructions`. */
|
|
766
|
+
readonly instructionFiles?: readonly AgentInstructionFileRef[];
|
|
608
767
|
readonly plugins?: readonly {
|
|
609
768
|
/** Canonical app-preflighted plugin ID. */
|
|
610
769
|
readonly name: string;
|
|
@@ -638,6 +797,8 @@ interface AgentFleetCompiler {
|
|
|
638
797
|
interface ResolvedEnvironmentScope {
|
|
639
798
|
readonly placementIdentity: string;
|
|
640
799
|
readonly workspaceRoot: string;
|
|
800
|
+
/** Physical provider workspace identifier; defaults to the verified storage scope. */
|
|
801
|
+
readonly runtimeWorkspaceId?: string;
|
|
641
802
|
readonly templatePath?: string;
|
|
642
803
|
readonly provisioningFingerprint: string;
|
|
643
804
|
readonly provisionRuntime?: (input: {
|
|
@@ -646,81 +807,116 @@ interface ResolvedEnvironmentScope {
|
|
|
646
807
|
}) => Promise<WorkspaceProvisioningResult | undefined>;
|
|
647
808
|
}
|
|
648
809
|
interface ResolvedAgentRuntimeScope {
|
|
649
|
-
/**
|
|
810
|
+
/** Persisted semantic compatibility identity. */
|
|
650
811
|
readonly identity: string;
|
|
812
|
+
/** Stable physical binding slot, independent of semantic resource revisions. */
|
|
813
|
+
readonly physicalBindingIdentity?: string;
|
|
814
|
+
/** Canonical digest of the immutable plugin/resource inputs used by reload. */
|
|
815
|
+
readonly resourceInputDigest?: string;
|
|
816
|
+
/**
|
|
817
|
+
* Side-effect-free fence for path-backed reload resources. The Host invokes
|
|
818
|
+
* it after classification, immediately before the effect, and after every
|
|
819
|
+
* awaited apply/load stage so a successful receipt always matches the
|
|
820
|
+
* resourceInputDigest recorded in the ledger.
|
|
821
|
+
*/
|
|
822
|
+
readonly revalidateResourceInputs?: () => Promise<void>;
|
|
651
823
|
readonly environment: ResolvedEnvironmentScope;
|
|
652
824
|
readonly sessionNamespace: string;
|
|
653
825
|
readonly pi?: PiHarnessOptions;
|
|
654
826
|
readonly extraTools?: readonly AgentTool[];
|
|
827
|
+
readonly includeFilesystemTools?: boolean;
|
|
828
|
+
readonly includeUploadTools?: boolean;
|
|
829
|
+
readonly sessionDir?: string;
|
|
830
|
+
readonly reloadMetadata?: {
|
|
831
|
+
readonly diagnostics?: ReadonlyArray<{
|
|
832
|
+
readonly source: string;
|
|
833
|
+
readonly message: string;
|
|
834
|
+
readonly pluginId?: string;
|
|
835
|
+
}>;
|
|
836
|
+
readonly restartWarnings?: ReadonlyArray<{
|
|
837
|
+
readonly id: string;
|
|
838
|
+
readonly surfaces: readonly string[];
|
|
839
|
+
readonly message: string;
|
|
840
|
+
}>;
|
|
841
|
+
};
|
|
842
|
+
/**
|
|
843
|
+
* Host-internal reload mutation. Candidate identity fields above must be
|
|
844
|
+
* resolved without mutating plugin, backend, or runtime resource state.
|
|
845
|
+
* The Host invokes this callback only after durable ownership, admission,
|
|
846
|
+
* immutable identity classification, and the binding operation fence.
|
|
847
|
+
*/
|
|
848
|
+
readonly applyReload?: (input: {
|
|
849
|
+
readonly runtimeBundle: RuntimeBundle;
|
|
850
|
+
}) => Promise<{
|
|
851
|
+
readonly diagnostics?: ReadonlyArray<{
|
|
852
|
+
readonly source: string;
|
|
853
|
+
readonly message: string;
|
|
854
|
+
readonly pluginId?: string;
|
|
855
|
+
}>;
|
|
856
|
+
readonly restartWarnings?: ReadonlyArray<{
|
|
857
|
+
readonly id: string;
|
|
858
|
+
readonly surfaces: readonly string[];
|
|
859
|
+
readonly message: string;
|
|
860
|
+
}>;
|
|
861
|
+
} | undefined>;
|
|
655
862
|
readonly getFilesystemBindings?: (input: {
|
|
656
863
|
readonly scope: VerifiedAgentScopeClaim;
|
|
657
864
|
readonly sessionId?: string;
|
|
658
865
|
readonly requestId: string;
|
|
659
866
|
}) => Promise<readonly RuntimeFilesystemBinding[] | undefined>;
|
|
867
|
+
/**
|
|
868
|
+
* Skill-resource locator/catalog snapshot for the current reload
|
|
869
|
+
* generation. Threaded through the capability-projection layer so
|
|
870
|
+
* `/skills` can resolve package-managed skill locators without going
|
|
871
|
+
* through the legacy path-shaped `additionalSkillPaths` hot-reload API.
|
|
872
|
+
*/
|
|
873
|
+
readonly getSkillResourceSnapshot?: (input: {
|
|
874
|
+
readonly scope: VerifiedAgentScopeClaim;
|
|
875
|
+
readonly sessionId?: string;
|
|
876
|
+
readonly requestId: string;
|
|
877
|
+
}) => Promise<AgentSkillResourceSnapshot | undefined>;
|
|
660
878
|
readonly systemPromptAppend?: string;
|
|
661
879
|
readonly loadSystemPromptAppend?: () => Promise<string | undefined>;
|
|
662
880
|
}
|
|
663
|
-
interface
|
|
664
|
-
readonly
|
|
665
|
-
readonly
|
|
666
|
-
readonly service: AgentCoreSessionService;
|
|
667
|
-
readonly tools: readonly AgentTool[];
|
|
668
|
-
readonly runtimeBundle: RuntimeBundle;
|
|
669
|
-
readonly readyTracker: ReadyStatusTracker;
|
|
670
|
-
retire(): Promise<void>;
|
|
671
|
-
}
|
|
672
|
-
/** Narrow Host-owned facade used only while mounting the compatibility profile. */
|
|
673
|
-
interface AgentHostLegacyProjectionRuntime {
|
|
674
|
-
readonly gateway: AgentGateway;
|
|
675
|
-
resolveComposition(agentTypeId: string, scope: AuthorizedAgentScope): Promise<AgentHostLegacyProjectionComposition>;
|
|
676
|
-
createAddressedRoutes(options: {
|
|
677
|
-
readonly authorizeRequest: (request: FastifyRequest) => Promise<AuthorizedAgentScope>;
|
|
678
|
-
readonly defaultAgentTypeId: string;
|
|
679
|
-
}): FastifyPluginAsync;
|
|
680
|
-
createPiChatService(input: {
|
|
681
|
-
readonly service: AgentCoreSessionService;
|
|
682
|
-
readonly scope: AuthorizedAgentScope;
|
|
683
|
-
readonly agentTypeId: string;
|
|
684
|
-
}): PiChatSessionService;
|
|
685
|
-
}
|
|
686
|
-
interface AgentHostLegacyProjectionLifecycle {
|
|
687
|
-
startDraining(): void;
|
|
688
|
-
closeBindings(): Promise<void>;
|
|
689
|
-
}
|
|
690
|
-
interface AgentHostLegacyRoutePolicyMountInput {
|
|
691
|
-
readonly app: fastify.FastifyInstance;
|
|
692
|
-
readonly runtime: AgentHostLegacyProjectionRuntime;
|
|
693
|
-
readonly defaultAgentTypeId: string;
|
|
694
|
-
registerLifecycle(lifecycle: AgentHostLegacyProjectionLifecycle): void;
|
|
881
|
+
interface AuthorizedEnvironmentIntent {
|
|
882
|
+
readonly kind: 'http-route' | 'dispatcher' | 'agent-binding';
|
|
883
|
+
readonly requestId: string;
|
|
695
884
|
}
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
*/
|
|
700
|
-
|
|
701
|
-
|
|
885
|
+
interface AgentHostEnvironmentScope extends ResolvedEnvironmentScope {
|
|
886
|
+
/** App-owned environment decoration applied once to the canonical provider generation. */
|
|
887
|
+
readonly transformRuntimeBundle?: (runtimeBundle: RuntimeBundle) => RuntimeBundle | Promise<RuntimeBundle>;
|
|
888
|
+
/** Evaluated for every authorized operation; never cached as placement authority. */
|
|
889
|
+
readonly resolveFilesystemBindings?: (input: {
|
|
890
|
+
readonly verifiedClaim: VerifiedAgentScopeClaim;
|
|
891
|
+
readonly requestId: string;
|
|
892
|
+
}) => Promise<readonly RuntimeFilesystemBinding[] | undefined>;
|
|
702
893
|
}
|
|
703
|
-
interface
|
|
704
|
-
readonly
|
|
894
|
+
interface AgentHostEnvironmentLease {
|
|
895
|
+
readonly workspace: Workspace;
|
|
896
|
+
readonly gitWorkspace: Workspace;
|
|
897
|
+
readonly fileSearch: FileSearch;
|
|
898
|
+
readonly filesystemBindings?: readonly RuntimeFilesystemBinding[];
|
|
899
|
+
readonly readiness: Readonly<AgentCapabilityReadiness>;
|
|
900
|
+
readonly signal: AbortSignal;
|
|
901
|
+
release(): void;
|
|
902
|
+
}
|
|
903
|
+
interface AgentHostDispatcherRunInput extends WorkspaceAgentDirectRunInput {
|
|
904
|
+
readonly authorizedScope: AuthorizedAgentScope;
|
|
905
|
+
readonly request?: FastifyRequest;
|
|
906
|
+
}
|
|
907
|
+
interface AgentHostDirectProjectionOptions {
|
|
908
|
+
readonly authorizeAgentRequest: (request: FastifyRequest) => Promise<AuthorizedAgentScope>;
|
|
909
|
+
readonly filterModels?: ModelsRoutesOptions['filterModels'];
|
|
910
|
+
readonly sessionChangesTracker?: SessionChangesTracker;
|
|
911
|
+
readonly defaultSessionId?: string;
|
|
705
912
|
}
|
|
706
|
-
/** Addressed Gateway projection, optionally with its frozen Pi-chat aliases. */
|
|
707
|
-
type AgentHostAddressedHttpProjectionOptions = AgentHostHttpProjectionBaseOptions & {
|
|
708
|
-
readonly authorizeRequest: (request: FastifyRequest) => Promise<AuthorizedAgentScope>;
|
|
709
|
-
readonly legacyPiChatAliases?: boolean;
|
|
710
|
-
readonly legacyRoutePolicy?: never;
|
|
711
|
-
};
|
|
712
|
-
/** Full legacy/application route profile with its own normalized scope bridge. */
|
|
713
|
-
type AgentHostLegacyHttpProjectionOptions = AgentHostHttpProjectionBaseOptions & {
|
|
714
|
-
readonly legacyRoutePolicy: AgentHostLegacyRoutePolicy;
|
|
715
|
-
readonly authorizeRequest?: never;
|
|
716
|
-
readonly legacyPiChatAliases?: never;
|
|
717
|
-
};
|
|
718
|
-
type AgentHostHttpProjectionOptions = AgentHostAddressedHttpProjectionOptions | AgentHostLegacyHttpProjectionOptions;
|
|
719
913
|
interface AgentHostDescription {
|
|
720
914
|
readonly hostId: string;
|
|
721
915
|
readonly agents: readonly {
|
|
722
916
|
readonly agentTypeId: string;
|
|
723
917
|
readonly label: string;
|
|
918
|
+
/** Computed definition identity digest (instructions + knowledge bytes), when the spec carries one. */
|
|
919
|
+
readonly definitionDigest?: string;
|
|
724
920
|
}[];
|
|
725
921
|
readonly draining: boolean;
|
|
726
922
|
}
|
|
@@ -738,13 +934,29 @@ interface CreateAgentHostOptions {
|
|
|
738
934
|
readonly runtimeModeAdapter: RuntimeModeAdapter;
|
|
739
935
|
readonly runtimeHost?: AgentRuntimeHostOperations;
|
|
740
936
|
readonly sessionRoot?: string;
|
|
741
|
-
readonly
|
|
937
|
+
readonly resolveAuthorizedEnvironmentScope?: (input: {
|
|
938
|
+
readonly authorizedScope: AuthorizedAgentScope;
|
|
939
|
+
readonly verifiedClaim: VerifiedAgentScopeClaim;
|
|
940
|
+
readonly intent: AuthorizedEnvironmentIntent;
|
|
941
|
+
}) => Promise<AgentHostEnvironmentScope>;
|
|
942
|
+
readonly resolveAuthorizedAgentRuntimeScope?: (input: {
|
|
943
|
+
readonly authorizedScope: AuthorizedAgentScope;
|
|
944
|
+
readonly verifiedClaim: VerifiedAgentScopeClaim;
|
|
742
945
|
readonly agentTypeId: string;
|
|
743
|
-
readonly
|
|
744
|
-
|
|
946
|
+
readonly intent: AuthorizedEnvironmentIntent & {
|
|
947
|
+
readonly kind: 'agent-binding';
|
|
948
|
+
readonly operation: 'new-binding' | 'existing-session' | 'reload';
|
|
949
|
+
readonly sessionId?: string;
|
|
950
|
+
};
|
|
951
|
+
readonly environment: AgentHostEnvironmentScope;
|
|
952
|
+
}) => Promise<Omit<ResolvedAgentRuntimeScope, 'environment'>>;
|
|
745
953
|
readonly telemetry?: TelemetrySink;
|
|
746
954
|
readonly metering?: AgentMeteringSink;
|
|
747
955
|
readonly requestLedger?: AgentRequestLedger;
|
|
956
|
+
/** Durable effect ledger path, independent of transcript/session storage. */
|
|
957
|
+
readonly requestLedgerPath?: string;
|
|
958
|
+
/** Explicit test/dev opt-in for an in-memory ledger. */
|
|
959
|
+
readonly inMemoryRequestLedgerMode?: 'test' | 'development';
|
|
748
960
|
readonly requestRetentionMs?: number;
|
|
749
961
|
readonly effectAdmission?: AgentEffectAdmission;
|
|
750
962
|
readonly shutdownGraceMs?: number;
|
|
@@ -753,7 +965,12 @@ interface CreateAgentHostOptions {
|
|
|
753
965
|
interface CreatedAgentHost {
|
|
754
966
|
readonly host: AgentHostHandle;
|
|
755
967
|
readonly gateway: AgentGateway;
|
|
756
|
-
|
|
968
|
+
registerDirectRoutes(options: AgentHostDirectProjectionOptions): FastifyPluginAsync;
|
|
969
|
+
acquireEnvironment(input: {
|
|
970
|
+
readonly authorizedScope: AuthorizedAgentScope;
|
|
971
|
+
readonly intent: AuthorizedEnvironmentIntent;
|
|
972
|
+
}): Promise<AgentHostEnvironmentLease>;
|
|
973
|
+
runWithWorkspaceAgent(input: AgentHostDispatcherRunInput, run: (binding: LeaseBoundWorkspaceAgent) => Promise<void>): Promise<void>;
|
|
757
974
|
}
|
|
758
975
|
|
|
759
|
-
export { type
|
|
976
|
+
export { type PiExtensionFactory as $, type AgentGatewayEffect as A, type BuiltinRuntimeModeId as B, type ConfiguredAgentHostAgentSpec as C, type AgentFleetCompiler as D, type AgentRequestTarget as E, type RuntimeFilesystemAccessDecision as F, type AgentHostDescription as G, type AgentHostDirectProjectionOptions as H, type AgentHostDispatcherRunInput as I, type AgentHostEnvironmentLease as J, type AgentHostHandle as K, type LegacyDefaultAgentHostSpec as L, type ModeContext as M, type MeteringReleaseInput as N, type MeteringReleaseReason as O, type ProvisionWorkspaceRuntimeOptions as P, type MeteringReservationResult as Q, type RuntimeModeAdapter as R, type MeteringReserveInput as S, type MeteringRunKind as T, type MeteringRunScope as U, type MeteringRunStatus as V, type WorkspaceProvisioningResult as W, type MeteringSettleInput as X, type MeteringUsage as Y, type MeteringUsageInput as Z, PI_PACKAGE_RESOURCE_FILTERS as _, type PiPackageSource as a, type PluginSkillSource as a0, type ResolvedEnvironmentScope as a1, type RuntimeFilesystemBindingOperations as a2, type RuntimeNodePackageSpec as a3, type RuntimeProvisioningContribution as a4, type RuntimePythonSpec as a5, type RuntimeTemplateContribution as a6, type WorkspaceProvisioningExecResult as a7, compactPiPackages as a8, mergePiPackageSources as a9, normalizeMeteringUsage as aa, piPackageSourceKey as ab, type RuntimeModeId as b, type AgentRuntimeHostOperations as c, type RuntimeBashStrategy as d, type RuntimeFilesystemStrategy as e, type WorkspaceProvisioningAdapter as f, type AgentInstructionFileRef as g, type AgentHostAgentSpec as h, type RuntimeBundle as i, type PiHarnessOptions as j, type AgentMeteringSink as k, type RuntimeFilesystemBinding as l, type CreatedAgentHost as m, type MeteringErrorLogger as n, ReadyStatusTracker as o, type ResolvedAgentRuntimeScope as p, type CreateAgentHostOptions as q, type CompiledAgentHostAgentSpec as r, type AgentRequestLedger as s, type AgentEffectAdmission as t, type AuthorizedEnvironmentIntent as u, type AgentHostEnvironmentScope as v, type AgentRequestKey as w, type AgentRequestLedgerPrepareResult as x, type AgentRequestFailure as y, type AgentRequestLedgerRecord as z };
|
package/docs/AGENT_GATEWAY_V0.md
CHANGED
|
@@ -97,19 +97,22 @@ shorthand. Prompts add `displayContent?`, `model?`, `thinkingLevel?`,
|
|
|
97
97
|
|
|
98
98
|
## Error codes
|
|
99
99
|
|
|
100
|
-
|
|
100
|
+
Fifteen, exhaustive, order-stable, exported as both a const map and
|
|
101
101
|
`AGENT_GATEWAY_ERROR_CODES`:
|
|
102
102
|
|
|
103
103
|
`AGENT_TYPE_UNKNOWN` · `AGENT_SESSION_NOT_FOUND` · `AGENT_SCOPE_DENIED` ·
|
|
104
104
|
`AGENT_SESSION_REPLAY_GAP` · `AGENT_SESSION_CURSOR_AHEAD` ·
|
|
105
105
|
`AGENT_SESSION_CURSOR_EXPIRED` · `AGENT_SESSION_CURSOR_INVALID` ·
|
|
106
|
-
`AGENT_REQUEST_CONFLICT` · `
|
|
106
|
+
`AGENT_REQUEST_CONFLICT` · `AGENT_REQUEST_IN_PROGRESS` ·
|
|
107
|
+
`AGENT_REQUEST_OUTCOME_UNKNOWN` · `AGENT_RUNTIME_RESTART_REQUIRED` ·
|
|
107
108
|
`AGENT_COMMAND_INVALID_STATE` · `AGENT_SESSION_RUNTIME_SCOPE_MISMATCH` ·
|
|
108
109
|
`AGENT_SHARED_ENVIRONMENT_UNAVAILABLE` · `AGENT_GATEWAY_CLOSED`
|
|
109
110
|
|
|
110
111
|
HTTP mapping lives in `server/agent-host/httpProjection.ts`
|
|
111
112
|
(`statusForGatewayError`). Note `AGENT_SESSION_RUNTIME_SCOPE_MISMATCH`,
|
|
112
|
-
`AGENT_REQUEST_CONFLICT
|
|
113
|
+
`AGENT_REQUEST_CONFLICT`, `AGENT_REQUEST_IN_PROGRESS`,
|
|
114
|
+
`AGENT_RUNTIME_RESTART_REQUIRED`, and `AGENT_COMMAND_INVALID_STATE` project to
|
|
115
|
+
**409**.
|
|
113
116
|
|
|
114
117
|
## Conformance levels
|
|
115
118
|
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# Workspace agent packages
|
|
2
|
+
|
|
3
|
+
With `BORING_AGENT_FLEET=1`, a single-workspace host may discover an agent
|
|
4
|
+
definition from either the trusted repository's `.agents/personas/` packages
|
|
5
|
+
or a local package path registered in that workspace's
|
|
6
|
+
`.pi/settings.json#packages`. Registration makes an agent package discoverable.
|
|
7
|
+
It does not activate the agent: the class-B `.agents/factory/fleet.yaml` roster
|
|
8
|
+
must also seat the package's `boring.agent.definitionId`.
|
|
9
|
+
|
|
10
|
+
Agent fleet changes are boot-time changes. `/reload` can refresh ordinary
|
|
11
|
+
plugin resources, but installing, updating, seating, unseating, or removing an
|
|
12
|
+
agent requires restarting the workspace/CLI host.
|
|
13
|
+
|
|
14
|
+
The CLI workspaces hub has one Agent Host shared by every registered workspace.
|
|
15
|
+
Its global fleet therefore admits only personas from the trusted repository's
|
|
16
|
+
`.agents/personas/`; it does not admit agent definitions from any workspace's
|
|
17
|
+
local package registrations. Local packages keep their ordinary plugin
|
|
18
|
+
surfaces in their owning workspace. Seating workspace-local agent definitions
|
|
19
|
+
in workspaces mode requires a future workspace-scoped fleet boundary.
|
|
20
|
+
|
|
21
|
+
## Install and seat
|
|
22
|
+
|
|
23
|
+
From the workspace root, register a local package directory:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
boring-ui-plugin install --local --workspace . ../agent-packages/my-agent
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
The package keeps all of its normal plugin surfaces. Its agent contribution is
|
|
30
|
+
still inert until the fleet roster names its definition id:
|
|
31
|
+
|
|
32
|
+
```yaml
|
|
33
|
+
seats:
|
|
34
|
+
- seat: my-agent
|
|
35
|
+
agentTypeId: my-agent-definition
|
|
36
|
+
skills: []
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Restart a single-workspace host with `BORING_AGENT_FLEET=1`. A valid seated
|
|
40
|
+
package appears in the agent catalog. An installed package without a matching
|
|
41
|
+
seat remains inert and reports `AGENT_DEFINITION_UNSEATED` during fleet
|
|
42
|
+
composition. The shared CLI workspaces hub never admits the local agent
|
|
43
|
+
contribution, even when the global roster names its definition id.
|
|
44
|
+
|
|
45
|
+
## Update
|
|
46
|
+
|
|
47
|
+
1. Update the source directory and bump both package/agent versions as needed.
|
|
48
|
+
2. For repository personas under `.agents/personas/`, run
|
|
49
|
+
`pnpm write:skill-digests` from the repository root.
|
|
50
|
+
3. Restart the workspace/CLI host.
|
|
51
|
+
|
|
52
|
+
Digest refresh is intentionally repository-local in v1. The script reads only
|
|
53
|
+
`.agents/personas/`; it does not rewrite pins for agent packages installed from
|
|
54
|
+
another local directory. Such packages must already have matching
|
|
55
|
+
seat-authoritative skill pins. A mismatch excludes only that seat with
|
|
56
|
+
`AGENT_FLEET_SEAT_SKILL_DIGEST_MISMATCH`; the rest of the fleet still boots.
|
|
57
|
+
|
|
58
|
+
## Unseat or remove
|
|
59
|
+
|
|
60
|
+
To make a package inert but keep it installed, remove its seat from
|
|
61
|
+
`.agents/factory/fleet.yaml` and restart.
|
|
62
|
+
|
|
63
|
+
To remove its workspace registration as well:
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
boring-ui-plugin remove --local --workspace . my-agent-plugin-id
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Then restart. If the roster still names the removed definition, that seat is
|
|
70
|
+
excluded with `AGENT_FLEET_SEAT_PERSONA_INVALID` while other agents boot.
|
|
71
|
+
|
|
72
|
+
## v1 distribution boundary
|
|
73
|
+
|
|
74
|
+
Repository personas may contribute agents to any fleet in v1. A
|
|
75
|
+
workspace-registered local package path may contribute an agent only to a
|
|
76
|
+
single-workspace host; it never enters the CLI workspaces hub's global fleet.
|
|
77
|
+
Git/npm package sources — including their materialized `.pi/git/` and
|
|
78
|
+
`.pi/npm/` directories — cannot contribute an agent until the
|
|
79
|
+
remote-distribution trust gate ships. All excluded packages' non-agent plugin
|
|
80
|
+
surfaces continue through the normal plugin pipeline unchanged.
|