tinker-agent 1.0.65 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +36 -0
- package/LICENSE +201 -0
- package/NOTICE +6 -0
- package/README.md +90 -9
- package/bin/tinker.js +39 -0
- package/node_modules/ansi-regex/index.d.ts +33 -0
- package/node_modules/ansi-regex/index.js +14 -0
- package/node_modules/ansi-regex/license +9 -0
- package/node_modules/ansi-regex/package.json +61 -0
- package/node_modules/ansi-regex/readme.md +66 -0
- package/node_modules/ansi-styles/index.d.ts +236 -0
- package/node_modules/ansi-styles/index.js +223 -0
- package/node_modules/ansi-styles/license +9 -0
- package/node_modules/ansi-styles/package.json +54 -0
- package/node_modules/ansi-styles/readme.md +173 -0
- package/node_modules/chalk/license +9 -0
- package/node_modules/chalk/package.json +83 -0
- package/node_modules/chalk/readme.md +297 -0
- package/node_modules/chalk/source/index.d.ts +325 -0
- package/node_modules/chalk/source/index.js +225 -0
- package/node_modules/chalk/source/utilities.js +33 -0
- package/node_modules/chalk/source/vendor/ansi-styles/index.d.ts +236 -0
- package/node_modules/chalk/source/vendor/ansi-styles/index.js +223 -0
- package/node_modules/chalk/source/vendor/supports-color/browser.d.ts +1 -0
- package/node_modules/chalk/source/vendor/supports-color/browser.js +34 -0
- package/node_modules/chalk/source/vendor/supports-color/index.d.ts +55 -0
- package/node_modules/chalk/source/vendor/supports-color/index.js +190 -0
- package/node_modules/character-entities/index.d.ts +6 -0
- package/node_modules/character-entities/index.js +2132 -0
- package/node_modules/character-entities/license +22 -0
- package/node_modules/character-entities/package.json +78 -0
- package/node_modules/character-entities/readme.md +152 -0
- package/node_modules/decode-named-character-reference/index.d.ts +13 -0
- package/node_modules/decode-named-character-reference/index.d.ts.map +1 -0
- package/node_modules/decode-named-character-reference/index.dom.d.ts +6 -0
- package/node_modules/decode-named-character-reference/index.dom.d.ts.map +1 -0
- package/node_modules/decode-named-character-reference/index.dom.js +32 -0
- package/node_modules/decode-named-character-reference/index.js +19 -0
- package/node_modules/decode-named-character-reference/license +22 -0
- package/node_modules/decode-named-character-reference/package.json +90 -0
- package/node_modules/decode-named-character-reference/readme.md +136 -0
- package/node_modules/get-east-asian-width/index.d.ts +60 -0
- package/node_modules/get-east-asian-width/index.js +30 -0
- package/node_modules/get-east-asian-width/license +9 -0
- package/node_modules/get-east-asian-width/lookup-data.js +21 -0
- package/node_modules/get-east-asian-width/lookup.js +138 -0
- package/node_modules/get-east-asian-width/package.json +71 -0
- package/node_modules/get-east-asian-width/readme.md +65 -0
- package/node_modules/get-east-asian-width/utilities.js +24 -0
- package/node_modules/has-flag/index.d.ts +39 -0
- package/node_modules/has-flag/index.js +8 -0
- package/node_modules/has-flag/license +9 -0
- package/node_modules/has-flag/package.json +49 -0
- package/node_modules/has-flag/readme.md +74 -0
- package/node_modules/is-fullwidth-code-point/index.d.ts +17 -0
- package/node_modules/is-fullwidth-code-point/index.js +12 -0
- package/node_modules/is-fullwidth-code-point/license +9 -0
- package/node_modules/is-fullwidth-code-point/package.json +53 -0
- package/node_modules/is-fullwidth-code-point/readme.md +31 -0
- package/node_modules/markdansi/LICENSE +21 -0
- package/node_modules/markdansi/README.md +167 -0
- package/node_modules/markdansi/dist/ast.d.ts +99 -0
- package/node_modules/markdansi/dist/ast.js +1 -0
- package/node_modules/markdansi/dist/cli.d.ts +17 -0
- package/node_modules/markdansi/dist/cli.js +208 -0
- package/node_modules/markdansi/dist/hyperlink.d.ts +9 -0
- package/node_modules/markdansi/dist/hyperlink.js +26 -0
- package/node_modules/markdansi/dist/index.d.ts +10 -0
- package/node_modules/markdansi/dist/index.js +16 -0
- package/node_modules/markdansi/dist/parser.d.ts +2 -0
- package/node_modules/markdansi/dist/parser.js +205 -0
- package/node_modules/markdansi/dist/render.d.ts +9 -0
- package/node_modules/markdansi/dist/render.js +680 -0
- package/node_modules/markdansi/dist/stream.d.ts +39 -0
- package/node_modules/markdansi/dist/stream.js +192 -0
- package/node_modules/markdansi/dist/theme.d.ts +18 -0
- package/node_modules/markdansi/dist/theme.js +105 -0
- package/node_modules/markdansi/dist/types.d.ts +58 -0
- package/node_modules/markdansi/dist/types.js +1 -0
- package/node_modules/markdansi/dist/wrap.d.ts +10 -0
- package/node_modules/markdansi/dist/wrap.js +73 -0
- package/node_modules/markdansi/docs/spec.md +110 -0
- package/node_modules/markdansi/package.json +78 -0
- package/node_modules/markdansi/tsconfig.json +18 -0
- package/node_modules/marked/LICENSE +44 -0
- package/node_modules/marked/README.md +115 -0
- package/node_modules/marked/bin/main.js +284 -0
- package/node_modules/marked/bin/marked.js +16 -0
- package/node_modules/marked/lib/marked.d.ts +760 -0
- package/node_modules/marked/lib/marked.esm.js +77 -0
- package/node_modules/marked/lib/marked.esm.js.map +7 -0
- package/node_modules/marked/lib/marked.umd.js +79 -0
- package/node_modules/marked/lib/marked.umd.js.map +7 -0
- package/node_modules/marked/man/marked.1 +113 -0
- package/node_modules/marked/man/marked.1.md +93 -0
- package/node_modules/marked/package.json +103 -0
- package/node_modules/slice-ansi/index.d.ts +19 -0
- package/node_modules/slice-ansi/index.js +317 -0
- package/node_modules/slice-ansi/license +10 -0
- package/node_modules/slice-ansi/package.json +59 -0
- package/node_modules/slice-ansi/readme.md +55 -0
- package/node_modules/slice-ansi/tokenize-ansi.js +752 -0
- package/node_modules/string-width/index.d.ts +39 -0
- package/node_modules/string-width/index.js +203 -0
- package/node_modules/string-width/license +9 -0
- package/node_modules/string-width/package.json +65 -0
- package/node_modules/string-width/readme.md +66 -0
- package/node_modules/strip-ansi/index.d.ts +15 -0
- package/node_modules/strip-ansi/index.js +19 -0
- package/node_modules/strip-ansi/license +9 -0
- package/node_modules/strip-ansi/package.json +59 -0
- package/node_modules/strip-ansi/readme.md +37 -0
- package/node_modules/supports-color/browser.d.ts +1 -0
- package/node_modules/supports-color/browser.js +35 -0
- package/node_modules/supports-color/index.d.ts +55 -0
- package/node_modules/supports-color/index.js +202 -0
- package/node_modules/supports-color/license +9 -0
- package/node_modules/supports-color/package.json +64 -0
- package/node_modules/supports-color/readme.md +75 -0
- package/node_modules/supports-hyperlinks/browser.js +10 -0
- package/node_modules/supports-hyperlinks/index.d.ts +25 -0
- package/node_modules/supports-hyperlinks/index.js +163 -0
- package/node_modules/supports-hyperlinks/license +10 -0
- package/node_modules/supports-hyperlinks/package.json +47 -0
- package/node_modules/supports-hyperlinks/readme.md +45 -0
- package/package.json +41 -10
- package/patches/markdansi@0.3.2.patch +22 -2
- package/src/agent/context-builder.ts +24 -10
- package/src/agent/context-meter.ts +89 -5
- package/src/agent/loop.ts +107 -10
- package/src/agent/runtime-session.ts +1437 -82
- package/src/agent/session-ledger.ts +169 -29
- package/src/agent/types.ts +12 -1
- package/src/agent/user-prompt-projection.ts +62 -0
- package/src/cli/config.ts +57 -14
- package/src/cli/model-profiles.ts +124 -0
- package/src/cli/run-runner.ts +4 -1
- package/src/cli/tui-runner.tsx +68 -30
- package/src/context/compiled-context-hash.ts +1 -1
- package/src/context/compiled-context-validator.ts +92 -15
- package/src/context/context-automation-policy.ts +121 -0
- package/src/context/context-manager.ts +390 -11
- package/src/context/context-policy.ts +8 -0
- package/src/context/context-protocol-validator.ts +11 -1
- package/src/context/context-revision-compiler.ts +190 -27
- package/src/context/context-revision.ts +105 -19
- package/src/context/context-surface.ts +329 -0
- package/src/context/prefix-retirement-planner.ts +570 -0
- package/src/context/protocol-frame.ts +30 -3
- package/src/context/recall-retirement-contract.ts +27 -0
- package/src/context/swap-planner.ts +34 -10
- package/src/events/observation-text-log.ts +3 -3
- package/src/events/stdout-event-printer.ts +39 -3
- package/src/events/types.ts +172 -35
- package/src/ids/runtime-id.ts +6 -0
- package/src/ids/uuid-v7.ts +7 -0
- package/src/image/image-asset-store.ts +319 -0
- package/src/image/image-input-policy.ts +14 -0
- package/src/image/image-probe.ts +233 -0
- package/src/image/image-types.ts +262 -0
- package/src/instructions/project-instructions.ts +4 -1
- package/src/mcp/mcp-manager.ts +83 -19
- package/src/model/fake-model-client.ts +9 -1
- package/src/model/input-token-estimator.ts +25 -0
- package/src/model/model-client.ts +60 -0
- package/src/model/model-request-preflight.ts +1 -0
- package/src/model/moonshot-input-token-estimator.ts +107 -0
- package/src/model/openai-chat-mapping.ts +77 -1
- package/src/model/openai-chat-model-client.ts +389 -59
- package/src/model/openai-chat-stream.ts +272 -0
- package/src/model/prompt-prefix-hash.ts +2 -4
- package/src/model/token-estimator.ts +4 -0
- package/src/observation/observation-builder.ts +29 -0
- package/src/session/resume-projection.ts +94 -34
- package/src/session/session-catalog.ts +4 -4
- package/src/session/session-errors.ts +1 -1
- package/src/session/session-history-reader.ts +151 -4
- package/src/session/session-last-response-reader.ts +189 -0
- package/src/session/session-schema.ts +349 -35
- package/src/session/session-store.ts +3266 -255
- package/src/session/sqlite-session-ledger.ts +9 -4
- package/src/skills/skill-catalog.ts +182 -0
- package/src/skills/skill-context.ts +364 -0
- package/src/skills/skill-loader.ts +779 -0
- package/src/skills/skill-tool.ts +297 -0
- package/src/tools/edit.ts +51 -64
- package/src/tools/ensure-parent-directory.ts +6 -0
- package/src/tools/read.ts +2 -2
- package/src/tools/recall.ts +43 -40
- package/src/tools/registry.ts +24 -3
- package/src/tools/ripgrep.ts +3 -2
- package/src/tools/types.ts +43 -4
- package/src/tools/write.ts +20 -31
- package/src/tui/app.tsx +333 -96
- package/src/tui/clipboard.ts +5 -0
- package/src/tui/components/mcp-panel.tsx +28 -0
- package/src/tui/components/prompt-input.tsx +790 -257
- package/src/tui/components/skills-panel.tsx +31 -0
- package/src/tui/components/timeline.tsx +30 -1
- package/src/tui/event-store.ts +85 -2
- package/src/tui/file-mention.ts +234 -0
- package/src/tui/line-editor.ts +1 -0
- package/src/tui/project-slash-commands.ts +229 -0
- package/src/tui/prompt-draft.ts +510 -0
- package/src/tui/prompt-history.ts +294 -22
- package/src/tui/slash-commands.ts +46 -2
- package/src/tui/tui-session-controller.ts +110 -48
- package/src/tui/workspace-file-search.ts +94 -0
|
@@ -4,7 +4,7 @@ import type { SessionId } from "../ids/runtime-id";
|
|
|
4
4
|
import { SessionError } from "./session-errors";
|
|
5
5
|
|
|
6
6
|
export const SESSION_APPLICATION_ID = 0x544b5231;
|
|
7
|
-
export const SESSION_SCHEMA_VERSION =
|
|
7
|
+
export const SESSION_SCHEMA_VERSION = 9;
|
|
8
8
|
|
|
9
9
|
type SchemaDefinition = {
|
|
10
10
|
type: "table" | "index" | "trigger" | "view";
|
|
@@ -27,7 +27,7 @@ const schemaDefinitions: readonly SchemaDefinition[] = [
|
|
|
27
27
|
name: "session_meta",
|
|
28
28
|
sql: `CREATE TABLE session_meta (
|
|
29
29
|
singleton INTEGER PRIMARY KEY CHECK (singleton = 1),
|
|
30
|
-
schema_version INTEGER NOT NULL CHECK (schema_version =
|
|
30
|
+
schema_version INTEGER NOT NULL CHECK (schema_version = 9),
|
|
31
31
|
schema_fingerprint TEXT NOT NULL,
|
|
32
32
|
initialization_state TEXT NOT NULL CHECK (initialization_state IN ('creating', 'ready')),
|
|
33
33
|
session_id TEXT NOT NULL UNIQUE,
|
|
@@ -37,10 +37,9 @@ const schemaDefinitions: readonly SchemaDefinition[] = [
|
|
|
37
37
|
project_instruction_file TEXT CHECK (project_instruction_file IS NULL OR project_instruction_file IN ('AGENTS.md', 'CLAUDE.md')),
|
|
38
38
|
project_instruction_byte_length INTEGER CHECK (project_instruction_byte_length IS NULL OR project_instruction_byte_length >= 1),
|
|
39
39
|
project_instruction_sha256 TEXT CHECK (project_instruction_sha256 IS NULL OR length(project_instruction_sha256) = 64),
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
active_revision_id TEXT NOT NULL,
|
|
40
|
+
session_compatibility_json TEXT,
|
|
41
|
+
session_compatibility_sha256 TEXT,
|
|
42
|
+
active_revision_id TEXT,
|
|
44
43
|
next_turn_number INTEGER NOT NULL CHECK (next_turn_number >= 1),
|
|
45
44
|
next_event_sequence INTEGER NOT NULL CHECK (next_event_sequence >= 1),
|
|
46
45
|
open_count INTEGER NOT NULL CHECK (open_count >= 1),
|
|
@@ -51,10 +50,13 @@ const schemaDefinitions: readonly SchemaDefinition[] = [
|
|
|
51
50
|
last_close_reason TEXT CHECK (last_close_reason IS NULL OR last_close_reason IN (
|
|
52
51
|
'oneshot_complete', 'tui_exit', 'session_switch', 'runner_failed', 'initialization_failed'
|
|
53
52
|
)),
|
|
54
|
-
CHECK ((
|
|
53
|
+
CHECK ((session_compatibility_json IS NULL) = (session_compatibility_sha256 IS NULL)),
|
|
55
54
|
CHECK ((project_instruction_file IS NULL) = (project_instruction_byte_length IS NULL)),
|
|
56
55
|
CHECK ((project_instruction_file IS NULL) = (project_instruction_sha256 IS NULL)),
|
|
57
|
-
CHECK (
|
|
56
|
+
CHECK (
|
|
57
|
+
(initialization_state = 'creating' AND session_compatibility_json IS NULL AND active_revision_id IS NULL) OR
|
|
58
|
+
(initialization_state = 'ready' AND session_compatibility_json IS NOT NULL AND active_revision_id IS NOT NULL)
|
|
59
|
+
)
|
|
58
60
|
) STRICT`,
|
|
59
61
|
},
|
|
60
62
|
{
|
|
@@ -188,13 +190,72 @@ const schemaDefinitions: readonly SchemaDefinition[] = [
|
|
|
188
190
|
CHECK (raw_json IS NULL OR json_valid(raw_json)),
|
|
189
191
|
CHECK (
|
|
190
192
|
(completion_kind = 'returned' AND raw_json IS NOT NULL AND raw_sha256 IS NOT NULL AND
|
|
191
|
-
observation_format
|
|
193
|
+
observation_format IS NOT NULL AND length(observation_format) > 0 AND synthetic_reason IS NULL AND synthetic_detail IS NULL) OR
|
|
192
194
|
(completion_kind = 'synthetic' AND raw_json IS NULL AND raw_sha256 IS NULL AND
|
|
193
195
|
observation_format IS NULL AND synthetic_reason IS NOT NULL)
|
|
194
196
|
),
|
|
195
197
|
CHECK ((synthetic_reason = 'failed_active') = (synthetic_detail IS NOT NULL))
|
|
196
198
|
) STRICT`,
|
|
197
199
|
},
|
|
200
|
+
{
|
|
201
|
+
type: "table",
|
|
202
|
+
name: "image_assets",
|
|
203
|
+
sql: `CREATE TABLE image_assets (
|
|
204
|
+
asset_id TEXT PRIMARY KEY
|
|
205
|
+
CHECK (length(asset_id) = 64 AND asset_id NOT GLOB '*[^0-9a-f]*'),
|
|
206
|
+
mime_type TEXT NOT NULL
|
|
207
|
+
CHECK (mime_type IN ('image/png', 'image/jpeg', 'image/webp')),
|
|
208
|
+
byte_length INTEGER NOT NULL CHECK (byte_length > 0),
|
|
209
|
+
width INTEGER NOT NULL CHECK (width > 0),
|
|
210
|
+
height INTEGER NOT NULL CHECK (height > 0),
|
|
211
|
+
created_at TEXT NOT NULL
|
|
212
|
+
) STRICT`,
|
|
213
|
+
},
|
|
214
|
+
{
|
|
215
|
+
type: "table",
|
|
216
|
+
name: "message_image_attachments",
|
|
217
|
+
sql: `CREATE TABLE message_image_attachments (
|
|
218
|
+
message_id TEXT NOT NULL,
|
|
219
|
+
attachment_id TEXT NOT NULL CHECK (length(attachment_id) = 36),
|
|
220
|
+
asset_id TEXT NOT NULL,
|
|
221
|
+
position INTEGER NOT NULL CHECK (position >= 0),
|
|
222
|
+
label TEXT NOT NULL CHECK (length(label) > 0),
|
|
223
|
+
range_start INTEGER NOT NULL CHECK (range_start >= 0),
|
|
224
|
+
range_end INTEGER NOT NULL CHECK (range_end > range_start),
|
|
225
|
+
original_name TEXT NOT NULL CHECK (length(original_name) > 0),
|
|
226
|
+
PRIMARY KEY (message_id, attachment_id),
|
|
227
|
+
UNIQUE (message_id, position),
|
|
228
|
+
UNIQUE (message_id, label),
|
|
229
|
+
UNIQUE (message_id, range_start, range_end),
|
|
230
|
+
FOREIGN KEY (message_id) REFERENCES messages(message_id),
|
|
231
|
+
FOREIGN KEY (asset_id) REFERENCES image_assets(asset_id)
|
|
232
|
+
) STRICT`,
|
|
233
|
+
},
|
|
234
|
+
{
|
|
235
|
+
type: "table",
|
|
236
|
+
name: "context_surfaces",
|
|
237
|
+
sql: `CREATE TABLE context_surfaces (
|
|
238
|
+
surface_id TEXT PRIMARY KEY,
|
|
239
|
+
session_id TEXT NOT NULL,
|
|
240
|
+
system_prompt TEXT NOT NULL CHECK (length(system_prompt) > 0),
|
|
241
|
+
system_prompt_sha256 TEXT NOT NULL CHECK (length(system_prompt_sha256) = 64),
|
|
242
|
+
recall_contract_version TEXT NOT NULL CHECK (length(recall_contract_version) BETWEEN 1 AND 64),
|
|
243
|
+
project_instruction_json TEXT CHECK (project_instruction_json IS NULL OR json_valid(project_instruction_json)),
|
|
244
|
+
skill_catalog_json TEXT NOT NULL CHECK (json_valid(skill_catalog_json)),
|
|
245
|
+
skill_catalog_sha256 TEXT NOT NULL CHECK (length(skill_catalog_sha256) = 64),
|
|
246
|
+
active_skills_json TEXT NOT NULL CHECK (json_valid(active_skills_json)),
|
|
247
|
+
active_skills_sha256 TEXT NOT NULL CHECK (length(active_skills_sha256) = 64),
|
|
248
|
+
tool_definitions_json TEXT NOT NULL CHECK (json_valid(tool_definitions_json)),
|
|
249
|
+
tool_definitions_sha256 TEXT NOT NULL CHECK (length(tool_definitions_sha256) = 64),
|
|
250
|
+
tool_schema_sha256 TEXT NOT NULL CHECK (length(tool_schema_sha256) = 64),
|
|
251
|
+
request_config_sha256 TEXT NOT NULL CHECK (length(request_config_sha256) = 64),
|
|
252
|
+
request_max_output_tokens INTEGER NOT NULL CHECK (request_max_output_tokens >= 1),
|
|
253
|
+
surface_sha256 TEXT NOT NULL CHECK (length(surface_sha256) = 64),
|
|
254
|
+
created_at TEXT NOT NULL,
|
|
255
|
+
UNIQUE (session_id, surface_id),
|
|
256
|
+
FOREIGN KEY (session_id) REFERENCES session_meta(session_id)
|
|
257
|
+
) STRICT`,
|
|
258
|
+
},
|
|
198
259
|
{
|
|
199
260
|
type: "table",
|
|
200
261
|
name: "context_revisions",
|
|
@@ -203,30 +264,63 @@ const schemaDefinitions: readonly SchemaDefinition[] = [
|
|
|
203
264
|
session_id TEXT NOT NULL,
|
|
204
265
|
revision_number INTEGER NOT NULL CHECK (revision_number >= 1),
|
|
205
266
|
parent_revision_id TEXT,
|
|
206
|
-
kind TEXT NOT NULL CHECK (kind IN ('initial_full', 'swap_only')),
|
|
207
|
-
|
|
267
|
+
kind TEXT NOT NULL CHECK (kind IN ('initial_full', 'swap_only', 'surface_refresh', 'prefix_retirement', 'skills_update')),
|
|
268
|
+
surface_id TEXT NOT NULL,
|
|
269
|
+
surface_sha256 TEXT NOT NULL CHECK (length(surface_sha256) = 64),
|
|
270
|
+
keep_from_ordinal INTEGER NOT NULL CHECK (keep_from_ordinal >= 1),
|
|
208
271
|
source_through_ordinal INTEGER NOT NULL CHECK (source_through_ordinal >= 1),
|
|
209
272
|
added_override_count INTEGER NOT NULL CHECK (added_override_count >= 0),
|
|
210
|
-
|
|
211
|
-
|
|
273
|
+
active_override_count INTEGER NOT NULL CHECK (active_override_count >= 0),
|
|
274
|
+
active_override_manifest_sha256 TEXT NOT NULL CHECK (length(active_override_manifest_sha256) = 64),
|
|
212
275
|
canonical_sequence_sha256 TEXT NOT NULL CHECK (length(canonical_sequence_sha256) = 64),
|
|
213
276
|
rendered_message_sha256 TEXT NOT NULL CHECK (length(rendered_message_sha256) = 64),
|
|
214
277
|
policy_version TEXT,
|
|
215
278
|
renderer_format TEXT,
|
|
216
279
|
plan_sha256 TEXT CHECK (plan_sha256 IS NULL OR length(plan_sha256) = 64),
|
|
280
|
+
change_manifest_sha256 TEXT CHECK (change_manifest_sha256 IS NULL OR length(change_manifest_sha256) = 64),
|
|
281
|
+
activation_manifest_sha256 TEXT CHECK (activation_manifest_sha256 IS NULL OR length(activation_manifest_sha256) = 64),
|
|
282
|
+
retired_through_ordinal INTEGER CHECK (retired_through_ordinal IS NULL OR retired_through_ordinal >= 2),
|
|
283
|
+
retired_turn_count INTEGER CHECK (retired_turn_count IS NULL OR retired_turn_count >= 1),
|
|
284
|
+
retired_frame_count INTEGER CHECK (retired_frame_count IS NULL OR retired_frame_count >= 1),
|
|
285
|
+
retired_message_count INTEGER CHECK (retired_message_count IS NULL OR retired_message_count >= 1),
|
|
217
286
|
created_at TEXT NOT NULL,
|
|
218
287
|
UNIQUE (session_id, revision_number),
|
|
219
288
|
FOREIGN KEY (session_id) REFERENCES session_meta(session_id),
|
|
220
289
|
FOREIGN KEY (parent_revision_id) REFERENCES context_revisions(revision_id),
|
|
290
|
+
FOREIGN KEY (session_id, surface_id) REFERENCES context_surfaces(session_id, surface_id),
|
|
221
291
|
CHECK (
|
|
222
292
|
(kind = 'initial_full' AND revision_number = 1 AND parent_revision_id IS NULL AND
|
|
223
293
|
source_through_ordinal = 1 AND added_override_count = 0 AND
|
|
224
|
-
|
|
225
|
-
renderer_format IS NULL AND plan_sha256 IS NULL
|
|
294
|
+
active_override_count = 0 AND policy_version IS NULL AND
|
|
295
|
+
renderer_format IS NULL AND plan_sha256 IS NULL AND change_manifest_sha256 IS NULL AND activation_manifest_sha256 IS NULL AND
|
|
296
|
+
retired_through_ordinal IS NULL AND retired_turn_count IS NULL AND
|
|
297
|
+
retired_frame_count IS NULL AND retired_message_count IS NULL) OR
|
|
226
298
|
(kind = 'swap_only' AND revision_number >= 2 AND parent_revision_id IS NOT NULL AND
|
|
227
|
-
added_override_count >= 1 AND
|
|
299
|
+
added_override_count >= 1 AND active_override_count >= added_override_count AND
|
|
228
300
|
policy_version = 'swap-only-v1' AND
|
|
229
|
-
renderer_format = 'swap-observation-v1' AND plan_sha256 IS NOT NULL
|
|
301
|
+
renderer_format = 'swap-observation-v1' AND plan_sha256 IS NOT NULL AND
|
|
302
|
+
change_manifest_sha256 IS NULL AND activation_manifest_sha256 IS NULL AND retired_through_ordinal IS NULL AND
|
|
303
|
+
retired_turn_count IS NULL AND retired_frame_count IS NULL AND
|
|
304
|
+
retired_message_count IS NULL) OR
|
|
305
|
+
(kind = 'surface_refresh' AND revision_number >= 2 AND parent_revision_id IS NOT NULL AND
|
|
306
|
+
added_override_count = 0 AND policy_version IS NULL AND renderer_format IS NULL AND
|
|
307
|
+
plan_sha256 IS NULL AND change_manifest_sha256 IS NOT NULL AND activation_manifest_sha256 IS NULL AND
|
|
308
|
+
retired_through_ordinal IS NULL AND retired_turn_count IS NULL AND
|
|
309
|
+
retired_frame_count IS NULL AND retired_message_count IS NULL) OR
|
|
310
|
+
(kind = 'prefix_retirement' AND revision_number >= 2 AND parent_revision_id IS NOT NULL AND
|
|
311
|
+
keep_from_ordinal > 1 AND retired_through_ordinal = keep_from_ordinal - 1 AND
|
|
312
|
+
added_override_count = 0 AND policy_version = 'recall-first-retirement-v1' AND
|
|
313
|
+
renderer_format IS NULL AND plan_sha256 IS NOT NULL AND
|
|
314
|
+
change_manifest_sha256 IS NULL AND activation_manifest_sha256 IS NULL AND retired_turn_count >= 1 AND
|
|
315
|
+
retired_frame_count >= 1 AND retired_message_count >= 1)
|
|
316
|
+
OR
|
|
317
|
+
(kind = 'skills_update' AND revision_number >= 2 AND parent_revision_id IS NOT NULL AND
|
|
318
|
+
added_override_count >= 1 AND active_override_count >= added_override_count AND
|
|
319
|
+
policy_version = 'agent-skills-v1' AND
|
|
320
|
+
renderer_format = 'skill-activation-receipt-v1' AND plan_sha256 IS NULL AND
|
|
321
|
+
change_manifest_sha256 IS NOT NULL AND activation_manifest_sha256 IS NOT NULL AND
|
|
322
|
+
retired_through_ordinal IS NULL AND retired_turn_count IS NULL AND
|
|
323
|
+
retired_frame_count IS NULL AND retired_message_count IS NULL)
|
|
230
324
|
)
|
|
231
325
|
) STRICT`,
|
|
232
326
|
},
|
|
@@ -240,14 +334,14 @@ const schemaDefinitions: readonly SchemaDefinition[] = [
|
|
|
240
334
|
frame_id TEXT NOT NULL,
|
|
241
335
|
ordinal INTEGER NOT NULL CHECK (ordinal >= 1),
|
|
242
336
|
representation TEXT NOT NULL CHECK (representation = 'swapped'),
|
|
243
|
-
renderer_format TEXT NOT NULL CHECK (renderer_format
|
|
337
|
+
renderer_format TEXT NOT NULL CHECK (renderer_format IN ('swap-observation-v1', 'skill-activation-receipt-v1')),
|
|
244
338
|
source TEXT NOT NULL,
|
|
245
339
|
original_content_sha256 TEXT NOT NULL CHECK (length(original_content_sha256) = 64),
|
|
246
340
|
rendered_content TEXT NOT NULL CHECK (length(rendered_content) > 0),
|
|
247
341
|
rendered_content_sha256 TEXT NOT NULL CHECK (length(rendered_content_sha256) = 64),
|
|
248
342
|
original_bytes INTEGER NOT NULL CHECK (original_bytes > 0),
|
|
249
343
|
rendered_bytes INTEGER NOT NULL CHECK (rendered_bytes > 0),
|
|
250
|
-
byte_savings INTEGER NOT NULL
|
|
344
|
+
byte_savings INTEGER NOT NULL,
|
|
251
345
|
created_at TEXT NOT NULL,
|
|
252
346
|
PRIMARY KEY (introduced_revision_id, message_id),
|
|
253
347
|
UNIQUE (session_id, message_id),
|
|
@@ -256,7 +350,32 @@ const schemaDefinitions: readonly SchemaDefinition[] = [
|
|
|
256
350
|
FOREIGN KEY (session_id) REFERENCES session_meta(session_id),
|
|
257
351
|
FOREIGN KEY (message_id) REFERENCES messages(message_id),
|
|
258
352
|
FOREIGN KEY (frame_id) REFERENCES protocol_frames(frame_id),
|
|
259
|
-
CHECK (original_bytes = rendered_bytes + byte_savings)
|
|
353
|
+
CHECK (original_bytes = rendered_bytes + byte_savings),
|
|
354
|
+
CHECK (renderer_format <> 'swap-observation-v1' OR byte_savings > 0)
|
|
355
|
+
) STRICT`,
|
|
356
|
+
},
|
|
357
|
+
{
|
|
358
|
+
type: "table",
|
|
359
|
+
name: "skill_activations",
|
|
360
|
+
sql: `CREATE TABLE skill_activations (
|
|
361
|
+
activation_message_id TEXT PRIMARY KEY REFERENCES messages(message_id),
|
|
362
|
+
tool_call_id TEXT NOT NULL UNIQUE REFERENCES tool_results(tool_call_id),
|
|
363
|
+
session_id TEXT NOT NULL REFERENCES session_meta(session_id),
|
|
364
|
+
name TEXT NOT NULL,
|
|
365
|
+
scope TEXT NOT NULL CHECK (scope IN ('project', 'user')),
|
|
366
|
+
skill_file_sha256 TEXT NOT NULL CHECK (length(skill_file_sha256) = 64),
|
|
367
|
+
state TEXT NOT NULL CHECK (state IN ('pending', 'dispatched', 'promoted', 'rejected')),
|
|
368
|
+
dispatched_iteration_id TEXT REFERENCES iterations(iteration_id),
|
|
369
|
+
settled_revision_id TEXT REFERENCES context_revisions(revision_id),
|
|
370
|
+
rejection_reason TEXT,
|
|
371
|
+
created_at TEXT NOT NULL,
|
|
372
|
+
updated_at TEXT NOT NULL,
|
|
373
|
+
CHECK (
|
|
374
|
+
(state = 'pending' AND dispatched_iteration_id IS NULL AND settled_revision_id IS NULL AND rejection_reason IS NULL) OR
|
|
375
|
+
(state = 'dispatched' AND dispatched_iteration_id IS NOT NULL AND settled_revision_id IS NULL AND rejection_reason IS NULL) OR
|
|
376
|
+
(state = 'promoted' AND dispatched_iteration_id IS NOT NULL AND settled_revision_id IS NOT NULL AND rejection_reason IS NULL) OR
|
|
377
|
+
(state = 'rejected' AND settled_revision_id IS NOT NULL AND rejection_reason IS NOT NULL)
|
|
378
|
+
)
|
|
260
379
|
) STRICT`,
|
|
261
380
|
},
|
|
262
381
|
{
|
|
@@ -289,6 +408,11 @@ const schemaDefinitions: readonly SchemaDefinition[] = [
|
|
|
289
408
|
name: "idx_context_overrides_revision_ordinal",
|
|
290
409
|
sql: "CREATE INDEX idx_context_overrides_revision_ordinal ON context_overrides(introduced_revision_id, ordinal)",
|
|
291
410
|
},
|
|
411
|
+
{
|
|
412
|
+
type: "index",
|
|
413
|
+
name: "idx_skill_activations_session_state",
|
|
414
|
+
sql: "CREATE INDEX idx_skill_activations_session_state ON skill_activations(session_id, state, activation_message_id)",
|
|
415
|
+
},
|
|
292
416
|
{
|
|
293
417
|
type: "index",
|
|
294
418
|
name: "idx_frames_session_ordinal",
|
|
@@ -299,6 +423,11 @@ const schemaDefinitions: readonly SchemaDefinition[] = [
|
|
|
299
423
|
name: "idx_messages_frame_ordinal",
|
|
300
424
|
sql: "CREATE INDEX idx_messages_frame_ordinal ON messages(frame_id, ordinal)",
|
|
301
425
|
},
|
|
426
|
+
{
|
|
427
|
+
type: "index",
|
|
428
|
+
name: "idx_message_image_attachments_asset",
|
|
429
|
+
sql: "CREATE INDEX idx_message_image_attachments_asset ON message_image_attachments(asset_id)",
|
|
430
|
+
},
|
|
302
431
|
{
|
|
303
432
|
type: "index",
|
|
304
433
|
name: "idx_turns_session_recent",
|
|
@@ -341,8 +470,64 @@ const schemaDefinitions: readonly SchemaDefinition[] = [
|
|
|
341
470
|
},
|
|
342
471
|
...immutableTriggers("messages"),
|
|
343
472
|
...immutableTriggers("tool_results"),
|
|
473
|
+
...immutableTriggers("image_assets"),
|
|
474
|
+
...immutableTriggers("message_image_attachments"),
|
|
475
|
+
...immutableTriggers("context_surfaces"),
|
|
344
476
|
...immutableTriggers("context_revisions"),
|
|
345
477
|
...immutableTriggers("context_overrides"),
|
|
478
|
+
{
|
|
479
|
+
type: "trigger",
|
|
480
|
+
name: "skill_activations_no_delete",
|
|
481
|
+
sql: `CREATE TRIGGER skill_activations_no_delete BEFORE DELETE ON skill_activations
|
|
482
|
+
BEGIN SELECT RAISE(ABORT, 'skill_activations cannot be deleted'); END`,
|
|
483
|
+
},
|
|
484
|
+
{
|
|
485
|
+
type: "trigger",
|
|
486
|
+
name: "skill_activations_validate_insert",
|
|
487
|
+
sql: `CREATE TRIGGER skill_activations_validate_insert BEFORE INSERT ON skill_activations
|
|
488
|
+
WHEN NOT (
|
|
489
|
+
NEW.session_id = (SELECT session_id FROM session_meta WHERE singleton = 1) AND
|
|
490
|
+
NEW.state = 'pending' AND NEW.dispatched_iteration_id IS NULL AND
|
|
491
|
+
NEW.settled_revision_id IS NULL AND NEW.rejection_reason IS NULL AND
|
|
492
|
+
EXISTS (
|
|
493
|
+
SELECT 1 FROM messages m
|
|
494
|
+
JOIN tool_results tr ON tr.tool_message_id = m.message_id
|
|
495
|
+
WHERE m.message_id = NEW.activation_message_id
|
|
496
|
+
AND m.session_id = NEW.session_id AND m.tool_call_id = NEW.tool_call_id
|
|
497
|
+
AND m.name = 'Skill' AND m.role = 'tool' AND m.origin = 'tool'
|
|
498
|
+
AND tr.tool_call_id = NEW.tool_call_id AND tr.session_id = NEW.session_id
|
|
499
|
+
AND tr.completion_kind = 'returned'
|
|
500
|
+
AND json_extract(tr.raw_json, '$.kind') = 'skill'
|
|
501
|
+
AND json_extract(tr.raw_json, '$.ok') = 1
|
|
502
|
+
AND json_extract(tr.raw_json, '$.status') = 'loaded'
|
|
503
|
+
AND json_extract(tr.raw_json, '$.name') = NEW.name
|
|
504
|
+
AND json_extract(tr.raw_json, '$.scope') = NEW.scope
|
|
505
|
+
AND json_extract(tr.raw_json, '$.sha256') = NEW.skill_file_sha256
|
|
506
|
+
)
|
|
507
|
+
)
|
|
508
|
+
BEGIN SELECT RAISE(ABORT, 'invalid skill activation insert'); END`,
|
|
509
|
+
},
|
|
510
|
+
{
|
|
511
|
+
type: "trigger",
|
|
512
|
+
name: "skill_activations_monotonic_update",
|
|
513
|
+
sql: `CREATE TRIGGER skill_activations_monotonic_update BEFORE UPDATE ON skill_activations
|
|
514
|
+
WHEN NOT (
|
|
515
|
+
OLD.activation_message_id = NEW.activation_message_id AND
|
|
516
|
+
OLD.tool_call_id = NEW.tool_call_id AND OLD.session_id = NEW.session_id AND
|
|
517
|
+
OLD.name = NEW.name AND OLD.scope = NEW.scope AND
|
|
518
|
+
OLD.skill_file_sha256 = NEW.skill_file_sha256 AND OLD.created_at = NEW.created_at AND
|
|
519
|
+
((OLD.state = 'pending' AND NEW.state = 'dispatched' AND
|
|
520
|
+
NEW.dispatched_iteration_id IS NOT NULL AND NEW.settled_revision_id IS NULL AND NEW.rejection_reason IS NULL) OR
|
|
521
|
+
(OLD.state = 'pending' AND NEW.state = 'rejected' AND
|
|
522
|
+
NEW.dispatched_iteration_id IS NULL AND NEW.settled_revision_id IS NOT NULL AND NEW.rejection_reason IS NOT NULL) OR
|
|
523
|
+
(OLD.state = 'dispatched' AND NEW.state IN ('promoted', 'rejected') AND
|
|
524
|
+
NEW.dispatched_iteration_id = OLD.dispatched_iteration_id AND
|
|
525
|
+
NEW.settled_revision_id IS NOT NULL AND
|
|
526
|
+
((NEW.state = 'promoted' AND NEW.rejection_reason IS NULL) OR
|
|
527
|
+
(NEW.state = 'rejected' AND NEW.rejection_reason IS NOT NULL))))
|
|
528
|
+
)
|
|
529
|
+
BEGIN SELECT RAISE(ABORT, 'invalid skill activation transition'); END`,
|
|
530
|
+
},
|
|
346
531
|
{
|
|
347
532
|
type: "trigger",
|
|
348
533
|
name: "context_revisions_validate_insert",
|
|
@@ -350,16 +535,85 @@ const schemaDefinitions: readonly SchemaDefinition[] = [
|
|
|
350
535
|
BEFORE INSERT ON context_revisions
|
|
351
536
|
WHEN NOT (
|
|
352
537
|
NEW.session_id = (SELECT session_id FROM session_meta WHERE singleton = 1) AND
|
|
353
|
-
((NEW.kind = 'initial_full' AND
|
|
354
|
-
|
|
355
|
-
|
|
538
|
+
((NEW.kind = 'initial_full' AND NEW.revision_number = 1 AND
|
|
539
|
+
(SELECT initialization_state FROM session_meta WHERE singleton = 1) = 'creating' AND
|
|
540
|
+
(SELECT active_revision_id FROM session_meta WHERE singleton = 1) IS NULL AND
|
|
541
|
+
NOT EXISTS (SELECT 1 FROM context_revisions WHERE session_id = NEW.session_id) AND
|
|
542
|
+
NEW.surface_sha256 = (SELECT surface_sha256 FROM context_surfaces WHERE surface_id = NEW.surface_id)) OR
|
|
356
543
|
(NEW.kind = 'swap_only' AND
|
|
357
544
|
NEW.parent_revision_id = (SELECT active_revision_id FROM session_meta WHERE singleton = 1) AND
|
|
358
545
|
NEW.revision_number = 1 + COALESCE((
|
|
359
546
|
SELECT revision_number FROM context_revisions
|
|
360
547
|
WHERE revision_id = NEW.parent_revision_id AND session_id = NEW.session_id
|
|
361
548
|
), 0) AND
|
|
362
|
-
NEW.source_through_ordinal = COALESCE((SELECT MAX(ordinal) FROM messages), 0)
|
|
549
|
+
NEW.source_through_ordinal = COALESCE((SELECT MAX(ordinal) FROM messages), 0) AND
|
|
550
|
+
EXISTS (SELECT 1 FROM protocol_frames WHERE state = 'closed' AND last_ordinal = NEW.source_through_ordinal) AND
|
|
551
|
+
NEW.surface_id = (SELECT surface_id FROM context_revisions WHERE revision_id = NEW.parent_revision_id) AND
|
|
552
|
+
NEW.surface_sha256 = (SELECT surface_sha256 FROM context_revisions WHERE revision_id = NEW.parent_revision_id) AND
|
|
553
|
+
NEW.keep_from_ordinal = (SELECT keep_from_ordinal FROM context_revisions WHERE revision_id = NEW.parent_revision_id) AND
|
|
554
|
+
NEW.active_override_count = (SELECT active_override_count FROM context_revisions WHERE revision_id = NEW.parent_revision_id) + NEW.added_override_count) OR
|
|
555
|
+
(NEW.kind = 'surface_refresh' AND
|
|
556
|
+
NEW.parent_revision_id = (SELECT active_revision_id FROM session_meta WHERE singleton = 1) AND
|
|
557
|
+
NEW.revision_number = 1 + COALESCE((
|
|
558
|
+
SELECT revision_number FROM context_revisions
|
|
559
|
+
WHERE revision_id = NEW.parent_revision_id AND session_id = NEW.session_id
|
|
560
|
+
), 0) AND
|
|
561
|
+
NEW.source_through_ordinal = COALESCE((SELECT MAX(ordinal) FROM messages), 0) AND
|
|
562
|
+
EXISTS (SELECT 1 FROM protocol_frames WHERE state = 'closed' AND last_ordinal = NEW.source_through_ordinal) AND
|
|
563
|
+
NEW.surface_id <> (SELECT surface_id FROM context_revisions WHERE revision_id = NEW.parent_revision_id) AND
|
|
564
|
+
NEW.surface_sha256 = (SELECT surface_sha256 FROM context_surfaces WHERE surface_id = NEW.surface_id) AND
|
|
565
|
+
NEW.keep_from_ordinal = (SELECT keep_from_ordinal FROM context_revisions WHERE revision_id = NEW.parent_revision_id) AND
|
|
566
|
+
NEW.active_override_count = (SELECT active_override_count FROM context_revisions WHERE revision_id = NEW.parent_revision_id) AND
|
|
567
|
+
NEW.active_override_manifest_sha256 = (SELECT active_override_manifest_sha256 FROM context_revisions WHERE revision_id = NEW.parent_revision_id)) OR
|
|
568
|
+
(NEW.kind = 'skills_update' AND
|
|
569
|
+
NEW.parent_revision_id = (SELECT active_revision_id FROM session_meta WHERE singleton = 1) AND
|
|
570
|
+
NEW.revision_number = 1 + COALESCE((
|
|
571
|
+
SELECT revision_number FROM context_revisions
|
|
572
|
+
WHERE revision_id = NEW.parent_revision_id AND session_id = NEW.session_id
|
|
573
|
+
), 0) AND
|
|
574
|
+
NEW.source_through_ordinal = COALESCE((SELECT MAX(ordinal) FROM messages), 0) AND
|
|
575
|
+
EXISTS (SELECT 1 FROM protocol_frames WHERE state = 'closed' AND last_ordinal = NEW.source_through_ordinal) AND
|
|
576
|
+
NEW.surface_sha256 = (SELECT surface_sha256 FROM context_surfaces WHERE surface_id = NEW.surface_id) AND
|
|
577
|
+
NEW.keep_from_ordinal = (SELECT keep_from_ordinal FROM context_revisions WHERE revision_id = NEW.parent_revision_id) AND
|
|
578
|
+
NEW.active_override_count = (SELECT active_override_count FROM context_revisions WHERE revision_id = NEW.parent_revision_id) + NEW.added_override_count) OR
|
|
579
|
+
(NEW.kind = 'prefix_retirement' AND
|
|
580
|
+
NEW.parent_revision_id = (SELECT active_revision_id FROM session_meta WHERE singleton = 1) AND
|
|
581
|
+
NEW.revision_number = 1 + COALESCE((
|
|
582
|
+
SELECT revision_number FROM context_revisions
|
|
583
|
+
WHERE revision_id = NEW.parent_revision_id AND session_id = NEW.session_id
|
|
584
|
+
), 0) AND
|
|
585
|
+
NEW.source_through_ordinal = COALESCE((SELECT MAX(ordinal) FROM messages), 0) AND
|
|
586
|
+
EXISTS (SELECT 1 FROM protocol_frames WHERE state = 'closed' AND last_ordinal = NEW.source_through_ordinal) AND
|
|
587
|
+
NEW.surface_id = (SELECT surface_id FROM context_revisions WHERE revision_id = NEW.parent_revision_id) AND
|
|
588
|
+
NEW.surface_sha256 = (SELECT surface_sha256 FROM context_revisions WHERE revision_id = NEW.parent_revision_id) AND
|
|
589
|
+
NEW.keep_from_ordinal > (SELECT keep_from_ordinal FROM context_revisions WHERE revision_id = NEW.parent_revision_id) AND
|
|
590
|
+
EXISTS (
|
|
591
|
+
SELECT 1 FROM messages m
|
|
592
|
+
JOIN protocol_frames pf ON pf.frame_id = m.frame_id
|
|
593
|
+
JOIN turns t ON t.turn_id = m.turn_id
|
|
594
|
+
WHERE m.ordinal = NEW.keep_from_ordinal AND m.role = 'user'
|
|
595
|
+
AND pf.kind = 'user' AND pf.state = 'closed'
|
|
596
|
+
AND pf.first_ordinal = NEW.keep_from_ordinal
|
|
597
|
+
AND pf.last_ordinal = NEW.keep_from_ordinal
|
|
598
|
+
AND t.status <> 'open'
|
|
599
|
+
) AND
|
|
600
|
+
EXISTS (
|
|
601
|
+
SELECT 1 FROM messages m
|
|
602
|
+
JOIN protocol_frames pf ON pf.frame_id = m.frame_id
|
|
603
|
+
JOIN turns t ON t.turn_id = m.turn_id
|
|
604
|
+
WHERE m.ordinal = NEW.keep_from_ordinal - 1
|
|
605
|
+
AND pf.state = 'closed' AND pf.last_ordinal = NEW.keep_from_ordinal - 1
|
|
606
|
+
AND t.status <> 'open'
|
|
607
|
+
) AND
|
|
608
|
+
NEW.active_override_count = (
|
|
609
|
+
SELECT COUNT(*) FROM context_overrides co
|
|
610
|
+
JOIN context_revisions introduced
|
|
611
|
+
ON introduced.revision_id = co.introduced_revision_id
|
|
612
|
+
JOIN context_revisions parent
|
|
613
|
+
ON parent.revision_id = NEW.parent_revision_id
|
|
614
|
+
WHERE introduced.revision_number <= parent.revision_number
|
|
615
|
+
AND co.ordinal >= NEW.keep_from_ordinal
|
|
616
|
+
)))
|
|
363
617
|
)
|
|
364
618
|
BEGIN SELECT RAISE(ABORT, 'invalid context revision insert'); END`,
|
|
365
619
|
},
|
|
@@ -373,7 +627,9 @@ const schemaDefinitions: readonly SchemaDefinition[] = [
|
|
|
373
627
|
SELECT 1 FROM context_revisions cr
|
|
374
628
|
WHERE cr.revision_id = NEW.introduced_revision_id
|
|
375
629
|
AND cr.session_id = NEW.session_id
|
|
376
|
-
AND cr.kind = 'swap_only'
|
|
630
|
+
AND ((cr.kind = 'swap_only' AND NEW.renderer_format = 'swap-observation-v1') OR
|
|
631
|
+
(cr.kind = 'skills_update' AND NEW.renderer_format = 'skill-activation-receipt-v1'))
|
|
632
|
+
AND NEW.ordinal >= cr.keep_from_ordinal
|
|
377
633
|
AND NEW.ordinal <= cr.source_through_ordinal
|
|
378
634
|
) AND
|
|
379
635
|
EXISTS (
|
|
@@ -394,10 +650,15 @@ const schemaDefinitions: readonly SchemaDefinition[] = [
|
|
|
394
650
|
AND tr.session_id = NEW.session_id
|
|
395
651
|
AND tr.frame_id = NEW.frame_id
|
|
396
652
|
AND tr.observation_sha256 = NEW.original_content_sha256
|
|
653
|
+
AND (NEW.renderer_format <> 'skill-activation-receipt-v1' OR
|
|
654
|
+
(m.name = 'Skill' AND tr.completion_kind = 'returned' AND
|
|
655
|
+
json_extract(tr.raw_json, '$.kind') = 'skill' AND
|
|
656
|
+
json_extract(tr.raw_json, '$.ok') = 1 AND
|
|
657
|
+
json_extract(tr.raw_json, '$.status') = 'loaded'))
|
|
397
658
|
) AND
|
|
398
659
|
NEW.source = 'ctx://message/' || NEW.message_id AND
|
|
399
660
|
length(CAST(NEW.rendered_content AS BLOB)) = NEW.rendered_bytes AND
|
|
400
|
-
NEW.rendered_bytes < NEW.original_bytes
|
|
661
|
+
(NEW.renderer_format <> 'swap-observation-v1' OR NEW.rendered_bytes < NEW.original_bytes)
|
|
401
662
|
)
|
|
402
663
|
BEGIN SELECT RAISE(ABORT, 'invalid context override insert'); END`,
|
|
403
664
|
},
|
|
@@ -519,10 +780,16 @@ const schemaDefinitions: readonly SchemaDefinition[] = [
|
|
|
519
780
|
NEW.open_count >= OLD.open_count AND
|
|
520
781
|
((OLD.initialization_state = 'creating' AND NEW.initialization_state IN ('creating', 'ready')) OR
|
|
521
782
|
(OLD.initialization_state = 'ready' AND NEW.initialization_state = 'ready')) AND
|
|
522
|
-
(OLD.
|
|
523
|
-
(OLD.
|
|
524
|
-
(OLD.
|
|
525
|
-
|
|
783
|
+
(OLD.session_compatibility_json IS NULL OR NEW.session_compatibility_json = OLD.session_compatibility_json) AND
|
|
784
|
+
(OLD.session_compatibility_sha256 IS NULL OR NEW.session_compatibility_sha256 = OLD.session_compatibility_sha256) AND
|
|
785
|
+
((OLD.active_revision_id IS NULL AND NEW.active_revision_id IS NOT NULL AND
|
|
786
|
+
OLD.initialization_state = 'creating' AND NEW.initialization_state = 'ready' AND
|
|
787
|
+
EXISTS (
|
|
788
|
+
SELECT 1 FROM context_revisions initial
|
|
789
|
+
WHERE initial.revision_id = NEW.active_revision_id
|
|
790
|
+
AND initial.session_id = OLD.session_id
|
|
791
|
+
AND initial.kind = 'initial_full'
|
|
792
|
+
)) OR OLD.active_revision_id = NEW.active_revision_id OR EXISTS (
|
|
526
793
|
SELECT 1
|
|
527
794
|
FROM context_revisions previous
|
|
528
795
|
JOIN context_revisions next
|
|
@@ -532,12 +799,36 @@ const schemaDefinitions: readonly SchemaDefinition[] = [
|
|
|
532
799
|
WHERE previous.revision_id = OLD.active_revision_id
|
|
533
800
|
AND next.revision_id = NEW.active_revision_id
|
|
534
801
|
AND next.session_id = OLD.session_id
|
|
535
|
-
AND next.kind
|
|
802
|
+
AND next.kind IN ('swap_only', 'surface_refresh', 'prefix_retirement', 'skills_update')
|
|
536
803
|
AND next.added_override_count = (
|
|
537
804
|
SELECT COUNT(*) FROM context_overrides
|
|
538
805
|
WHERE introduced_revision_id = next.revision_id
|
|
539
806
|
)
|
|
540
|
-
AND next.
|
|
807
|
+
AND ((next.kind = 'swap_only' AND
|
|
808
|
+
next.keep_from_ordinal = previous.keep_from_ordinal AND
|
|
809
|
+
next.active_override_count = previous.active_override_count + next.added_override_count AND
|
|
810
|
+
next.surface_id = previous.surface_id) OR
|
|
811
|
+
(next.kind = 'surface_refresh' AND
|
|
812
|
+
next.keep_from_ordinal = previous.keep_from_ordinal AND
|
|
813
|
+
next.active_override_count = previous.active_override_count AND
|
|
814
|
+
next.added_override_count = 0 AND
|
|
815
|
+
next.active_override_manifest_sha256 = previous.active_override_manifest_sha256 AND
|
|
816
|
+
next.surface_id <> previous.surface_id) OR
|
|
817
|
+
(next.kind = 'skills_update' AND
|
|
818
|
+
next.keep_from_ordinal = previous.keep_from_ordinal AND
|
|
819
|
+
next.active_override_count = previous.active_override_count + next.added_override_count AND
|
|
820
|
+
next.surface_sha256 = (SELECT surface_sha256 FROM context_surfaces WHERE surface_id = next.surface_id)) OR
|
|
821
|
+
(next.kind = 'prefix_retirement' AND
|
|
822
|
+
next.keep_from_ordinal > previous.keep_from_ordinal AND
|
|
823
|
+
next.added_override_count = 0 AND
|
|
824
|
+
next.surface_id = previous.surface_id AND
|
|
825
|
+
next.active_override_count = (
|
|
826
|
+
SELECT COUNT(*) FROM context_overrides co
|
|
827
|
+
JOIN context_revisions introduced
|
|
828
|
+
ON introduced.revision_id = co.introduced_revision_id
|
|
829
|
+
WHERE introduced.revision_number <= previous.revision_number
|
|
830
|
+
AND co.ordinal >= next.keep_from_ordinal
|
|
831
|
+
)))
|
|
541
832
|
AND NOT EXISTS (SELECT 1 FROM context_measurement_state)
|
|
542
833
|
))
|
|
543
834
|
)
|
|
@@ -545,7 +836,7 @@ const schemaDefinitions: readonly SchemaDefinition[] = [
|
|
|
545
836
|
},
|
|
546
837
|
];
|
|
547
838
|
|
|
548
|
-
export const
|
|
839
|
+
export const SESSION_SCHEMA_V9_FINGERPRINT = sha256(
|
|
549
840
|
stableJsonStringify({
|
|
550
841
|
definitions: schemaDefinitions.map((definition) => ({
|
|
551
842
|
type: definition.type,
|
|
@@ -575,7 +866,30 @@ export function createSessionSchema(database: Database): void {
|
|
|
575
866
|
database.exec(`PRAGMA application_id = ${SESSION_APPLICATION_ID}`);
|
|
576
867
|
database.exec(`PRAGMA user_version = ${SESSION_SCHEMA_VERSION}`);
|
|
577
868
|
for (const definition of schemaDefinitions) {
|
|
578
|
-
|
|
869
|
+
try {
|
|
870
|
+
database.exec(definition.sql);
|
|
871
|
+
} catch (error) {
|
|
872
|
+
throw new Error(
|
|
873
|
+
`Failed to create session schema ${definition.type} ${definition.name}.`,
|
|
874
|
+
{ cause: error },
|
|
875
|
+
);
|
|
876
|
+
}
|
|
877
|
+
}
|
|
878
|
+
}
|
|
879
|
+
|
|
880
|
+
export function dropSessionCloneTriggers(database: Database): void {
|
|
881
|
+
for (const definition of schemaDefinitions) {
|
|
882
|
+
if (definition.type === "trigger") {
|
|
883
|
+
database.exec(`DROP TRIGGER ${definition.name}`);
|
|
884
|
+
}
|
|
885
|
+
}
|
|
886
|
+
}
|
|
887
|
+
|
|
888
|
+
export function reinstallSessionCloneTriggers(database: Database): void {
|
|
889
|
+
for (const definition of schemaDefinitions) {
|
|
890
|
+
if (definition.type === "trigger") {
|
|
891
|
+
database.exec(definition.sql);
|
|
892
|
+
}
|
|
579
893
|
}
|
|
580
894
|
}
|
|
581
895
|
|
|
@@ -648,7 +962,7 @@ export function verifySessionSchema(database: Database, sessionId?: SessionId):
|
|
|
648
962
|
throw new SessionError(
|
|
649
963
|
"SESSION_SCHEMA_INVALID",
|
|
650
964
|
"verify_schema",
|
|
651
|
-
"Session FTS configuration does not match schema
|
|
965
|
+
"Session FTS configuration does not match schema v9.",
|
|
652
966
|
{ sessionId },
|
|
653
967
|
);
|
|
654
968
|
}
|