@hachej/boring-agent 0.1.92 → 0.1.94
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/{chunk-IWBC6SF7.js → chunk-2TMS2RU2.js} +15 -2
- package/dist/{chunk-CJ2BW2W2.js → chunk-EOMY2HDT.js} +1 -0
- package/dist/{chunk-V3ZD3T3G.js → chunk-N4AATPH7.js} +258 -76
- package/dist/core/index.d.ts +2 -2
- package/dist/core/index.js +1 -1
- package/dist/{createHarness-PMYRKDE4.js → createHarness-UCD74XXK.js} +1 -1
- package/dist/{errors-C38f6pol.d.ts → errors-G6T6S7PQ.d.ts} +2 -0
- package/dist/front/index.d.ts +71 -8
- package/dist/front/index.js +910 -619
- package/dist/front/styles.css +253 -109
- package/dist/{lease-BqeCLGPL.d.ts → lease-CusB-uLg.d.ts} +3 -1
- package/dist/{piChatSessionService-BrPqKrpY.d.ts → piChatSessionService-C0KbcGw9.d.ts} +7 -1
- package/dist/server/agent-host/testing/gatewayConformance.d.ts +3 -3
- package/dist/server/agent-host/testing/gatewayConformance.js +77 -0
- package/dist/server/index.d.ts +44 -5
- package/dist/server/index.js +3 -3
- package/dist/server/worker/index.js +3 -3
- package/dist/shared/index.d.ts +4 -4
- package/dist/{types-uQozUhGt.d.ts → types-C-Eroi__.d.ts} +2 -2
- package/docs/AGENT_GATEWAY_V0.md +152 -0
- package/package.json +4 -4
|
@@ -286,6 +286,83 @@ function gatewayConformance(options) {
|
|
|
286
286
|
expect(await connection.stop({ requestId: "stop" })).toEqual(stop);
|
|
287
287
|
await connection.close();
|
|
288
288
|
});
|
|
289
|
+
it("keeps strict-idle busy admission retryable and idempotent", async () => {
|
|
290
|
+
const fixture = await options.createFixture();
|
|
291
|
+
const scope = fixture.issueScope();
|
|
292
|
+
const ref = await createSession(fixture, scope, "strict-idle-retry");
|
|
293
|
+
const connection = await fixture.gateway.connectSession({ scope, ref });
|
|
294
|
+
const input = {
|
|
295
|
+
kind: "prompt",
|
|
296
|
+
requestId: "strict-review",
|
|
297
|
+
clientNonce: "strict-review",
|
|
298
|
+
content: "model-facing review",
|
|
299
|
+
displayContent: "Visible review",
|
|
300
|
+
requireIdle: true
|
|
301
|
+
};
|
|
302
|
+
fixture.setActivity(ref, "running");
|
|
303
|
+
await expectCode(connection.send(input), AgentGatewayErrorCode.AGENT_COMMAND_INVALID_STATE);
|
|
304
|
+
fixture.setActivity(ref, "idle");
|
|
305
|
+
const accepted = await connection.send(input);
|
|
306
|
+
expect(accepted).toMatchObject({ accepted: true, disposition: "prompt" });
|
|
307
|
+
await expect(connection.send(input)).resolves.toMatchObject({ ...accepted, duplicate: true });
|
|
308
|
+
await expectCode(
|
|
309
|
+
connection.send({ ...input, displayContent: "changed payload" }),
|
|
310
|
+
AgentGatewayErrorCode.AGENT_REQUEST_CONFLICT
|
|
311
|
+
);
|
|
312
|
+
await connection.close();
|
|
313
|
+
});
|
|
314
|
+
it("admits exactly one of two concurrent strict-idle prompts", async () => {
|
|
315
|
+
const fixture = await options.createFixture();
|
|
316
|
+
const scope = fixture.issueScope();
|
|
317
|
+
const ref = await createSession(fixture, scope, "strict-idle-race");
|
|
318
|
+
const connection = await fixture.gateway.connectSession({ scope, ref });
|
|
319
|
+
fixture.setActivity(ref, "idle");
|
|
320
|
+
const outcome = async (requestId) => {
|
|
321
|
+
try {
|
|
322
|
+
await connection.send({
|
|
323
|
+
kind: "prompt",
|
|
324
|
+
requestId,
|
|
325
|
+
clientNonce: requestId,
|
|
326
|
+
content: requestId,
|
|
327
|
+
requireIdle: true
|
|
328
|
+
});
|
|
329
|
+
return "accepted";
|
|
330
|
+
} catch (error) {
|
|
331
|
+
return error.code;
|
|
332
|
+
}
|
|
333
|
+
};
|
|
334
|
+
const outcomes = await Promise.all([outcome("strict-a"), outcome("strict-b")]);
|
|
335
|
+
expect(outcomes.sort()).toEqual([
|
|
336
|
+
AgentGatewayErrorCode.AGENT_COMMAND_INVALID_STATE,
|
|
337
|
+
"accepted"
|
|
338
|
+
].sort());
|
|
339
|
+
await connection.close();
|
|
340
|
+
});
|
|
341
|
+
it("keeps ordinary error recovery while strict-idle prompts reject error state", async () => {
|
|
342
|
+
const fixture = await options.createFixture();
|
|
343
|
+
const scope = fixture.issueScope();
|
|
344
|
+
const strictRef = await createSession(fixture, scope, "strict-error");
|
|
345
|
+
const strictConnection = await fixture.gateway.connectSession({ scope, ref: strictRef });
|
|
346
|
+
fixture.setActivity(strictRef, "error");
|
|
347
|
+
await expectCode(strictConnection.send({
|
|
348
|
+
kind: "prompt",
|
|
349
|
+
requestId: "strict-error-prompt",
|
|
350
|
+
clientNonce: "strict-error-prompt",
|
|
351
|
+
content: "strict",
|
|
352
|
+
requireIdle: true
|
|
353
|
+
}), AgentGatewayErrorCode.AGENT_COMMAND_INVALID_STATE);
|
|
354
|
+
await strictConnection.close();
|
|
355
|
+
const recoveryRef = await createSession(fixture, scope, "ordinary-error");
|
|
356
|
+
const recoveryConnection = await fixture.gateway.connectSession({ scope, ref: recoveryRef });
|
|
357
|
+
fixture.setActivity(recoveryRef, "error");
|
|
358
|
+
await expect(recoveryConnection.send({
|
|
359
|
+
kind: "prompt",
|
|
360
|
+
requestId: "ordinary-recovery",
|
|
361
|
+
clientNonce: "ordinary-recovery",
|
|
362
|
+
content: "recover"
|
|
363
|
+
})).resolves.toMatchObject({ disposition: "prompt" });
|
|
364
|
+
await recoveryConnection.close();
|
|
365
|
+
});
|
|
289
366
|
it("covers the complete command-state table and queue selector semantics", async () => {
|
|
290
367
|
const fixture = await options.createFixture();
|
|
291
368
|
const scope = fixture.issueScope();
|
package/dist/server/index.d.ts
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
import { P as ProvisionWorkspaceRuntimeOptions, W as WorkspaceProvisioningResult, R as RuntimeModeAdapter, a as RuntimeModeId, B as BuiltinRuntimeModeId, b as AgentRuntimeHostOperations, c as RuntimeBashStrategy, d as RuntimeFilesystemStrategy, M as ModeContext, e as WorkspaceProvisioningAdapter, f as RuntimeBundle, g as PiHarnessOptions, h as AgentMeteringSink, i as RuntimeFilesystemBinding, j as MeteringErrorLogger, k as ReadyStatusTracker, l as ResolvedAgentRuntimeScope, C as CreateAgentHostOptions, m as CompiledAgentHostAgentSpec, n as AgentRequestLedger, o as AgentEffectAdmission, p as AgentRequestKey, q as CreatedAgentHost, r as AgentFleetCompiler, A as AgentGatewayEffect, s as AgentRequestTarget, t as AgentRequestLedgerRecord, u as AgentRequestFailure, v as AgentHostLegacyRoutePolicy } from '../types-
|
|
2
|
-
export { w as AgentHostAddressedHttpProjectionOptions, x as AgentHostAgentSpec, y as AgentHostDescription, z as AgentHostHandle, D as AgentHostHttpProjectionOptions, E as AgentHostLegacyHttpProjectionOptions, F as AgentHostLegacyProjectionComposition, G as AgentHostLegacyProjectionLifecycle, H as AgentHostLegacyProjectionRuntime, I as AgentHostLegacyRoutePolicyMountInput, J as ConfiguredAgentHostAgentSpec, L as LegacyDefaultAgentHostSpec, K as MeteringReleaseInput, N as MeteringReleaseReason, O as MeteringReservationResult, Q as MeteringReserveInput, S as MeteringRunKind, T as MeteringRunScope, U as MeteringRunStatus, V as MeteringSettleInput, X as MeteringUsage, Y as MeteringUsageInput, Z as PI_PACKAGE_RESOURCE_FILTERS, _ as PiExtensionFactory, $ as PiPackageSource, a0 as PluginSkillSource, a1 as ResolvedEnvironmentScope, a2 as RuntimeFilesystemBindingOperations, a3 as RuntimeNodePackageSpec, a4 as RuntimeProvisioningContribution, a5 as RuntimePythonSpec, a6 as RuntimeTemplateContribution, a7 as WorkspaceProvisioningExecResult, a8 as compactPiPackages, a9 as createResourceSettingsManager, aa as mergePiPackageSources, ab as normalizeMeteringUsage, ac as piPackageSourceKey } from '../types-
|
|
1
|
+
import { P as ProvisionWorkspaceRuntimeOptions, W as WorkspaceProvisioningResult, R as RuntimeModeAdapter, a as RuntimeModeId, B as BuiltinRuntimeModeId, b as AgentRuntimeHostOperations, c as RuntimeBashStrategy, d as RuntimeFilesystemStrategy, M as ModeContext, e as WorkspaceProvisioningAdapter, f as RuntimeBundle, g as PiHarnessOptions, h as AgentMeteringSink, i as RuntimeFilesystemBinding, j as MeteringErrorLogger, k as ReadyStatusTracker, l as ResolvedAgentRuntimeScope, C as CreateAgentHostOptions, m as CompiledAgentHostAgentSpec, n as AgentRequestLedger, o as AgentEffectAdmission, p as AgentRequestKey, q as CreatedAgentHost, r as AgentFleetCompiler, A as AgentGatewayEffect, s as AgentRequestTarget, t as AgentRequestLedgerRecord, u as AgentRequestFailure, v as AgentHostLegacyRoutePolicy } from '../types-C-Eroi__.js';
|
|
2
|
+
export { w as AgentHostAddressedHttpProjectionOptions, x as AgentHostAgentSpec, y as AgentHostDescription, z as AgentHostHandle, D as AgentHostHttpProjectionOptions, E as AgentHostLegacyHttpProjectionOptions, F as AgentHostLegacyProjectionComposition, G as AgentHostLegacyProjectionLifecycle, H as AgentHostLegacyProjectionRuntime, I as AgentHostLegacyRoutePolicyMountInput, J as ConfiguredAgentHostAgentSpec, L as LegacyDefaultAgentHostSpec, K as MeteringReleaseInput, N as MeteringReleaseReason, O as MeteringReservationResult, Q as MeteringReserveInput, S as MeteringRunKind, T as MeteringRunScope, U as MeteringRunStatus, V as MeteringSettleInput, X as MeteringUsage, Y as MeteringUsageInput, Z as PI_PACKAGE_RESOURCE_FILTERS, _ as PiExtensionFactory, $ as PiPackageSource, a0 as PluginSkillSource, a1 as ResolvedEnvironmentScope, a2 as RuntimeFilesystemBindingOperations, a3 as RuntimeNodePackageSpec, a4 as RuntimeProvisioningContribution, a5 as RuntimePythonSpec, a6 as RuntimeTemplateContribution, a7 as WorkspaceProvisioningExecResult, a8 as compactPiPackages, a9 as createResourceSettingsManager, aa as mergePiPackageSources, ab as normalizeMeteringUsage, ac as piPackageSourceKey } from '../types-C-Eroi__.js';
|
|
3
3
|
import { E as ExecOptions, a as ExecResult, W as WorkspaceChangeEvent, b as Workspace, S as Sandbox } from '../sandbox-DAD8cWQR.js';
|
|
4
4
|
import { R as RemoteWorkerWorkspaceOp, a as RemoteWorkerWorkspaceResult, b as RemoteWorkerExecRequest } from '../middleware-CzW8n7B7.js';
|
|
5
5
|
export { c as REMOTE_WORKER_PROVIDER, d as REMOTE_WORKER_RUNTIME_CWD, e as RemoteWorkerErrorPayload, f as RemoteWorkerExecResponse, g as RemoteWorkerFsEventEnvelope, W as WORKER_INTERNAL_TOKEN_HEADER, h as WORKER_REQUEST_ID_HEADER, i as WORKER_WORKSPACE_ID_HEADER, j as createAgentAuthMiddleware } from '../middleware-CzW8n7B7.js';
|
|
6
6
|
import { SandboxProviderV1, WorkspaceSandboxPairV1 } from '@hachej/boring-sandbox/shared';
|
|
7
|
-
import { S as SandboxHandleStore, C as CompiledAgentBundle, a as Sha256Digest, A as AgentDeployment, b as ShareEntryStore, P as PluginRestartWarning, W as WorkspaceAgentDispatcherContext, c as WorkspaceAgentDispatcher, d as ProviderId, e as CredentialFieldId, R as ResolvedCredentialMaterialV1, f as AuthorizedWorkspaceCredentialScopeV1, V as VerifiedWorkspaceCredentialAuthorityV1, g as WorkspaceCredentialAuthorityVerifierV1, h as CredentialConsumerBindingRegistryV1, i as ProviderRegistryV1, j as WorkspaceCredentialResolverV1, k as ProviderCredentialRefV1, l as ResolvedCredentialLeaseV1 } from '../lease-
|
|
7
|
+
import { S as SandboxHandleStore, C as CompiledAgentBundle, a as Sha256Digest, A as AgentDeployment, b as ShareEntryStore, P as PluginRestartWarning, W as WorkspaceAgentDispatcherContext, c as WorkspaceAgentDispatcher, d as ProviderId, e as CredentialFieldId, R as ResolvedCredentialMaterialV1, f as AuthorizedWorkspaceCredentialScopeV1, V as VerifiedWorkspaceCredentialAuthorityV1, g as WorkspaceCredentialAuthorityVerifierV1, h as CredentialConsumerBindingRegistryV1, i as ProviderRegistryV1, j as WorkspaceCredentialResolverV1, k as ProviderCredentialRefV1, l as ResolvedCredentialLeaseV1 } from '../lease-CusB-uLg.js';
|
|
8
8
|
import { s as AgentConfig, b as Agent, d as AgentActor, j as AgentEvent, t as AgentTool, u as AgentHarnessFactory, T as TelemetrySink, A as AgentHarness } from '../harness-Cc48o6uS.js';
|
|
9
9
|
export { v as AgentHarnessFactoryInput } from '../harness-Cc48o6uS.js';
|
|
10
10
|
import { b as PiChatEvent, E as ErrorCode, l as SessionCtx, S as SessionStore, m as SessionListOptions, k as SessionSummary, n as PiChatSnapshot, c as PromptPayload, d as PromptReceipt, F as FollowUpPayload, e as FollowUpReceipt, f as QueueClearPayload, g as QueueClearReceipt, I as InterruptPayload, i as StopPayload, j as StopReceipt } from '../piChatEvent-BsMp3MSo.js';
|
|
11
|
-
import { A as AgentGateway, a as AuthorizedAgentScope, b as AgentSessionRef, c as AgentSessionActivity, V as VerifiedAgentScopeClaim, d as AgentSessionSummary, e as AgentSessionStateSnapshot, f as AgentSessionConnection, J as JsonValue, g as AgentGatewayErrorDTO } from '../errors-
|
|
11
|
+
import { A as AgentGateway, a as AuthorizedAgentScope, b as AgentSessionRef, c as AgentSessionActivity, V as VerifiedAgentScopeClaim, d as AgentSessionSummary, e as AgentSessionStateSnapshot, f as AgentSessionConnection, J as JsonValue, g as AgentGatewayErrorDTO } from '../errors-G6T6S7PQ.js';
|
|
12
12
|
import { IncomingMessage, ServerResponse } from 'node:http';
|
|
13
13
|
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
14
14
|
import { FastifyRequest, FastifyInstance, FastifyPluginAsync } from 'fastify';
|
|
15
|
-
import { i as PiSessionRequestContext, g as PiChatSessionService, h as PiSessionCreateInit, e as PiChatEventSubscriber, P as PiChatEventStreamResult, a as AgentEffectAdmission$1 } from '../piChatSessionService-
|
|
15
|
+
import { i as PiSessionRequestContext, g as PiChatSessionService, h as PiSessionCreateInit, e as PiChatEventSubscriber, P as PiChatEventStreamResult, a as AgentEffectAdmission$1 } from '../piChatSessionService-C0KbcGw9.js';
|
|
16
16
|
import { BoringAgentRuntimePaths } from '@hachej/boring-sandbox/providers/node-workspace';
|
|
17
17
|
import '@hachej/boring-bash/agent';
|
|
18
18
|
import '@mariozechner/pi-coding-agent';
|
|
@@ -558,9 +558,39 @@ interface RuntimeEnvContribution {
|
|
|
558
558
|
interface WorkspaceAgentDispatcherResolveOptions {
|
|
559
559
|
request?: FastifyRequest;
|
|
560
560
|
}
|
|
561
|
+
interface PiSessionVisibleUserTurnTarget {
|
|
562
|
+
/** Advisory snapshot; sendIfIdle is the authoritative atomic admission. */
|
|
563
|
+
isIdle(): Promise<boolean>;
|
|
564
|
+
sendIfIdle(input: {
|
|
565
|
+
/** Stable across busy/transient retries; also used as the Pi client nonce. */
|
|
566
|
+
requestId: string;
|
|
567
|
+
message: string;
|
|
568
|
+
displayMessage?: string;
|
|
569
|
+
}): Promise<{
|
|
570
|
+
status: 'accepted';
|
|
571
|
+
cursor: number;
|
|
572
|
+
duplicate?: boolean;
|
|
573
|
+
} | {
|
|
574
|
+
status: 'busy';
|
|
575
|
+
} | {
|
|
576
|
+
status: 'gone';
|
|
577
|
+
}>;
|
|
578
|
+
}
|
|
579
|
+
interface BoundPiSession {
|
|
580
|
+
/** Trusted target closed over one exact logical Pi session. */
|
|
581
|
+
visibleUserMessageTarget: PiSessionVisibleUserTurnTarget;
|
|
582
|
+
}
|
|
561
583
|
interface WorkspaceAgentDispatcherBinding {
|
|
562
584
|
dispatcher: WorkspaceAgentDispatcher;
|
|
563
585
|
workspace: Workspace;
|
|
586
|
+
/**
|
|
587
|
+
* Trusted host seam used by local integrations that must bind durable work
|
|
588
|
+
* to the exact logical Pi session before accepting it.
|
|
589
|
+
*/
|
|
590
|
+
bindPiSession?(sessionId: string, sessionCtx?: {
|
|
591
|
+
workspaceId?: string;
|
|
592
|
+
userId?: string;
|
|
593
|
+
}): Promise<BoundPiSession>;
|
|
564
594
|
}
|
|
565
595
|
interface WorkspaceAgentDispatcherResolver {
|
|
566
596
|
resolve(ctx: WorkspaceAgentDispatcherContext, options?: WorkspaceAgentDispatcherResolveOptions): Promise<WorkspaceAgentDispatcher>;
|
|
@@ -759,6 +789,12 @@ declare class HarnessPiChatService implements PiChatSessionService {
|
|
|
759
789
|
private createChannelOnce;
|
|
760
790
|
private buildChannel;
|
|
761
791
|
private readDurableLatestPiChatSeq;
|
|
792
|
+
/**
|
|
793
|
+
* Validate the persisted session identity and instantiate its lazily-created
|
|
794
|
+
* Pi adapter under the same full cache key. This is intentionally a narrow
|
|
795
|
+
* trusted-host seam rather than another browser route.
|
|
796
|
+
*/
|
|
797
|
+
ensurePiSessionBound(ctx: PiSessionRequestContext, sessionId: string): Promise<void>;
|
|
762
798
|
private assertCanAccessSession;
|
|
763
799
|
private sessionKey;
|
|
764
800
|
}
|
|
@@ -861,6 +897,7 @@ interface CreateValidatingAgentFleetCompilerOptions {
|
|
|
861
897
|
*/
|
|
862
898
|
declare function createValidatingAgentFleetCompiler(options: CreateValidatingAgentFleetCompilerOptions): AgentFleetCompiler;
|
|
863
899
|
|
|
900
|
+
type RetryableSessionGuard = () => Promise<AgentGatewayErrorDTO | undefined>;
|
|
864
901
|
declare class EmbeddedAgentGateway implements AgentGateway {
|
|
865
902
|
private readonly runtime;
|
|
866
903
|
private readonly cursorSecret;
|
|
@@ -912,10 +949,12 @@ declare class EmbeddedAgentGateway implements AgentGateway {
|
|
|
912
949
|
readonly requestId: string;
|
|
913
950
|
readonly payload: JsonValue;
|
|
914
951
|
readonly action: () => Promise<unknown>;
|
|
952
|
+
readonly retryableGuard?: RetryableSessionGuard;
|
|
915
953
|
}): Promise<unknown>;
|
|
916
954
|
private effect;
|
|
917
955
|
private replayReceipt;
|
|
918
956
|
private failure;
|
|
957
|
+
private promptAdmission;
|
|
919
958
|
private withWriter;
|
|
920
959
|
private encodeCursor;
|
|
921
960
|
private decodeCursor;
|
package/dist/server/index.js
CHANGED
|
@@ -62,15 +62,15 @@ import {
|
|
|
62
62
|
sandboxRuntimeHostOperations,
|
|
63
63
|
shareResourceUri,
|
|
64
64
|
withResolvedCredential
|
|
65
|
-
} from "../chunk-
|
|
65
|
+
} from "../chunk-N4AATPH7.js";
|
|
66
66
|
import {
|
|
67
67
|
PI_PACKAGE_RESOURCE_FILTERS,
|
|
68
68
|
compactPiPackages,
|
|
69
69
|
createResourceSettingsManager,
|
|
70
70
|
mergePiPackageSources,
|
|
71
71
|
piPackageSourceKey
|
|
72
|
-
} from "../chunk-
|
|
73
|
-
import "../chunk-
|
|
72
|
+
} from "../chunk-2TMS2RU2.js";
|
|
73
|
+
import "../chunk-EOMY2HDT.js";
|
|
74
74
|
import "../chunk-NITBKFG6.js";
|
|
75
75
|
import "../chunk-AQBXNPMD.js";
|
|
76
76
|
import "../chunk-WSQ5QNIY.js";
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
WORKER_INTERNAL_TOKEN_HEADER,
|
|
3
3
|
constantTimeTokenEqual
|
|
4
|
-
} from "../../chunk-
|
|
5
|
-
import "../../chunk-
|
|
6
|
-
import "../../chunk-
|
|
4
|
+
} from "../../chunk-N4AATPH7.js";
|
|
5
|
+
import "../../chunk-2TMS2RU2.js";
|
|
6
|
+
import "../../chunk-EOMY2HDT.js";
|
|
7
7
|
import "../../chunk-NITBKFG6.js";
|
|
8
8
|
import "../../chunk-AQBXNPMD.js";
|
|
9
9
|
import "../../chunk-WSQ5QNIY.js";
|
package/dist/shared/index.d.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { t as AgentTool } from '../harness-Cc48o6uS.js';
|
|
2
2
|
export { c as AGENT_NOT_IMPLEMENTED_UNTIL_T1, b as Agent, d as AgentActor, e as AgentCoreHarness, f as AgentCoreHarnessFactory, g as AgentCorePromptInput, h as AgentCoreSessionAdapter, i as AgentCoreSessionSnapshot, j as AgentEvent, A as AgentHarness, k as AgentMessageContent, l as AgentMessagePart, m as AgentNotImplementedError, a as AgentReadiness, n as AgentReadinessStatus, o as AgentResolveInputResponse, x as AgentRuntimeAdapter, p as AgentSendInput, q as AgentStartReceipt, r as AgentStreamOptions, s as CoreAgentConfig, J as JSONSchema, M as MessageAttachment, R as RunContext, S as SendMessageInput, y as TelemetryEvent, T as TelemetrySink, z as ToolExecContext, B as ToolResult, C as noopTelemetry, D as safeCapture, E as sessionStreamPath } from '../harness-Cc48o6uS.js';
|
|
3
|
-
import { m as SchemaValidationError, n as AgentSchemaIssue, a as Sha256Digest, o as AgentSchemaValidationResult, p as CredentialConsumerBindingId, e as CredentialFieldId, k as ProviderCredentialRefV1, f as AuthorizedWorkspaceCredentialScopeV1 } from '../lease-
|
|
4
|
-
export { q as AgentDefinition, r as AgentDefinitionDigestAsset, s as AgentDefinitionReference, t as AgentDefinitionValidationError, A as AgentDeployment, u as AgentDeploymentValidationError, v as CommandNotifyPayload, C as CompiledAgentBundle, w as CompiledAgentDefinition, x as CreateShareEntryInput, h as CredentialConsumerBindingRegistryV1, y as CredentialConsumerBindingV1, z as CredentialConsumerKindV1, B as CredentialDeliveryV1, D as CredentialFieldDefinitionV1, E as ExternalManagedAccountReferenceDefinitionV1, I as InMemoryShareEntryStore, O as OpaqueRefSchema, F as OpaqueShareLocatorIdSchema, G as PROVIDER_CREDENTIAL_REF_VERSION, H as ProviderCategoryV1, J as ProviderCredentialDefinitionV1, K as ProviderCredentialRefFactoryV1, L as ProviderDefinitionV1, d as ProviderId, i as ProviderRegistryV1, l as ResolvedCredentialLeaseV1, R as ResolvedCredentialMaterialV1, M as SandboxHandleRecord, S as SandboxHandleStore, N as Sha256DigestSchema, Q as ShareEntryErrorCode, T as ShareEntryProvenance, U as ShareEntryProvenanceSchema, X as ShareEntryResolution, b as ShareEntryStore, Y as ShareEntryTombstone, Z as ShareEntryV1, _ as ShareEntryV1Schema, $ as ShareEntryValidationError, V as VerifiedWorkspaceCredentialAuthorityV1, a0 as VerifiedWorkspaceCredentialPrincipalV1, a1 as WORKSPACE_AGENT_PLUGINS_RELOADED_EVENT, a2 as WORKSPACE_COMMAND_NOTIFY_EVENT, a3 as WorkspaceAgentDispatch, c as WorkspaceAgentDispatcher, W as WorkspaceAgentDispatcherContext, a4 as WorkspaceAgentDispatcherDispatchInput, a5 as WorkspaceAgentDispatcherSendInput, a6 as WorkspaceAgentGatewayBinding, g as WorkspaceCredentialAuthorityVerifierV1, j as WorkspaceCredentialResolverV1, a7 as createAgentAssetDigest, a8 as createAgentDefinitionDigest, a9 as createAgentDeploymentDigest, aa as createCredentialConsumerBindingRegistryV1, ab as createProviderCredentialRefFactoryV1, ac as createProviderRegistryV1, ad as resolveShareEntry, ae as validateAgentDefinition, af as validateAgentDeployment } from '../lease-
|
|
3
|
+
import { m as SchemaValidationError, n as AgentSchemaIssue, a as Sha256Digest, o as AgentSchemaValidationResult, p as CredentialConsumerBindingId, e as CredentialFieldId, k as ProviderCredentialRefV1, f as AuthorizedWorkspaceCredentialScopeV1 } from '../lease-CusB-uLg.js';
|
|
4
|
+
export { q as AgentDefinition, r as AgentDefinitionDigestAsset, s as AgentDefinitionReference, t as AgentDefinitionValidationError, A as AgentDeployment, u as AgentDeploymentValidationError, v as CommandNotifyPayload, C as CompiledAgentBundle, w as CompiledAgentDefinition, x as CreateShareEntryInput, h as CredentialConsumerBindingRegistryV1, y as CredentialConsumerBindingV1, z as CredentialConsumerKindV1, B as CredentialDeliveryV1, D as CredentialFieldDefinitionV1, E as ExternalManagedAccountReferenceDefinitionV1, I as InMemoryShareEntryStore, O as OpaqueRefSchema, F as OpaqueShareLocatorIdSchema, G as PROVIDER_CREDENTIAL_REF_VERSION, H as ProviderCategoryV1, J as ProviderCredentialDefinitionV1, K as ProviderCredentialRefFactoryV1, L as ProviderDefinitionV1, d as ProviderId, i as ProviderRegistryV1, l as ResolvedCredentialLeaseV1, R as ResolvedCredentialMaterialV1, M as SandboxHandleRecord, S as SandboxHandleStore, N as Sha256DigestSchema, Q as ShareEntryErrorCode, T as ShareEntryProvenance, U as ShareEntryProvenanceSchema, X as ShareEntryResolution, b as ShareEntryStore, Y as ShareEntryTombstone, Z as ShareEntryV1, _ as ShareEntryV1Schema, $ as ShareEntryValidationError, V as VerifiedWorkspaceCredentialAuthorityV1, a0 as VerifiedWorkspaceCredentialPrincipalV1, a1 as WORKSPACE_AGENT_PLUGINS_RELOADED_EVENT, a2 as WORKSPACE_COMMAND_NOTIFY_EVENT, a3 as WorkspaceAgentDispatch, c as WorkspaceAgentDispatcher, W as WorkspaceAgentDispatcherContext, a4 as WorkspaceAgentDispatcherDispatchInput, a5 as WorkspaceAgentDispatcherSendInput, a6 as WorkspaceAgentGatewayBinding, g as WorkspaceCredentialAuthorityVerifierV1, j as WorkspaceCredentialResolverV1, a7 as createAgentAssetDigest, a8 as createAgentDefinitionDigest, a9 as createAgentDeploymentDigest, aa as createCredentialConsumerBindingRegistryV1, ab as createProviderCredentialRefFactoryV1, ac as createProviderRegistryV1, ad as resolveShareEntry, ae as validateAgentDefinition, af as validateAgentDeployment } from '../lease-CusB-uLg.js';
|
|
5
5
|
import { b as Workspace, S as Sandbox } from '../sandbox-DAD8cWQR.js';
|
|
6
6
|
export { e as Entry, E as ExecOptions, a as ExecResult, I as IsolatedCodeInput, f as IsolatedCodeOutput, g as SandboxCapability, d as Stat, c as WorkspaceRuntimeContext, h as WorkspaceWatchControlEvent } from '../sandbox-DAD8cWQR.js';
|
|
7
7
|
import { B as BoringChatPart, T as ToolUiMetadata, A as AgentConsumptionErrorCode } from '../piChatEvent-BsMp3MSo.js';
|
|
8
8
|
export { p as AgentDefinitionErrorCode, q as AgentDeploymentErrorCode, r as ApiErrorPayload, s as ApiErrorPayloadSchema, t as ApiErrorResponse, u as ApiErrorResponseSchema, a as BoringChatMessage, v as ChatAttachmentPayload, C as ChatError, o as ChatModelSelection, w as ChatSubmitPayload, h as CommandReceipt, x as ERROR_CODES, E as ErrorCode, y as ErrorLogFields, z as ErrorLogFieldsSchema, F as FollowUpPayload, e as FollowUpReceipt, I as InterruptPayload, D as InterruptReceipt, b as PiChatEvent, G as PiChatHeartbeatFrame, n as PiChatSnapshot, P as PiChatStatus, H as PiChatStreamFrame, c as PromptPayload, d as PromptReceipt, f as QueueClearPayload, g as QueueClearReceipt, Q as QueuedUserMessage, l as SessionCtx, J as SessionDetail, S as SessionStore, k as SessionSummary, i as StopPayload, j as StopReceipt, K as ThinkingLevel, L as extractToolUiMetadata, M as isToolUiMetadata } from '../piChatEvent-BsMp3MSo.js';
|
|
9
|
-
import { F as FileSearch } from '../errors-
|
|
10
|
-
export { i as AGENT_GATEWAY_ERROR_CODES, j as AgentFollowUpCommand, A as AgentGateway, k as AgentGatewayError, l as AgentGatewayErrorCode, g as AgentGatewayErrorDTO, m as AgentPromptCommand, h as AgentScopeVerifier, n as AgentSendReceipt, c as AgentSessionActivity, f as AgentSessionConnection, o as AgentSessionEvent, p as AgentSessionPage, b as AgentSessionRef, e as AgentSessionStateSnapshot, d as AgentSessionSummary, q as AgentSummary, r as AuthSubjectId, a as AuthorizedAgentScope, s as AuthorizedAgentSessionQuery, C as ConnectAgentSessionInput, t as CreateAgentSessionInput, D as DeleteAgentSessionInput, I as IdempotentAgentControl, u as IdempotentAgentSend, v as IdempotentQueueClear, w as JsonPrimitive, x as JsonSafe, J as JsonValue, L as ListAgentsInput, R as ReadAgentSessionStateInput, y as RenameAgentSessionInput, V as VerifiedAgentScopeClaim, W as WorkspaceScopeId } from '../errors-
|
|
9
|
+
import { F as FileSearch } from '../errors-G6T6S7PQ.js';
|
|
10
|
+
export { i as AGENT_GATEWAY_ERROR_CODES, j as AgentFollowUpCommand, A as AgentGateway, k as AgentGatewayError, l as AgentGatewayErrorCode, g as AgentGatewayErrorDTO, m as AgentPromptCommand, h as AgentScopeVerifier, n as AgentSendReceipt, c as AgentSessionActivity, f as AgentSessionConnection, o as AgentSessionEvent, p as AgentSessionPage, b as AgentSessionRef, e as AgentSessionStateSnapshot, d as AgentSessionSummary, q as AgentSummary, r as AuthSubjectId, a as AuthorizedAgentScope, s as AuthorizedAgentSessionQuery, C as ConnectAgentSessionInput, t as CreateAgentSessionInput, D as DeleteAgentSessionInput, I as IdempotentAgentControl, u as IdempotentAgentSend, v as IdempotentQueueClear, w as JsonPrimitive, x as JsonSafe, J as JsonValue, L as ListAgentsInput, R as ReadAgentSessionStateInput, y as RenameAgentSessionInput, V as VerifiedAgentScopeClaim, W as WorkspaceScopeId } from '../errors-G6T6S7PQ.js';
|
|
11
11
|
import { z } from 'zod';
|
|
12
12
|
import '@mariozechner/pi-coding-agent';
|
|
13
13
|
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import * as fastify from 'fastify';
|
|
2
2
|
import { FastifyRequest, FastifyPluginAsync } from 'fastify';
|
|
3
3
|
import { w as ToolReadinessRequirement, T as TelemetrySink, b as Agent, A as AgentHarness, t as AgentTool, u as AgentHarnessFactory } from './harness-Cc48o6uS.js';
|
|
4
|
-
import { F as FileSearch, b as AgentSessionRef, V as VerifiedAgentScopeClaim, g as AgentGatewayErrorDTO, J as JsonValue, a as AuthorizedAgentScope, A as AgentGateway, h as AgentScopeVerifier } from './errors-
|
|
4
|
+
import { F as FileSearch, b as AgentSessionRef, V as VerifiedAgentScopeClaim, g as AgentGatewayErrorDTO, J as JsonValue, a as AuthorizedAgentScope, A as AgentGateway, h as AgentScopeVerifier } from './errors-G6T6S7PQ.js';
|
|
5
5
|
import { o as ChatModelSelection } from './piChatEvent-BsMp3MSo.js';
|
|
6
6
|
import { b as Workspace, c as WorkspaceRuntimeContext, S as Sandbox } from './sandbox-DAD8cWQR.js';
|
|
7
7
|
import { RuntimeHostOperations } from '@hachej/boring-bash/agent';
|
|
8
8
|
import { CreateNodeWorkspaceOptions, BoringAgentRuntimePaths } from '@hachej/boring-sandbox/providers/node-workspace';
|
|
9
9
|
import { PackageSource, ExtensionFactory, SettingsManager } from '@mariozechner/pi-coding-agent';
|
|
10
|
-
import { A as AgentCoreSessionService, g as PiChatSessionService } from './piChatSessionService-
|
|
10
|
+
import { A as AgentCoreSessionService, g as PiChatSessionService } from './piChatSessionService-C0KbcGw9.js';
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
13
|
* Generic metering seam for hosts that bill native Pi usage.
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
# AgentGateway v0 — the session contract
|
|
2
|
+
|
|
3
|
+
**Kind:** technical contract. **Governs:** the gateway surface only.
|
|
4
|
+
**Does not govern:** sequencing (see `docs/DIRECTION.md`), architecture rulings
|
|
5
|
+
(see `docs/DECISIONS.md`), or history (see `docs/issues/909/plan.md`).
|
|
6
|
+
|
|
7
|
+
This file supersedes `docs/issues/909/plan.md` §6 as the binding description of
|
|
8
|
+
the gateway contract. §6 was written before implementation and drifted; it is
|
|
9
|
+
retained there as a historical record, not as a build target.
|
|
10
|
+
|
|
11
|
+
Source of truth is the code: `packages/agent/src/shared/gateway/types.ts` and
|
|
12
|
+
`errors.ts`. If this file and those files disagree, the code wins and this file
|
|
13
|
+
is a bug. Keep them together — that colocation is the point. The v0 contract
|
|
14
|
+
lived in an issue folder nobody updated, and it silently stopped matching the
|
|
15
|
+
types within one release.
|
|
16
|
+
|
|
17
|
+
## Scope discipline
|
|
18
|
+
|
|
19
|
+
`AuthorizedAgentScope` is an **issuer-owned runtime capability, not a transport
|
|
20
|
+
DTO**. It carries a `unique symbol` brand, so it cannot be forged by spreading
|
|
21
|
+
an object across a boundary. It must be re-checked against issuer identity and
|
|
22
|
+
current membership on every use — possession is not authorization.
|
|
23
|
+
|
|
24
|
+
```ts
|
|
25
|
+
interface AuthorizedAgentScope {
|
|
26
|
+
readonly workspaceScopeId: WorkspaceScopeId
|
|
27
|
+
readonly authSubjectId: AuthSubjectId
|
|
28
|
+
readonly [authorizedAgentScope]: true // brand
|
|
29
|
+
}
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Only the app-owned verifier returns identity facts, as
|
|
33
|
+
`VerifiedAgentScopeClaim`. `AgentSessionRef` deliberately carries **no
|
|
34
|
+
`hostId`** — session refs are `{ agentTypeId, sessionId }` and nothing else.
|
|
35
|
+
|
|
36
|
+
## The 7 methods (+ close)
|
|
37
|
+
|
|
38
|
+
```ts
|
|
39
|
+
interface AgentGateway {
|
|
40
|
+
listAgents(input: ListAgentsInput): Promise<readonly AgentSummary[]>
|
|
41
|
+
listSessions(input: AuthorizedAgentSessionQuery): Promise<AgentSessionPage>
|
|
42
|
+
createSession(input: CreateAgentSessionInput): Promise<AgentSessionRef>
|
|
43
|
+
connectSession(input: ConnectAgentSessionInput): Promise<AgentSessionConnection>
|
|
44
|
+
readSessionState(input: ReadAgentSessionStateInput): Promise<AgentSessionStateSnapshot>
|
|
45
|
+
renameSession(input: RenameAgentSessionInput): Promise<AgentSessionSummary>
|
|
46
|
+
deleteSession(input: DeleteAgentSessionInput): Promise<void>
|
|
47
|
+
close(): Promise<void>
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### Input DTOs — scope is NESTED
|
|
52
|
+
|
|
53
|
+
**This is the correction.** §6 froze the scope fields as inherited
|
|
54
|
+
(`interface CreateAgentSessionInput extends AuthorizedAgentScope`). The shipped
|
|
55
|
+
contract nests scope under its own field on **every** input:
|
|
56
|
+
|
|
57
|
+
```ts
|
|
58
|
+
interface ListAgentsInput { scope }
|
|
59
|
+
interface AuthorizedAgentSessionQuery{ scope; agentTypeId?; cursor?; limit? }
|
|
60
|
+
interface CreateAgentSessionInput { scope; agentTypeId; requestId; title? }
|
|
61
|
+
interface ConnectAgentSessionInput { scope; ref; cursor? }
|
|
62
|
+
interface ReadAgentSessionStateInput { scope; ref }
|
|
63
|
+
interface RenameAgentSessionInput { scope; ref; requestId; title }
|
|
64
|
+
interface DeleteAgentSessionInput { scope; ref; requestId }
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Nesting keeps the branded capability a single indivisible value instead of
|
|
68
|
+
scattering its fields across every DTO, which is why callers adopted it. Code
|
|
69
|
+
written against §6's inherited form does not typecheck.
|
|
70
|
+
|
|
71
|
+
Note `listAgents` takes `ListAgentsInput`, not a bare `AuthorizedAgentScope`.
|
|
72
|
+
|
|
73
|
+
### Output DTOs
|
|
74
|
+
|
|
75
|
+
`AgentSummary` (`agentTypeId`, `label`, `description?`, `definition?{version,digest}`),
|
|
76
|
+
`AgentSessionSummary` (`ref`, `title`, `status`, `createdAt`, `updatedAt`),
|
|
77
|
+
`AgentSessionPage` (`sessions`, `nextCursor?`), and the receipts
|
|
78
|
+
(`CommandReceipt`, `AgentSendReceipt`, `QueueClearReceipt`, `StopReceipt`) are
|
|
79
|
+
unchanged from §6, field for field.
|
|
80
|
+
|
|
81
|
+
Session activity is the extracted alias `AgentSessionActivity`:
|
|
82
|
+
`'idle' | 'running' | 'aborting' | 'error'`.
|
|
83
|
+
|
|
84
|
+
`AgentSessionStateSnapshot.state` is **`JsonSafe<PiChatSnapshot>`**, not the raw
|
|
85
|
+
snapshot §6 named — the transport boundary is expressed in the type.
|
|
86
|
+
|
|
87
|
+
`JsonSafe<T>` itself differs from §6's version: it hoists `unknown extends T` to
|
|
88
|
+
the top, maps functions to `never`, and terminates non-object/non-array at
|
|
89
|
+
`never`. Read it from `types.ts`; do not reimplement it from memory.
|
|
90
|
+
|
|
91
|
+
### Commands
|
|
92
|
+
|
|
93
|
+
`AgentPromptCommand` and `AgentFollowUpCommand` both require
|
|
94
|
+
**`{ requestId, clientNonce, content }`** — there is no `text` or `kind:'user'`
|
|
95
|
+
shorthand. Prompts add `displayContent?`, `model?`, `thinkingLevel?`,
|
|
96
|
+
`attachments?`; follow-ups add `clientSeq`.
|
|
97
|
+
|
|
98
|
+
## Error codes
|
|
99
|
+
|
|
100
|
+
Thirteen, exhaustive, order-stable, exported as both a const map and
|
|
101
|
+
`AGENT_GATEWAY_ERROR_CODES`:
|
|
102
|
+
|
|
103
|
+
`AGENT_TYPE_UNKNOWN` · `AGENT_SESSION_NOT_FOUND` · `AGENT_SCOPE_DENIED` ·
|
|
104
|
+
`AGENT_SESSION_REPLAY_GAP` · `AGENT_SESSION_CURSOR_AHEAD` ·
|
|
105
|
+
`AGENT_SESSION_CURSOR_EXPIRED` · `AGENT_SESSION_CURSOR_INVALID` ·
|
|
106
|
+
`AGENT_REQUEST_CONFLICT` · `AGENT_REQUEST_OUTCOME_UNKNOWN` ·
|
|
107
|
+
`AGENT_COMMAND_INVALID_STATE` · `AGENT_SESSION_RUNTIME_SCOPE_MISMATCH` ·
|
|
108
|
+
`AGENT_SHARED_ENVIRONMENT_UNAVAILABLE` · `AGENT_GATEWAY_CLOSED`
|
|
109
|
+
|
|
110
|
+
HTTP mapping lives in `server/agent-host/httpProjection.ts`
|
|
111
|
+
(`statusForGatewayError`). Note `AGENT_SESSION_RUNTIME_SCOPE_MISMATCH`,
|
|
112
|
+
`AGENT_REQUEST_CONFLICT` and `AGENT_COMMAND_INVALID_STATE` project to **409**.
|
|
113
|
+
|
|
114
|
+
## Conformance levels
|
|
115
|
+
|
|
116
|
+
- **Level B** — bounded replay within a process lifetime, plus snapshot
|
|
117
|
+
rehydrate. This is what ships. A cursor older than the replay window, or one
|
|
118
|
+
from before a restart, yields `REPLAY_GAP` / `CURSOR_AHEAD` and the client
|
|
119
|
+
refetches state. Never a silent gap.
|
|
120
|
+
- **Level D** — durable replay across restarts and processes. Specified,
|
|
121
|
+
deliberately skipped, and owner-annotated in
|
|
122
|
+
`server/agent-host/testing/gatewayConformance.ts`. Owned by the streaming
|
|
123
|
+
lane (#1009).
|
|
124
|
+
|
|
125
|
+
The suite is parameterized by `replayLevel`/`paginationLevel`; a Level D host
|
|
126
|
+
must pass the same file with the flag raised.
|
|
127
|
+
|
|
128
|
+
## Keyset pagination
|
|
129
|
+
|
|
130
|
+
Cursors are HMAC-signed and bound to scope and filter; tampering or reuse under
|
|
131
|
+
a different filter yields `AGENT_SESSION_CURSOR_INVALID`. Ordering is total, so
|
|
132
|
+
a session mutated between pages shifts predictably rather than vanishing.
|
|
133
|
+
|
|
134
|
+
## Known descope
|
|
135
|
+
|
|
136
|
+
§10 of the 909 plan carries an unchecked acceptance box demanding recursive
|
|
137
|
+
JSON/size/depth validation of attachment and path leaves on the transport
|
|
138
|
+
boundary. §6.4 descoped exactly that to v2, and the conformance suite skips it
|
|
139
|
+
(`v2 remote wire validates JSON event leaves, paths, depth, and size`). The
|
|
140
|
+
plan is internally inconsistent on this point; the descope is what shipped.
|
|
141
|
+
Anything relying on recursive leaf validation must not assume it exists.
|
|
142
|
+
|
|
143
|
+
## Construction
|
|
144
|
+
|
|
145
|
+
`createAgentHost()` is the single construction funnel — see
|
|
146
|
+
`server/agent-host/createAgentHost.ts` and Decision 29. It is a
|
|
147
|
+
deployment-static composition helper that returns a gateway and a `close()`; it
|
|
148
|
+
is **not** the AgentHost deployment/publication machinery that Decisions 25–28
|
|
149
|
+
rejected. Future internal/external host tiers belong to #905, not here.
|
|
150
|
+
|
|
151
|
+
`scripts/check-alignment-invariants.mjs` enforces that nothing outside an
|
|
152
|
+
allowlist calls it.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hachej/boring-agent",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.94",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"description": "Pane-embeddable coding agent. Ships direct/local/vercel-sandbox execution modes behind one interface.",
|
|
@@ -91,9 +91,9 @@
|
|
|
91
91
|
"use-stick-to-bottom": "^1.1.6",
|
|
92
92
|
"yaml": "^2.9.0",
|
|
93
93
|
"zod": "^3.25.76",
|
|
94
|
-
"@hachej/boring-bash": "0.1.
|
|
95
|
-
"@hachej/boring-sandbox": "0.1.
|
|
96
|
-
"@hachej/boring-ui-kit": "0.1.
|
|
94
|
+
"@hachej/boring-bash": "0.1.94",
|
|
95
|
+
"@hachej/boring-sandbox": "0.1.94",
|
|
96
|
+
"@hachej/boring-ui-kit": "0.1.94"
|
|
97
97
|
},
|
|
98
98
|
"devDependencies": {
|
|
99
99
|
"@vercel/sandbox": "2.7.1",
|