@cydm/happy-elves 0.1.0-beta.31 → 0.1.0-beta.310
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/app.js +10 -0
- package/apps/cli/dist/commands/daemon.js +92 -4
- package/apps/cli/dist/commands/gateway.d.ts +2 -0
- package/apps/cli/dist/commands/gateway.js +429 -0
- package/apps/cli/dist/commands/lib/args.js +49 -0
- package/apps/cli/dist/commands/lib/bootstrap-daemon.d.ts +2 -2
- package/apps/cli/dist/commands/lib/bootstrap-daemon.js +2 -2
- package/apps/cli/dist/commands/lib/doctor.d.ts +11 -0
- package/apps/cli/dist/commands/lib/doctor.js +276 -11
- package/apps/cli/dist/commands/lib/gateway-store.d.ts +38 -0
- package/apps/cli/dist/commands/lib/gateway-store.js +33 -0
- package/apps/cli/dist/commands/lib/index.d.ts +4 -2
- package/apps/cli/dist/commands/lib/index.js +2 -0
- package/apps/cli/dist/commands/lib/json.d.ts +2 -2
- package/apps/cli/dist/commands/lib/json.js +5 -2
- package/apps/cli/dist/commands/lib/local-daemon.d.ts +1 -0
- package/apps/cli/dist/commands/lib/local-daemon.js +14 -0
- package/apps/cli/dist/commands/lib/paths.d.ts +2 -0
- package/apps/cli/dist/commands/lib/paths.js +2 -0
- package/apps/cli/dist/commands/lib/relay-db-audit.d.ts +37 -0
- package/apps/cli/dist/commands/lib/relay-db-audit.js +300 -0
- 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 +15 -1
- package/apps/cli/dist/commands/lib/session-output.js +214 -6
- package/apps/cli/dist/commands/lib/session-view.d.ts +2 -2
- package/apps/cli/dist/commands/lib/status.js +5 -1
- package/apps/cli/dist/commands/lib/types.d.ts +4 -2
- package/apps/cli/dist/commands/lib/usage.js +123 -10
- package/apps/cli/dist/commands/lib/workspace.d.ts +2 -2
- package/apps/cli/dist/commands/lib/workspace.js +63 -10
- package/apps/cli/dist/commands/machine.js +50 -9
- package/apps/cli/dist/commands/memory.d.ts +2 -0
- package/apps/cli/dist/commands/memory.js +179 -0
- package/apps/cli/dist/commands/relay.js +29 -2
- package/apps/cli/dist/commands/release.d.ts +2 -0
- package/apps/cli/dist/commands/release.js +197 -0
- package/apps/cli/dist/commands/remote.js +10 -2
- package/apps/cli/dist/commands/schedule.d.ts +2 -0
- package/apps/cli/dist/commands/schedule.js +273 -0
- package/apps/cli/dist/commands/session.js +517 -5
- package/apps/cli/dist/commands/turn.js +225 -9
- package/apps/cli/dist/commands/workspace.d.ts +2 -0
- package/apps/cli/dist/commands/workspace.js +68 -0
- package/apps/cli/package.json +6 -0
- package/apps/daemon/dist/gateway/adapters.d.ts +38 -0
- package/apps/daemon/dist/gateway/adapters.js +2 -0
- package/apps/daemon/dist/gateway/feishu.d.ts +65 -0
- package/apps/daemon/dist/gateway/feishu.js +493 -0
- package/apps/daemon/dist/gateway/format.d.ts +2 -0
- package/apps/daemon/dist/gateway/format.js +19 -0
- package/apps/daemon/dist/gateway/handler.d.ts +7 -0
- package/apps/daemon/dist/gateway/handler.js +151 -0
- package/apps/daemon/dist/gateway/runtime.d.ts +33 -0
- package/apps/daemon/dist/gateway/runtime.js +850 -0
- package/apps/daemon/dist/gateway/store.d.ts +92 -0
- package/apps/daemon/dist/gateway/store.js +268 -0
- package/apps/daemon/dist/memory/handler.d.ts +7 -0
- package/apps/daemon/dist/memory/handler.js +105 -0
- package/apps/daemon/dist/memory/manager.d.ts +44 -0
- package/apps/daemon/dist/memory/manager.js +359 -0
- package/apps/daemon/dist/paths.d.ts +3 -0
- package/apps/daemon/dist/paths.js +3 -0
- package/apps/daemon/dist/relay/admission.d.ts +30 -0
- package/apps/daemon/dist/relay/admission.js +31 -0
- package/apps/daemon/dist/relay/connection.js +37 -1
- package/apps/daemon/dist/relay/devtools.d.ts +1 -1
- package/apps/daemon/dist/relay/register.js +2 -0
- package/apps/daemon/dist/relay/send.d.ts +2 -2
- package/apps/daemon/dist/relay/send.js +2 -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/external-provider.js +187 -17
- package/apps/daemon/dist/runtime.d.ts +1 -2
- package/apps/daemon/dist/runtime.js +0 -3
- package/apps/daemon/dist/schedule/handler.d.ts +9 -0
- package/apps/daemon/dist/schedule/handler.js +148 -0
- package/apps/daemon/dist/schedule/runner.d.ts +21 -0
- package/apps/daemon/dist/schedule/runner.js +547 -0
- package/apps/daemon/dist/schedule/store.d.ts +9 -0
- package/apps/daemon/dist/schedule/store.js +143 -0
- 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 +76 -24
- package/apps/daemon/dist/session/file-preview.d.ts +1 -1
- package/apps/daemon/dist/session/lifecycle.d.ts +26 -3
- package/apps/daemon/dist/session/lifecycle.js +161 -22
- package/apps/daemon/dist/session/metadata.d.ts +2 -2
- package/apps/daemon/dist/session/metadata.js +42 -1
- package/apps/daemon/dist/session/primitives.d.ts +1 -1
- package/apps/daemon/dist/session/primitives.js +37 -6
- package/apps/daemon/dist/session/prompt.d.ts +28 -1
- package/apps/daemon/dist/session/prompt.js +340 -5
- package/apps/daemon/dist/session/reconcile.d.ts +3 -0
- package/apps/daemon/dist/session/reconcile.js +235 -0
- package/apps/daemon/dist/session/runtime-handle.d.ts +1 -1
- package/apps/daemon/dist/start.js +5 -1
- package/apps/daemon/dist/state.d.ts +2 -2
- package/apps/daemon/dist/turn-coordinator.d.ts +1 -0
- package/apps/daemon/dist/turn-coordinator.js +4 -0
- package/apps/daemon/dist/types.d.ts +16 -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 +42 -2
- package/apps/relay/dist/controller-handlers.js +349 -37
- package/apps/relay/dist/db.js +296 -2
- package/apps/relay/dist/errors.d.ts +2 -1
- package/apps/relay/dist/errors.js +3 -1
- package/apps/relay/dist/http-routes.js +659 -33
- package/apps/relay/dist/http-schemas.d.ts +156 -0
- package/apps/relay/dist/http-schemas.js +85 -0
- package/apps/relay/dist/index.js +31 -1
- package/apps/relay/dist/machine-handlers.d.ts +15 -7
- package/apps/relay/dist/machine-handlers.js +567 -27
- 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 +41 -3
- package/apps/relay/dist/relay-context.js +244 -19
- package/apps/relay/dist/repositories.d.ts +2 -2
- package/apps/relay/dist/repositories.js +28 -1
- package/apps/relay/dist/runtime-bindings.d.ts +25 -0
- package/apps/relay/dist/runtime-bindings.js +49 -0
- package/apps/relay/dist/scope.d.ts +1 -1
- package/apps/relay/dist/types.d.ts +71 -1
- package/apps/relay/dist/websocket.js +2 -0
- package/package.json +5 -11
- package/packages/agent-sdk/dist/index.d.ts +80 -0
- package/packages/agent-sdk/dist/index.js +16 -0
- package/packages/client/dist/account.d.ts +35 -2
- package/packages/client/dist/account.js +98 -1
- package/packages/client/dist/client.d.ts +59 -6
- package/packages/client/dist/client.js +312 -58
- package/packages/client/dist/index.d.ts +1 -1
- package/packages/client/dist/parsers.d.ts +28 -2
- package/packages/client/dist/parsers.js +167 -0
- package/packages/client/dist/transport.d.ts +21 -1
- package/packages/client/dist/transport.js +69 -6
- package/packages/client/dist/types.d.ts +177 -1
- package/packages/client/dist/validation.d.ts +1 -1
- package/packages/runtime/dist/index.d.ts +66 -0
- package/packages/runtime-acpx/dist/index.d.ts +1 -1
- package/packages/runtime-acpx/dist/index.js +8 -0
- 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 +2 -1
- package/packages/runtime-cli/dist/claude-turn.js +29 -9
- package/packages/runtime-cli/dist/codex-app-server.d.ts +8 -3
- package/packages/runtime-cli/dist/codex-app-server.js +122 -25
- package/packages/runtime-cli/dist/codex-history.d.ts +1 -2
- package/packages/runtime-cli/dist/codex-history.js +11 -5
- package/packages/runtime-cli/dist/codex-protocol.d.ts +2 -2
- package/packages/runtime-cli/dist/codex-protocol.js +4 -4
- 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/index.js +108 -2
- package/packages/runtime-cli/dist/permissions.d.ts +1 -1
- package/packages/runtime-cli/dist/session-store.d.ts +2 -1
- package/packages/runtime-cli/dist/session-store.js +9 -8
- package/packages/shared/dist/index.d.ts +2 -0
- package/packages/shared/dist/index.js +2 -0
- package/packages/shared/dist/protocol-schemas.d.ts +1077 -0
- package/packages/shared/dist/protocol-schemas.js +273 -0
- package/packages/shared/dist/protocol-types.d.ts +371 -3
- package/packages/shared/dist/protocol.d.ts +181 -2
- package/packages/shared/dist/protocol.js +197 -1
- package/packages/shared/dist/session-tags.d.ts +12 -0
- package/packages/shared/dist/session-tags.js +50 -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
|
@@ -2,7 +2,10 @@ import { decryptJson } from "../../../../packages/shared/dist/index.js";
|
|
|
2
2
|
import { appendAudit } from "../audit.js";
|
|
3
3
|
import { getRuntime } from "../runtime.js";
|
|
4
4
|
import { activePromptRequests, completedPromptRequests, sessions, sessionTurns } from "../state.js";
|
|
5
|
+
import { handleGatewayTurnTerminal } from "../gateway/runtime.js";
|
|
6
|
+
import { maybePromoteMemory, prepareMemoryContext, writeTurnMemory } from "../memory/manager.js";
|
|
5
7
|
import { attachClaimedTurn, claimSessionTurn, releaseSessionTurn, sendCommandResponse, sendReliable } from "../relay/send.js";
|
|
8
|
+
import { settleScheduleTurnTerminal } from "../schedule/runner.js";
|
|
6
9
|
import { emitEvent, runtimeEventToPayload } from "./events.js";
|
|
7
10
|
import { replaceAuthoritativeTranscript, resumeSession, usesAuthoritativeTranscript } from "./lifecycle.js";
|
|
8
11
|
import { encryptedSessionMetadata, sessionFallbackFromCommand } from "./metadata.js";
|
|
@@ -22,14 +25,19 @@ export async function handlePrompt(ws, config, command) {
|
|
|
22
25
|
}
|
|
23
26
|
if (activePromptRequests.has(command.requestId))
|
|
24
27
|
return;
|
|
25
|
-
const
|
|
28
|
+
const fallback = await sessionFallbackFromCommand(config, command);
|
|
29
|
+
let session = sessions.get(command.sessionId);
|
|
26
30
|
if (!session) {
|
|
27
|
-
const resumed = await resumeSession(ws, config, command.sessionId, command.requestId,
|
|
31
|
+
const resumed = await resumeSession(ws, config, command.sessionId, command.requestId, fallback, false);
|
|
28
32
|
if (!resumed)
|
|
29
33
|
return;
|
|
30
34
|
await handlePrompt(ws, config, command);
|
|
31
35
|
return;
|
|
32
36
|
}
|
|
37
|
+
if (fallback?.tags && fallback.tags.length > 0) {
|
|
38
|
+
session = { ...session, tags: fallback.tags };
|
|
39
|
+
sessions.set(command.sessionId, session);
|
|
40
|
+
}
|
|
33
41
|
if (!claimSessionTurn(command.sessionId, command.requestId, command.turnId, "prompt")) {
|
|
34
42
|
await sendCommandResponse(ws, {
|
|
35
43
|
type: "machine:error",
|
|
@@ -49,25 +57,69 @@ export async function handlePrompt(ws, config, command) {
|
|
|
49
57
|
activePromptRequests.delete(command.requestId);
|
|
50
58
|
releaseSessionTurn(command.sessionId, command.requestId);
|
|
51
59
|
};
|
|
60
|
+
let phase = "decrypt-prompt";
|
|
52
61
|
try {
|
|
53
62
|
const prompt = await decryptJson(config.accountSecret, command.encryptedPrompt);
|
|
54
|
-
const
|
|
63
|
+
const rawText = prompt.type === "user_prompt" ? prompt.text : JSON.stringify(prompt);
|
|
64
|
+
const promptAttachments = prompt.type === "user_prompt" ? normalizePromptAttachments(prompt.attachments) : [];
|
|
65
|
+
phase = "prepare-attachments";
|
|
66
|
+
const preparedPrompt = preparePromptAttachments(rawText, promptAttachments);
|
|
67
|
+
phase = "decrypt-memory-options";
|
|
68
|
+
const memoryOptions = await decryptMemoryOptions(config, command);
|
|
69
|
+
phase = "prepare-memory-context";
|
|
70
|
+
const memoryContext = memoryOptions
|
|
71
|
+
? await prepareMemoryContext(memoryOptions, preparedPrompt.text)
|
|
72
|
+
: { text: preparedPrompt.text, used: [], options: undefined };
|
|
73
|
+
const text = memoryContext.text;
|
|
74
|
+
phase = "emit-submitted";
|
|
55
75
|
await emitEvent(ws, config, command.sessionId, command.turnId, {
|
|
56
76
|
type: "status",
|
|
57
77
|
text: "Prompt submitted to runtime",
|
|
58
78
|
});
|
|
79
|
+
if (memoryOptions) {
|
|
80
|
+
phase = "emit-memory-status";
|
|
81
|
+
await emitEvent(ws, config, command.sessionId, command.turnId, {
|
|
82
|
+
type: "status",
|
|
83
|
+
tag: "memory",
|
|
84
|
+
text: memoryOptions.mode === "off"
|
|
85
|
+
? "Memory mode off for this turn"
|
|
86
|
+
: memoryContext.used.length > 0
|
|
87
|
+
? `Memory ${memoryOptions.mode} used: ${memoryContext.used.map((item) => `${item.path}:${item.citation.startLine}-${item.citation.endLine}`).join(", ")}`
|
|
88
|
+
: `Memory ${memoryOptions.mode}: no relevant citations found`,
|
|
89
|
+
});
|
|
90
|
+
if (memoryContext.used.length > 0 && memoryOptions.mode !== "off") {
|
|
91
|
+
await emitEvent(ws, config, command.sessionId, command.turnId, {
|
|
92
|
+
type: "memory_used",
|
|
93
|
+
mode: memoryOptions.mode,
|
|
94
|
+
projectKey: memoryOptions.projectKey,
|
|
95
|
+
memories: memoryContext.used.map((item) => ({
|
|
96
|
+
id: item.id,
|
|
97
|
+
layer: item.layer,
|
|
98
|
+
path: item.path,
|
|
99
|
+
...(item.title ? { title: item.title } : {}),
|
|
100
|
+
citation: item.citation,
|
|
101
|
+
})),
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
}
|
|
59
105
|
const previousBackendSessionId = session.handle.backendSessionId;
|
|
106
|
+
const model = modelFromCommand(command.model) ?? session.model ?? session.handle.model;
|
|
107
|
+
phase = "start-turn";
|
|
60
108
|
const turn = getRuntime(session.cwd).startTurn({
|
|
61
109
|
handle: session.handle,
|
|
62
110
|
text,
|
|
63
111
|
mode: "prompt",
|
|
64
112
|
permissionMode: command.permissionMode,
|
|
113
|
+
model,
|
|
114
|
+
attachments: preparedPrompt.runtimeAttachments,
|
|
65
115
|
requestId: command.requestId,
|
|
66
116
|
timeoutMs: command.timeoutMs,
|
|
67
117
|
});
|
|
118
|
+
phase = "attach-turn";
|
|
68
119
|
if (!attachClaimedTurn(command.sessionId, command.requestId, command.turnId, turn)) {
|
|
69
120
|
throw new Error(`Session turn claim was lost before start: ${command.sessionId}`);
|
|
70
121
|
}
|
|
122
|
+
phase = "audit-turn-start";
|
|
71
123
|
await appendAudit({
|
|
72
124
|
sessionId: command.sessionId,
|
|
73
125
|
machineId: config.machineId,
|
|
@@ -78,13 +130,46 @@ export async function handlePrompt(ws, config, command) {
|
|
|
78
130
|
requestId: command.requestId,
|
|
79
131
|
turnId: command.turnId,
|
|
80
132
|
promptChars: text.length,
|
|
133
|
+
rawPromptChars: rawText.length,
|
|
134
|
+
attachmentCount: promptAttachments.length,
|
|
135
|
+
runtimeAttachmentCount: preparedPrompt.runtimeAttachments.length,
|
|
81
136
|
permissionMode: command.permissionMode ?? "approve-reads",
|
|
137
|
+
model,
|
|
138
|
+
memoryMode: memoryOptions?.mode,
|
|
139
|
+
usedMemories: memoryContext.used.map((item) => ({ path: item.path, citation: item.citation })),
|
|
82
140
|
},
|
|
83
141
|
});
|
|
142
|
+
let outputPreview = "";
|
|
143
|
+
phase = "stream-turn";
|
|
84
144
|
for await (const event of turn.events) {
|
|
85
|
-
|
|
145
|
+
const payload = runtimeEventToPayload(event);
|
|
146
|
+
if (payload.type === "text_delta" && payload.stream !== "thought") {
|
|
147
|
+
outputPreview = truncateOutputPreview(`${outputPreview}${payload.text}`, 4000);
|
|
148
|
+
}
|
|
149
|
+
await emitEvent(ws, config, command.sessionId, command.turnId, payload);
|
|
86
150
|
}
|
|
151
|
+
phase = "await-turn-result";
|
|
87
152
|
const result = await turn.result;
|
|
153
|
+
phase = "write-memory";
|
|
154
|
+
const dailyMemory = await writeTurnMemory(memoryOptions, {
|
|
155
|
+
promptText: rawText,
|
|
156
|
+
outputPreview,
|
|
157
|
+
requestId: command.requestId,
|
|
158
|
+
turnId: command.turnId,
|
|
159
|
+
status: result.status,
|
|
160
|
+
});
|
|
161
|
+
const promotedMemory = await maybePromoteMemory(memoryOptions, rawText);
|
|
162
|
+
if (dailyMemory || promotedMemory) {
|
|
163
|
+
await emitEvent(ws, config, command.sessionId, command.turnId, {
|
|
164
|
+
type: "status",
|
|
165
|
+
tag: "memory",
|
|
166
|
+
text: [
|
|
167
|
+
dailyMemory ? `Memory daily write: ${dailyMemory.path}` : "",
|
|
168
|
+
promotedMemory ? `Memory promoted: ${promotedMemory.path}` : "",
|
|
169
|
+
].filter(Boolean).join(" · "),
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
phase = "refresh-runtime-metadata";
|
|
88
173
|
const refreshedMetadata = session.handle.backendSessionId
|
|
89
174
|
? await encryptedSessionMetadata(config, command.sessionId, session, {
|
|
90
175
|
currentHead: result.currentHead,
|
|
@@ -106,6 +191,7 @@ export async function handlePrompt(ws, config, command) {
|
|
|
106
191
|
},
|
|
107
192
|
});
|
|
108
193
|
}
|
|
194
|
+
phase = "emit-terminal";
|
|
109
195
|
await emitEvent(ws, config, command.sessionId, command.turnId, result.status === "failed"
|
|
110
196
|
? {
|
|
111
197
|
type: "done",
|
|
@@ -121,8 +207,10 @@ export async function handlePrompt(ws, config, command) {
|
|
|
121
207
|
currentHead: result.currentHead,
|
|
122
208
|
lastTurnId: result.lastTurnId,
|
|
123
209
|
});
|
|
124
|
-
|
|
210
|
+
phase = "refresh-authoritative-transcript";
|
|
211
|
+
await refreshAuthoritativeTranscriptAfterTurn(ws, config, session, command.requestId, result.currentHead, result.lastTurnId, result.status);
|
|
125
212
|
releasePromptTurn();
|
|
213
|
+
phase = "send-turn-done";
|
|
126
214
|
await sendReliable({
|
|
127
215
|
type: "machine:turnDone",
|
|
128
216
|
sessionId: command.sessionId,
|
|
@@ -133,6 +221,27 @@ export async function handlePrompt(ws, config, command) {
|
|
|
133
221
|
error: result.status === "failed" ? result.error.message : undefined,
|
|
134
222
|
encryptedMetadata: refreshedMetadata,
|
|
135
223
|
}, ws);
|
|
224
|
+
phase = "terminal-hooks";
|
|
225
|
+
await handleGatewayTurnTerminal(config, {
|
|
226
|
+
sessionId: command.sessionId,
|
|
227
|
+
requestId: command.requestId,
|
|
228
|
+
turnId: command.turnId,
|
|
229
|
+
status: result.status,
|
|
230
|
+
stopReason: result.status === "failed" ? undefined : result.stopReason,
|
|
231
|
+
error: result.status === "failed" ? result.error.message : undefined,
|
|
232
|
+
outputPreview,
|
|
233
|
+
}).catch((error) => {
|
|
234
|
+
console.error(`Gateway terminal hook failed for ${command.turnId}: ${error instanceof Error ? error.message : String(error)}`);
|
|
235
|
+
});
|
|
236
|
+
await settleScheduleTurnTerminal({
|
|
237
|
+
requestId: command.requestId,
|
|
238
|
+
turnId: command.turnId,
|
|
239
|
+
status: result.status,
|
|
240
|
+
error: result.status === "failed" ? result.error.message : undefined,
|
|
241
|
+
outputPreview,
|
|
242
|
+
}).catch((error) => {
|
|
243
|
+
console.error(`Schedule terminal hook failed for ${command.turnId}: ${error instanceof Error ? error.message : String(error)}`);
|
|
244
|
+
});
|
|
136
245
|
completedPromptRequests.set(command.requestId, {
|
|
137
246
|
sessionId: command.sessionId,
|
|
138
247
|
turnId: command.turnId,
|
|
@@ -152,10 +261,148 @@ export async function handlePrompt(ws, config, command) {
|
|
|
152
261
|
},
|
|
153
262
|
});
|
|
154
263
|
}
|
|
264
|
+
catch (error) {
|
|
265
|
+
const response = promptFailureResponse(command, phase, error);
|
|
266
|
+
await appendAudit(promptFailureAuditEvent(config, command, phase, error)).catch((auditError) => {
|
|
267
|
+
console.error(`Prompt failure audit failed for ${command.turnId}: ${auditError instanceof Error ? auditError.message : String(auditError)}`);
|
|
268
|
+
});
|
|
269
|
+
await sendCommandResponse(ws, response);
|
|
270
|
+
}
|
|
155
271
|
finally {
|
|
156
272
|
releasePromptTurn();
|
|
157
273
|
}
|
|
158
274
|
}
|
|
275
|
+
export async function handleOptionResponse(ws, config, command) {
|
|
276
|
+
if (command.type !== "machine:optionResponse")
|
|
277
|
+
return;
|
|
278
|
+
const activeTurnId = sessionTurns.activeTurnId(command.sessionId);
|
|
279
|
+
const activeTurn = sessionTurns.activeTurn(command.sessionId);
|
|
280
|
+
if (!activeTurn || activeTurnId !== command.turnId) {
|
|
281
|
+
await sendCommandResponse(ws, {
|
|
282
|
+
type: "machine:error",
|
|
283
|
+
requestId: command.requestId,
|
|
284
|
+
sessionId: command.sessionId,
|
|
285
|
+
code: "OPTION_REQUEST_NOT_ACTIVE",
|
|
286
|
+
message: "No matching active turn is waiting for this option response",
|
|
287
|
+
});
|
|
288
|
+
return;
|
|
289
|
+
}
|
|
290
|
+
if (!activeTurn.respondOption) {
|
|
291
|
+
await sendCommandResponse(ws, {
|
|
292
|
+
type: "machine:error",
|
|
293
|
+
requestId: command.requestId,
|
|
294
|
+
sessionId: command.sessionId,
|
|
295
|
+
code: "OPTION_RESPONSE_UNSUPPORTED",
|
|
296
|
+
message: "This runtime does not support Happy Elves option responses",
|
|
297
|
+
});
|
|
298
|
+
return;
|
|
299
|
+
}
|
|
300
|
+
await activeTurn.respondOption({
|
|
301
|
+
optionRequestId: command.optionRequestId,
|
|
302
|
+
...(command.selectedOptionId ? { selectedOptionId: command.selectedOptionId } : {}),
|
|
303
|
+
...(command.text ? { text: command.text } : {}),
|
|
304
|
+
});
|
|
305
|
+
await emitEvent(ws, config, command.sessionId, command.turnId, {
|
|
306
|
+
type: "option_response",
|
|
307
|
+
optionRequestId: command.optionRequestId,
|
|
308
|
+
...(command.selectedOptionId ? { selectedOptionId: command.selectedOptionId } : {}),
|
|
309
|
+
...(command.text ? { text: command.text } : {}),
|
|
310
|
+
});
|
|
311
|
+
await sendCommandResponse(ws, {
|
|
312
|
+
type: "machine:optionResponded",
|
|
313
|
+
requestId: command.requestId,
|
|
314
|
+
sessionId: command.sessionId,
|
|
315
|
+
turnId: command.turnId,
|
|
316
|
+
optionRequestId: command.optionRequestId,
|
|
317
|
+
});
|
|
318
|
+
}
|
|
319
|
+
function modelFromCommand(value) {
|
|
320
|
+
return typeof value === "string" && value.trim() ? value.trim() : undefined;
|
|
321
|
+
}
|
|
322
|
+
export function promptFailureResponse(command, phase, error) {
|
|
323
|
+
const code = promptFailureCode(phase, error);
|
|
324
|
+
return {
|
|
325
|
+
type: "machine:error",
|
|
326
|
+
requestId: command.requestId,
|
|
327
|
+
sessionId: command.sessionId,
|
|
328
|
+
code,
|
|
329
|
+
message: promptFailureMessage(code, error),
|
|
330
|
+
};
|
|
331
|
+
}
|
|
332
|
+
export function promptFailureAuditEvent(config, command, phase, error) {
|
|
333
|
+
const code = promptFailureCode(phase, error);
|
|
334
|
+
return {
|
|
335
|
+
sessionId: command.sessionId,
|
|
336
|
+
machineId: config.machineId,
|
|
337
|
+
actor: "system",
|
|
338
|
+
action: "turn.prompt.failed",
|
|
339
|
+
summary: `Failed to run prompt turn ${command.turnId}`,
|
|
340
|
+
evidence: {
|
|
341
|
+
requestId: command.requestId,
|
|
342
|
+
turnId: command.turnId,
|
|
343
|
+
code,
|
|
344
|
+
phase,
|
|
345
|
+
message: safeErrorMessage(error),
|
|
346
|
+
},
|
|
347
|
+
};
|
|
348
|
+
}
|
|
349
|
+
function promptFailureCode(phase, error) {
|
|
350
|
+
if (phase === "decrypt-prompt" && isCryptoOperationFailure(error))
|
|
351
|
+
return "PROMPT_DECRYPT_FAILED";
|
|
352
|
+
if (phase === "decrypt-memory-options" && isCryptoOperationFailure(error))
|
|
353
|
+
return "MEMORY_OPTIONS_DECRYPT_FAILED";
|
|
354
|
+
if (phase === "start-turn" || phase === "attach-turn")
|
|
355
|
+
return "TURN_START_FAILED";
|
|
356
|
+
if (phase === "stream-turn" || phase === "await-turn-result")
|
|
357
|
+
return "TURN_RUNTIME_FAILED";
|
|
358
|
+
if (phase === "refresh-runtime-metadata")
|
|
359
|
+
return "SESSION_METADATA_REFRESH_FAILED";
|
|
360
|
+
if (phase === "emit-submitted" || phase === "emit-memory-status" || phase === "emit-terminal")
|
|
361
|
+
return "SESSION_EVENT_EMIT_FAILED";
|
|
362
|
+
return "PROMPT_EXECUTION_FAILED";
|
|
363
|
+
}
|
|
364
|
+
function promptFailureMessage(code, error) {
|
|
365
|
+
if (code === "PROMPT_DECRYPT_FAILED") {
|
|
366
|
+
return "Failed to decrypt the prompt for this daemon. Re-pair the daemon with the correct account secret.";
|
|
367
|
+
}
|
|
368
|
+
if (code === "MEMORY_OPTIONS_DECRYPT_FAILED") {
|
|
369
|
+
return "Failed to decrypt memory options for this turn.";
|
|
370
|
+
}
|
|
371
|
+
return safeErrorMessage(error);
|
|
372
|
+
}
|
|
373
|
+
function isCryptoOperationFailure(error) {
|
|
374
|
+
const record = error && typeof error === "object" ? error : {};
|
|
375
|
+
const name = typeof record.name === "string" ? record.name : "";
|
|
376
|
+
const code = typeof record.code === "string" ? record.code : "";
|
|
377
|
+
const message = safeErrorMessage(error);
|
|
378
|
+
return name === "OperationError" ||
|
|
379
|
+
code === "ERR_OSSL_BAD_DECRYPT" ||
|
|
380
|
+
/operation-specific reason|decrypt|authentication tag|Unsupported state or unable to authenticate data/i.test(message);
|
|
381
|
+
}
|
|
382
|
+
function safeErrorMessage(error) {
|
|
383
|
+
if (error instanceof Error && error.message)
|
|
384
|
+
return error.message;
|
|
385
|
+
return String(error);
|
|
386
|
+
}
|
|
387
|
+
async function decryptMemoryOptions(config, command) {
|
|
388
|
+
if (!command.encryptedMemoryOptions)
|
|
389
|
+
return undefined;
|
|
390
|
+
try {
|
|
391
|
+
const options = await decryptJson(config.accountSecret, command.encryptedMemoryOptions);
|
|
392
|
+
if (!options || typeof options.projectKey !== "string")
|
|
393
|
+
return undefined;
|
|
394
|
+
if (options.mode !== "off" && options.mode !== "readonly" && options.mode !== "readwrite")
|
|
395
|
+
return undefined;
|
|
396
|
+
return {
|
|
397
|
+
mode: options.mode,
|
|
398
|
+
projectKey: options.projectKey,
|
|
399
|
+
...(typeof options.topN === "number" && options.topN > 0 ? { topN: options.topN } : {}),
|
|
400
|
+
};
|
|
401
|
+
}
|
|
402
|
+
catch {
|
|
403
|
+
return undefined;
|
|
404
|
+
}
|
|
405
|
+
}
|
|
159
406
|
async function refreshAuthoritativeTranscriptAfterTurn(ws, config, session, requestId, currentHead, lastTurnId, status) {
|
|
160
407
|
if (!usesAuthoritativeTranscript(session))
|
|
161
408
|
return;
|
|
@@ -163,6 +410,8 @@ async function refreshAuthoritativeTranscriptAfterTurn(ws, config, session, requ
|
|
|
163
410
|
const backfill = await replaceAuthoritativeTranscript(ws, config, session, undefined, {
|
|
164
411
|
currentHead,
|
|
165
412
|
lastTurnId,
|
|
413
|
+
replacementKind: "command",
|
|
414
|
+
requestId,
|
|
166
415
|
...(status ? { status } : {}),
|
|
167
416
|
});
|
|
168
417
|
sessions.set(session.sessionId, { ...session, historicalBackfill: {
|
|
@@ -221,6 +470,92 @@ export async function handleCancel(ws, config, command) {
|
|
|
221
470
|
status: "cancelled",
|
|
222
471
|
lastTurnId: turnId,
|
|
223
472
|
}, ws);
|
|
473
|
+
await handleGatewayTurnTerminal(config, {
|
|
474
|
+
sessionId: command.sessionId,
|
|
475
|
+
requestId: command.requestId,
|
|
476
|
+
turnId,
|
|
477
|
+
status: "cancelled",
|
|
478
|
+
stopReason: command.reason,
|
|
479
|
+
}).catch((error) => {
|
|
480
|
+
console.error(`Gateway cancel hook failed for ${turnId}: ${error instanceof Error ? error.message : String(error)}`);
|
|
481
|
+
});
|
|
482
|
+
await settleScheduleTurnTerminal({
|
|
483
|
+
requestId: command.requestId,
|
|
484
|
+
turnId,
|
|
485
|
+
status: "cancelled",
|
|
486
|
+
error: command.reason,
|
|
487
|
+
}).catch((error) => {
|
|
488
|
+
console.error(`Schedule cancel hook failed for ${turnId}: ${error instanceof Error ? error.message : String(error)}`);
|
|
489
|
+
});
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
function truncateOutputPreview(value, maxChars) {
|
|
493
|
+
if (value.length <= maxChars)
|
|
494
|
+
return value;
|
|
495
|
+
return value.slice(value.length - maxChars);
|
|
496
|
+
}
|
|
497
|
+
function normalizePromptAttachments(value) {
|
|
498
|
+
if (!Array.isArray(value))
|
|
499
|
+
return [];
|
|
500
|
+
return value.flatMap((attachment) => {
|
|
501
|
+
if (!attachment ||
|
|
502
|
+
typeof attachment.id !== "string" ||
|
|
503
|
+
typeof attachment.name !== "string" ||
|
|
504
|
+
typeof attachment.mediaType !== "string" ||
|
|
505
|
+
typeof attachment.data !== "string" ||
|
|
506
|
+
typeof attachment.sizeBytes !== "number")
|
|
507
|
+
return [];
|
|
508
|
+
return [{
|
|
509
|
+
id: attachment.id,
|
|
510
|
+
name: attachment.name,
|
|
511
|
+
mediaType: attachment.mediaType,
|
|
512
|
+
sizeBytes: attachment.sizeBytes,
|
|
513
|
+
data: attachment.data,
|
|
514
|
+
}];
|
|
515
|
+
});
|
|
516
|
+
}
|
|
517
|
+
function preparePromptAttachments(text, attachments) {
|
|
518
|
+
const textBlocks = [];
|
|
519
|
+
const runtimeAttachments = [];
|
|
520
|
+
for (const attachment of attachments) {
|
|
521
|
+
const decodedText = decodeTextAttachment(attachment);
|
|
522
|
+
if (decodedText !== undefined) {
|
|
523
|
+
textBlocks.push([
|
|
524
|
+
`--- Attachment: ${attachment.name} (${attachment.mediaType}, ${attachment.sizeBytes} bytes) ---`,
|
|
525
|
+
decodedText,
|
|
526
|
+
"--- End attachment ---",
|
|
527
|
+
].join("\n"));
|
|
528
|
+
continue;
|
|
529
|
+
}
|
|
530
|
+
runtimeAttachments.push({
|
|
531
|
+
name: attachment.name,
|
|
532
|
+
mediaType: attachment.mediaType,
|
|
533
|
+
sizeBytes: attachment.sizeBytes,
|
|
534
|
+
data: attachment.data,
|
|
535
|
+
});
|
|
536
|
+
}
|
|
537
|
+
return {
|
|
538
|
+
text: textBlocks.length > 0
|
|
539
|
+
? `${text}\n\nAttached text files:\n\n${textBlocks.join("\n\n")}`
|
|
540
|
+
: text,
|
|
541
|
+
runtimeAttachments,
|
|
542
|
+
};
|
|
543
|
+
}
|
|
544
|
+
function decodeTextAttachment(attachment) {
|
|
545
|
+
const mediaType = attachment.mediaType.toLowerCase();
|
|
546
|
+
const textLike = mediaType.startsWith("text/") ||
|
|
547
|
+
mediaType.includes("json") ||
|
|
548
|
+
mediaType.includes("xml") ||
|
|
549
|
+
mediaType.includes("yaml") ||
|
|
550
|
+
mediaType.includes("csv") ||
|
|
551
|
+
/\.(txt|md|markdown|json|jsonl|yaml|yml|csv|tsv|log|xml|html|css|js|ts|tsx|jsx|vue|py|rb|go|rs|java|c|cc|cpp|h|hpp|sh|zsh|bash|ps1)$/iu.test(attachment.name);
|
|
552
|
+
if (!textLike)
|
|
553
|
+
return undefined;
|
|
554
|
+
try {
|
|
555
|
+
return Buffer.from(attachment.data, "base64").toString("utf8").slice(0, 64 * 1024);
|
|
556
|
+
}
|
|
557
|
+
catch {
|
|
558
|
+
return undefined;
|
|
224
559
|
}
|
|
225
560
|
}
|
|
226
561
|
//# sourceMappingURL=prompt.js.map
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
import { appendAudit } from "../audit.js";
|
|
2
|
+
import { handleGatewayTurnTerminal } from "../gateway/runtime.js";
|
|
3
|
+
import { getRuntime } from "../runtime.js";
|
|
4
|
+
import { sessions, sessionTurns } from "../state.js";
|
|
5
|
+
import { sendCommandResponse } from "../relay/send.js";
|
|
6
|
+
import { settleScheduleTurnTerminal } from "../schedule/runner.js";
|
|
7
|
+
import { commandSessionMetadata } from "./metadata.js";
|
|
8
|
+
export async function handleReconcileTurn(ws, config, command) {
|
|
9
|
+
if (command.type !== "machine:reconcileTurn")
|
|
10
|
+
return;
|
|
11
|
+
const activeClaim = sessionTurns.activeClaim(command.sessionId);
|
|
12
|
+
if (activeClaim && (!command.turnId || activeClaim.turnId === command.turnId)) {
|
|
13
|
+
await sendReconcileResult(ws, config, command, {
|
|
14
|
+
sessionId: command.sessionId,
|
|
15
|
+
turnId: activeClaim.turnId,
|
|
16
|
+
requestId: activeClaim.requestId,
|
|
17
|
+
status: "active",
|
|
18
|
+
reason: "Daemon still has an in-memory active turn claim",
|
|
19
|
+
evidence: { type: "in_memory", detail: activeClaim.source },
|
|
20
|
+
});
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
const state = await sessionStateForReconcile(config, command);
|
|
24
|
+
if (!state) {
|
|
25
|
+
await sendReconcileResult(ws, config, command, {
|
|
26
|
+
sessionId: command.sessionId,
|
|
27
|
+
turnId: command.turnId,
|
|
28
|
+
requestId: command.activeRequestId,
|
|
29
|
+
providerTurnId: command.providerTurnId,
|
|
30
|
+
status: "uninspectable",
|
|
31
|
+
reason: "Session runtime handle is not loaded and no persisted provider handle was available",
|
|
32
|
+
evidence: { type: "missing", detail: "session-runtime-handle" },
|
|
33
|
+
});
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
const runtime = getRuntime(state.cwd);
|
|
37
|
+
let inspection;
|
|
38
|
+
if (runtime.inspectTurn) {
|
|
39
|
+
inspection = await runtime.inspectTurn({
|
|
40
|
+
handle: state.handle,
|
|
41
|
+
turnId: command.turnId,
|
|
42
|
+
providerTurnId: command.providerTurnId,
|
|
43
|
+
requestId: command.activeRequestId,
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
else if (runtime.readHistoricalSessionEvents && state.handle.backendSessionId) {
|
|
47
|
+
try {
|
|
48
|
+
const events = await runtime.readHistoricalSessionEvents({
|
|
49
|
+
agent: state.agent,
|
|
50
|
+
cwd: state.cwd,
|
|
51
|
+
runtimeSessionId: state.handle.backendSessionId,
|
|
52
|
+
handle: state.handle,
|
|
53
|
+
});
|
|
54
|
+
inspection = inspectHistoricalEvents(events, {
|
|
55
|
+
turnId: command.turnId,
|
|
56
|
+
providerTurnId: command.providerTurnId,
|
|
57
|
+
fallbackProviderTurnId: state.handle.backendSessionId,
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
inspection = {
|
|
62
|
+
status: "unknown",
|
|
63
|
+
providerTurnId: command.providerTurnId ?? state.handle.backendSessionId,
|
|
64
|
+
reason: error instanceof Error ? error.message : String(error),
|
|
65
|
+
evidence: "provider-history-error",
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
inspection = {
|
|
71
|
+
status: "uninspectable",
|
|
72
|
+
providerTurnId: command.providerTurnId ?? state.handle.backendSessionId,
|
|
73
|
+
reason: "Runtime does not support inspectTurn or historical event reads",
|
|
74
|
+
evidence: "unsupported",
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
const result = reconcileResultFromInspection(command, inspection);
|
|
78
|
+
await appendAudit({
|
|
79
|
+
sessionId: command.sessionId,
|
|
80
|
+
machineId: config.machineId,
|
|
81
|
+
actor: "system",
|
|
82
|
+
action: "turn.reconcile",
|
|
83
|
+
summary: `Reconcile ${command.turnId ?? command.providerTurnId ?? "latest"}: ${result.status}`,
|
|
84
|
+
evidence: {
|
|
85
|
+
requestId: command.requestId,
|
|
86
|
+
turnId: command.turnId,
|
|
87
|
+
activeRequestId: command.activeRequestId,
|
|
88
|
+
providerTurnId: command.providerTurnId,
|
|
89
|
+
result,
|
|
90
|
+
},
|
|
91
|
+
});
|
|
92
|
+
await sendReconcileResult(ws, config, command, result);
|
|
93
|
+
if (result.status === "terminal" && result.terminalStatus && result.turnId) {
|
|
94
|
+
await settleTerminalSideEffects(config, result);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
async function sendReconcileResult(ws, config, command, result) {
|
|
98
|
+
await sendCommandResponse(ws, {
|
|
99
|
+
type: "machine:turnReconciled",
|
|
100
|
+
requestId: command.requestId,
|
|
101
|
+
machineId: config.machineId,
|
|
102
|
+
result,
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
async function sessionStateForReconcile(config, command) {
|
|
106
|
+
const existing = sessions.get(command.sessionId);
|
|
107
|
+
if (existing)
|
|
108
|
+
return existing;
|
|
109
|
+
const metadata = await commandSessionMetadata(config, command.encryptedMetadata);
|
|
110
|
+
if (!metadata?.runtime)
|
|
111
|
+
return undefined;
|
|
112
|
+
const handle = handleFromMetadata(command.sessionId, metadata);
|
|
113
|
+
if (!handle)
|
|
114
|
+
return undefined;
|
|
115
|
+
return {
|
|
116
|
+
sessionId: command.sessionId,
|
|
117
|
+
agent: metadata.agent ?? handle.runtimeSessionName,
|
|
118
|
+
cwd: metadata.cwd || handle.cwd || process.cwd(),
|
|
119
|
+
name: metadata.name ?? command.sessionId,
|
|
120
|
+
handle,
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
function handleFromMetadata(sessionId, metadata) {
|
|
124
|
+
const runtime = metadata.runtime;
|
|
125
|
+
if (!runtime)
|
|
126
|
+
return undefined;
|
|
127
|
+
const runtimeSessionName = runtime.runtimeSessionName ?? metadata.agent;
|
|
128
|
+
if (!runtimeSessionName)
|
|
129
|
+
return undefined;
|
|
130
|
+
return {
|
|
131
|
+
sessionKey: sessionId,
|
|
132
|
+
backend: runtime.backend ?? "unknown",
|
|
133
|
+
runtimeSessionName,
|
|
134
|
+
cwd: metadata.cwd,
|
|
135
|
+
acpxRecordId: runtime.acpxRecordId,
|
|
136
|
+
backendSessionId: runtime.backendSessionId,
|
|
137
|
+
agentSessionId: runtime.agentSessionId,
|
|
138
|
+
externalProviderId: runtime.externalProviderId,
|
|
139
|
+
externalHandle: runtime.externalHandle,
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
function reconcileResultFromInspection(command, inspection) {
|
|
143
|
+
const base = {
|
|
144
|
+
sessionId: command.sessionId,
|
|
145
|
+
turnId: command.turnId,
|
|
146
|
+
requestId: command.activeRequestId,
|
|
147
|
+
providerTurnId: inspection.providerTurnId ?? command.providerTurnId,
|
|
148
|
+
evidence: evidenceFromInspection(inspection),
|
|
149
|
+
};
|
|
150
|
+
if (inspection.status === "terminal") {
|
|
151
|
+
return {
|
|
152
|
+
...base,
|
|
153
|
+
status: "terminal",
|
|
154
|
+
terminalStatus: inspection.terminalStatus,
|
|
155
|
+
currentHead: inspection.currentHead,
|
|
156
|
+
lastTurnId: inspection.lastTurnId,
|
|
157
|
+
error: inspection.error,
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
return {
|
|
161
|
+
...base,
|
|
162
|
+
status: inspection.status,
|
|
163
|
+
reason: inspection.status === "active" ? undefined : inspection.reason,
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
function evidenceFromInspection(inspection) {
|
|
167
|
+
if (inspection.evidence?.includes("history"))
|
|
168
|
+
return { type: "provider_history", detail: inspection.evidence };
|
|
169
|
+
if (inspection.evidence?.includes("unsupported"))
|
|
170
|
+
return { type: "unsupported", detail: inspection.evidence };
|
|
171
|
+
if (inspection.evidence?.includes("missing"))
|
|
172
|
+
return { type: "missing", detail: inspection.evidence };
|
|
173
|
+
if (inspection.evidence)
|
|
174
|
+
return { type: "provider_inspect", detail: inspection.evidence };
|
|
175
|
+
return undefined;
|
|
176
|
+
}
|
|
177
|
+
function inspectHistoricalEvents(events, input) {
|
|
178
|
+
const candidates = new Set([input.turnId, input.providerTurnId].filter((value) => typeof value === "string" && value.length > 0));
|
|
179
|
+
const providerTurnId = input.providerTurnId ?? input.fallbackProviderTurnId;
|
|
180
|
+
const relevant = candidates.size === 0
|
|
181
|
+
? events
|
|
182
|
+
: events.filter((event) => {
|
|
183
|
+
if (candidates.has(event.turnId))
|
|
184
|
+
return true;
|
|
185
|
+
if (event.payload.type !== "done")
|
|
186
|
+
return false;
|
|
187
|
+
return Boolean((event.payload.currentHead && candidates.has(event.payload.currentHead)) ||
|
|
188
|
+
(event.payload.lastTurnId && candidates.has(event.payload.lastTurnId)));
|
|
189
|
+
});
|
|
190
|
+
if (relevant.length === 0) {
|
|
191
|
+
return {
|
|
192
|
+
status: "not_found",
|
|
193
|
+
providerTurnId,
|
|
194
|
+
reason: "No provider history event matched the requested turn",
|
|
195
|
+
evidence: "provider-history-empty",
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
const done = [...relevant].reverse().find((event) => event.payload.type === "done");
|
|
199
|
+
if (done?.payload.type === "done") {
|
|
200
|
+
return {
|
|
201
|
+
status: "terminal",
|
|
202
|
+
terminalStatus: done.payload.status,
|
|
203
|
+
currentHead: done.payload.currentHead,
|
|
204
|
+
lastTurnId: done.payload.lastTurnId ?? done.turnId,
|
|
205
|
+
providerTurnId: done.payload.lastTurnId ?? done.payload.currentHead ?? providerTurnId,
|
|
206
|
+
error: done.payload.error,
|
|
207
|
+
evidence: "provider-history-terminal",
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
return {
|
|
211
|
+
status: "active",
|
|
212
|
+
providerTurnId,
|
|
213
|
+
evidence: "provider-history-nonterminal-events",
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
async function settleTerminalSideEffects(config, result) {
|
|
217
|
+
await handleGatewayTurnTerminal(config, {
|
|
218
|
+
sessionId: result.sessionId,
|
|
219
|
+
requestId: result.requestId ?? result.turnId ?? "",
|
|
220
|
+
turnId: result.turnId ?? result.lastTurnId ?? "",
|
|
221
|
+
status: result.terminalStatus ?? "completed",
|
|
222
|
+
error: result.error,
|
|
223
|
+
}).catch((error) => {
|
|
224
|
+
console.error(`Gateway reconcile terminal hook failed for ${result.turnId}: ${error instanceof Error ? error.message : String(error)}`);
|
|
225
|
+
});
|
|
226
|
+
await settleScheduleTurnTerminal({
|
|
227
|
+
requestId: result.requestId ?? result.turnId ?? "",
|
|
228
|
+
turnId: result.turnId ?? result.lastTurnId ?? "",
|
|
229
|
+
status: result.terminalStatus ?? "completed",
|
|
230
|
+
error: result.error,
|
|
231
|
+
}).catch((error) => {
|
|
232
|
+
console.error(`Schedule reconcile terminal hook failed for ${result.turnId}: ${error instanceof Error ? error.message : String(error)}`);
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
//# sourceMappingURL=reconcile.js.map
|