@byok-sdk/client 0.12.0 → 0.14.0
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/README.md +93 -0
- package/dist/adapters/claude/process-client.d.ts +24 -0
- package/dist/adapters/codex/process-runner.d.ts +46 -1
- package/dist/adapters/index.js +433 -33
- package/dist/adapters/index.js.map +1 -1
- package/dist/adapters/pi/events.d.ts +1 -1
- package/dist/adapters/pi/pi-adapter.d.ts +3 -0
- package/dist/adapters/pi/rpc-client.d.ts +47 -1
- package/dist/adapters/pi/subagents-policy-extension.js +1 -1
- package/dist/adapters/pi/subagents-policy-extension.js.map +1 -1
- package/dist/adapters/pi/team-interaction-extension.d.ts +24 -0
- package/dist/adapters/pi/team-interaction-extension.js +81 -0
- package/dist/adapters/pi/team-interaction-extension.js.map +1 -0
- package/dist/adapters/process-tree.d.ts +74 -4
- package/dist/adapters/provider-credential-environment.d.ts +1 -1
- package/dist/adapters/win32-job-object.d.ts +101 -0
- package/dist/agent-home.d.ts +74 -0
- package/dist/agent-memory/index.d.ts +1 -1
- package/dist/agent-memory/index.js.map +1 -1
- package/dist/bin/byok-agent-memory-mcp.js.map +1 -1
- package/dist/bin/byok-agent-message-mcp.js.map +1 -1
- package/dist/bin/byok-agent-team-mcp.js.map +1 -1
- package/dist/bin/byok-agent.js +9571 -8272
- package/dist/bin/byok-agent.js.map +1 -1
- package/dist/bin/byok-approval-mcp.js.map +1 -1
- package/dist/bin/commands/team-pi-relay.d.ts +24 -0
- package/dist/bin/commands/team-relay.d.ts +11 -0
- package/dist/bin/team-codex-relay.d.ts +32 -0
- package/dist/bin/team-notification-relay.d.ts +40 -0
- package/dist/bin/team-pi-session.d.ts +59 -0
- package/dist/daemon/agent-egress-policy.d.ts +8 -0
- package/dist/daemon/connection-manager.d.ts +66 -224
- package/dist/daemon/control-protocol.d.ts +10 -1
- package/dist/daemon/create-daemon.d.ts +58 -13
- package/dist/daemon/event-spill.d.ts +90 -0
- package/dist/daemon/journal/journal.d.ts +15 -3
- package/dist/daemon/journal/sqlite-journal.d.ts +7 -2
- package/dist/daemon/long-poll-transport.d.ts +28 -70
- package/dist/daemon/observer.d.ts +1 -1
- package/dist/daemon/task-runner.d.ts +31 -0
- package/dist/daemon/team-workspace.d.ts +9 -0
- package/dist/daemon/url.d.ts +10 -12
- package/dist/diagnostics/support-bundle.d.ts +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1334 -696
- package/dist/index.js.map +1 -1
- package/package.json +9 -8
- package/dist/daemon/ws-transport.d.ts +0 -139
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import type { AgentEgressPolicy, RuntimeId } from '@byok-sdk/protocol';
|
|
2
2
|
import type { PermissionPolicy } from '@byok-sdk/protocol';
|
|
3
3
|
import type { RuntimeAdapter, GitWorkspaceConfig, McpToolsetConfig, McpToolsetObservation, McpToolsetRegistryStatus, McpToolsetReloadReceipt } from '../types';
|
|
4
|
-
import { type AgentHomeProjection } from '../agent-home';
|
|
4
|
+
import { type AgentHomeExecutionStatus, type AgentHomeProjection } from '../agent-home';
|
|
5
5
|
import type { AgentRef } from '../agent-home';
|
|
6
6
|
import { type LocalAgentReleaseIdentity } from '../release-identity';
|
|
7
|
-
import type { BackoffOptions, LivenessOptions } from './ws-transport';
|
|
8
7
|
import { type OperationalHealthSnapshot } from './operational-health';
|
|
9
8
|
import { type DaemonEventListener, type DaemonTaskInfo, type Unsubscribe } from './observer';
|
|
10
9
|
import { GitWorkspaceManager } from './git-workspace';
|
|
@@ -132,6 +131,26 @@ export interface DaemonConfig {
|
|
|
132
131
|
* after the SDK-owned Agent home has passed construction-time preflight.
|
|
133
132
|
*/
|
|
134
133
|
strictAgentOnly?: boolean;
|
|
134
|
+
/**
|
|
135
|
+
* WP0: how many Attempts this daemon lets execute CONCURRENTLY in one
|
|
136
|
+
* canonical Agent home, across every lane and every session. Default
|
|
137
|
+
* {@link DEFAULT_MAX_CONCURRENT_MUTABLE_SESSIONS_PER_AGENT_HOME} (1).
|
|
138
|
+
*
|
|
139
|
+
* The canonical home is every Agent session's cwd, so each concurrent
|
|
140
|
+
* Attempt in it is another writer of the same `MEMORY.md`, `notes/` and
|
|
141
|
+
* `.git`. At the default, a second offer for a home that already has an
|
|
142
|
+
* active Attempt is declined retryably before adapter preparation, the
|
|
143
|
+
* claim, or any process side effect — the busy-home contract downstream
|
|
144
|
+
* hosts already depend on.
|
|
145
|
+
*
|
|
146
|
+
* Raising it above 1 is an explicit host choice that re-enables the
|
|
147
|
+
* 0.12.0 concurrent-session behaviour, including its co-writing exposure;
|
|
148
|
+
* the SDK never falls back to it on its own. Validated up front, the same
|
|
149
|
+
* way `maxTaskOutputBytes` is: a positive safe integer, so `0`, a negative
|
|
150
|
+
* number, `NaN` and a non-integer are construction errors rather than a
|
|
151
|
+
* silently reinterpreted "unlimited".
|
|
152
|
+
*/
|
|
153
|
+
maxConcurrentMutableSessionsPerAgentHome?: number;
|
|
135
154
|
/**
|
|
136
155
|
* Explicit Agent-local/cloud egress selection. Omission still enforces the
|
|
137
156
|
* SDK metadata/status projection, but does not advertise or admit the new
|
|
@@ -257,7 +276,7 @@ export interface DaemonConfig {
|
|
|
257
276
|
/**
|
|
258
277
|
* M5: explicit escape hatch for `url.ts`'s `assertServerUrlAllowed` — see
|
|
259
278
|
* that function's own doc comment for the full allow/deny rule. Default
|
|
260
|
-
* (unset/`false`): a `serverUrl` using plaintext `
|
|
279
|
+
* (unset/`false`): a `serverUrl` using plaintext `http:` is only
|
|
261
280
|
* accepted when its host is loopback (`localhost`/`*.localhost`,
|
|
262
281
|
* `127.0.0.0/8`, `::1`); anything else over plaintext throws a typed
|
|
263
282
|
* `InsecureServerUrlError` from `pair()`/`start()` below, BEFORE any
|
|
@@ -268,7 +287,7 @@ export interface DaemonConfig {
|
|
|
268
287
|
* server) — doing so also logs a loud `console.warn` (see
|
|
269
288
|
* `checkServerUrl`, this file) every time it actually changes the
|
|
270
289
|
* outcome. Never overrides an unsupported scheme (anything other than
|
|
271
|
-
* `http:`/`https
|
|
290
|
+
* `http:`/`https:`), which is refused unconditionally.
|
|
272
291
|
*/
|
|
273
292
|
dangerouslyAllowInsecureRemote?: boolean;
|
|
274
293
|
/**
|
|
@@ -288,6 +307,36 @@ export interface DaemonConfig {
|
|
|
288
307
|
* explicitly instead to opt out of enforcement altogether.
|
|
289
308
|
*/
|
|
290
309
|
maxTaskOutputBytes?: number;
|
|
310
|
+
/**
|
|
311
|
+
* Per-EVENT inline ceiling (default {@link DEFAULT_MAX_INLINE_EVENT_BYTES},
|
|
312
|
+
* 64 KiB) for the two `AgentEvent` fields a runtime authors freely:
|
|
313
|
+
* `tool_use.input` and `tool_result.output`. An event whose serialization
|
|
314
|
+
* exceeds this leaves `TaskRunner.pump` with that field replaced by a
|
|
315
|
+
* UTF-8-safe head/tail preview (`{ preview: { head, tail } }`) and an
|
|
316
|
+
* additive `spill` descriptor; the full JSON serialization is uploaded to
|
|
317
|
+
* the blob plane under an idempotent, content-addressed key, and
|
|
318
|
+
* `spill.blob` is where a consumer reads it back. If the upload fails the
|
|
319
|
+
* preview still ships, carrying `spill.unstoredReason` instead — omission
|
|
320
|
+
* is always described, never silent.
|
|
321
|
+
*
|
|
322
|
+
* This is a per-event bound, orthogonal to `maxTaskOutputBytes` (a
|
|
323
|
+
* whole-task total, counted AFTER spilling) and to
|
|
324
|
+
* `progressBatch.maxBatchBytes` (a per-batch wire budget).
|
|
325
|
+
*
|
|
326
|
+
* **Consumer contract:** `spill`'s presence is the only signal that the
|
|
327
|
+
* inline field is a preview. A consumer that renders `tool_result.output`
|
|
328
|
+
* without checking `spill` renders a truncation as the whole result.
|
|
329
|
+
*
|
|
330
|
+
* Must be a positive safe integer of at least
|
|
331
|
+
* {@link MIN_MAX_INLINE_EVENT_BYTES} (4096) — below that a legitimate
|
|
332
|
+
* `spill` descriptor no longer fits inside the cap it exists to enforce.
|
|
333
|
+
* Anything else (0, negative, non-integer, `NaN`,
|
|
334
|
+
* `Number.POSITIVE_INFINITY`) is a config validation error thrown
|
|
335
|
+
* synchronously from `createDaemonWithAdapters`/`createDaemon`; there is
|
|
336
|
+
* no opt-out, because "unbounded event" is exactly the state this exists
|
|
337
|
+
* to prevent.
|
|
338
|
+
*/
|
|
339
|
+
maxInlineEventBytes?: number;
|
|
291
340
|
/**
|
|
292
341
|
* Host-owned batching policy for normalized `task.progress` events.
|
|
293
342
|
* `maxBatchBytes`, when set, measures exactly the UTF-8 bytes of
|
|
@@ -475,8 +524,6 @@ export interface DaemonStatus {
|
|
|
475
524
|
localAgentRelease: Readonly<LocalAgentReleaseIdentity>;
|
|
476
525
|
paired: boolean;
|
|
477
526
|
connected: boolean;
|
|
478
|
-
/** True once the connection has fallen back to long-poll (protocol §8) — transport info only (finding F6): long-poll is a full transport, so work still proceeds normally while this holds; outbound envelopes POST to /byok/messages instead of going out over WS. */
|
|
479
|
-
degraded: boolean;
|
|
480
527
|
/** True once the server has revoked this device (401 on challenge/token, protocol §6.3). The only recourse is calling `pair()` again — the daemon does not keep retrying on its own. */
|
|
481
528
|
revoked: boolean;
|
|
482
529
|
deviceId?: string;
|
|
@@ -489,6 +536,8 @@ export interface DaemonStatus {
|
|
|
489
536
|
toolsets: McpToolsetRegistryStatus;
|
|
490
537
|
/** Content-free egress lane watermarks and typed last-drop facts. */
|
|
491
538
|
egress: AgentEgressStatus;
|
|
539
|
+
/** WP0: per-canonical-Agent-home execution serialization — see {@link AgentHomeExecutionStatus}. */
|
|
540
|
+
agentHomeExecution: AgentHomeExecutionStatus;
|
|
492
541
|
}
|
|
493
542
|
export interface Daemon {
|
|
494
543
|
/** Pairing result is intentionally credential-blind. */
|
|
@@ -538,10 +587,10 @@ export interface Daemon {
|
|
|
538
587
|
/** M3-2a: same as {@link approve} but rejects — see that method's doc comment. */
|
|
539
588
|
reject(taskId: string, reason?: string): Promise<void>;
|
|
540
589
|
}
|
|
541
|
-
/** Internal seam so tests can substitute stub adapters / faster
|
|
590
|
+
/** Internal seam so tests can substitute stub adapters / faster batch and long-poll timing. `createDaemonWithAdapters` (which takes this) is also the real entry point for products supplying a hand-built adapter set `createDaemon` can't construct on its own — e.g. custom adapter options, or an adapter that REPLACES a bundled runtime's implementation under the same id. Honest limit: an adapter id outside `pi`/`claude`/`codex` cannot pass wire validation today — `RuntimeIdSchema` (`@byok-sdk/protocol`) is a closed `z.enum(['pi', 'claude', 'codex'])`, and `isRuntimeId` filtering below (see `detectRuntimes`) drops any detected adapter outside that set before it ever reaches a wire-visible field. A genuinely fourth/namespaced runtime id is a future protocol change, not something this seam enables today. */
|
|
542
591
|
export interface DaemonOverrides {
|
|
543
|
-
|
|
544
|
-
|
|
592
|
+
/** Test-only synchronous kill points; never supplied by production configuration. */
|
|
593
|
+
executionRecoveryFault?: (step: 'terminal:before-send' | 'terminal:queued' | 'outbound:before-post' | 'outbound:after-ack') => void;
|
|
545
594
|
/** M4 Phase 3: overrides `TaskRunner`'s default out-of-band approval wait (`DEFAULT_APPROVAL_TIMEOUT_MS`, 10 minutes) before an unanswered `requestApproval` force-resolves as a fail-closed rejection. */
|
|
546
595
|
approvalTimeoutMs?: number;
|
|
547
596
|
/** Finding F5: overrides for the control-socket shutdown path's own bounded waits — see `TaskRunner.shutdownTask`'s and `ConnectionManager.stop`'s own doc comments. Both default to 5s; neither affects an ordinary (non-shutdown-RPC) `daemon.stop()` call. */
|
|
@@ -552,10 +601,6 @@ export interface DaemonOverrides {
|
|
|
552
601
|
outboxDrainTimeoutMs?: number;
|
|
553
602
|
};
|
|
554
603
|
longPoll?: {
|
|
555
|
-
/** Consecutive never-acked WS connect failures before falling back to long-poll. Default 3. */
|
|
556
|
-
wsFailureThreshold?: number;
|
|
557
|
-
/** While long-polling, how often to retry establishing WS. Default 5 minutes. */
|
|
558
|
-
wsRetryIntervalMs?: number;
|
|
559
604
|
/** Backoff between failed long-poll HTTP attempts. Default 2s. */
|
|
560
605
|
retryDelayMs?: number;
|
|
561
606
|
/** Minimum delay before the next long-poll request after an empty (no-events) response — avoids busy-looping against a server that responds instantly. Default 250ms. */
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import type { AgentEvent } from '@byok-sdk/protocol';
|
|
2
|
+
import type { BlobResolver } from './blob-client';
|
|
3
|
+
/**
|
|
4
|
+
* Default per-event inline ceiling (64 KiB) for the two `AgentEvent` variants
|
|
5
|
+
* that carry runtime-authored payloads (`tool_use.input`,
|
|
6
|
+
* `tool_result.output`) — see `DaemonConfig.maxInlineEventBytes`
|
|
7
|
+
* (`create-daemon.ts`) for the host-facing contract.
|
|
8
|
+
*
|
|
9
|
+
* 64 KiB is the same threshold `sendArtifact` already uses to decide inline
|
|
10
|
+
* vs. blob for an artifact (`MAX_INLINE_ARTIFACT_BYTES`): one number for "a
|
|
11
|
+
* payload this daemon is willing to put on the activity wire".
|
|
12
|
+
*/
|
|
13
|
+
export declare const DEFAULT_MAX_INLINE_EVENT_BYTES: number;
|
|
14
|
+
/**
|
|
15
|
+
* Smallest accepted `maxInlineEventBytes`. Below this a legitimate spill
|
|
16
|
+
* descriptor (`field` + byte counts + a `BlobRef` whose `blobId` is chosen by
|
|
17
|
+
* the server, plus the event's own `type`/`tool`/`toolCallId`) stops fitting
|
|
18
|
+
* inside the cap it is supposed to keep the event under, which would turn a
|
|
19
|
+
* host's configuration mistake into a per-event runtime invariant failure.
|
|
20
|
+
* Enforced up front at `DaemonConfig` validation, never here.
|
|
21
|
+
*/
|
|
22
|
+
export declare const MIN_MAX_INLINE_EVENT_BYTES = 4096;
|
|
23
|
+
/**
|
|
24
|
+
* Worst-case JSON cost of the `,"spill":{…}` fragment when the descriptor
|
|
25
|
+
* carries an `unstoredReason` rather than a server-chosen `BlobRef`.
|
|
26
|
+
*
|
|
27
|
+
* Every part is bounded by construction, which a `BlobRef` is not — its
|
|
28
|
+
* `blobId` is an arbitrary-length server-chosen string:
|
|
29
|
+
*
|
|
30
|
+
* ```
|
|
31
|
+
* ,"spill": 9
|
|
32
|
+
* { 1
|
|
33
|
+
* "field":"output", 17 ("output" is the longer of the two)
|
|
34
|
+
* "totalBytes":<=16 digits>, 30
|
|
35
|
+
* "omittedBytes":<=16 digits>, 32 (never exceeds totalBytes)
|
|
36
|
+
* "contentType":"application/json", 33 (a module constant)
|
|
37
|
+
* "unstoredReason": 17
|
|
38
|
+
* "<=512 bytes of escaped reason>" 514 (MAX_UNSTORED_REASON_BYTES + 2 quotes)
|
|
39
|
+
* } 1
|
|
40
|
+
* ----
|
|
41
|
+
* 654
|
|
42
|
+
* ```
|
|
43
|
+
*
|
|
44
|
+
* Rounded up to 768 so digit-count growth cannot invalidate it. Because the
|
|
45
|
+
* event is spread first and `spill` written last, a bounded event is EXACTLY
|
|
46
|
+
* the empty-preview skeleton plus this fragment — so refusing to spill unless
|
|
47
|
+
* `skeleton + MAX_SPILL_DESCRIPTOR_BYTES <= maxInlineBytes` is what makes the
|
|
48
|
+
* final cap check unreachable rather than merely unlikely. `event-spill.test.ts`
|
|
49
|
+
* asserts this against a maximally escaping reason instead of trusting the
|
|
50
|
+
* comment.
|
|
51
|
+
*/
|
|
52
|
+
export declare const MAX_SPILL_DESCRIPTOR_BYTES = 768;
|
|
53
|
+
export interface EventSpillDeps {
|
|
54
|
+
/** Effective inline ceiling for this daemon; already validated at the `DaemonConfig` layer. */
|
|
55
|
+
maxInlineBytes: number;
|
|
56
|
+
/** Only the upload half of `BlobResolver` is needed, so a test double stays minimal. */
|
|
57
|
+
blobClient: Pick<BlobResolver, 'uploadArtifact'>;
|
|
58
|
+
/** Scopes the upload's idempotency key to the task that produced the event. */
|
|
59
|
+
taskId: string;
|
|
60
|
+
/** Task lifecycle authority — aborting it stops the spill upload with the rest of the task's blob I/O. */
|
|
61
|
+
signal?: AbortSignal;
|
|
62
|
+
/** Diagnostic seam. Called only on a path that loses information (upload failure, or an event this policy cannot bound). */
|
|
63
|
+
log?: (message: string) => void;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Bound one normalized `AgentEvent` at the daemon's ingestion boundary
|
|
67
|
+
* (`TaskRunner.pump`).
|
|
68
|
+
*
|
|
69
|
+
* An event whose serialized form already fits `maxInlineBytes` is returned
|
|
70
|
+
* **as the same object reference** — the overwhelming majority of events pay
|
|
71
|
+
* exactly one `JSON.stringify` and nothing else, and no downstream identity
|
|
72
|
+
* comparison changes meaning.
|
|
73
|
+
*
|
|
74
|
+
* An oversized `tool_use` / `tool_result` has its runtime-authored field
|
|
75
|
+
* (`input` / `output`) uploaded to the blob plane in full and REPLACED inline
|
|
76
|
+
* by `{ preview: { head, tail } }`, with an additive `spill` descriptor
|
|
77
|
+
* carrying either the resulting `BlobRef` or a bounded `unstoredReason`. The
|
|
78
|
+
* replacement is *measured* against the cap, never assumed to fit: the
|
|
79
|
+
* preview budget is whatever is left after the rest of the event and the
|
|
80
|
+
* real descriptor, and it is shrunk until `JSON.stringify(result)` actually
|
|
81
|
+
* fits (JSON escaping can cost several bytes per source character, so the
|
|
82
|
+
* byte budget alone is not a bound).
|
|
83
|
+
*
|
|
84
|
+
* Storage failure is never silent and never fatal: the preview still ships,
|
|
85
|
+
* `unstoredReason` says why the omitted bytes are unreadable, and `log` is
|
|
86
|
+
* called. The runtime's own transcript still holds the content, so failing
|
|
87
|
+
* the task over a telemetry upload would trade a real result for an
|
|
88
|
+
* observability problem.
|
|
89
|
+
*/
|
|
90
|
+
export declare function spillOversizedEvent(event: AgentEvent, deps: EventSpillDeps): Promise<AgentEvent>;
|
|
@@ -124,18 +124,21 @@ export interface LocalTransitionRecord {
|
|
|
124
124
|
/** Whether the cloud has confirmed the terminal this daemon produced (§12.7.3's "terminal 生成后、truth 写入前" window). */
|
|
125
125
|
export type TerminalTruthState = 'pending' | 'confirmed' | 'failed';
|
|
126
126
|
/**
|
|
127
|
-
*
|
|
128
|
-
*
|
|
127
|
+
* One immutable canonical terminal and its delivery projection. Bytes are the
|
|
128
|
+
* replay authority; the hash is checked against them, never used as a substitute.
|
|
129
129
|
*/
|
|
130
130
|
export interface LocalTerminalRecord {
|
|
131
131
|
readonly taskId: string;
|
|
132
|
-
readonly terminalType: 'complete' | 'failed' | 'cancelled';
|
|
132
|
+
readonly terminalType: 'complete' | 'failed' | 'cancelled' | 'declined';
|
|
133
|
+
readonly bytes: string;
|
|
133
134
|
readonly payloadHash: string;
|
|
134
135
|
readonly truthState: TerminalTruthState;
|
|
135
136
|
/** How many times delivery to the cloud has been attempted. */
|
|
136
137
|
readonly attempt: number;
|
|
137
138
|
readonly lastError?: string;
|
|
138
139
|
readonly recordedAt: string;
|
|
140
|
+
/** Committed atomically with the original interruption report. */
|
|
141
|
+
readonly recovery?: RecoveryOutcome;
|
|
139
142
|
}
|
|
140
143
|
/** A task the journal knows about that has no terminal and no recovery marker — i.e. one this daemon was in the middle of when it stopped. */
|
|
141
144
|
export interface RecoverableTask {
|
|
@@ -147,6 +150,7 @@ export interface RecoverableTask {
|
|
|
147
150
|
readonly claimedRuntime?: string;
|
|
148
151
|
readonly workspaceRef?: string;
|
|
149
152
|
readonly updatedAt: string;
|
|
153
|
+
readonly envelopeBytes: string;
|
|
150
154
|
}
|
|
151
155
|
/**
|
|
152
156
|
* What recovery decided about a task. `interrupted` is the honest default for
|
|
@@ -262,6 +266,14 @@ export interface LocalTaskJournal {
|
|
|
262
266
|
recordTransition(record: LocalTransitionRecord): Promise<void>;
|
|
263
267
|
/** Record (or update the retry state of) a task's terminal. Idempotent by task id: a replay with the same payload hash is a no-op beyond retry bookkeeping. */
|
|
264
268
|
recordTerminal(record: LocalTerminalRecord): Promise<void>;
|
|
269
|
+
/** Exact original terminal bytes, including rejected records, until acknowledged. */
|
|
270
|
+
listPendingTerminals(identity: JournalIdentity): Promise<LocalTerminalRecord[]>;
|
|
271
|
+
/** A successful authenticated transport disposition, bound to the original bytes. */
|
|
272
|
+
confirmTerminal(taskId: string, payloadHash: string): Promise<void>;
|
|
273
|
+
rejectTerminal(taskId: string, payloadHash: string, reason: string): Promise<void>;
|
|
274
|
+
/** Includes old interruption markers without reports; they must not hide pending work. */
|
|
275
|
+
listRecoveryTasks(identity: JournalIdentity): Promise<RecoverableTask[]>;
|
|
276
|
+
readTask(taskId: string, identity: JournalIdentity): Promise<RecoverableTask | undefined>;
|
|
265
277
|
/** Tasks with no terminal and no recovery marker — what this daemon was in the middle of when it last stopped. */
|
|
266
278
|
listRecoverable(): Promise<RecoverableTask[]>;
|
|
267
279
|
/** Close out one recoverable task by writing its recovery marker. Never deletes; a marked row is on §12.7.2.1's never-auto-delete list. */
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type AdmissionRecord, type CategoryUsage, type CleanableCategory, type CleanupCandidate, type CleanupResult, type CompactOptions, type CompactResult, type JournalReceipt, type LocalStorageUsage, type LocalTaskJournal, type LocalTerminalRecord, type LocalTransitionRecord, type RecoverableTask, type RecoveryOutcome, type ReceivedEnvelopeRecord, type StorageCategory } from './journal';
|
|
1
|
+
import { type JournalIdentity, type AdmissionRecord, type CategoryUsage, type CleanableCategory, type CleanupCandidate, type CleanupResult, type CompactOptions, type CompactResult, type JournalReceipt, type LocalStorageUsage, type LocalTaskJournal, type LocalTerminalRecord, type LocalTransitionRecord, type RecoverableTask, type RecoveryOutcome, type ReceivedEnvelopeRecord, type StorageCategory } from './journal';
|
|
2
2
|
import { JournalHandleCleanupError, type JournalOpenFaultSeam } from './sqlite-support';
|
|
3
3
|
export { JournalHandleCleanupError };
|
|
4
4
|
/** The single database file, per §12.7.2's "建议单库 `<storeDir>/daemon.db`". */
|
|
@@ -24,7 +24,7 @@ export declare const DEFAULT_JOURNAL_BUSY_TIMEOUT_MS = 5000;
|
|
|
24
24
|
* (`util/secure-dir.ts`): a seam the production path never supplies, exercised
|
|
25
25
|
* from any host.
|
|
26
26
|
*/
|
|
27
|
-
export type JournalFaultStep = 'append:before-begin' | 'append:after-envelope' | 'append:after-task' | 'append:after-receipt' | 'append:before-commit' | 'admission:before-commit' | 'transition:before-commit' | 'terminal:before-commit' | 'recovery:before-commit' | 'cleanup:before-commit' | 'prune:before-commit';
|
|
27
|
+
export type JournalFaultStep = 'append:before-begin' | 'append:after-envelope' | 'append:after-task' | 'append:after-receipt' | 'append:before-commit' | 'append:after-commit' | 'admission:before-commit' | 'transition:before-commit' | 'terminal:before-commit' | 'terminal:after-commit' | 'recovery:after-commit' | 'confirm:before-commit' | 'confirm:after-commit' | 'recovery:before-commit' | 'cleanup:before-commit' | 'prune:before-commit';
|
|
28
28
|
export interface JournalFaultSeam {
|
|
29
29
|
/** Throw to simulate a crash or IO error at exactly this step. Return normally to proceed. */
|
|
30
30
|
onStep?(step: JournalFaultStep): void;
|
|
@@ -79,6 +79,11 @@ export declare class SqliteLocalTaskJournal implements LocalTaskJournal {
|
|
|
79
79
|
* first fact stands.
|
|
80
80
|
*/
|
|
81
81
|
recordTerminal(record: LocalTerminalRecord): Promise<void>;
|
|
82
|
+
readTask(taskId: string, identity: JournalIdentity): Promise<RecoverableTask | undefined>;
|
|
83
|
+
listRecoveryTasks(identity: JournalIdentity): Promise<RecoverableTask[]>;
|
|
84
|
+
listPendingTerminals(identity: JournalIdentity): Promise<LocalTerminalRecord[]>;
|
|
85
|
+
confirmTerminal(taskId: string, payloadHash: string): Promise<void>;
|
|
86
|
+
rejectTerminal(taskId: string, payloadHash: string, reason: string): Promise<void>;
|
|
82
87
|
/**
|
|
83
88
|
* What this daemon was in the middle of: a task whose offer envelope is
|
|
84
89
|
* durable, that has no terminal, that was not declined, and that recovery
|
|
@@ -33,71 +33,24 @@ export interface LongPollClientOptions {
|
|
|
33
33
|
serverUrl: string;
|
|
34
34
|
auth: AuthManager;
|
|
35
35
|
getCursor: () => number | undefined;
|
|
36
|
-
|
|
36
|
+
/** Returns false when the envelope was a local duplicate and no handler was queued. */
|
|
37
|
+
onEnvelope: (envelope: Envelope) => boolean | void;
|
|
37
38
|
/**
|
|
38
39
|
* Capabilities advertised by the server that produced the current poll
|
|
39
40
|
* response. Called before any envelopes from that response are delivered.
|
|
40
41
|
* An older responder omitting the additive field is reported as `[]`.
|
|
41
42
|
*/
|
|
42
43
|
onServerCapabilities?: (capabilities: string[]) => void;
|
|
44
|
+
/** Called when a failed poll invalidates the preceding response's capability snapshot. */
|
|
45
|
+
onServerCapabilitiesInvalidated?: () => void;
|
|
46
|
+
/** Called after a poll fails and before the retry delay begins. */
|
|
47
|
+
onPollFailure?: () => void;
|
|
43
48
|
/** Called once the device is found to be revoked (401 surfaced through {@link AuthManager}) — the loop stops itself rather than retrying. */
|
|
44
49
|
onRevoked?: () => void;
|
|
45
50
|
/** Called when the server cannot replay the durable cursor supplied to this poll. */
|
|
46
51
|
onReplayCursorTooOld?: (error: ReplayCursorTooOldError) => void;
|
|
47
|
-
/**
|
|
48
|
-
*
|
|
49
|
-
* called ONLY for a batch entry that failed to parse because its `type`
|
|
50
|
-
* is entirely unrecognized (`parseMessage` throwing
|
|
51
|
-
* {@link UnknownMessageTypeError} — mirrors `ws-transport.ts`'s identical
|
|
52
|
-
* per-frame tolerance for that SPECIFIC failure) and which still carries a
|
|
53
|
-
* numeric envelope-level `seq` AND a recognizably task-class `type` (a
|
|
54
|
-
* `task.` prefix — see `extractSkippableSeq`'s own doc comment for why a
|
|
55
|
-
* `conn.*`-shaped or type-less entry is deliberately excluded, mirroring
|
|
56
|
-
* F2's "conn.* is never cursor-tracked" rule), so the caller can advance
|
|
57
|
-
* its cursor/watermark past it even though there is no real `Envelope` to
|
|
58
|
-
* hand to `onEnvelope`. Without this, a persistently-redelivered
|
|
59
|
-
* unrecognized-type entry (the real server retains and redelivers an
|
|
60
|
-
* un-acked envelope, protocol §9) would keep reappearing at the same
|
|
61
|
-
* cursor position forever.
|
|
62
|
-
*
|
|
63
|
-
* Finding F1: a RECOGNIZED type that fails schema validation
|
|
64
|
-
* ({@link EnvelopeValidationError} — e.g. a `task.offer` whose
|
|
65
|
-
* `PermissionPolicy` rejects an unknown constraint) is deliberately NOT
|
|
66
|
-
* reported here. That failure is a genuinely malformed control message,
|
|
67
|
-
* not forward-compat tolerance — forwarding its `seq` here would
|
|
68
|
-
* permanently ack a message the daemon never actually understood (the
|
|
69
|
-
* server would stop redelivering it, silently stranding whatever it was
|
|
70
|
-
* offering). The WS path never had this hazard (an unparseable WS frame
|
|
71
|
-
* has no skip-side cursor bookkeeping at all — see
|
|
72
|
-
* `ws-transport.ts` — so it simply gets redelivered later); this callback
|
|
73
|
-
* being scoped to `UnknownMessageTypeError` only is what makes long-poll
|
|
74
|
-
* match that same "no silent permanent ack" property for real. Optional
|
|
75
|
-
* only for constructor/test convenience — `ConnectionManager` always
|
|
76
|
-
* supplies it.
|
|
77
|
-
*/
|
|
78
|
-
onSkippedSeq?: (seq: number) => void;
|
|
79
|
-
/**
|
|
80
|
-
* Finding R1 (cross-model re-review — the F1 fix alone was NOT-CLOSED):
|
|
81
|
-
* called for a batch entry whose `type` WAS recognized but whose payload
|
|
82
|
-
* failed schema validation ({@link EnvelopeValidationError}) — a genuine
|
|
83
|
-
* delivery failure at that specific seq, not forward-compat tolerance
|
|
84
|
-
* (contrast {@link onSkippedSeq}, which is scoped to the opposite case,
|
|
85
|
-
* an entirely unrecognized type). F1's own fix — simply not forwarding
|
|
86
|
-
* this seq to `onSkippedSeq` — turned out to be insufficient on its own:
|
|
87
|
-
* a LATER valid envelope in the same or a later batch would still
|
|
88
|
-
* silently advance the durable cursor PAST this seq once its own handler
|
|
89
|
-
* succeeded, since nothing had told `ConnectionManager` this seq needed
|
|
90
|
-
* the same stall treatment a thrown handler failure already gets — an
|
|
91
|
-
* INDIRECT permanent ack, one hop removed from the exact bug F1 set out
|
|
92
|
-
* to fix. `ConnectionManager` (`noteValidationFailure`) engages
|
|
93
|
-
* `stalledAtSeq` for this seq the same way `process()`'s own catch block
|
|
94
|
-
* does for a real thrown handler — freezing `dedupWatermark()` at the
|
|
95
|
-
* durable cursor (so the server's retain-and-redeliver semantics,
|
|
96
|
-
* protocol §9, keep this seq alive) and, via that SAME existing
|
|
97
|
-
* machinery, holding back the cursor for anything else delivered after it
|
|
98
|
-
* in the same batch too, exactly as a real handler failure already would.
|
|
99
|
-
* Optional only for constructor/test convenience — `ConnectionManager`
|
|
100
|
-
* always supplies it.
|
|
52
|
+
/** Unknown or malformed executable messages have no durable disposition.
|
|
53
|
+
* Freeze their sequence; a later valid message must not acknowledge them.
|
|
101
54
|
*/
|
|
102
55
|
onValidationFailedSeq?: (seq: number) => void;
|
|
103
56
|
/**
|
|
@@ -114,7 +67,7 @@ export interface LongPollClientOptions {
|
|
|
114
67
|
* `ConnectionManager` always supplies it.
|
|
115
68
|
*/
|
|
116
69
|
isStalled?: () => boolean;
|
|
117
|
-
/** Backoff between failed poll attempts (network/HTTP errors),
|
|
70
|
+
/** Backoff between failed poll attempts (network/HTTP errors), stalled cycles, and duplicate-only cycles that made no cursor progress. The reference server holds a genuinely idle request open ~50s itself (protocol §8). Default 2s. */
|
|
118
71
|
retryDelayMs?: number;
|
|
119
72
|
/** Deterministic delay authority for automatic failed/stalled cycles. */
|
|
120
73
|
retryDelayForAttempt?: (attempt: number, baseDelayMs: number) => number;
|
|
@@ -128,24 +81,29 @@ export interface LongPollClientOptions {
|
|
|
128
81
|
*/
|
|
129
82
|
idleDelayMs?: number;
|
|
130
83
|
}
|
|
84
|
+
/** A fully-read frozen-v1 count acknowledgement for the batch that was posted. */
|
|
85
|
+
export interface MessageBatchPostResult {
|
|
86
|
+
readonly accepted: number;
|
|
87
|
+
readonly rejected?: number;
|
|
88
|
+
}
|
|
131
89
|
/**
|
|
132
|
-
* Protocol §8 long-poll
|
|
133
|
-
*
|
|
134
|
-
*
|
|
135
|
-
*
|
|
136
|
-
* see docs/protocol.md §8).
|
|
90
|
+
* Protocol §8 long-poll transport: `GET /byok/events?cursor=N` in a loop,
|
|
91
|
+
* plus `POST /byok/messages` for the daemon's own outbound envelopes
|
|
92
|
+
* (finding F6 — long-poll is a full transport, not receive-only: see
|
|
93
|
+
* docs/protocol.md §8).
|
|
137
94
|
*
|
|
138
|
-
* Design B (finding N4): this is a stateless drainer
|
|
139
|
-
*
|
|
140
|
-
* `
|
|
141
|
-
*
|
|
142
|
-
*
|
|
143
|
-
*
|
|
144
|
-
* currently active) lives in the caller (`ConnectionManager.drainOutbox`).
|
|
95
|
+
* Design B (finding N4): this is a stateless drainer; it holds no outbound
|
|
96
|
+
* queue of its own. `ConnectionManager` owns the single shared outbox;
|
|
97
|
+
* `postBatch` is a single POST attempt, reporting only frozen-v1 accepted and
|
|
98
|
+
* rejected counts after its response body has been read and validated. All
|
|
99
|
+
* retry/backoff and rejection isolation policy lives in the caller
|
|
100
|
+
* (`ConnectionManager.drainOutbox`).
|
|
145
101
|
*/
|
|
146
102
|
export declare class LongPollClient {
|
|
147
103
|
private readonly opts;
|
|
148
104
|
private running;
|
|
105
|
+
/** Owns exactly one active loop generation, including its held GET and retry delays. */
|
|
106
|
+
private loopAbortController;
|
|
149
107
|
/**
|
|
150
108
|
* Finding R1: seqs this loop has already `console.warn`'d about for a
|
|
151
109
|
* validation-failed (recognized-type, invalid-payload) entry — a poison
|
|
@@ -204,8 +162,8 @@ export declare class LongPollClient {
|
|
|
204
162
|
* (`ConnectionHub.handleInbound`), so a resend of the SAME batch (same
|
|
205
163
|
* envelope `id`s — the caller must never rebuild them) is deduped
|
|
206
164
|
* server-side into a safe no-op rather than reprocessed (§9). Returns
|
|
207
|
-
*
|
|
165
|
+
* validated frozen-v1 counts only after a readable response body.
|
|
208
166
|
*/
|
|
209
|
-
postBatch(envelopes: Envelope[]): Promise<
|
|
167
|
+
postBatch(envelopes: Envelope[]): Promise<MessageBatchPostResult | undefined>;
|
|
210
168
|
private loop;
|
|
211
169
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type AgentEvent, type BlobRef, type Envelope, type RuntimeInfo, type TaskState } from '@byok-sdk/protocol';
|
|
2
|
-
import type { ConnectionState } from './
|
|
2
|
+
import type { ConnectionState } from './connection-manager';
|
|
3
3
|
/**
|
|
4
4
|
* M3-2a: local observability for the daemon — the seam a CLI (M3-2b) drives a
|
|
5
5
|
* live task feed, a task list, and approve/reject/unpair from, all LOCALLY
|
|
@@ -177,6 +177,15 @@ export type ResultDocumentExtractor = (finalOutput: string, task: ResultDocument
|
|
|
177
177
|
* opt-out pin.
|
|
178
178
|
*/
|
|
179
179
|
export declare const DEFAULT_MAX_TASK_OUTPUT_BYTES: number;
|
|
180
|
+
/**
|
|
181
|
+
* WP0: default number of Attempts allowed to execute concurrently in one
|
|
182
|
+
* canonical Agent home. One — the canonical home is every Agent session's
|
|
183
|
+
* cwd, so a second concurrent Attempt is a second writer of the same
|
|
184
|
+
* `MEMORY.md`, `notes/` and `.git`. Raising it is an explicit host choice
|
|
185
|
+
* (`DaemonConfig.maxConcurrentMutableSessionsPerAgentHome`) that re-enables
|
|
186
|
+
* the 0.12.0 co-writing exposure; there is no implicit fallback to it.
|
|
187
|
+
*/
|
|
188
|
+
export declare const DEFAULT_MAX_CONCURRENT_MUTABLE_SESSIONS_PER_AGENT_HOME = 1;
|
|
180
189
|
export interface TaskRunnerDeps {
|
|
181
190
|
adapters: RuntimeAdapter[];
|
|
182
191
|
runtimeAllowlist?: string[];
|
|
@@ -204,6 +213,13 @@ export interface TaskRunnerDeps {
|
|
|
204
213
|
agentHome?: AgentHomeManager;
|
|
205
214
|
/** Local authority: legacy offers are declined after journal/dedup/cancel precedence. */
|
|
206
215
|
strictAgentOnly?: boolean;
|
|
216
|
+
/**
|
|
217
|
+
* WP0: how many Attempts may execute concurrently in ONE canonical Agent
|
|
218
|
+
* home — see `DaemonConfig.maxConcurrentMutableSessionsPerAgentHome`'s own
|
|
219
|
+
* doc comment (`create-daemon.ts`) for the validated contract. Unset
|
|
220
|
+
* defaults to {@link DEFAULT_MAX_CONCURRENT_MUTABLE_SESSIONS_PER_AGENT_HOME}.
|
|
221
|
+
*/
|
|
222
|
+
maxConcurrentMutableSessionsPerAgentHome?: number;
|
|
207
223
|
/** Exact host-selected policy accepted by `task.offer_for_agent_with_egress`. */
|
|
208
224
|
agentEgressPolicy?: Readonly<AgentEgressPolicy>;
|
|
209
225
|
/** Always-present projection/sanitizer consumer; it defaults to metadata-only. */
|
|
@@ -212,6 +228,8 @@ export interface TaskRunnerDeps {
|
|
|
212
228
|
agentSessionHandoffs?: AgentSessionHandoffStore;
|
|
213
229
|
deviceId: string;
|
|
214
230
|
send: (envelope: Envelope) => void;
|
|
231
|
+
/** Fsync the execution commitment before claim/runtime side effects. */
|
|
232
|
+
beforeClaim?: (taskId: string, runtime: string) => Promise<void>;
|
|
215
233
|
blobClient: BlobResolver;
|
|
216
234
|
batcherOptions?: ProgressBatcherOptions;
|
|
217
235
|
/**
|
|
@@ -314,6 +332,15 @@ export interface TaskRunnerDeps {
|
|
|
314
332
|
* interface (`shutdownInterruptTimeoutMs`, `approvalTimeoutMs`).
|
|
315
333
|
*/
|
|
316
334
|
maxTaskOutputBytes?: number;
|
|
335
|
+
/**
|
|
336
|
+
* Per-event inline ceiling for `tool_use.input` / `tool_result.output` —
|
|
337
|
+
* see `DaemonConfig.maxInlineEventBytes` (`create-daemon.ts`) for the full
|
|
338
|
+
* contract and {@link DEFAULT_MAX_INLINE_EVENT_BYTES} for the default.
|
|
339
|
+
* Validated (positive safe integer, at least
|
|
340
|
+
* `MIN_MAX_INLINE_EVENT_BYTES`) at the `DaemonConfig` layer, not here —
|
|
341
|
+
* this seam trusts its caller, same as `maxTaskOutputBytes` above.
|
|
342
|
+
*/
|
|
343
|
+
maxInlineEventBytes?: number;
|
|
317
344
|
/**
|
|
318
345
|
* M4 (additive-minor, `task.approval_resolved`): the capabilities advertised
|
|
319
346
|
* by the CURRENT transport's server (`conn.ack` on WS, the latest successful
|
|
@@ -553,6 +580,10 @@ export declare class TaskRunner {
|
|
|
553
580
|
usesAgentEgress(taskId: string): boolean;
|
|
554
581
|
/** M5 batch-3 (workstream 2): effective `maxTaskOutputBytes` cap for this daemon — see {@link DEFAULT_MAX_TASK_OUTPUT_BYTES}'s own doc comment. */
|
|
555
582
|
private get maxTaskOutputBytes();
|
|
583
|
+
/** Effective per-event inline ceiling for this daemon — see `DaemonConfig.maxInlineEventBytes`. */
|
|
584
|
+
private get maxInlineEventBytes();
|
|
585
|
+
/** WP0: effective per-canonical-Agent-home Attempt cap — see {@link DEFAULT_MAX_CONCURRENT_MUTABLE_SESSIONS_PER_AGENT_HOME}. */
|
|
586
|
+
private get maxConcurrentMutableSessionsPerAgentHome();
|
|
556
587
|
/**
|
|
557
588
|
* M4 Phase 4 (part B.3, observability): per-active-task queue watermarks
|
|
558
589
|
* for the control socket's `status` result — see
|
|
@@ -191,6 +191,15 @@ export declare class LocalTeamWorkspace {
|
|
|
191
191
|
expiresAt: string;
|
|
192
192
|
}>>;
|
|
193
193
|
postMessage(input: TeamPostMessageInput): Promise<TeamMessageAcceptedReceipt>;
|
|
194
|
+
/** Metadata-only operator notification view. Never advances delivery or acknowledgement. */
|
|
195
|
+
notificationSnapshot(input: TeamReadMessagesInput): Promise<{
|
|
196
|
+
workspaceId: string;
|
|
197
|
+
memberId: string;
|
|
198
|
+
registryRevision: TeamWorkspaceRevision;
|
|
199
|
+
expiresAt: string;
|
|
200
|
+
acknowledgedThroughSeq: number;
|
|
201
|
+
latestPeerSeq: number | null;
|
|
202
|
+
}>;
|
|
194
203
|
readMessages(input: TeamReadMessagesInput): Promise<TeamReadMessagesResult>;
|
|
195
204
|
ackMessages(input: TeamAckMessagesInput): Promise<TeamAckReceipt>;
|
|
196
205
|
private resolveLease;
|
package/dist/daemon/url.d.ts
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
/** Normalize a configured `serverUrl` (
|
|
1
|
+
/** Normalize a configured HTTP(S) `serverUrl` (any path) to a base with no path/query. */
|
|
2
2
|
export declare function toHttpBase(serverUrl: string): string;
|
|
3
|
-
/** Derive the `/byok/ws` WebSocket URL from a configured `serverUrl`. */
|
|
4
|
-
export declare function toWsUrl(serverUrl: string): string;
|
|
5
3
|
/**
|
|
6
4
|
* Which route a transport diagnostic is about, in the only two fields that
|
|
7
5
|
* are safe to keep: the host (with port) and the path.
|
|
@@ -15,7 +13,7 @@ export declare function toWsUrl(serverUrl: string): string;
|
|
|
15
13
|
* by formatting a raw URL of its own.
|
|
16
14
|
*/
|
|
17
15
|
export interface TransportEndpoint {
|
|
18
|
-
readonly transport: '
|
|
16
|
+
readonly transport: 'long-poll';
|
|
19
17
|
/** `URL.host` — hostname plus port when non-default. Never userinfo. */
|
|
20
18
|
readonly host: string;
|
|
21
19
|
/** `URL.pathname` — no query, no fragment. */
|
|
@@ -43,7 +41,7 @@ export declare class InsecureServerUrlError extends Error {
|
|
|
43
41
|
}
|
|
44
42
|
export interface AssertServerUrlAllowedOptions {
|
|
45
43
|
/**
|
|
46
|
-
* Explicit escape hatch: when `true`,
|
|
44
|
+
* Explicit escape hatch: when `true`, an `http:` `serverUrl` whose
|
|
47
45
|
* host is NOT loopback is allowed through instead of throwing. Does
|
|
48
46
|
* nothing for an unsupported scheme (see {@link assertServerUrlAllowed}'s
|
|
49
47
|
* own doc comment) — that rejection is unconditional. Threaded from
|
|
@@ -57,25 +55,25 @@ export interface AssertServerUrlAllowedOptions {
|
|
|
57
55
|
}
|
|
58
56
|
/**
|
|
59
57
|
* M5: transport-security gate for a configured `serverUrl` — refuses
|
|
60
|
-
* plaintext (`
|
|
58
|
+
* plaintext (`http:`) transport to any non-loopback host, so a device
|
|
61
59
|
* can never be talked into pairing with (and sending its pairing code /
|
|
62
60
|
* device credentials to) a remote host in the clear. Call this ONCE at each
|
|
63
61
|
* real entry point a raw, operator-supplied `serverUrl` first enters the
|
|
64
62
|
* client (`create-daemon.ts`'s `pair()`/`start()`) rather than inside
|
|
65
|
-
* `toHttpBase
|
|
66
|
-
*
|
|
63
|
+
* `toHttpBase` itself: long-poll and blob-client both read `serverUrl` from
|
|
64
|
+
* that same `DaemonConfig`, never
|
|
67
65
|
* an independently-supplied URL of their own, so those two call sites are
|
|
68
66
|
* already the single common path every one of them goes through.
|
|
69
67
|
*
|
|
70
68
|
* Rules, checked in order:
|
|
71
|
-
* - `https
|
|
69
|
+
* - `https:` — always allowed, any host (TLS is the actual
|
|
72
70
|
* plaintext-network defense; this gate has nothing further to add there).
|
|
73
|
-
* - `http
|
|
71
|
+
* - `http:` — allowed only when the hostname is loopback: exactly
|
|
74
72
|
* `localhost` or any `*.localhost` subdomain, an IPv4 literal in
|
|
75
73
|
* `127.0.0.0/8`, or the IPv6 loopback `::1` — see {@link isLoopbackHostname}.
|
|
76
|
-
* - `http
|
|
74
|
+
* - `http:` to any other host — refused with a clear, typed
|
|
77
75
|
* {@link InsecureServerUrlError} naming the redacted scheme/host/path and the fix
|
|
78
|
-
* (use `
|
|
76
|
+
* (use `https:`, or pass `dangerouslyAllowInsecureRemote: true` if
|
|
79
77
|
* this is a deliberate, understood exception) — UNLESS
|
|
80
78
|
* `opts.dangerouslyAllowInsecureRemote` is `true`.
|
|
81
79
|
* - Any other scheme (or a `serverUrl` that fails to parse as a URL at
|
|
@@ -28,7 +28,7 @@ export interface SupportBundle {
|
|
|
28
28
|
status: 'online';
|
|
29
29
|
pid: number;
|
|
30
30
|
uptimeMs: number;
|
|
31
|
-
transport: 'connecting' | 'open' | 'closed' | '
|
|
31
|
+
transport: 'connecting' | 'open' | 'closed' | 'revoked' | 'unavailable';
|
|
32
32
|
activeTaskCount: number;
|
|
33
33
|
pendingApprovalCount: number;
|
|
34
34
|
operationalHealth: {
|
package/dist/index.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ export type { AgentRef } from './agent-home';
|
|
|
3
3
|
export { AgentHomeError, AgentRefValidationError, AgentHomeResolutionError, AgentHomeCollisionError, AgentHomeBusyError, AgentHomeLeaseCorruptError, AgentHomeLayout, AgentHomeLeaseManager, AgentHomeManager, createAgentHomeProjection, createAgentHomeProjectionConsumer, AGENT_HOME_PROJECTION_STATE_FILE, stableAgentHomeOwnerId, validateAgentRef, } from './agent-home';
|
|
4
4
|
export { AgentSessionHandoffStore, AgentSessionHandoffStoreError, AgentSessionHandoffCorruptError, AgentSessionHandoffMismatchError, } from './daemon/agent-session-handoff-store';
|
|
5
5
|
export type { AgentSessionHandoff, AgentSessionHandoffMatch, AgentTaskTerminalEvidence, AgentTaskTerminalMatch, AgentTerminalCause, } from './daemon/agent-session-handoff-store';
|
|
6
|
-
export type { AgentHomeResolution, AgentHomeProjection, AgentHomeProjectionInput, AgentHomeProjectionApplyInput, AgentHomeProjectionFunction, AgentHomeProjectionApplyFunction, AgentHomeLease, AgentHomeBinding, AgentHomeExecutionLease, AgentHomeExecutionBinding, } from './agent-home';
|
|
6
|
+
export type { AgentHomeResolution, AgentHomeProjection, AgentHomeProjectionInput, AgentHomeProjectionApplyInput, AgentHomeProjectionFunction, AgentHomeProjectionApplyFunction, AgentHomeLease, AgentHomeBinding, AgentHomeExecutionLease, AgentHomeExecutionBinding, AgentHomeExecutionStatus, } from './agent-home';
|
|
7
7
|
export { localStateRelocation, LocalStateRelocationError, LocalStateRelocationBusyError, LocalStateRelocationIntegrityError, } from './local-state-relocation';
|
|
8
8
|
export type { LocalStateRelocationInput, LocalStateRelocationLease, } from './local-state-relocation';
|
|
9
9
|
export { PolicyUnsupportedError, SteerUnsupportedError, freezeRuntimeAdapterDescriptor, sealRuntimeOperationManifest } from './types';
|
|
@@ -61,7 +61,7 @@ export { SKILL_PACKS_CAPABILITY, SKILL_PACKS_DIRNAME, SKILL_PACK_AUDIT_FILENAME,
|
|
|
61
61
|
export type { InstallSkillPacksOptions, InstalledSkillPack, ProjectedSkillPack, SkillPackInstallErrorCode, SkillPackInstallResult, SkillPackLock, } from './daemon/skill-pack-installer';
|
|
62
62
|
export { TruthMemoryClient, TruthMemoryClientError } from './daemon/truth-memory-client';
|
|
63
63
|
export type { LocalMemoryFilter, MemorySelector, TruthManifestQueryInput, TruthManifestRecord, TruthMemoryClientErrorCode, TruthMemoryClientOptions, TruthMemoryMetric, TruthSnapshotCandidateInput, TruthSnapshotWriteInput, TruthTerminalWriteInput, TruthWriteBody, TruthWriteResult, VerifiedTruthRecord, } from './daemon/truth-memory-client';
|
|
64
|
-
export type { ConnectionState } from './daemon/
|
|
64
|
+
export type { ConnectionState } from './daemon/connection-manager';
|
|
65
65
|
export { ReplayCursorTooOldError } from './daemon/replay-cursor';
|
|
66
66
|
export { BlobClient, BlobRequestAbortedError } from './daemon/blob-client';
|
|
67
67
|
export type { BlobClientOptions, BlobRequestAbortReason, BlobRequestOptions, BlobResolver } from './daemon/blob-client';
|