maka-agent 0.2.0-dev.23.20260906 → 0.2.0-dev.25.20260908
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +38 -19
- package/README.zh-CN.md +34 -19
- package/dist/acp/maka-acp-agent.js +2 -1
- package/dist/acp/session-configuration.js +143 -0
- package/dist/acp/session-registry.js +90 -4
- package/dist/cli-core.js +2 -0
- package/dist/pi-transcript-tools.js +6 -0
- package/dist/pi-transcript.js +5 -12
- package/dist/pi-tui-layout.js +56 -10
- package/dist/pi-tui-pickers.js +102 -1
- package/dist/pi-tui-runner.js +230 -46
- package/dist/pi-tui-todo.js +221 -0
- package/dist/pi-tui-transcript-viewer.js +134 -7
- package/dist/runtime-host-cli-context.js +224 -78
- package/dist/runtime-host-cli-installation.js +8 -2
- package/dist/runtime-host-cli.js +31 -1
- package/dist/runtime-host-handoff-surface.js +106 -0
- package/dist/runtime-host-installed-update-bootstrap.js +13 -0
- package/dist/runtime-host-installed-update-coordinator.js +33 -0
- package/dist/runtime-host-lifecycle-transaction.js +9 -1
- package/dist/runtime-host-local-handoff.js +48 -5
- package/dist/runtime-host-local-managed-activation.js +84 -0
- package/dist/runtime-host-local-source-retirement.js +18 -2
- package/dist/runtime-host-managed-lifecycle-manager.js +1 -0
- package/dist/runtime-host-operator-retirement.js +50 -0
- package/dist/runtime-host-service-manager.js +3 -3
- package/dist/runtime-host-session-channel.js +13 -0
- package/dist/runtime-host-session-driver.js +46 -26
- package/dist/runtime-host-session-update.js +62 -0
- package/dist/runtime-host-tui-command.js +38 -73
- package/dist/runtime-host-tui-context.js +1 -0
- package/dist/runtime-host-tui-owner.js +226 -0
- package/dist/tui-copy-catalog.js +219 -6
- package/dist/tui-host-owner-copy.js +24 -0
- package/native/runtime-host-windows-task-launcher/prebuilds/win32-x64/maka-runtime-host-task-launcher.exe +0 -0
- package/node_modules/@maka/core/dist/agent-run.js +1 -0
- package/node_modules/@maka/core/dist/attachments.js +3 -0
- package/node_modules/@maka/core/dist/canonical-json.js +27 -0
- package/node_modules/@maka/core/dist/canonical-runtime-event.js +3 -1
- package/node_modules/@maka/core/dist/capabilities.js +35 -0
- package/node_modules/@maka/core/dist/computer-use.js +0 -1
- package/node_modules/@maka/core/dist/display-redaction.js +18 -0
- package/node_modules/@maka/core/dist/llm-connections.js +13 -0
- package/node_modules/@maka/core/dist/model-call-attempt.js +2 -0
- package/node_modules/@maka/core/dist/model-failure.js +40 -0
- package/node_modules/@maka/core/dist/model-metadata.generated.js +4 -4
- package/node_modules/@maka/core/dist/model-metadata.js +7 -3
- package/node_modules/@maka/core/dist/model-web-search.js +5 -4
- package/node_modules/@maka/core/dist/provider-registry.js +45 -4
- package/node_modules/@maka/core/dist/record-schema.js +9 -2
- package/node_modules/@maka/core/dist/redaction.js +35 -0
- package/node_modules/@maka/core/dist/run-composition.js +77 -2
- package/node_modules/@maka/core/dist/runtime-boundary.js +31 -11
- package/node_modules/@maka/core/dist/runtime-event.js +37 -6
- package/node_modules/@maka/core/dist/runtime-handoff.js +98 -0
- package/node_modules/@maka/core/dist/runtime-invocation.js +1 -1
- package/node_modules/@maka/core/dist/runtime-logical-execution.js +112 -0
- package/node_modules/@maka/core/dist/session.js +84 -56
- package/node_modules/@maka/core/dist/slash-command-catalog.js +3 -0
- package/node_modules/@maka/core/dist/tool-result-archive-evidence.js +20 -0
- package/node_modules/@maka/core/dist/tool-result-record-schema.js +2 -1
- package/node_modules/@maka/core/dist/usage-record-schema.js +26 -35
- package/node_modules/@maka/core/package.json +5 -0
- package/node_modules/@maka/eval/dist/experiment-directory.js +4 -13
- package/node_modules/@maka/mcp/dist/index.js +131 -1
- package/node_modules/@maka/runtime/dist/agent-run-inspect.js +0 -13
- package/node_modules/@maka/runtime/dist/agent-run.js +351 -105
- package/node_modules/@maka/runtime/dist/ai-sdk-backend.js +29 -13
- package/node_modules/@maka/runtime/dist/ai-sdk-compaction.js +109 -34
- package/node_modules/@maka/runtime/dist/ai-sdk-turn.js +184 -183
- package/node_modules/@maka/runtime/dist/archive-read-tool.js +2 -2
- package/node_modules/@maka/runtime/dist/context-budget-helpers.js +0 -16
- package/node_modules/@maka/runtime/dist/context-budget.js +14 -9
- package/node_modules/@maka/runtime/dist/conversation-copy.js +158 -15
- package/node_modules/@maka/runtime/dist/github-copilot-oauth-enrollment.js +3 -3
- package/node_modules/@maka/runtime/dist/goal-continuation.js +36 -4
- package/node_modules/@maka/runtime/dist/history-compact-checkpoint.js +18 -9
- package/node_modules/@maka/runtime/dist/history-compact-summarizer.js +30 -22
- package/node_modules/@maka/runtime/dist/history-compaction.js +29 -4
- package/node_modules/@maka/runtime/dist/ledger-tool-result-archive-reader.js +174 -0
- package/node_modules/@maka/runtime/dist/mcp-tools.js +7 -2
- package/node_modules/@maka/runtime/dist/message-authority.js +9 -0
- package/node_modules/@maka/runtime/dist/model-adapter.js +19 -98
- package/node_modules/@maka/runtime/dist/model-factory.js +19 -81
- package/node_modules/@maka/runtime/dist/model-fetcher.js +49 -2
- package/node_modules/@maka/runtime/dist/model-history.js +0 -112
- package/node_modules/@maka/runtime/dist/model-runtime.js +85 -111
- package/node_modules/@maka/runtime/dist/native-web-search-tool.js +2 -1
- package/node_modules/@maka/runtime/dist/openai-codex-history-compactor.js +2 -2
- package/node_modules/@maka/runtime/dist/opencode-session-header.js +4 -2
- package/node_modules/@maka/runtime/dist/plugin-runtime.js +20 -10
- package/node_modules/@maka/runtime/dist/plugin-tool-service.js +205 -0
- package/node_modules/@maka/runtime/dist/provider-error-classification.js +84 -123
- package/node_modules/@maka/runtime/dist/provider-request-telemetry.js +76 -109
- package/node_modules/@maka/runtime/dist/request-shape.js +23 -0
- package/node_modules/@maka/runtime/dist/run-handoff-gate.js +97 -0
- package/node_modules/@maka/runtime/dist/runtime-event-backfill.js +83 -55
- package/node_modules/@maka/runtime/dist/runtime-event-read-model.js +121 -159
- package/node_modules/@maka/runtime/dist/runtime-kernel.js +157 -112
- package/node_modules/@maka/runtime/dist/runtime-ledger-repair.js +160 -79
- package/node_modules/@maka/runtime/dist/runtime-read-model.js +30 -89
- package/node_modules/@maka/runtime/dist/runtime-resume.js +80 -4
- package/node_modules/@maka/runtime/dist/session-event-runtime-mapper.js +5 -0
- package/node_modules/@maka/runtime/dist/session-manager.js +171 -288
- package/node_modules/@maka/runtime/dist/session-projection-helpers.js +0 -27
- package/node_modules/@maka/runtime/dist/stream-graph-coordinator.js +21 -0
- package/node_modules/@maka/runtime/dist/stream-graph-supervisor-tools.js +0 -5
- package/node_modules/@maka/runtime/dist/subscription-model-fetch.js +3 -4
- package/node_modules/@maka/runtime/dist/test-connection.js +16 -17
- package/node_modules/@maka/runtime/dist/tool-activation-identity.js +41 -0
- package/node_modules/@maka/runtime/dist/tool-availability.js +11 -1
- package/node_modules/@maka/runtime/dist/tool-result-archive-encoding.js +38 -0
- package/node_modules/@maka/runtime/dist/tool-result-archive-resource.js +63 -1
- package/node_modules/@maka/runtime/dist/tool-result-archive-transition.js +42 -12
- package/node_modules/@maka/runtime/dist/tool-result-archive.js +27 -4
- package/node_modules/@maka/runtime/dist/tool-runtime.js +3 -61
- package/node_modules/@maka/runtime/package.json +2 -0
- package/node_modules/@maka/runtime-host/dist/adapter/session-projector.js +35 -0
- package/node_modules/@maka/runtime-host/dist/client/connect-or-spawn.js +9 -1
- package/node_modules/@maka/runtime-host/dist/client/connection.js +3 -0
- package/node_modules/@maka/runtime-host/dist/client/host-handoff-copy.js +179 -0
- package/node_modules/@maka/runtime-host/dist/client/host-handoff.js +275 -0
- package/node_modules/@maka/runtime-host/dist/client/host-retirement.js +26 -5
- package/node_modules/@maka/runtime-host/dist/client/index.js +2 -0
- package/node_modules/@maka/runtime-host/dist/client/launcher.js +3 -0
- package/node_modules/@maka/runtime-host/dist/client/remote-compatibility-error.js +2 -0
- package/node_modules/@maka/runtime-host/dist/client/session-subscription.js +46 -5
- package/node_modules/@maka/runtime-host/dist/control/endpoint.js +1 -3
- package/node_modules/@maka/runtime-host/dist/node-error.js +22 -0
- package/node_modules/@maka/runtime-host/dist/operator/index.js +2 -1
- package/node_modules/@maka/runtime-host/dist/operator/managed-deployment.js +1 -3
- package/node_modules/@maka/runtime-host/dist/operator/retirement-cancellation.js +20 -0
- package/node_modules/@maka/runtime-host/dist/peer-mesh/limits.js +0 -1
- package/node_modules/@maka/runtime-host/dist/peer-mesh/model.js +1 -1
- package/node_modules/@maka/runtime-host/dist/peer-reachability/publisher.js +1 -3
- package/node_modules/@maka/runtime-host/dist/protocol/host-status.js +21 -12
- package/node_modules/@maka/runtime-host/dist/protocol/index.js +29 -1
- package/node_modules/@maka/runtime-host/dist/protocol/operations.js +1 -0
- package/node_modules/@maka/runtime-host/dist/protocol/plan.js +1 -0
- package/node_modules/@maka/runtime-host/dist/protocol/plugin-platform.js +27 -5
- package/node_modules/@maka/runtime-host/dist/protocol/project-catalog.js +2 -2
- package/node_modules/@maka/runtime-host/dist/protocol/session-continuity.js +40 -20
- package/node_modules/@maka/runtime-host/dist/protocol/session-transcript.js +0 -5
- package/node_modules/@maka/runtime-host/dist/protocol/session-turns.js +29 -58
- package/node_modules/@maka/runtime-host/dist/protocol/turn.js +11 -1
- package/node_modules/@maka/runtime-host/dist/protocol/workhub-coordination.js +31 -2
- package/node_modules/@maka/runtime-host/dist/server/access-credential-store.js +1 -0
- package/node_modules/@maka/runtime-host/dist/server/agent-graph-coordinator.js +0 -3
- package/node_modules/@maka/runtime-host/dist/server/canonical-turn-snapshot.js +19 -4
- package/node_modules/@maka/runtime-host/dist/server/connection-session.js +7 -6
- package/node_modules/@maka/runtime-host/dist/server/execution-artifacts.js +32 -32
- package/node_modules/@maka/runtime-host/dist/server/execution-composition.js +144 -33
- package/node_modules/@maka/runtime-host/dist/server/execution-model-authority.js +5 -5
- package/node_modules/@maka/runtime-host/dist/server/execution-model-composition.js +45 -16
- package/node_modules/@maka/runtime-host/dist/server/goal-coordinator.js +40 -1
- package/node_modules/@maka/runtime-host/dist/server/host-kernel.js +96 -17
- package/node_modules/@maka/runtime-host/dist/server/host-residency-registry.js +13 -7
- package/node_modules/@maka/runtime-host/dist/server/hosted-execution-admission-registry.js +3 -1
- package/node_modules/@maka/runtime-host/dist/server/hosted-execution-recovery.js +124 -62
- package/node_modules/@maka/runtime-host/dist/server/interactive-run-composer.js +47 -22
- package/node_modules/@maka/runtime-host/dist/server/message-coordinator.js +76 -6
- package/node_modules/@maka/runtime-host/dist/server/plugin-platform-coordinator.js +6 -0
- package/node_modules/@maka/runtime-host/dist/server/plugin-platform.js +6 -0
- package/node_modules/@maka/runtime-host/dist/server/root-turn-coordinator.js +325 -73
- package/node_modules/@maka/runtime-host/dist/server/scheduled-task-coordinator.js +37 -2
- package/node_modules/@maka/runtime-host/dist/server/serial-outbound-writer.js +45 -3
- package/node_modules/@maka/runtime-host/dist/server/session-catalog-coordinator.js +50 -7
- package/node_modules/@maka/runtime-host/dist/server/session-continuity-coordinator.js +87 -25
- package/node_modules/@maka/runtime-host/dist/server/session-retirement-coordinator.js +5 -2
- package/node_modules/@maka/runtime-host/dist/server/session-revision-coordinator.js +12 -55
- package/node_modules/@maka/runtime-host/dist/server/session-sidecar-purge.js +1 -16
- package/node_modules/@maka/runtime-host/dist/server/session-transcript-pager.js +0 -1
- package/node_modules/@maka/runtime-host/dist/server/session-transcript-reader.js +460 -70
- package/node_modules/@maka/runtime-host/dist/server/shared-session-transcript.js +1 -1
- package/node_modules/@maka/runtime-host/dist/server/storage-maintenance.js +109 -0
- package/node_modules/@maka/runtime-host/dist/server/workhub-coordination-action-gate.js +20 -2
- package/node_modules/@maka/runtime-host/dist/server/workhub-coordination-coordinator.js +13 -4
- package/node_modules/@maka/runtime-host/dist/server/workhub-message-attachments.js +46 -0
- package/node_modules/@maka/storage/dist/artifact-store.js +21 -10
- package/node_modules/@maka/storage/dist/artifact-stores.js +1 -1
- package/node_modules/@maka/storage/dist/claude-code-session-adapter.js +0 -5
- package/node_modules/@maka/storage/dist/codex-session-adapter.js +284 -198
- package/node_modules/@maka/storage/dist/context-offload-snapshot.js +325 -0
- package/node_modules/@maka/storage/dist/execution-stores.js +9 -7
- package/node_modules/@maka/storage/dist/file-session-repository.js +1012 -0
- package/node_modules/@maka/storage/dist/git-exec.js +61 -0
- package/node_modules/@maka/storage/dist/git-worktree-child-executor.js +8 -35
- package/node_modules/@maka/storage/dist/goal-authority.js +2 -2
- package/node_modules/@maka/storage/dist/interaction-store.js +2 -2
- package/node_modules/@maka/storage/dist/opencode-session-adapter.js +0 -4
- package/node_modules/@maka/storage/dist/operational-state-backup.js +9 -5
- package/node_modules/@maka/storage/dist/project-catalog.js +2 -23
- package/node_modules/@maka/storage/dist/runtime-event-invariants.js +2 -2
- package/node_modules/@maka/storage/dist/runtime-event-persistence.js +1 -0
- package/node_modules/@maka/storage/dist/runtime-policy/connection-catalog-document.js +8 -3
- package/node_modules/@maka/storage/dist/runtime-transcript-query.js +308 -0
- package/node_modules/@maka/storage/dist/scheduled-task-store.js +249 -283
- package/node_modules/@maka/storage/dist/session-bundle-manifest.js +5 -17
- package/node_modules/@maka/storage/dist/session-bundle-policy.js +26 -5
- package/node_modules/@maka/storage/dist/session-copy-cleanup.js +2 -1
- package/node_modules/@maka/storage/dist/session-message-projection.js +15 -0
- package/node_modules/@maka/storage/dist/session-repository.js +767 -0
- package/node_modules/@maka/storage/dist/session-store.js +25 -99
- package/node_modules/@maka/storage/dist/sqlite-artifact-metadata.js +10 -3
- package/node_modules/@maka/storage/dist/sqlite-context-offload-store.js +24 -8
- package/node_modules/@maka/storage/dist/sqlite-core-execution-schema.js +7 -1
- package/node_modules/@maka/storage/dist/sqlite-runtime-schema.js +44 -1
- package/node_modules/@maka/storage/dist/sqlite-runtime-store.js +130 -27
- package/node_modules/@maka/storage/dist/sqlite-session-metadata-store.js +109 -892
- package/node_modules/@maka/storage/dist/storage-id.js +28 -0
- package/node_modules/@maka/storage/dist/tool-result-archive-evidence.js +138 -0
- package/node_modules/@maka/storage/dist/workspace-identity.js +2 -15
- package/node_modules/@maka/storage/dist/workspace-version-authority-internal.js +1 -8
- package/node_modules/@maka/storage/package.json +2 -0
- package/package.json +1 -1
|
@@ -0,0 +1,308 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Licensed to the Apache Software Foundation (ASF) under one
|
|
3
|
+
* or more contributor license agreements. See the NOTICE file
|
|
4
|
+
* distributed with this work for additional information
|
|
5
|
+
* regarding copyright ownership. The ASF licenses this file
|
|
6
|
+
* to you under the Apache License, Version 2.0 (the
|
|
7
|
+
* "License"); you may not use this file except in compliance
|
|
8
|
+
* with the License. You may obtain a copy of the License at
|
|
9
|
+
*
|
|
10
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
+
*
|
|
12
|
+
* Unless required by applicable law or agreed to in writing,
|
|
13
|
+
* software distributed under the License is distributed on an
|
|
14
|
+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
15
|
+
* KIND, either express or implied. See the License for the
|
|
16
|
+
* specific language governing permissions and limitations
|
|
17
|
+
* under the License.
|
|
18
|
+
*/
|
|
19
|
+
import { decodeRuntimeEvent } from '@maka/core/runtime-event';
|
|
20
|
+
/**
|
|
21
|
+
* SQL counterpart of isTerminalRuntimeEvent; shared with the ledger store.
|
|
22
|
+
*
|
|
23
|
+
* The `json_valid` guard is what keeps this usable as a partial index: SQLite
|
|
24
|
+
* evaluates the index predicate over every row while building it, and
|
|
25
|
+
* `json_extract` on a malformed payload fails the whole statement. That would
|
|
26
|
+
* abort the migration that creates the index, roll back its version bump, and
|
|
27
|
+
* leave the next open to try — and fail — again.
|
|
28
|
+
*/
|
|
29
|
+
export const TERMINAL_RUNTIME_EVENT_SQL = `(
|
|
30
|
+
json_valid(payload_json)
|
|
31
|
+
AND (
|
|
32
|
+
json_extract(payload_json, '$.actions.endInvocation') = 1
|
|
33
|
+
OR json_extract(payload_json, '$.status') IN ('completed', 'failed', 'aborted', 'cancelled')
|
|
34
|
+
)
|
|
35
|
+
)`;
|
|
36
|
+
export class RuntimeTranscriptOversizedTurnError extends Error {
|
|
37
|
+
name = 'RuntimeTranscriptOversizedTurnError';
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* A Turn the Session transcript shows: one this Session ran itself rather than
|
|
41
|
+
* on behalf of a subagent.
|
|
42
|
+
*
|
|
43
|
+
* This is a fact about the invocation, not about any row it produces — which
|
|
44
|
+
* rows it produces is the read model's question, and is not asked here.
|
|
45
|
+
*/
|
|
46
|
+
const visibleOpening = (payload) => `
|
|
47
|
+
(${payload} IS NOT NULL
|
|
48
|
+
AND (json_extract(${payload}, '$.lineage.parentRunId') IS NULL
|
|
49
|
+
OR (json_extract(${payload}, '$.source.kind') <> 'fresh'
|
|
50
|
+
AND json_extract(${payload}, '$.lineage.agentId') IS NULL)))`;
|
|
51
|
+
/** Where an invocation ends; NULL while it is still running. */
|
|
52
|
+
const endingOrdinal = (invocation) => `
|
|
53
|
+
(SELECT MIN(o2.ordinal) FROM runtime_events t
|
|
54
|
+
JOIN runtime_session_event_ordinals o2 ON o2.event_id = t.event_id
|
|
55
|
+
WHERE t.invocation_id = ${invocation}
|
|
56
|
+
AND ${TERMINAL_RUNTIME_EVENT_SQL.replaceAll('payload_json', 't.payload_json')})`;
|
|
57
|
+
/**
|
|
58
|
+
* A Session migrated from run headers keeps some openings beside the ledger
|
|
59
|
+
* rather than in it, ordered by the anchor event each one names.
|
|
60
|
+
*/
|
|
61
|
+
const migratedOpening = `
|
|
62
|
+
FROM runtime_legacy_invocation_openings legacy
|
|
63
|
+
JOIN runtime_session_event_ordinals o ON o.event_id = legacy.anchor_event_id
|
|
64
|
+
WHERE legacy.session_id = :sessionId
|
|
65
|
+
AND ${visibleOpening('legacy.opening_json')}
|
|
66
|
+
AND NOT EXISTS (
|
|
67
|
+
SELECT 1 FROM runtime_events opened
|
|
68
|
+
WHERE opened.invocation_id = legacy.invocation_id
|
|
69
|
+
AND opened.event_kind = 'invocation_opened'
|
|
70
|
+
)`;
|
|
71
|
+
const ledgerOpening = `
|
|
72
|
+
FROM runtime_session_event_ordinals o
|
|
73
|
+
JOIN runtime_events e ON e.event_id = o.event_id
|
|
74
|
+
WHERE o.session_id = :sessionId
|
|
75
|
+
AND e.event_kind = 'invocation_opened'
|
|
76
|
+
AND ${visibleOpening("json_extract(e.payload_json, '$.content')")}`;
|
|
77
|
+
/** Either shelf's opening for one invocation, reached from an event it owns. */
|
|
78
|
+
const openingOrdinal = (invocation) => `
|
|
79
|
+
COALESCE(
|
|
80
|
+
(SELECT o3.ordinal FROM runtime_events op
|
|
81
|
+
JOIN runtime_session_event_ordinals o3 ON o3.event_id = op.event_id
|
|
82
|
+
WHERE op.invocation_id = ${invocation} AND op.event_kind = 'invocation_opened'),
|
|
83
|
+
(SELECT o3.ordinal FROM runtime_legacy_invocation_openings lg
|
|
84
|
+
JOIN runtime_session_event_ordinals o3 ON o3.event_id = lg.anchor_event_id
|
|
85
|
+
WHERE lg.invocation_id = ${invocation}))`;
|
|
86
|
+
const openingContent = (invocation) => `
|
|
87
|
+
COALESCE(
|
|
88
|
+
(SELECT json_extract(op.payload_json, '$.content') FROM runtime_events op
|
|
89
|
+
WHERE op.invocation_id = ${invocation} AND op.event_kind = 'invocation_opened'),
|
|
90
|
+
(SELECT lg.opening_json FROM runtime_legacy_invocation_openings lg
|
|
91
|
+
WHERE lg.invocation_id = ${invocation}))`;
|
|
92
|
+
/** Selects invocations by Session ordinal. Payloads are decoded, never classified. */
|
|
93
|
+
export class RuntimeTranscriptQuery {
|
|
94
|
+
db;
|
|
95
|
+
invocation;
|
|
96
|
+
constructor(db, invocation) {
|
|
97
|
+
this.db = db;
|
|
98
|
+
this.invocation = invocation;
|
|
99
|
+
}
|
|
100
|
+
highWater(sessionId) {
|
|
101
|
+
// The furthest a transcript reaches is the last ending on it.
|
|
102
|
+
const [row] = this.byEnding(sessionId, {
|
|
103
|
+
order: 'DESC',
|
|
104
|
+
from: 0,
|
|
105
|
+
throughOrdinal: Number.MAX_SAFE_INTEGER,
|
|
106
|
+
limit: 1,
|
|
107
|
+
});
|
|
108
|
+
return row?.last ?? null;
|
|
109
|
+
}
|
|
110
|
+
invocations(sessionId, request) {
|
|
111
|
+
assertOrdinal(request.throughOrdinal);
|
|
112
|
+
assertOrdinal(request.position);
|
|
113
|
+
if (request.direction !== 'older' && request.direction !== 'newer') {
|
|
114
|
+
throw new Error('Invalid transcript direction');
|
|
115
|
+
}
|
|
116
|
+
// An invocation is selected by where its own events sit, so a walk that
|
|
117
|
+
// starts inside a Turn still finds that Turn and can serve its rows. Both
|
|
118
|
+
// ends are the invocation's own two events — its opening and its ending —
|
|
119
|
+
// rather than the extremes of everything between them.
|
|
120
|
+
//
|
|
121
|
+
// Each direction walks the end of the Turn that `position` bounds, which
|
|
122
|
+
// is the one the ordinal index can seek to: backward that is the opening,
|
|
123
|
+
// forward the ending. Neither assumes Turns do not overlap, and each stops
|
|
124
|
+
// at the page, so a page costs the page rather than the Session.
|
|
125
|
+
const rows = request.direction === 'older'
|
|
126
|
+
? this.byOpening(sessionId, request)
|
|
127
|
+
: this.byEnding(sessionId, {
|
|
128
|
+
order: 'ASC',
|
|
129
|
+
from: request.position,
|
|
130
|
+
throughOrdinal: request.throughOrdinal,
|
|
131
|
+
limit: request.limit,
|
|
132
|
+
}).sort((a, b) => a.first - b.first);
|
|
133
|
+
return rows.map((row) => ({
|
|
134
|
+
invocation: this.invocation(sessionId, row.invocation_id),
|
|
135
|
+
firstOrdinal: row.first,
|
|
136
|
+
lastOrdinal: row.last,
|
|
137
|
+
events: this.events(row.invocation_id, request),
|
|
138
|
+
}));
|
|
139
|
+
}
|
|
140
|
+
landmarks(sessionId, throughOrdinal, limit) {
|
|
141
|
+
assertOrdinal(throughOrdinal);
|
|
142
|
+
if (limit < 1)
|
|
143
|
+
return [];
|
|
144
|
+
// Evenly spaced Turn starts, chosen before any payload is read.
|
|
145
|
+
const rows = this.db
|
|
146
|
+
.prepare(`
|
|
147
|
+
WITH settled AS (
|
|
148
|
+
SELECT e.invocation_id AS invocation_id, o.ordinal AS ordinal ${ledgerOpening}
|
|
149
|
+
AND ${endingOrdinal('e.invocation_id')} <= :throughOrdinal
|
|
150
|
+
UNION ALL
|
|
151
|
+
SELECT legacy.invocation_id, o.ordinal ${migratedOpening}
|
|
152
|
+
AND ${endingOrdinal('legacy.invocation_id')} <= :throughOrdinal
|
|
153
|
+
), candidates AS (
|
|
154
|
+
SELECT invocation_id, ordinal,
|
|
155
|
+
ROW_NUMBER() OVER (ORDER BY ordinal) - 1 AS rank, COUNT(*) OVER () AS total
|
|
156
|
+
FROM settled
|
|
157
|
+
), samples(n) AS (
|
|
158
|
+
SELECT 0 UNION ALL SELECT n + 1 FROM samples WHERE n + 1 < :limit
|
|
159
|
+
)
|
|
160
|
+
SELECT DISTINCT invocation_id, ordinal FROM candidates
|
|
161
|
+
JOIN samples ON rank = CASE WHEN :limit = 1 THEN total - 1
|
|
162
|
+
ELSE CAST(n * (total - 1) / (:limit - 1) AS INTEGER) END
|
|
163
|
+
ORDER BY ordinal
|
|
164
|
+
`)
|
|
165
|
+
.all({ sessionId, throughOrdinal, limit });
|
|
166
|
+
return rows.map((row) => {
|
|
167
|
+
// The prompt is the Turn's first user text event, which is what the read
|
|
168
|
+
// model projects a user message from. Only that one event is loaded: a
|
|
169
|
+
// landmark is a label, and projecting whole Turns to build a scrollbar
|
|
170
|
+
// would read most of the Session.
|
|
171
|
+
const prompt = this.db
|
|
172
|
+
.prepare(`
|
|
173
|
+
SELECT o.ordinal, e.event_id FROM runtime_events e
|
|
174
|
+
JOIN runtime_session_event_ordinals o ON o.event_id = e.event_id
|
|
175
|
+
WHERE e.invocation_id = ? AND o.ordinal <= ?
|
|
176
|
+
AND e.event_kind = 'text' AND json_extract(e.payload_json, '$.role') = 'user'
|
|
177
|
+
ORDER BY e.event_seq LIMIT 1
|
|
178
|
+
`)
|
|
179
|
+
.get(row.invocation_id, throughOrdinal);
|
|
180
|
+
return {
|
|
181
|
+
invocation: this.invocation(sessionId, row.invocation_id),
|
|
182
|
+
firstOrdinal: row.ordinal,
|
|
183
|
+
...(prompt
|
|
184
|
+
? { prompt: { ordinal: prompt.ordinal, event: this.event(prompt.event_id) } }
|
|
185
|
+
: {}),
|
|
186
|
+
};
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* The page of settled visible invocations that opened at or before
|
|
191
|
+
* `position`, newest first.
|
|
192
|
+
*
|
|
193
|
+
* The two shelves are read as separate statements and merged rather than
|
|
194
|
+
* unioned, so each keeps its own index walk and stops at the page — and the
|
|
195
|
+
* common Session pays nothing for a table its history never wrote to.
|
|
196
|
+
*/
|
|
197
|
+
byOpening(sessionId, request) {
|
|
198
|
+
const bind = {
|
|
199
|
+
sessionId,
|
|
200
|
+
position: request.position,
|
|
201
|
+
throughOrdinal: request.throughOrdinal,
|
|
202
|
+
limit: request.limit,
|
|
203
|
+
};
|
|
204
|
+
const ledger = this.db
|
|
205
|
+
.prepare(`
|
|
206
|
+
SELECT e.invocation_id AS invocation_id, o.ordinal AS first,
|
|
207
|
+
${endingOrdinal('e.invocation_id')} AS last
|
|
208
|
+
${ledgerOpening}
|
|
209
|
+
AND o.ordinal <= :position
|
|
210
|
+
AND ${endingOrdinal('e.invocation_id')} <= :throughOrdinal
|
|
211
|
+
ORDER BY o.ordinal DESC
|
|
212
|
+
LIMIT :limit
|
|
213
|
+
`)
|
|
214
|
+
.all(bind);
|
|
215
|
+
const migrated = this.db
|
|
216
|
+
.prepare(`
|
|
217
|
+
SELECT legacy.invocation_id AS invocation_id, o.ordinal AS first,
|
|
218
|
+
${endingOrdinal('legacy.invocation_id')} AS last
|
|
219
|
+
${migratedOpening}
|
|
220
|
+
AND o.ordinal <= :position
|
|
221
|
+
AND ${endingOrdinal('legacy.invocation_id')} <= :throughOrdinal
|
|
222
|
+
ORDER BY o.ordinal DESC
|
|
223
|
+
LIMIT :limit
|
|
224
|
+
`)
|
|
225
|
+
.all(bind);
|
|
226
|
+
if (migrated.length === 0)
|
|
227
|
+
return ledger;
|
|
228
|
+
return [...ledger, ...migrated].sort((a, b) => b.first - a.first).slice(0, request.limit);
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* The page of settled visible invocations whose ending sits between `from`
|
|
232
|
+
* and `throughOrdinal`, in `order` of that ending.
|
|
233
|
+
*
|
|
234
|
+
* An ending is an event of the invocation like any other, so this walks the
|
|
235
|
+
* same ordinal index — one statement, because the ending is on the ledger
|
|
236
|
+
* whichever shelf the opening came from.
|
|
237
|
+
*/
|
|
238
|
+
byEnding(sessionId, bounds) {
|
|
239
|
+
return this.db
|
|
240
|
+
.prepare(`
|
|
241
|
+
SELECT ending.invocation_id AS invocation_id,
|
|
242
|
+
${openingOrdinal('ending.invocation_id')} AS first,
|
|
243
|
+
o.ordinal AS last
|
|
244
|
+
FROM runtime_session_event_ordinals o
|
|
245
|
+
JOIN runtime_events ending ON ending.event_id = o.event_id
|
|
246
|
+
WHERE o.session_id = :sessionId
|
|
247
|
+
AND o.ordinal BETWEEN :from AND :throughOrdinal
|
|
248
|
+
AND ${TERMINAL_RUNTIME_EVENT_SQL.replaceAll('payload_json', 'ending.payload_json')}
|
|
249
|
+
AND o.ordinal = ${endingOrdinal('ending.invocation_id')}
|
|
250
|
+
AND ${visibleOpening(openingContent('ending.invocation_id'))}
|
|
251
|
+
ORDER BY o.ordinal ${bounds.order}
|
|
252
|
+
LIMIT :limit
|
|
253
|
+
`)
|
|
254
|
+
.all({
|
|
255
|
+
sessionId,
|
|
256
|
+
from: bounds.from,
|
|
257
|
+
throughOrdinal: bounds.throughOrdinal,
|
|
258
|
+
limit: bounds.limit,
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
events(invocationId, limits) {
|
|
262
|
+
// Walked row by row: the limits cap what one Turn may pull into memory, so
|
|
263
|
+
// a check after `.all()` has already paid the cost it was meant to refuse.
|
|
264
|
+
const cursor = this.db
|
|
265
|
+
.prepare(`
|
|
266
|
+
SELECT o.ordinal, e.event_id, e.session_id, e.invocation_id, e.run_id, e.turn_id, e.payload_json
|
|
267
|
+
FROM runtime_events e JOIN runtime_session_event_ordinals o ON o.event_id = e.event_id
|
|
268
|
+
WHERE e.invocation_id = ? ORDER BY e.event_seq
|
|
269
|
+
`)
|
|
270
|
+
.iterate(invocationId);
|
|
271
|
+
const events = [];
|
|
272
|
+
let bytes = 0;
|
|
273
|
+
for (const row of cursor) {
|
|
274
|
+
if (events.length === limits.maxEvents) {
|
|
275
|
+
throw new RuntimeTranscriptOversizedTurnError(`Turn ${invocationId} holds more RuntimeEvents than a transcript page may read`);
|
|
276
|
+
}
|
|
277
|
+
bytes += Buffer.byteLength(row.payload_json);
|
|
278
|
+
if (bytes > limits.maxBytes) {
|
|
279
|
+
throw new RuntimeTranscriptOversizedTurnError(`Turn ${invocationId} holds more RuntimeEvent bytes than a transcript page may read`);
|
|
280
|
+
}
|
|
281
|
+
events.push({ ordinal: row.ordinal, event: decodeStoredEvent(row) });
|
|
282
|
+
}
|
|
283
|
+
return events;
|
|
284
|
+
}
|
|
285
|
+
event(id) {
|
|
286
|
+
const row = this.db
|
|
287
|
+
.prepare('SELECT event_id, session_id, invocation_id, run_id, turn_id, payload_json FROM runtime_events WHERE event_id = ?')
|
|
288
|
+
.get(id);
|
|
289
|
+
if (!row)
|
|
290
|
+
throw new Error(`Transcript RuntimeEvent ${id} is missing`);
|
|
291
|
+
return decodeStoredEvent(row);
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
function decodeStoredEvent(row) {
|
|
295
|
+
const event = decodeRuntimeEvent(JSON.parse(row.payload_json));
|
|
296
|
+
if (event.id !== row.event_id ||
|
|
297
|
+
event.sessionId !== row.session_id ||
|
|
298
|
+
event.invocationId !== row.invocation_id ||
|
|
299
|
+
event.runId !== row.run_id ||
|
|
300
|
+
event.turnId !== row.turn_id) {
|
|
301
|
+
throw new Error(`Transcript RuntimeEvent ${row.event_id} has inconsistent storage identity`);
|
|
302
|
+
}
|
|
303
|
+
return event;
|
|
304
|
+
}
|
|
305
|
+
function assertOrdinal(value) {
|
|
306
|
+
if (!Number.isSafeInteger(value) || value < 0)
|
|
307
|
+
throw new Error('Invalid transcript event ordinal');
|
|
308
|
+
}
|