@cydm/happy-elves 0.1.0-beta.36 → 0.1.0-beta.38
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/apps/cli/dist/commands/lib/bootstrap-daemon.d.ts +2 -2
- package/apps/cli/dist/commands/lib/index.d.ts +2 -2
- package/apps/cli/dist/commands/lib/json.d.ts +1 -1
- package/apps/cli/dist/commands/lib/relay-http.d.ts +1 -1
- package/apps/cli/dist/commands/lib/scope.d.ts +1 -1
- package/apps/cli/dist/commands/lib/session-output.d.ts +2 -1
- package/apps/cli/dist/commands/lib/session-output.js +3 -0
- package/apps/cli/dist/commands/lib/session-view.d.ts +2 -2
- package/apps/cli/dist/commands/lib/types.d.ts +2 -2
- package/apps/cli/dist/commands/lib/workspace.d.ts +2 -2
- package/apps/cli/dist/commands/session.js +37 -1
- package/apps/daemon/dist/relay/devtools.d.ts +1 -1
- package/apps/daemon/dist/relay/send.d.ts +2 -2
- package/apps/daemon/dist/relay/send.js +1 -0
- package/apps/daemon/dist/relay-http.d.ts +1 -1
- package/apps/daemon/dist/runtime/external-provider.d.ts +1 -1
- package/apps/daemon/dist/runtime.d.ts +1 -2
- package/apps/daemon/dist/runtime.js +0 -3
- package/apps/daemon/dist/session/create-session.d.ts +1 -1
- package/apps/daemon/dist/session/directory.d.ts +1 -1
- package/apps/daemon/dist/session/events.d.ts +15 -2
- package/apps/daemon/dist/session/events.js +45 -2
- package/apps/daemon/dist/session/file-preview.d.ts +1 -1
- package/apps/daemon/dist/session/lifecycle.d.ts +5 -1
- package/apps/daemon/dist/session/lifecycle.js +51 -7
- package/apps/daemon/dist/session/metadata.d.ts +1 -1
- package/apps/daemon/dist/session/metadata.js +28 -0
- package/apps/daemon/dist/session/primitives.d.ts +1 -1
- package/apps/daemon/dist/session/primitives.js +22 -3
- package/apps/daemon/dist/session/prompt.d.ts +1 -1
- package/apps/daemon/dist/session/prompt.js +2 -0
- package/apps/daemon/dist/session/runtime-handle.d.ts +1 -1
- package/apps/daemon/dist/state.d.ts +2 -2
- package/apps/daemon/dist/types.d.ts +9 -1
- package/apps/daemon/package.json +3 -25
- package/apps/relay/dist/connections.d.ts +2 -0
- package/apps/relay/dist/controller-handlers.d.ts +7 -2
- package/apps/relay/dist/controller-handlers.js +45 -4
- package/apps/relay/dist/db.js +8 -0
- package/apps/relay/dist/index.js +2 -0
- package/apps/relay/dist/machine-handlers.d.ts +2 -1
- package/apps/relay/dist/machine-handlers.js +235 -9
- package/apps/relay/dist/projections.d.ts +1 -1
- package/apps/relay/dist/projections.js +13 -0
- package/apps/relay/dist/relay-context.d.ts +7 -2
- package/apps/relay/dist/relay-context.js +68 -18
- package/apps/relay/dist/repositories.d.ts +2 -2
- package/apps/relay/dist/scope.d.ts +1 -1
- package/apps/relay/dist/types.d.ts +5 -1
- package/package.json +2 -10
- package/packages/client/dist/account.d.ts +1 -1
- package/packages/client/dist/client.d.ts +2 -2
- package/packages/client/dist/parsers.d.ts +1 -1
- package/packages/client/dist/transport.d.ts +1 -1
- package/packages/client/dist/types.d.ts +1 -1
- package/packages/client/dist/validation.d.ts +1 -1
- package/packages/runtime-acpx/dist/index.d.ts +1 -1
- package/packages/runtime-cli/dist/claude-history.d.ts +1 -2
- package/packages/runtime-cli/dist/claude-history.js +0 -3
- package/packages/runtime-cli/dist/claude-session-store.d.ts +0 -1
- package/packages/runtime-cli/dist/claude-session-store.js +1 -1
- package/packages/runtime-cli/dist/claude-turn.d.ts +1 -1
- package/packages/runtime-cli/dist/codex-app-server.d.ts +1 -1
- package/packages/runtime-cli/dist/codex-history.d.ts +1 -2
- package/packages/runtime-cli/dist/codex-history.js +0 -3
- package/packages/runtime-cli/dist/history-merge.d.ts +1 -1
- package/packages/runtime-cli/dist/index.d.ts +1 -1
- package/packages/runtime-cli/dist/permissions.d.ts +1 -1
- package/packages/runtime-cli/dist/session-store.d.ts +1 -1
- package/packages/shared/dist/protocol-schemas.d.ts +6 -0
- package/packages/shared/dist/protocol-schemas.js +6 -0
- package/packages/shared/dist/protocol-types.d.ts +11 -3
- package/packages/shared/dist/protocol.d.ts +14 -2
- package/packages/shared/dist/protocol.js +23 -0
- package/apps/cli/dist/commands/account.js.map +0 -1
- package/apps/cli/dist/commands/app.js.map +0 -1
- package/apps/cli/dist/commands/collect.js.map +0 -1
- package/apps/cli/dist/commands/command.js.map +0 -1
- package/apps/cli/dist/commands/config.js.map +0 -1
- package/apps/cli/dist/commands/daemon.js.map +0 -1
- package/apps/cli/dist/commands/lib/args.js.map +0 -1
- package/apps/cli/dist/commands/lib/audit.js.map +0 -1
- package/apps/cli/dist/commands/lib/bootstrap-config.js.map +0 -1
- package/apps/cli/dist/commands/lib/bootstrap-daemon.js.map +0 -1
- package/apps/cli/dist/commands/lib/bootstrap-output.js.map +0 -1
- package/apps/cli/dist/commands/lib/bootstrap.js.map +0 -1
- package/apps/cli/dist/commands/lib/config.js.map +0 -1
- package/apps/cli/dist/commands/lib/doctor.js.map +0 -1
- package/apps/cli/dist/commands/lib/exit.js.map +0 -1
- package/apps/cli/dist/commands/lib/index.js.map +0 -1
- package/apps/cli/dist/commands/lib/json.js.map +0 -1
- package/apps/cli/dist/commands/lib/local-daemon.js.map +0 -1
- package/apps/cli/dist/commands/lib/loop-store.js.map +0 -1
- package/apps/cli/dist/commands/lib/paths.js.map +0 -1
- package/apps/cli/dist/commands/lib/relay-http.js.map +0 -1
- package/apps/cli/dist/commands/lib/scope.js.map +0 -1
- package/apps/cli/dist/commands/lib/session-output.js.map +0 -1
- package/apps/cli/dist/commands/lib/session-view.js.map +0 -1
- package/apps/cli/dist/commands/lib/status.js.map +0 -1
- package/apps/cli/dist/commands/lib/types.js.map +0 -1
- package/apps/cli/dist/commands/lib/usage.js.map +0 -1
- package/apps/cli/dist/commands/lib/workspace.js.map +0 -1
- package/apps/cli/dist/commands/loop.js.map +0 -1
- package/apps/cli/dist/commands/machine.js.map +0 -1
- package/apps/cli/dist/commands/relay.js.map +0 -1
- package/apps/cli/dist/commands/remote.js.map +0 -1
- package/apps/cli/dist/commands/session.js.map +0 -1
- package/apps/cli/dist/commands/token.js.map +0 -1
- package/apps/cli/dist/commands/turn.js.map +0 -1
- package/apps/cli/dist/errors.js.map +0 -1
- package/apps/cli/dist/index.js.map +0 -1
- package/apps/daemon/dist/app.js.map +0 -1
- package/apps/daemon/dist/args.js.map +0 -1
- package/apps/daemon/dist/audit.js.map +0 -1
- package/apps/daemon/dist/cli.js.map +0 -1
- package/apps/daemon/dist/config.js.map +0 -1
- package/apps/daemon/dist/errors.js.map +0 -1
- package/apps/daemon/dist/loop/runner.js.map +0 -1
- package/apps/daemon/dist/loop/store.js.map +0 -1
- package/apps/daemon/dist/pair.js.map +0 -1
- package/apps/daemon/dist/paths.js.map +0 -1
- package/apps/daemon/dist/process.js.map +0 -1
- package/apps/daemon/dist/relay/connection.js.map +0 -1
- package/apps/daemon/dist/relay/devtools.js.map +0 -1
- package/apps/daemon/dist/relay/register.js.map +0 -1
- package/apps/daemon/dist/relay/send.js.map +0 -1
- package/apps/daemon/dist/relay-http.js.map +0 -1
- package/apps/daemon/dist/runtime/external-provider.js.map +0 -1
- package/apps/daemon/dist/runtime.js.map +0 -1
- package/apps/daemon/dist/session/create-session.js.map +0 -1
- package/apps/daemon/dist/session/directory.js.map +0 -1
- package/apps/daemon/dist/session/events.js.map +0 -1
- package/apps/daemon/dist/session/file-preview.js.map +0 -1
- package/apps/daemon/dist/session/lifecycle.js.map +0 -1
- package/apps/daemon/dist/session/metadata.js.map +0 -1
- package/apps/daemon/dist/session/primitives.js.map +0 -1
- package/apps/daemon/dist/session/prompt.js.map +0 -1
- package/apps/daemon/dist/session/runtime-handle.js.map +0 -1
- package/apps/daemon/dist/start.js.map +0 -1
- package/apps/daemon/dist/state.js.map +0 -1
- package/apps/daemon/dist/turn-coordinator.js.map +0 -1
- package/apps/daemon/dist/types.js.map +0 -1
- package/apps/daemon/dist/utils.js.map +0 -1
- package/apps/relay/dist/auth.js.map +0 -1
- package/apps/relay/dist/connections.js.map +0 -1
- package/apps/relay/dist/controller-handlers.js.map +0 -1
- package/apps/relay/dist/db.js.map +0 -1
- package/apps/relay/dist/errors.js.map +0 -1
- package/apps/relay/dist/http-routes.js.map +0 -1
- package/apps/relay/dist/http-schemas.js.map +0 -1
- package/apps/relay/dist/index.js.map +0 -1
- package/apps/relay/dist/machine-handlers.js.map +0 -1
- package/apps/relay/dist/projections.js.map +0 -1
- package/apps/relay/dist/relay-context.js.map +0 -1
- package/apps/relay/dist/repositories.js.map +0 -1
- package/apps/relay/dist/retention.js.map +0 -1
- package/apps/relay/dist/scope.js.map +0 -1
- package/apps/relay/dist/security.js.map +0 -1
- package/apps/relay/dist/types.js.map +0 -1
- package/apps/relay/dist/websocket.js.map +0 -1
- package/apps/relay/package.json +0 -29
- package/packages/agent-sdk/dist/index.d.ts.map +0 -1
- package/packages/agent-sdk/dist/index.js.map +0 -1
- package/packages/agent-sdk/package.json +0 -20
- package/packages/client/dist/account.d.ts.map +0 -1
- package/packages/client/dist/account.js.map +0 -1
- package/packages/client/dist/client.d.ts.map +0 -1
- package/packages/client/dist/client.js.map +0 -1
- package/packages/client/dist/errors.d.ts.map +0 -1
- package/packages/client/dist/errors.js.map +0 -1
- package/packages/client/dist/http.d.ts.map +0 -1
- package/packages/client/dist/http.js.map +0 -1
- package/packages/client/dist/index.d.ts.map +0 -1
- package/packages/client/dist/index.js.map +0 -1
- package/packages/client/dist/parsers.d.ts.map +0 -1
- package/packages/client/dist/parsers.js.map +0 -1
- package/packages/client/dist/transport.d.ts.map +0 -1
- package/packages/client/dist/transport.js.map +0 -1
- package/packages/client/dist/types.d.ts.map +0 -1
- package/packages/client/dist/types.js.map +0 -1
- package/packages/client/dist/validation.d.ts.map +0 -1
- package/packages/client/dist/validation.js.map +0 -1
- package/packages/client/package.json +0 -22
- package/packages/pie-provider/dist/index.d.ts.map +0 -1
- package/packages/pie-provider/dist/index.js.map +0 -1
- package/packages/pie-provider/package.json +0 -26
- package/packages/runtime/dist/index.d.ts.map +0 -1
- package/packages/runtime/dist/index.js.map +0 -1
- package/packages/runtime/package.json +0 -19
- package/packages/runtime-acpx/dist/index.d.ts.map +0 -1
- package/packages/runtime-acpx/dist/index.js.map +0 -1
- package/packages/runtime-acpx/package.json +0 -23
- package/packages/runtime-cli/dist/async-queue.d.ts.map +0 -1
- package/packages/runtime-cli/dist/async-queue.js.map +0 -1
- package/packages/runtime-cli/dist/claude-history.d.ts.map +0 -1
- package/packages/runtime-cli/dist/claude-history.js.map +0 -1
- package/packages/runtime-cli/dist/claude-json.d.ts.map +0 -1
- package/packages/runtime-cli/dist/claude-json.js.map +0 -1
- package/packages/runtime-cli/dist/claude-rename.d.ts.map +0 -1
- package/packages/runtime-cli/dist/claude-rename.js.map +0 -1
- package/packages/runtime-cli/dist/claude-session-store.d.ts.map +0 -1
- package/packages/runtime-cli/dist/claude-session-store.js.map +0 -1
- package/packages/runtime-cli/dist/claude-turn.d.ts.map +0 -1
- package/packages/runtime-cli/dist/claude-turn.js.map +0 -1
- package/packages/runtime-cli/dist/codex-app-server.d.ts.map +0 -1
- package/packages/runtime-cli/dist/codex-app-server.js.map +0 -1
- package/packages/runtime-cli/dist/codex-approvals.d.ts.map +0 -1
- package/packages/runtime-cli/dist/codex-approvals.js.map +0 -1
- package/packages/runtime-cli/dist/codex-history.d.ts.map +0 -1
- package/packages/runtime-cli/dist/codex-history.js.map +0 -1
- package/packages/runtime-cli/dist/codex-json-rpc.d.ts.map +0 -1
- package/packages/runtime-cli/dist/codex-json-rpc.js.map +0 -1
- package/packages/runtime-cli/dist/codex-lifecycle.d.ts.map +0 -1
- package/packages/runtime-cli/dist/codex-lifecycle.js.map +0 -1
- package/packages/runtime-cli/dist/codex-protocol.d.ts.map +0 -1
- package/packages/runtime-cli/dist/codex-protocol.js.map +0 -1
- package/packages/runtime-cli/dist/command-resolver.d.ts.map +0 -1
- package/packages/runtime-cli/dist/command-resolver.js.map +0 -1
- package/packages/runtime-cli/dist/history-merge.d.ts.map +0 -1
- package/packages/runtime-cli/dist/history-merge.js.map +0 -1
- package/packages/runtime-cli/dist/index.d.ts.map +0 -1
- package/packages/runtime-cli/dist/index.js.map +0 -1
- package/packages/runtime-cli/dist/permissions.d.ts.map +0 -1
- package/packages/runtime-cli/dist/permissions.js.map +0 -1
- package/packages/runtime-cli/dist/session-store.d.ts.map +0 -1
- package/packages/runtime-cli/dist/session-store.js.map +0 -1
- package/packages/runtime-cli/package.json +0 -22
- package/packages/shared/dist/args.d.ts.map +0 -1
- package/packages/shared/dist/args.js.map +0 -1
- package/packages/shared/dist/crypto.d.ts.map +0 -1
- package/packages/shared/dist/crypto.js.map +0 -1
- package/packages/shared/dist/ids.d.ts.map +0 -1
- package/packages/shared/dist/ids.js.map +0 -1
- package/packages/shared/dist/index.d.ts.map +0 -1
- package/packages/shared/dist/index.js.map +0 -1
- package/packages/shared/dist/protocol-schemas.d.ts.map +0 -1
- package/packages/shared/dist/protocol-schemas.js.map +0 -1
- package/packages/shared/dist/protocol-types.d.ts.map +0 -1
- package/packages/shared/dist/protocol-types.js.map +0 -1
- package/packages/shared/dist/protocol.d.ts.map +0 -1
- package/packages/shared/dist/protocol.js.map +0 -1
- package/packages/shared/dist/session-name.d.ts.map +0 -1
- package/packages/shared/dist/session-name.js.map +0 -1
- package/packages/shared/dist/session-state.d.ts.map +0 -1
- package/packages/shared/dist/session-state.js.map +0 -1
- package/packages/shared/package.json +0 -24
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { ControllerClient } from "
|
|
2
|
-
import type { MachineSnapshot } from "
|
|
1
|
+
import type { ControllerClient } from "../../../../../packages/client/dist/index.js";
|
|
2
|
+
import type { MachineSnapshot } from "../../../../../packages/shared/dist/index.js";
|
|
3
3
|
import { localDaemonStatus, stopLocalDaemon } from "./local-daemon.js";
|
|
4
4
|
export declare function ensureDaemonRunning(relayUrl: string, cwd?: string): Promise<{
|
|
5
5
|
local: Awaited<ReturnType<typeof localDaemonStatus>>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export { ControllerClient, type ScopedTokenScope } from "
|
|
2
|
-
export { generateAccountSecret, randomId } from "
|
|
1
|
+
export { ControllerClient, type ScopedTokenScope } from "../../../../../packages/client/dist/index.js";
|
|
2
|
+
export { generateAccountSecret, randomId } from "../../../../../packages/shared/dist/index.js";
|
|
3
3
|
export { CliError } from "../../errors.js";
|
|
4
4
|
export * from "./args.js";
|
|
5
5
|
export * from "./audit.js";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { JsonEnvelope } from "
|
|
1
|
+
import type { JsonEnvelope } from "../../../../../packages/shared/dist/index.js";
|
|
2
2
|
export declare function ok<T>(type: string, data: T, meta?: JsonEnvelope["meta"]): void;
|
|
3
3
|
export declare function writeError(code: string, message: string, meta?: JsonEnvelope["meta"], capability?: string): void;
|
|
4
4
|
export declare function wantsJson(flags: Record<string, string | boolean>): boolean;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { PairingClaimResponse, PairingStartResponse } from "
|
|
1
|
+
import type { PairingClaimResponse, PairingStartResponse } from "../../../../../packages/shared/dist/index.js";
|
|
2
2
|
import { CliError } from "../../errors.js";
|
|
3
3
|
import type { CliConfig, DaemonConfig } from "./types.js";
|
|
4
4
|
export declare function relayHealth(relayUrl: string): Promise<{
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ControllerClient, ScopedTokenScope } from "
|
|
1
|
+
import type { ControllerClient, ScopedTokenScope } from "../../../../../packages/client/dist/index.js";
|
|
2
2
|
import type { LoopRecord, PermissionMode } from "./types.js";
|
|
3
3
|
export declare const DEFAULT_COMMAND_TIMEOUT_MS: number;
|
|
4
4
|
export declare function parseDurationMs(value: string | boolean | undefined, fallbackMs: number): number;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ControllerClient, DecodedSessionEvent } from "
|
|
1
|
+
import type { ControllerClient, DecodedSessionEvent } from "../../../../../packages/client/dist/index.js";
|
|
2
2
|
export declare function compactText(value: string, max?: number): string;
|
|
3
3
|
export declare function lastAssistantOutput(events: DecodedSessionEvent[]): string;
|
|
4
4
|
export declare function displayPath(filePath: string): string;
|
|
@@ -18,6 +18,7 @@ export type TurnSummary = {
|
|
|
18
18
|
turnId: string;
|
|
19
19
|
checkpointId?: string;
|
|
20
20
|
runtimeTurnId?: string;
|
|
21
|
+
turnSeq?: number;
|
|
21
22
|
status: "running" | "completed" | "failed" | "cancelled";
|
|
22
23
|
prompt: string;
|
|
23
24
|
output: string;
|
|
@@ -160,6 +160,8 @@ export function summarizeTurns(events) {
|
|
|
160
160
|
current.updatedAt = event.createdAt;
|
|
161
161
|
current.lastEventId = event.id;
|
|
162
162
|
current.eventCount += 1;
|
|
163
|
+
if (event.turnSeq !== undefined)
|
|
164
|
+
current.turnSeq = event.turnSeq;
|
|
163
165
|
const payload = event.decoded;
|
|
164
166
|
if (payload?.type === "user_prompt" && payload.text.trim()) {
|
|
165
167
|
current.promptChunks.push(payload.text.trim());
|
|
@@ -181,6 +183,7 @@ export function summarizeTurns(events) {
|
|
|
181
183
|
turnId: turn.turnId,
|
|
182
184
|
checkpointId: turn.checkpointId,
|
|
183
185
|
runtimeTurnId: turn.runtimeTurnId,
|
|
186
|
+
turnSeq: turn.turnSeq,
|
|
184
187
|
status: turn.status,
|
|
185
188
|
prompt: turn.promptChunks.join("\n").trim(),
|
|
186
189
|
output: turn.outputChunks.join("").trim() || turn.terminalText,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { ControllerClient, DecodedSessionEvent } from "
|
|
2
|
-
import type { MachineSnapshot, SessionSnapshot } from "
|
|
1
|
+
import type { ControllerClient, DecodedSessionEvent } from "../../../../../packages/client/dist/index.js";
|
|
2
|
+
import type { MachineSnapshot, SessionSnapshot } from "../../../../../packages/shared/dist/index.js";
|
|
3
3
|
import { type MachineMetadata, type OrchestrationSummary, type OrchestrationState } from "./types.js";
|
|
4
4
|
export declare function showMachine(client: ControllerClient, machine: MachineSnapshot): Promise<MachineSnapshot & {
|
|
5
5
|
defaultCwd?: string;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { ScopedTokenScope } from "
|
|
2
|
-
import type { SessionSnapshot } from "
|
|
1
|
+
import type { ScopedTokenScope } from "../../../../../packages/client/dist/index.js";
|
|
2
|
+
import type { SessionSnapshot } from "../../../../../packages/shared/dist/index.js";
|
|
3
3
|
export type CliConfig = {
|
|
4
4
|
relayUrl: string;
|
|
5
5
|
controllerToken: string;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { ControllerClient } from "
|
|
2
|
-
import type { HistoricalSessionSnapshot } from "
|
|
1
|
+
import type { ControllerClient } from "../../../../../packages/client/dist/index.js";
|
|
2
|
+
import type { HistoricalSessionSnapshot } from "../../../../../packages/shared/dist/index.js";
|
|
3
3
|
export type WorkspaceHistoricalSession = HistoricalSessionSnapshot & {
|
|
4
4
|
machineId: string;
|
|
5
5
|
machineName: string;
|
|
@@ -53,6 +53,7 @@ function compactTurnRef(turn) {
|
|
|
53
53
|
status: turn.status,
|
|
54
54
|
...(turn.prompt ? { promptPreview: compactText(turn.prompt, 180) } : {}),
|
|
55
55
|
time: turn.completedAt ?? turn.updatedAt,
|
|
56
|
+
...(turn.turnSeq !== undefined ? { turnSeq: turn.turnSeq } : {}),
|
|
56
57
|
};
|
|
57
58
|
}
|
|
58
59
|
function countBy(values) {
|
|
@@ -114,6 +115,38 @@ function eventCollectionDiagnostics(events) {
|
|
|
114
115
|
visiblePayloads: events.filter(isVisibleTranscriptPayloadEvent).length,
|
|
115
116
|
};
|
|
116
117
|
}
|
|
118
|
+
function headMatchesTurn(session, turn) {
|
|
119
|
+
if (!turn)
|
|
120
|
+
return false;
|
|
121
|
+
const turnHeads = new Set([
|
|
122
|
+
turn.checkpointId,
|
|
123
|
+
turn.runtimeTurnId,
|
|
124
|
+
turn.turnId,
|
|
125
|
+
].filter((value) => typeof value === "string" && value.length > 0));
|
|
126
|
+
if (session.currentHead?.startsWith("event:")) {
|
|
127
|
+
const eventId = Number(/^event:(\d+)$/.exec(session.currentHead)?.[1]);
|
|
128
|
+
if (Number.isFinite(eventId) && eventId >= turn.firstEventId && eventId <= turn.lastEventId)
|
|
129
|
+
return true;
|
|
130
|
+
}
|
|
131
|
+
return (session.currentHead !== undefined && turnHeads.has(session.currentHead)) ||
|
|
132
|
+
(session.lastTurnId !== undefined && turnHeads.has(session.lastTurnId));
|
|
133
|
+
}
|
|
134
|
+
function staleHeadSuspected(session, latestCompletedTurn) {
|
|
135
|
+
if (!latestCompletedTurn)
|
|
136
|
+
return false;
|
|
137
|
+
if (headMatchesTurn(session, latestCompletedTurn))
|
|
138
|
+
return false;
|
|
139
|
+
const basisTime = session.headBasis?.logicalTime;
|
|
140
|
+
const latestTime = latestCompletedTurn.completedAt ?? latestCompletedTurn.updatedAt;
|
|
141
|
+
if (basisTime !== undefined) {
|
|
142
|
+
if (latestTime !== basisTime)
|
|
143
|
+
return latestTime > basisTime;
|
|
144
|
+
if (session.headBasis?.turnSeq !== undefined && latestCompletedTurn.turnSeq !== undefined) {
|
|
145
|
+
return latestCompletedTurn.turnSeq > session.headBasis.turnSeq;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
return Boolean(session.currentHead || session.lastTurnId);
|
|
149
|
+
}
|
|
117
150
|
function stringMetadata(metadata, key) {
|
|
118
151
|
const value = metadata[key];
|
|
119
152
|
return typeof value === "string" ? value : undefined;
|
|
@@ -318,6 +351,7 @@ export async function handleSession({ domain, action, positional, flags }) {
|
|
|
318
351
|
historyModel: session.historyModel ?? "append-only",
|
|
319
352
|
currentHead: session.currentHead,
|
|
320
353
|
lastTurnId: session.lastTurnId,
|
|
354
|
+
headBasis: session.headBasis,
|
|
321
355
|
sourceSessionId: session.sourceSessionId,
|
|
322
356
|
sourceCheckpointId: session.sourceCheckpointId,
|
|
323
357
|
updatedAt: session.updatedAt,
|
|
@@ -358,6 +392,8 @@ export async function handleSession({ domain, action, positional, flags }) {
|
|
|
358
392
|
backfillAvailableEvents: numberMetadata(metadata, "availableHistoricalEvents"),
|
|
359
393
|
backfillEmittedEvents: numberMetadata(metadata, "backfilledEvents"),
|
|
360
394
|
backfillStatus: stringMetadata(metadata, "historicalBackfillStatus") ?? stringMetadata(metadata, "historicalBackfill"),
|
|
395
|
+
staleHeadSuspected: staleHeadSuspected(session, latestCompletedTurn),
|
|
396
|
+
headMatchesLatestCompletedTurn: headMatchesTurn(session, latestCompletedTurn),
|
|
361
397
|
},
|
|
362
398
|
};
|
|
363
399
|
if (wantsJson(flags) || wantsVerbose(flags)) {
|
|
@@ -369,8 +405,8 @@ export async function handleSession({ domain, action, positional, flags }) {
|
|
|
369
405
|
const runtime = isRecord(metadata.runtime) ? metadata.runtime : {};
|
|
370
406
|
console.log(`Runtime: ${stringMetadata(metadata, "importedFromRuntimeSessionId") ?? stringMetadata(runtime, "backendSessionId") ?? stringMetadata(runtime, "agentSessionId") ?? "-"}`);
|
|
371
407
|
console.log(`Backfill: ${data.diagnosis.backfillStatus ?? "-"} available=${data.diagnosis.backfillAvailableEvents ?? "-"} emitted=${data.diagnosis.backfillEmittedEvents ?? "-"}`);
|
|
408
|
+
console.log(`Head: ${session.currentHead ?? "-"} lastTurn=${session.lastTurnId ?? "-"} stale=${data.diagnosis.staleHeadSuspected ? "yes" : "no"}`);
|
|
372
409
|
console.log(`Latest page: ${latestPage.events.length} events, visible=${latestPage.events.filter(isVisibleTranscriptPayloadEvent).length}, hasMore=${latestPage.hasMoreBefore}`);
|
|
373
|
-
console.log(`Head: ${session.currentHead ?? "-"} lastTurn: ${session.lastTurnId ?? "-"}`);
|
|
374
410
|
}
|
|
375
411
|
return true;
|
|
376
412
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { MachineCommand } from "
|
|
1
|
+
import type { MachineCommand } from "../../../../packages/shared/dist/index.js";
|
|
2
2
|
import type { DaemonConfig } from "../types.js";
|
|
3
3
|
export declare function handleDiagnose(ws: WebSocket, config: DaemonConfig, command: MachineCommand): Promise<void>;
|
|
4
4
|
export declare function handleDevExec(ws: WebSocket, config: DaemonConfig, command: MachineCommand): Promise<void>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { MachineClientMessage } from "
|
|
2
|
-
import type { RuntimeTurn } from "
|
|
1
|
+
import type { MachineClientMessage } from "../../../../packages/shared/dist/index.js";
|
|
2
|
+
import type { RuntimeTurn } from "../../../../packages/runtime/dist/index.js";
|
|
3
3
|
import type { DaemonConfig } from "../types.js";
|
|
4
4
|
export declare function send(ws: WebSocket, message: unknown): void;
|
|
5
5
|
export declare function configureRelaySender(config: DaemonConfig): void;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type PairingClaimResponse, type ServerMessage } from "
|
|
1
|
+
import { type PairingClaimResponse, type ServerMessage } from "../../../packages/shared/dist/index.js";
|
|
2
2
|
import { DaemonCliError } from "./errors.js";
|
|
3
3
|
export declare function relayHttpError(response: Response, fallback: string): Promise<DaemonCliError>;
|
|
4
4
|
export declare function readRelayJson(response: Response, fallback: string): Promise<unknown>;
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import type { HappyElvesRuntime } from "
|
|
1
|
+
import type { HappyElvesRuntime } from "../../../packages/runtime/dist/index.js";
|
|
2
2
|
import type { PrimitiveSupport } from "./types.js";
|
|
3
3
|
export declare function getRuntime(defaultCwd: string): HappyElvesRuntime;
|
|
4
4
|
export declare function initializeRuntime(defaultCwd: string): Promise<void>;
|
|
5
|
-
export declare function runtimeDiagnostics(): Array<Record<string, unknown>>;
|
|
6
5
|
export declare function disposeRuntime(): void;
|
|
7
6
|
export declare function setRuntimeForTests(runtimeOverride: HappyElvesRuntime | null): void;
|
|
8
7
|
export declare function runtimePrimitiveSupport(runtimeInstance: HappyElvesRuntime): {
|
|
@@ -57,9 +57,6 @@ export async function initializeRuntime(defaultCwd) {
|
|
|
57
57
|
await runtimeInstance.initialize();
|
|
58
58
|
}
|
|
59
59
|
}
|
|
60
|
-
export function runtimeDiagnostics() {
|
|
61
|
-
return runtime?.diagnostics?.() ?? [];
|
|
62
|
-
}
|
|
63
60
|
export function disposeRuntime() {
|
|
64
61
|
runtime?.dispose?.();
|
|
65
62
|
runtime = null;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { MachineClientMessage, MachineCommand } from "
|
|
1
|
+
import type { MachineClientMessage, MachineCommand } from "../../../../packages/shared/dist/index.js";
|
|
2
2
|
type CreateSessionCommand = Extract<MachineCommand, {
|
|
3
3
|
type: "machine:createSession";
|
|
4
4
|
}>;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import type { MachineCommand } from "
|
|
1
|
+
import type { MachineCommand } from "../../../../packages/shared/dist/index.js";
|
|
2
2
|
import type { DaemonConfig } from "../types.js";
|
|
3
3
|
export declare function handleListDirectory(ws: WebSocket, config: DaemonConfig, command: MachineCommand): Promise<void>;
|
|
@@ -1,12 +1,15 @@
|
|
|
1
|
-
import { type EncryptedEnvelope, type SessionEventPayload } from "
|
|
2
|
-
import type { RuntimeEvent, RuntimeHistoricalEvent } from "
|
|
1
|
+
import { type EncryptedEnvelope, type SessionEventPayload, type SessionHeadAdvanceBasis } from "../../../../packages/shared/dist/index.js";
|
|
2
|
+
import type { RuntimeEvent, RuntimeHistoricalEvent } from "../../../../packages/runtime/dist/index.js";
|
|
3
3
|
import type { DaemonConfig } from "../types.js";
|
|
4
4
|
export declare function emitEvent(ws: WebSocket, config: DaemonConfig, sessionId: string, turnId: string, payload: SessionEventPayload): Promise<void>;
|
|
5
5
|
export declare function emitHistoricalEvents(ws: WebSocket, config: DaemonConfig, sessionId: string, events: RuntimeHistoricalEvent[], startIndex?: number): Promise<void>;
|
|
6
6
|
export declare function emitRuntimeTailEvents(ws: WebSocket, config: DaemonConfig, sessionId: string, events: RuntimeHistoricalEvent[], startIndex?: number): Promise<void>;
|
|
7
|
+
export declare function emitSessionHeadAdvanced(ws: WebSocket, sessionId: string, head: HistoricalSessionHead, encryptedMetadata?: EncryptedEnvelope): Promise<void>;
|
|
7
8
|
export declare function emitTranscriptReplacement(ws: WebSocket, config: DaemonConfig, sessionId: string, events: RuntimeHistoricalEvent[], input?: {
|
|
9
|
+
requestId?: string;
|
|
8
10
|
currentHead?: string;
|
|
9
11
|
lastTurnId?: string;
|
|
12
|
+
replacementKind?: "command" | "sync";
|
|
10
13
|
status?: "completed" | "cancelled" | "failed";
|
|
11
14
|
encryptedMetadata?: EncryptedEnvelope;
|
|
12
15
|
hasMoreBefore?: boolean;
|
|
@@ -17,4 +20,14 @@ export declare function emitTranscriptPrepended(ws: WebSocket, config: DaemonCon
|
|
|
17
20
|
hasMoreBefore?: boolean;
|
|
18
21
|
nextBefore?: string;
|
|
19
22
|
}): Promise<void>;
|
|
23
|
+
export type HistoricalSessionHead = {
|
|
24
|
+
currentHead: string;
|
|
25
|
+
lastTurnId: string;
|
|
26
|
+
basis: SessionHeadAdvanceBasis;
|
|
27
|
+
};
|
|
28
|
+
export declare function latestCompletedHistoricalHead(sessionId: string, events: RuntimeHistoricalEvent[], input?: {
|
|
29
|
+
preferTailBasisForExistingEvents?: boolean;
|
|
30
|
+
previousTotalEvents?: number;
|
|
31
|
+
tailStartIndex?: number;
|
|
32
|
+
}): HistoricalSessionHead | undefined;
|
|
20
33
|
export declare function runtimeEventToPayload(event: RuntimeEvent): SessionEventPayload;
|
|
@@ -32,12 +32,27 @@ export async function emitRuntimeTailEvents(ws, config, sessionId, events, start
|
|
|
32
32
|
}, ws);
|
|
33
33
|
}
|
|
34
34
|
}
|
|
35
|
+
export async function emitSessionHeadAdvanced(ws, sessionId, head, encryptedMetadata) {
|
|
36
|
+
await sendReliable({
|
|
37
|
+
type: "machine:sessionHeadAdvanced",
|
|
38
|
+
sessionId,
|
|
39
|
+
currentHead: head.currentHead,
|
|
40
|
+
lastTurnId: head.lastTurnId,
|
|
41
|
+
basis: head.basis,
|
|
42
|
+
encryptedMetadata,
|
|
43
|
+
}, ws);
|
|
44
|
+
}
|
|
35
45
|
export async function emitTranscriptReplacement(ws, config, sessionId, events, input = {}) {
|
|
46
|
+
const head = latestCompletedHistoricalHead(sessionId, events);
|
|
47
|
+
const fallbackHead = transcriptHead(events);
|
|
36
48
|
await sendReliable({
|
|
37
49
|
type: "machine:sessionTranscriptReplaced",
|
|
38
50
|
sessionId,
|
|
39
|
-
|
|
40
|
-
|
|
51
|
+
requestId: input.requestId,
|
|
52
|
+
currentHead: input.currentHead ?? head?.currentHead ?? fallbackHead.currentHead,
|
|
53
|
+
lastTurnId: input.lastTurnId ?? head?.lastTurnId ?? fallbackHead.lastTurnId,
|
|
54
|
+
basis: head?.basis,
|
|
55
|
+
replacementKind: input.replacementKind,
|
|
41
56
|
status: input.status,
|
|
42
57
|
hasMoreBefore: input.hasMoreBefore,
|
|
43
58
|
nextBefore: input.nextBefore,
|
|
@@ -79,6 +94,7 @@ async function encryptedRuntimeTailEvents(config, sessionId, events, startIndex
|
|
|
79
94
|
turnId: event.turnId,
|
|
80
95
|
seq: stableTailSeq,
|
|
81
96
|
messageId: runtimeTailEventMessageId(sessionId, event, stableTailSeq),
|
|
97
|
+
occurredAt: event.occurredAt,
|
|
82
98
|
payload: await encryptJson(config.accountSecret, `event:${sessionId}:${event.turnId}:${stableTailSeq}`, event.payload),
|
|
83
99
|
});
|
|
84
100
|
}
|
|
@@ -98,6 +114,33 @@ function transcriptHead(events) {
|
|
|
98
114
|
}
|
|
99
115
|
return events.at(-1)?.turnId ? { currentHead: events.at(-1)?.turnId, lastTurnId: events.at(-1)?.turnId } : {};
|
|
100
116
|
}
|
|
117
|
+
export function latestCompletedHistoricalHead(sessionId, events, input = {}) {
|
|
118
|
+
for (let index = events.length - 1; index >= 0; index -= 1) {
|
|
119
|
+
const event = events[index];
|
|
120
|
+
if (!event || event.payload.type !== "done" || event.payload.status !== "completed")
|
|
121
|
+
continue;
|
|
122
|
+
const seq = event.seq ?? index + 1;
|
|
123
|
+
const hasRuntimeTailMessageId = (input.tailStartIndex !== undefined && index >= input.tailStartIndex)
|
|
124
|
+
|| (input.previousTotalEvents !== undefined && index >= input.previousTotalEvents)
|
|
125
|
+
|| input.preferTailBasisForExistingEvents === true;
|
|
126
|
+
const eventMessageId = hasRuntimeTailMessageId
|
|
127
|
+
? runtimeTailEventMessageId(sessionId, event, seq)
|
|
128
|
+
: historicalEventMessageId(sessionId, event, seq);
|
|
129
|
+
const currentHead = event.payload.currentHead ?? event.payload.lastTurnId ?? event.turnId;
|
|
130
|
+
const lastTurnId = event.payload.lastTurnId ?? event.payload.currentHead ?? event.turnId;
|
|
131
|
+
return {
|
|
132
|
+
currentHead,
|
|
133
|
+
lastTurnId,
|
|
134
|
+
basis: {
|
|
135
|
+
turnId: event.turnId,
|
|
136
|
+
eventMessageId,
|
|
137
|
+
turnSeq: seq,
|
|
138
|
+
...(event.occurredAt !== undefined ? { occurredAt: event.occurredAt } : {}),
|
|
139
|
+
},
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
return undefined;
|
|
143
|
+
}
|
|
101
144
|
function historicalEventMessageId(sessionId, event, seq) {
|
|
102
145
|
const digest = createHash("sha256")
|
|
103
146
|
.update(JSON.stringify({ occurredAt: event.occurredAt, payload: event.payload, seq }))
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { FilePreviewMode, FilePreviewResult, MachineCommand } from "
|
|
1
|
+
import type { FilePreviewMode, FilePreviewResult, MachineCommand } from "../../../../packages/shared/dist/index.js";
|
|
2
2
|
import type { DaemonConfig } from "../types.js";
|
|
3
3
|
export declare function handlePreviewFile(ws: WebSocket, config: DaemonConfig, command: MachineCommand): Promise<void>;
|
|
4
4
|
export declare function buildFilePreview(config: DaemonConfig, rootPath: string, requestedPath: string, mode?: FilePreviewMode): Promise<FilePreviewResult>;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { type MachineCommand } from "
|
|
1
|
+
import { type MachineCommand } from "../../../../packages/shared/dist/index.js";
|
|
2
2
|
import type { DaemonConfig, HistoricalBackfillStatus, SessionFallback, SessionState } from "../types.js";
|
|
3
|
+
import { type HistoricalSessionHead } from "./events.js";
|
|
3
4
|
export type HistoricalBackfillResult = {
|
|
4
5
|
availableEvents: number;
|
|
5
6
|
cursor: number;
|
|
@@ -10,6 +11,7 @@ export type HistoricalBackfillResult = {
|
|
|
10
11
|
tailRepairedEvents: number;
|
|
11
12
|
totalEvents: number;
|
|
12
13
|
truncated: boolean;
|
|
14
|
+
head?: HistoricalSessionHead;
|
|
13
15
|
};
|
|
14
16
|
export declare function handleCreateSession(ws: WebSocket, config: DaemonConfig, command: MachineCommand): Promise<void>;
|
|
15
17
|
export declare function handleImportHistoricalSession(ws: WebSocket, config: DaemonConfig, command: MachineCommand): Promise<void>;
|
|
@@ -19,6 +21,8 @@ export declare function usesAuthoritativeTranscript(session: SessionState): bool
|
|
|
19
21
|
export declare function replaceAuthoritativeTranscript(ws: WebSocket, config: DaemonConfig, session: SessionState, runtimeSessionId?: string | undefined, input?: {
|
|
20
22
|
currentHead?: string;
|
|
21
23
|
lastTurnId?: string;
|
|
24
|
+
replacementKind?: "command" | "sync";
|
|
25
|
+
requestId?: string;
|
|
22
26
|
status?: "completed" | "cancelled" | "failed";
|
|
23
27
|
strict?: boolean;
|
|
24
28
|
}): Promise<HistoricalBackfillResult>;
|
|
@@ -4,7 +4,7 @@ import { getRuntime } from "../runtime.js";
|
|
|
4
4
|
import { sessions } from "../state.js";
|
|
5
5
|
import { claimCommandRequest, sendCommandResponse } from "../relay/send.js";
|
|
6
6
|
import { createSessionFailureAuditEvent, createSessionFailureResponse } from "./create-session.js";
|
|
7
|
-
import { emitHistoricalEvents, emitRuntimeTailEvents, emitTranscriptPrepended, emitTranscriptReplacement } from "./events.js";
|
|
7
|
+
import { emitHistoricalEvents, emitRuntimeTailEvents, emitSessionHeadAdvanced, emitTranscriptPrepended, emitTranscriptReplacement, latestCompletedHistoricalHead, } from "./events.js";
|
|
8
8
|
import { commandSessionMetadata, encryptedSessionMetadata, sessionFallbackFromCommand } from "./metadata.js";
|
|
9
9
|
const historicalBackfillEventLimit = 200;
|
|
10
10
|
export async function handleCreateSession(ws, config, command) {
|
|
@@ -461,8 +461,10 @@ export async function replaceAuthoritativeTranscript(ws, config, session, runtim
|
|
|
461
461
|
}
|
|
462
462
|
const result = authoritativeBackfillResult(page);
|
|
463
463
|
await emitTranscriptReplacement(ws, config, session.sessionId, page.events, {
|
|
464
|
+
requestId: input.requestId,
|
|
464
465
|
currentHead: input.currentHead ?? page.currentHead,
|
|
465
466
|
lastTurnId: input.lastTurnId ?? page.lastTurnId,
|
|
467
|
+
replacementKind: input.replacementKind,
|
|
466
468
|
status: input.status,
|
|
467
469
|
hasMoreBefore: page.hasMoreBefore,
|
|
468
470
|
nextBefore: page.nextBefore,
|
|
@@ -579,7 +581,15 @@ async function backfillHistoricalEvents(ws, config, session, runtimeSessionId =
|
|
|
579
581
|
await emitHistoricalEvents(ws, config, session.sessionId, olderWindow.events, olderWindow.startIndex);
|
|
580
582
|
}
|
|
581
583
|
const status = olderWindow.nextCursor > 0 ? "partial" : "completed";
|
|
582
|
-
|
|
584
|
+
const computedHead = latestCompletedHistoricalHead(session.sessionId, historicalEvents, {
|
|
585
|
+
...(previousBackfill?.totalEvents !== undefined && previousBackfill.head === undefined
|
|
586
|
+
? { preferTailBasisForExistingEvents: true }
|
|
587
|
+
: {}),
|
|
588
|
+
...(previousBackfill?.totalEvents !== undefined ? { previousTotalEvents: previousBackfill.totalEvents } : {}),
|
|
589
|
+
...(tailWindow.events.length > 0 ? { tailStartIndex: tailWindow.startIndex } : {}),
|
|
590
|
+
});
|
|
591
|
+
const head = preferPersistedHistoricalHeadBasis(computedHead, previousBackfill?.head);
|
|
592
|
+
const result = {
|
|
583
593
|
emittedEvents: tailWindow.events.length + olderWindow.events.length,
|
|
584
594
|
availableEvents: historicalEvents.length,
|
|
585
595
|
cursor: olderWindow.nextCursor,
|
|
@@ -588,7 +598,27 @@ async function backfillHistoricalEvents(ws, config, session, runtimeSessionId =
|
|
|
588
598
|
tailRepairedEvents: tailWindow.events.length,
|
|
589
599
|
totalEvents: historicalEvents.length,
|
|
590
600
|
truncated: status === "partial",
|
|
601
|
+
...(head ? { head } : {}),
|
|
591
602
|
};
|
|
603
|
+
if (head) {
|
|
604
|
+
const backfilledSession = withHistoricalBackfill(session, result);
|
|
605
|
+
await emitSessionHeadAdvanced(ws, session.sessionId, head, await encryptedSessionMetadata(config, session.sessionId, backfilledSession, {
|
|
606
|
+
...historicalBackfillMetadata(result),
|
|
607
|
+
historicalBackfilledAt: new Date().toISOString(),
|
|
608
|
+
}));
|
|
609
|
+
}
|
|
610
|
+
return result;
|
|
611
|
+
}
|
|
612
|
+
function preferPersistedHistoricalHeadBasis(computed, persisted) {
|
|
613
|
+
if (!computed || !persisted)
|
|
614
|
+
return computed;
|
|
615
|
+
if (computed.currentHead === persisted.currentHead &&
|
|
616
|
+
computed.lastTurnId === persisted.lastTurnId &&
|
|
617
|
+
computed.basis.turnId === persisted.basis.turnId &&
|
|
618
|
+
computed.basis.turnSeq === persisted.basis.turnSeq) {
|
|
619
|
+
return persisted;
|
|
620
|
+
}
|
|
621
|
+
return computed;
|
|
592
622
|
}
|
|
593
623
|
function completedBackfillResult(totalEvents) {
|
|
594
624
|
return {
|
|
@@ -665,6 +695,7 @@ function withHistoricalBackfill(session, backfill) {
|
|
|
665
695
|
...session,
|
|
666
696
|
historicalBackfill: {
|
|
667
697
|
cursor: backfill.cursor,
|
|
698
|
+
...(backfill.head ? { head: backfill.head } : {}),
|
|
668
699
|
providerCursor: backfill.providerCursor,
|
|
669
700
|
status: backfill.status,
|
|
670
701
|
totalEvents: backfill.totalEvents,
|
|
@@ -681,6 +712,7 @@ function historicalBackfillMetadata(backfill) {
|
|
|
681
712
|
backfilledEvents: backfill.emittedEvents,
|
|
682
713
|
historicalOlderBackfilledEvents: backfill.olderBackfilledEvents,
|
|
683
714
|
historicalTailRepairedEvents: backfill.tailRepairedEvents,
|
|
715
|
+
historicalHead: backfill.head,
|
|
684
716
|
availableHistoricalEvents: backfill.availableEvents,
|
|
685
717
|
truncatedHistoricalBackfill: backfill.truncated,
|
|
686
718
|
};
|
|
@@ -699,11 +731,22 @@ export async function handleClose(ws, config, command) {
|
|
|
699
731
|
return;
|
|
700
732
|
const session = sessions.get(command.sessionId);
|
|
701
733
|
const fallback = session ? undefined : await sessionFallbackFromCommand(config, command);
|
|
734
|
+
const fallbackHandle = fallback ? runtimeHandleFromFallback(command.sessionId, fallback.agent, fallback.cwd, fallback) : undefined;
|
|
735
|
+
const sessionForClose = session ?? (fallback && fallbackHandle
|
|
736
|
+
? {
|
|
737
|
+
sessionId: command.sessionId,
|
|
738
|
+
agent: fallback.agent,
|
|
739
|
+
cwd: fallback.cwd,
|
|
740
|
+
name: fallback.name,
|
|
741
|
+
handle: fallbackHandle,
|
|
742
|
+
historicalBackfill: fallback.historicalBackfill,
|
|
743
|
+
}
|
|
744
|
+
: undefined);
|
|
702
745
|
let runtimeCloseError;
|
|
703
|
-
if (
|
|
746
|
+
if (sessionForClose) {
|
|
704
747
|
try {
|
|
705
|
-
await getRuntime(
|
|
706
|
-
handle:
|
|
748
|
+
await getRuntime(sessionForClose.cwd).close({
|
|
749
|
+
handle: sessionForClose.handle,
|
|
707
750
|
reason: command.reason ?? "closed by controller",
|
|
708
751
|
});
|
|
709
752
|
}
|
|
@@ -722,8 +765,9 @@ export async function handleClose(ws, config, command) {
|
|
|
722
765
|
requestId: command.requestId,
|
|
723
766
|
reason: command.reason,
|
|
724
767
|
loaded: Boolean(session),
|
|
725
|
-
|
|
726
|
-
|
|
768
|
+
...(!session && fallbackHandle ? { runtimeHandleFallback: true } : {}),
|
|
769
|
+
agent: sessionForClose?.agent ?? fallback?.agent,
|
|
770
|
+
cwd: sessionForClose?.cwd ?? fallback?.cwd,
|
|
727
771
|
runtimeCloseError,
|
|
728
772
|
},
|
|
729
773
|
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type EncryptedEnvelope, type MachineCommand } from "
|
|
1
|
+
import { type EncryptedEnvelope, type MachineCommand } from "../../../../packages/shared/dist/index.js";
|
|
2
2
|
import type { DaemonConfig, SessionFallback, SessionMetadata, SessionState } from "../types.js";
|
|
3
3
|
export declare function encryptedSessionMetadata(config: DaemonConfig, sessionId: string, state: Pick<SessionState, "agent" | "cwd" | "name" | "handle">, extra: Record<string, unknown>): Promise<EncryptedEnvelope>;
|
|
4
4
|
export declare function commandSessionMetadata(config: DaemonConfig, encryptedMetadata?: EncryptedEnvelope): Promise<SessionMetadata | undefined>;
|
|
@@ -52,6 +52,7 @@ function historicalBackfillStateFromMetadata(metadata) {
|
|
|
52
52
|
if (status && totalEvents !== undefined && cursor !== undefined) {
|
|
53
53
|
return {
|
|
54
54
|
cursor: Math.min(cursor, totalEvents),
|
|
55
|
+
...(historicalHeadStateFromMetadata(metadata) ? { head: historicalHeadStateFromMetadata(metadata) } : {}),
|
|
55
56
|
...(typeof metadata.historicalBackfillProviderCursor === "string" ? { providerCursor: metadata.historicalBackfillProviderCursor } : {}),
|
|
56
57
|
status,
|
|
57
58
|
totalEvents,
|
|
@@ -60,6 +61,7 @@ function historicalBackfillStateFromMetadata(metadata) {
|
|
|
60
61
|
if (status === "completed") {
|
|
61
62
|
return {
|
|
62
63
|
cursor: 0,
|
|
64
|
+
...(historicalHeadStateFromMetadata(metadata) ? { head: historicalHeadStateFromMetadata(metadata) } : {}),
|
|
63
65
|
...(typeof metadata.historicalBackfillProviderCursor === "string" ? { providerCursor: metadata.historicalBackfillProviderCursor } : {}),
|
|
64
66
|
status: "completed",
|
|
65
67
|
totalEvents: totalEvents ?? 0,
|
|
@@ -70,6 +72,7 @@ function historicalBackfillStateFromMetadata(metadata) {
|
|
|
70
72
|
if (totalEvents !== undefined && backfilledEvents !== undefined) {
|
|
71
73
|
return {
|
|
72
74
|
cursor: Math.max(0, totalEvents - backfilledEvents),
|
|
75
|
+
...(historicalHeadStateFromMetadata(metadata) ? { head: historicalHeadStateFromMetadata(metadata) } : {}),
|
|
73
76
|
...(typeof metadata.historicalBackfillProviderCursor === "string" ? { providerCursor: metadata.historicalBackfillProviderCursor } : {}),
|
|
74
77
|
status: "partial",
|
|
75
78
|
totalEvents,
|
|
@@ -78,6 +81,31 @@ function historicalBackfillStateFromMetadata(metadata) {
|
|
|
78
81
|
}
|
|
79
82
|
return undefined;
|
|
80
83
|
}
|
|
84
|
+
function historicalHeadStateFromMetadata(metadata) {
|
|
85
|
+
const head = metadata.historicalHead;
|
|
86
|
+
if (!head || typeof head !== "object")
|
|
87
|
+
return undefined;
|
|
88
|
+
const basis = head.basis;
|
|
89
|
+
if (typeof head.currentHead !== "string" ||
|
|
90
|
+
typeof head.lastTurnId !== "string" ||
|
|
91
|
+
!basis ||
|
|
92
|
+
typeof basis !== "object" ||
|
|
93
|
+
typeof basis.turnId !== "string" ||
|
|
94
|
+
typeof basis.eventMessageId !== "string" ||
|
|
95
|
+
!Number.isInteger(basis.turnSeq)) {
|
|
96
|
+
return undefined;
|
|
97
|
+
}
|
|
98
|
+
return {
|
|
99
|
+
currentHead: head.currentHead,
|
|
100
|
+
lastTurnId: head.lastTurnId,
|
|
101
|
+
basis: {
|
|
102
|
+
turnId: basis.turnId,
|
|
103
|
+
eventMessageId: basis.eventMessageId,
|
|
104
|
+
turnSeq: basis.turnSeq,
|
|
105
|
+
...(typeof basis.occurredAt === "number" ? { occurredAt: basis.occurredAt } : {}),
|
|
106
|
+
},
|
|
107
|
+
};
|
|
108
|
+
}
|
|
81
109
|
function historicalBackfillStatus(value) {
|
|
82
110
|
return value === "partial" || value === "completed" ? value : undefined;
|
|
83
111
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type MachineCommand } from "
|
|
1
|
+
import { type MachineCommand } from "../../../../packages/shared/dist/index.js";
|
|
2
2
|
import type { DaemonConfig } from "../types.js";
|
|
3
3
|
export declare function handleRewind(ws: WebSocket, config: DaemonConfig, command: MachineCommand): Promise<void>;
|
|
4
4
|
export declare function handleFork(ws: WebSocket, config: DaemonConfig, command: MachineCommand): Promise<void>;
|
|
@@ -113,7 +113,11 @@ export async function handleRewind(ws, config, command) {
|
|
|
113
113
|
});
|
|
114
114
|
if (usesAuthoritativeTranscript(nextSession)) {
|
|
115
115
|
try {
|
|
116
|
-
const backfill = await replaceAuthoritativeTranscript(ws, config, nextSession, undefined,
|
|
116
|
+
const backfill = await replaceAuthoritativeTranscript(ws, config, nextSession, undefined, {
|
|
117
|
+
...head,
|
|
118
|
+
replacementKind: "command",
|
|
119
|
+
requestId: command.requestId,
|
|
120
|
+
});
|
|
117
121
|
sessions.set(command.sessionId, {
|
|
118
122
|
...nextSession,
|
|
119
123
|
historicalBackfill: {
|
|
@@ -241,6 +245,7 @@ export async function handleFork(ws, config, command) {
|
|
|
241
245
|
...primitiveRuntimeEvidence(source.handle, forkState.handle),
|
|
242
246
|
},
|
|
243
247
|
});
|
|
248
|
+
const authoritativeForkTranscript = usesAuthoritativeTranscript(forkState);
|
|
244
249
|
await sendCommandResponse(ws, {
|
|
245
250
|
type: "machine:sessionForked",
|
|
246
251
|
requestId: command.requestId,
|
|
@@ -248,6 +253,7 @@ export async function handleFork(ws, config, command) {
|
|
|
248
253
|
sourceCheckpointId,
|
|
249
254
|
sessionId: command.targetSessionId,
|
|
250
255
|
name: command.name,
|
|
256
|
+
...(authoritativeForkTranscript ? { transcriptPending: true } : {}),
|
|
251
257
|
encryptedMetadata: await encryptedSessionMetadata(config, command.targetSessionId, forkState, {
|
|
252
258
|
forkedAt: new Date().toISOString(),
|
|
253
259
|
importedFromRuntimeSessionId: sourceMetadata?.importedFromRuntimeSessionId,
|
|
@@ -256,10 +262,15 @@ export async function handleFork(ws, config, command) {
|
|
|
256
262
|
sourceCheckpointId,
|
|
257
263
|
}),
|
|
258
264
|
});
|
|
259
|
-
if (
|
|
265
|
+
if (authoritativeForkTranscript) {
|
|
260
266
|
try {
|
|
261
267
|
const targetHead = primitiveResultHead(result);
|
|
262
|
-
const backfill = await replaceAuthoritativeTranscript(ws, config, forkState, undefined,
|
|
268
|
+
const backfill = await replaceAuthoritativeTranscript(ws, config, forkState, undefined, {
|
|
269
|
+
...targetHead,
|
|
270
|
+
replacementKind: "command",
|
|
271
|
+
requestId: command.requestId,
|
|
272
|
+
status: "completed",
|
|
273
|
+
});
|
|
263
274
|
sessions.set(command.targetSessionId, {
|
|
264
275
|
...forkState,
|
|
265
276
|
historicalBackfill: {
|
|
@@ -279,6 +290,14 @@ export async function handleFork(ws, config, command) {
|
|
|
279
290
|
summary: `Failed to refresh fork target transcript ${command.targetSessionId}`,
|
|
280
291
|
evidence: { requestId: command.requestId, sourceSessionId: command.sessionId, error: error instanceof Error ? error.message : String(error) },
|
|
281
292
|
});
|
|
293
|
+
await sendCommandResponse(ws, {
|
|
294
|
+
type: "machine:error",
|
|
295
|
+
requestId: command.requestId,
|
|
296
|
+
sessionId: command.targetSessionId,
|
|
297
|
+
code: "SESSION_TRANSCRIPT_REPLACE_FAILED",
|
|
298
|
+
capability: "session.history",
|
|
299
|
+
message: error instanceof Error ? error.message : String(error),
|
|
300
|
+
});
|
|
282
301
|
}
|
|
283
302
|
}
|
|
284
303
|
}
|