@hachej/boring-agent 0.1.93 → 0.1.95
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-4TKUT7IL.js → chunk-2EMAKBVR.js} +272 -75
- package/dist/{chunk-CJ2BW2W2.js → chunk-EOMY2HDT.js} +1 -0
- package/dist/core/index.d.ts +2 -2
- package/dist/core/index.js +1 -1
- package/dist/{errors-C38f6pol.d.ts → errors-G6T6S7PQ.d.ts} +2 -0
- package/dist/front/index.d.ts +71 -9
- package/dist/front/index.js +931 -881
- package/dist/front/styles.css +261 -172
- 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 +45 -5
- package/dist/server/index.js +2 -2
- package/dist/server/worker/index.js +2 -2
- 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
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { D as InterruptReceipt, j as StopReceipt, p as AgentDefinitionErrorCode, q as AgentDeploymentErrorCode } from './piChatEvent-BsMp3MSo.js';
|
|
2
2
|
import { p as AgentSendInput, j as AgentEvent } from './harness-Cc48o6uS.js';
|
|
3
|
-
import { b as AgentSessionRef, n as AgentSendReceipt, A as AgentGateway, a as AuthorizedAgentScope } from './errors-
|
|
3
|
+
import { b as AgentSessionRef, n as AgentSendReceipt, A as AgentGateway, a as AuthorizedAgentScope } from './errors-G6T6S7PQ.js';
|
|
4
4
|
import { z } from 'zod';
|
|
5
5
|
import { b as Workspace } from './sandbox-DAD8cWQR.js';
|
|
6
6
|
|
|
@@ -10,6 +10,8 @@ interface WorkspaceAgentDispatcherContext {
|
|
|
10
10
|
}
|
|
11
11
|
type WorkspaceAgentDispatcherSendInput = Omit<AgentSendInput, 'ctx'>;
|
|
12
12
|
interface WorkspaceAgentDispatcherDispatchInput extends WorkspaceAgentDispatcherSendInput {
|
|
13
|
+
/** Optional title for a newly created addressed session. */
|
|
14
|
+
title?: string;
|
|
13
15
|
/** Durable caller-owned idempotency key. */
|
|
14
16
|
requestId: string;
|
|
15
17
|
/** Defaults to requestId. */
|
|
@@ -16,6 +16,10 @@ interface PiSessionCreateInit {
|
|
|
16
16
|
title?: string;
|
|
17
17
|
modelDefault?: ChatModelSelection;
|
|
18
18
|
}
|
|
19
|
+
/** Server-only prompt admission selector; browser schemas never accept requireIdle. */
|
|
20
|
+
type AgentPromptPayload = PromptPayload & {
|
|
21
|
+
readonly requireIdle?: true;
|
|
22
|
+
};
|
|
19
23
|
type PiChatReplayRangeError = {
|
|
20
24
|
type: 'replay_gap';
|
|
21
25
|
latestSeq: number;
|
|
@@ -45,13 +49,15 @@ interface PiChatSessionService {
|
|
|
45
49
|
readAttachment?(ctx: PiSessionRequestContext, sessionId: string, messageId: string, index: number): Promise<PiChatAttachmentResult>;
|
|
46
50
|
readState(ctx: PiSessionRequestContext, sessionId: string): Promise<PiChatSnapshot>;
|
|
47
51
|
subscribe(ctx: PiSessionRequestContext, sessionId: string, cursor: number, subscriber: PiChatEventSubscriber): Promise<PiChatEventStreamResult>;
|
|
48
|
-
prompt(ctx: PiSessionRequestContext, sessionId: string, payload:
|
|
52
|
+
prompt(ctx: PiSessionRequestContext, sessionId: string, payload: AgentPromptPayload): Promise<PromptReceipt>;
|
|
49
53
|
followUp(ctx: PiSessionRequestContext, sessionId: string, payload: FollowUpPayload): Promise<FollowUpReceipt>;
|
|
50
54
|
clearQueue(ctx: PiSessionRequestContext, sessionId: string, payload: QueueClearPayload): Promise<QueueClearReceipt>;
|
|
51
55
|
interrupt(ctx: PiSessionRequestContext, sessionId: string, payload: InterruptPayload): Promise<CommandReceipt>;
|
|
52
56
|
stop(ctx: PiSessionRequestContext, sessionId: string, payload: StopPayload): Promise<StopReceipt>;
|
|
53
57
|
}
|
|
54
58
|
interface AgentCoreSessionService extends PiChatSessionService {
|
|
59
|
+
/** Trusted host-only validation/binding seam; never exposed as an HTTP route. */
|
|
60
|
+
ensurePiSessionBound?(ctx: PiSessionRequestContext, sessionId: string): Promise<void>;
|
|
55
61
|
createSession(ctx: PiSessionRequestContext, init?: PiSessionCreateInit): Promise<SessionSummary>;
|
|
56
62
|
deleteSession(ctx: PiSessionRequestContext, sessionId: string): Promise<void>;
|
|
57
63
|
dispose?(): Promise<void>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { A as AgentGateway, a as AuthorizedAgentScope, b as AgentSessionRef, c as AgentSessionActivity } from '../../../errors-
|
|
2
|
-
import { A as AgentGatewayEffect } from '../../../types-
|
|
1
|
+
import { A as AgentGateway, a as AuthorizedAgentScope, b as AgentSessionRef, c as AgentSessionActivity } from '../../../errors-G6T6S7PQ.js';
|
|
2
|
+
import { A as AgentGatewayEffect } from '../../../types-C-Eroi__.js';
|
|
3
3
|
import '../../../piChatEvent-BsMp3MSo.js';
|
|
4
4
|
import 'zod';
|
|
5
5
|
import 'fastify';
|
|
@@ -8,7 +8,7 @@ import '@mariozechner/pi-coding-agent';
|
|
|
8
8
|
import '../../../sandbox-DAD8cWQR.js';
|
|
9
9
|
import '@hachej/boring-bash/agent';
|
|
10
10
|
import '@hachej/boring-sandbox/providers/node-workspace';
|
|
11
|
-
import '../../../piChatSessionService-
|
|
11
|
+
import '../../../piChatSessionService-C0KbcGw9.js';
|
|
12
12
|
|
|
13
13
|
/** G1 ships only the embedded bounded-replay contract. */
|
|
14
14
|
type GatewayReplayConformanceLevel = 'B';
|
|
@@ -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>;
|
|
@@ -721,6 +751,7 @@ declare class HarnessPiChatService implements PiChatSessionService {
|
|
|
721
751
|
}>;
|
|
722
752
|
readState(ctx: PiSessionRequestContext, sessionId: string): Promise<PiChatSnapshot>;
|
|
723
753
|
private readStateBeforeDispose;
|
|
754
|
+
private canRefreshFromPersistedState;
|
|
724
755
|
private harnessMayHaveLiveSession;
|
|
725
756
|
private readPersistedState;
|
|
726
757
|
subscribe(ctx: PiSessionRequestContext, sessionId: string, cursor: number, subscriber: PiChatEventSubscriber): Promise<PiChatEventStreamResult>;
|
|
@@ -759,6 +790,12 @@ declare class HarnessPiChatService implements PiChatSessionService {
|
|
|
759
790
|
private createChannelOnce;
|
|
760
791
|
private buildChannel;
|
|
761
792
|
private readDurableLatestPiChatSeq;
|
|
793
|
+
/**
|
|
794
|
+
* Validate the persisted session identity and instantiate its lazily-created
|
|
795
|
+
* Pi adapter under the same full cache key. This is intentionally a narrow
|
|
796
|
+
* trusted-host seam rather than another browser route.
|
|
797
|
+
*/
|
|
798
|
+
ensurePiSessionBound(ctx: PiSessionRequestContext, sessionId: string): Promise<void>;
|
|
762
799
|
private assertCanAccessSession;
|
|
763
800
|
private sessionKey;
|
|
764
801
|
}
|
|
@@ -861,6 +898,7 @@ interface CreateValidatingAgentFleetCompilerOptions {
|
|
|
861
898
|
*/
|
|
862
899
|
declare function createValidatingAgentFleetCompiler(options: CreateValidatingAgentFleetCompilerOptions): AgentFleetCompiler;
|
|
863
900
|
|
|
901
|
+
type RetryableSessionGuard = () => Promise<AgentGatewayErrorDTO | undefined>;
|
|
864
902
|
declare class EmbeddedAgentGateway implements AgentGateway {
|
|
865
903
|
private readonly runtime;
|
|
866
904
|
private readonly cursorSecret;
|
|
@@ -912,10 +950,12 @@ declare class EmbeddedAgentGateway implements AgentGateway {
|
|
|
912
950
|
readonly requestId: string;
|
|
913
951
|
readonly payload: JsonValue;
|
|
914
952
|
readonly action: () => Promise<unknown>;
|
|
953
|
+
readonly retryableGuard?: RetryableSessionGuard;
|
|
915
954
|
}): Promise<unknown>;
|
|
916
955
|
private effect;
|
|
917
956
|
private replayReceipt;
|
|
918
957
|
private failure;
|
|
958
|
+
private promptAdmission;
|
|
919
959
|
private withWriter;
|
|
920
960
|
private encodeCursor;
|
|
921
961
|
private decodeCursor;
|
package/dist/server/index.js
CHANGED
|
@@ -62,7 +62,7 @@ import {
|
|
|
62
62
|
sandboxRuntimeHostOperations,
|
|
63
63
|
shareResourceUri,
|
|
64
64
|
withResolvedCredential
|
|
65
|
-
} from "../chunk-
|
|
65
|
+
} from "../chunk-2EMAKBVR.js";
|
|
66
66
|
import {
|
|
67
67
|
PI_PACKAGE_RESOURCE_FILTERS,
|
|
68
68
|
compactPiPackages,
|
|
@@ -70,7 +70,7 @@ import {
|
|
|
70
70
|
mergePiPackageSources,
|
|
71
71
|
piPackageSourceKey
|
|
72
72
|
} from "../chunk-2TMS2RU2.js";
|
|
73
|
-
import "../chunk-
|
|
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-
|
|
4
|
+
} from "../../chunk-2EMAKBVR.js";
|
|
5
5
|
import "../../chunk-2TMS2RU2.js";
|
|
6
|
-
import "../../chunk-
|
|
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.95",
|
|
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-
|
|
95
|
-
"@hachej/boring-
|
|
96
|
-
"@hachej/boring-
|
|
94
|
+
"@hachej/boring-bash": "0.1.95",
|
|
95
|
+
"@hachej/boring-ui-kit": "0.1.95",
|
|
96
|
+
"@hachej/boring-sandbox": "0.1.95"
|
|
97
97
|
},
|
|
98
98
|
"devDependencies": {
|
|
99
99
|
"@vercel/sandbox": "2.7.1",
|