@lensagent/core 0.1.0 → 0.1.2
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 +63 -4
- package/config/lens.example.jsonc +36 -13
- package/dist/adapters/executor-router.d.ts +20 -0
- package/dist/adapters/executor-router.js +86 -0
- package/dist/adapters/executor.d.ts +9 -3
- package/dist/adapters/executor.js +196 -61
- package/dist/adapters/lsp.d.ts +2 -1
- package/dist/adapters/lsp.js +98 -41
- package/dist/adapters/mcp.js +52 -17
- package/dist/adapters/revert.d.ts +5 -4
- package/dist/adapters/revert.js +6 -64
- package/dist/adapters/web.d.ts +9 -0
- package/dist/adapters/web.js +244 -0
- package/dist/config/files.d.ts +14 -0
- package/dist/config/files.js +57 -0
- package/dist/config/runtime.d.ts +3 -4
- package/dist/config/runtime.js +116 -97
- package/dist/config/schema.d.ts +56 -10
- package/dist/config/schema.js +48 -8
- package/dist/contracts/capability.d.ts +27 -1
- package/dist/contracts/domain.d.ts +1 -0
- package/dist/contracts/model.d.ts +33 -6
- package/dist/contracts/review.d.ts +17 -0
- package/dist/contracts/review.js +1 -0
- package/dist/core/access-policy.d.ts +40 -0
- package/dist/core/access-policy.js +68 -0
- package/dist/core/access.d.ts +30 -2
- package/dist/core/access.js +159 -26
- package/dist/core/context-boundaries.d.ts +25 -0
- package/dist/core/context-boundaries.js +106 -0
- package/dist/core/context.d.ts +3 -0
- package/dist/core/context.js +11 -0
- package/dist/core/host.js +261 -173
- package/dist/entry/pair.d.ts +1 -0
- package/dist/entry/pair.js +14 -0
- package/dist/entry/run.js +1 -1
- package/dist/execution/lsp-process.d.ts +3 -2
- package/dist/execution/lsp-process.js +46 -28
- package/dist/http/server.d.ts +5 -0
- package/dist/http/server.js +262 -80
- package/dist/runtime/agent.d.ts +9 -4
- package/dist/runtime/agent.js +361 -286
- package/dist/runtime/artifacts.d.ts +13 -1
- package/dist/runtime/artifacts.js +137 -10
- package/dist/runtime/cache.d.ts +59 -16
- package/dist/runtime/cache.js +124 -43
- package/dist/runtime/calls.d.ts +1 -1
- package/dist/runtime/calls.js +164 -48
- package/dist/runtime/capabilities.d.ts +2 -2
- package/dist/runtime/capabilities.js +4 -5
- package/dist/runtime/cleanup.d.ts +5 -2
- package/dist/runtime/cleanup.js +48 -17
- package/dist/runtime/compaction.d.ts +9 -0
- package/dist/runtime/compaction.js +52 -0
- package/dist/runtime/context.d.ts +8 -4
- package/dist/runtime/context.js +115 -128
- package/dist/runtime/events.d.ts +7 -0
- package/dist/runtime/events.js +83 -0
- package/dist/runtime/images.d.ts +14 -0
- package/dist/runtime/images.js +82 -0
- package/dist/runtime/kernel-capabilities.d.ts +7 -1
- package/dist/runtime/kernel-capabilities.js +146 -68
- package/dist/runtime/model-audit.d.ts +9 -0
- package/dist/runtime/model-audit.js +39 -0
- package/dist/runtime/model.d.ts +109 -4
- package/dist/runtime/model.js +368 -143
- package/dist/runtime/observability.d.ts +1 -0
- package/dist/runtime/observability.js +60 -15
- package/dist/runtime/policy.d.ts +1 -1
- package/dist/runtime/policy.js +2 -2
- package/dist/runtime/profile.d.ts +2 -1
- package/dist/runtime/profile.js +12 -15
- package/dist/runtime/projects.d.ts +3 -1
- package/dist/runtime/projects.js +38 -17
- package/dist/runtime/ptc-worker.d.ts +1 -0
- package/dist/runtime/ptc-worker.js +97 -0
- package/dist/runtime/ptc.d.ts +16 -0
- package/dist/runtime/ptc.js +128 -0
- package/dist/runtime/results.d.ts +5 -4
- package/dist/runtime/results.js +29 -51
- package/dist/runtime/review.d.ts +4 -1
- package/dist/runtime/review.js +101 -22
- package/dist/runtime/scheduler.js +1 -0
- package/dist/runtime/skills.js +34 -5
- package/dist/runtime/task-audit.d.ts +21 -0
- package/dist/runtime/task-audit.js +122 -0
- package/dist/runtime/time.d.ts +9 -0
- package/dist/runtime/time.js +18 -0
- package/dist/runtime/tokenizer.d.ts +2 -0
- package/dist/runtime/tokenizer.js +26 -1
- package/dist/store/database.js +26 -1
- package/dist/store/event-log.d.ts +1 -0
- package/dist/store/event-log.js +22 -5
- package/dist/store/schema.d.ts +1 -1
- package/dist/store/schema.js +50 -1
- package/dist/store/store.d.ts +65 -19
- package/dist/store/store.js +986 -188
- package/package.json +18 -8
- package/proto/executor.proto +69 -55
package/dist/store/event-log.js
CHANGED
|
@@ -9,10 +9,14 @@ export class EventLog {
|
|
|
9
9
|
path;
|
|
10
10
|
#tail = Promise.resolve();
|
|
11
11
|
#hash = null;
|
|
12
|
+
#error;
|
|
12
13
|
constructor(root, path, fsync) {
|
|
13
14
|
this.fsync = fsync;
|
|
14
15
|
this.path = resolve(root, path);
|
|
15
16
|
}
|
|
17
|
+
get failed() {
|
|
18
|
+
return this.#error !== undefined;
|
|
19
|
+
}
|
|
16
20
|
async load() {
|
|
17
21
|
const records = await readEventLog(this.path).catch((error) => {
|
|
18
22
|
if (isMissing(error))
|
|
@@ -22,21 +26,34 @@ export class EventLog {
|
|
|
22
26
|
this.#hash = records.at(-1)?.hash ?? null;
|
|
23
27
|
}
|
|
24
28
|
append(revision, state) {
|
|
29
|
+
if (this.failed)
|
|
30
|
+
return;
|
|
25
31
|
this.#tail = this.#tail.then(async () => {
|
|
32
|
+
if (this.failed)
|
|
33
|
+
return;
|
|
26
34
|
const base = { revision, occurred_at: now(), previous_hash: this.#hash, state };
|
|
27
35
|
const record = { ...base, hash: hash(base) };
|
|
28
36
|
await mkdir(dirname(this.path), { recursive: true });
|
|
29
37
|
await appendFile(this.path, `${JSON.stringify(record)}\n`, 'utf8');
|
|
30
38
|
if (this.fsync) {
|
|
31
|
-
const file = await open(this.path, 'r');
|
|
32
|
-
|
|
33
|
-
|
|
39
|
+
const file = await open(this.path, 'r+');
|
|
40
|
+
try {
|
|
41
|
+
await file.sync();
|
|
42
|
+
}
|
|
43
|
+
finally {
|
|
44
|
+
await file.close();
|
|
45
|
+
}
|
|
34
46
|
}
|
|
35
47
|
this.#hash = record.hash;
|
|
48
|
+
}).catch((error) => {
|
|
49
|
+
// A failed append may have written only part of a record. Do not extend that chain.
|
|
50
|
+
this.#error = error instanceof Error ? error : new Error(String(error));
|
|
36
51
|
});
|
|
37
52
|
}
|
|
38
|
-
close() {
|
|
39
|
-
|
|
53
|
+
async close() {
|
|
54
|
+
await this.#tail;
|
|
55
|
+
if (this.#error !== undefined)
|
|
56
|
+
throw this.#error;
|
|
40
57
|
}
|
|
41
58
|
}
|
|
42
59
|
export async function readEventLog(path) {
|
package/dist/store/schema.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const schema = "\nPRAGMA foreign_keys = ON;\nPRAGMA journal_mode = WAL;\nPRAGMA synchronous = NORMAL;\nPRAGMA busy_timeout = 5000;\n\nCREATE TABLE IF NOT EXISTS instance (\n id INTEGER PRIMARY KEY CHECK (id = 1),\n epoch TEXT NOT NULL,\n state_revision INTEGER NOT NULL CHECK (state_revision >= 0),\n created_at TEXT NOT NULL\n) STRICT;\n\nCREATE TABLE IF NOT EXISTS projects (\n id TEXT PRIMARY KEY,\n name TEXT NOT NULL UNIQUE,\n archived_at TEXT,\n revision INTEGER NOT NULL CHECK (revision >= 0),\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL\n) STRICT;\n\nCREATE TABLE IF NOT EXISTS workspaces (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n name TEXT NOT NULL,\n is_default INTEGER NOT NULL CHECK (is_default IN (0, 1)),\n revision INTEGER NOT NULL CHECK (revision >= 0),\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n UNIQUE(project_id, name)\n) STRICT;\nCREATE UNIQUE INDEX IF NOT EXISTS workspace_default ON workspaces(project_id) WHERE is_default = 1;\n\nCREATE TABLE IF NOT EXISTS workspace_paths (\n workspace_id TEXT NOT NULL REFERENCES workspaces(id) ON DELETE CASCADE,\n ordinal INTEGER NOT NULL CHECK (ordinal >= 0),\n path TEXT NOT NULL,\n PRIMARY KEY(workspace_id, ordinal),\n UNIQUE(workspace_id, path)\n) STRICT;\n\nCREATE TABLE IF NOT EXISTS tasks (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n title TEXT NOT NULL,\n archived_at TEXT,\n revision INTEGER NOT NULL CHECK (revision >= 0),\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL\n) STRICT;\n\nCREATE TABLE IF NOT EXISTS sessions (\n id TEXT PRIMARY KEY,\n task_id TEXT NOT NULL REFERENCES tasks(id) ON DELETE CASCADE,\n title TEXT NOT NULL,\n archived_at TEXT,\n revision INTEGER NOT NULL CHECK (revision >= 0),\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL\n) STRICT;\n\nCREATE TABLE IF NOT EXISTS agents (\n id TEXT PRIMARY KEY,\n task_id TEXT NOT NULL REFERENCES tasks(id) ON DELETE CASCADE,\n session_id TEXT NOT NULL REFERENCES sessions(id) ON DELETE CASCADE,\n workspace_id TEXT NOT NULL REFERENCES workspaces(id) ON DELETE RESTRICT,\n parent_agent_id TEXT REFERENCES agents(id) ON DELETE SET NULL,\n name TEXT NOT NULL,\n state TEXT NOT NULL CHECK (state IN ('IDLE', 'RUNNING', 'WAITING', 'STOPPED')),\n model TEXT NOT NULL,\n model_reasoning_effort TEXT NOT NULL,\n policy_preset TEXT NOT NULL,\n context_revision INTEGER NOT NULL CHECK (context_revision >= 0),\n revision INTEGER NOT NULL CHECK (revision >= 0),\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL\n) STRICT;\n\nCREATE TABLE IF NOT EXISTS messages (\n id TEXT PRIMARY KEY,\n agent_id TEXT NOT NULL REFERENCES agents(id) ON DELETE CASCADE,\n source_agent_id TEXT REFERENCES agents(id) ON DELETE SET NULL,\n role TEXT NOT NULL CHECK (role IN ('system', 'user', 'assistant', 'tool')),\n content TEXT NOT NULL,\n metadata_json TEXT,\n created_at TEXT NOT NULL\n) STRICT;\n\nCREATE TABLE IF NOT EXISTS pending_messages (\n id TEXT PRIMARY KEY,\n agent_id TEXT NOT NULL REFERENCES agents(id) ON DELETE CASCADE,\n message_id TEXT NOT NULL REFERENCES messages(id) ON DELETE CASCADE,\n source_agent_id TEXT REFERENCES agents(id) ON DELETE SET NULL,\n content TEXT NOT NULL,\n ordinal INTEGER NOT NULL CHECK (ordinal >= 0),\n revision INTEGER NOT NULL CHECK (revision >= 0),\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n UNIQUE(agent_id, ordinal)\n) STRICT;\n\nCREATE TABLE IF NOT EXISTS runs (\n id TEXT PRIMARY KEY,\n agent_id TEXT NOT NULL REFERENCES agents(id) ON DELETE CASCADE,\n goal_message_ids_json TEXT NOT NULL DEFAULT '[]',\n initial_step_pending INTEGER NOT NULL DEFAULT 0 CHECK (initial_step_pending IN (0, 1)),\n state TEXT NOT NULL CHECK (state IN ('READY', 'RUNNING', 'WAITING', 'TERMINAL')),\n outcome TEXT CHECK (outcome IN ('success', 'failed', 'cancelled', 'interrupted')),\n error_code TEXT,\n revision INTEGER NOT NULL CHECK (revision >= 0),\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL\n) STRICT;\n\nCREATE TABLE IF NOT EXISTS steps (\n id TEXT PRIMARY KEY,\n run_id TEXT NOT NULL REFERENCES runs(id) ON DELETE CASCADE,\n turn_group_id TEXT NOT NULL REFERENCES context_turn_groups(id) ON DELETE RESTRICT,\n ordinal INTEGER NOT NULL CHECK (ordinal >= 0),\n state TEXT NOT NULL CHECK (state IN ('RUNNING', 'WAITING', 'TERMINAL')),\n outcome TEXT CHECK (outcome IN ('success', 'failed', 'cancelled', 'interrupted')),\n error_code TEXT,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n UNIQUE(run_id, ordinal)\n) STRICT;\n\nCREATE TABLE IF NOT EXISTS model_attempts (\n id TEXT PRIMARY KEY,\n agent_id TEXT NOT NULL REFERENCES agents(id) ON DELETE CASCADE,\n step_id TEXT REFERENCES steps(id) ON DELETE CASCADE,\n kind TEXT NOT NULL CHECK (kind IN ('agent', 'compaction')),\n sequence INTEGER NOT NULL CHECK (sequence >= 0),\n model TEXT NOT NULL,\n state TEXT NOT NULL CHECK (state IN ('PREPARED', 'RUNNING', 'TERMINAL')),\n outcome TEXT CHECK (outcome IN ('success', 'failed', 'cancelled', 'interrupted')),\n profile_id TEXT NOT NULL,\n profile_version INTEGER NOT NULL CHECK (profile_version >= 1),\n profile_digest TEXT NOT NULL,\n config_digest TEXT NOT NULL,\n context_revision INTEGER NOT NULL CHECK (context_revision >= 0),\n request_digest TEXT NOT NULL,\n preparation_json TEXT NOT NULL,\n usage_json TEXT,\n error_code TEXT,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n UNIQUE(agent_id, kind, sequence)\n) STRICT;\n\nCREATE TABLE IF NOT EXISTS attempt_capabilities (\n attempt_id TEXT NOT NULL REFERENCES model_attempts(id) ON DELETE CASCADE,\n ordinal INTEGER NOT NULL CHECK (ordinal >= 0),\n capability_id TEXT NOT NULL,\n schema_json TEXT NOT NULL,\n PRIMARY KEY(attempt_id, ordinal),\n UNIQUE(attempt_id, capability_id)\n) STRICT;\n\nCREATE TABLE IF NOT EXISTS attempt_tool_ordinals (\n attempt_id TEXT NOT NULL REFERENCES model_attempts(id) ON DELETE CASCADE,\n ordinal INTEGER NOT NULL CHECK (ordinal >= 0),\n provider_tool_id TEXT,\n complete INTEGER NOT NULL CHECK (complete IN (0, 1)),\n PRIMARY KEY(attempt_id, ordinal)\n) STRICT;\n\nCREATE TABLE IF NOT EXISTS call_partitions (\n id TEXT PRIMARY KEY,\n step_id TEXT NOT NULL REFERENCES steps(id) ON DELETE CASCADE,\n ordinal INTEGER NOT NULL CHECK (ordinal >= 0),\n mode TEXT NOT NULL CHECK (mode IN ('parallel', 'serial')),\n created_at TEXT NOT NULL,\n UNIQUE(step_id, ordinal)\n) STRICT;\n\nCREATE TABLE IF NOT EXISTS calls (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n workspace_id TEXT NOT NULL REFERENCES workspaces(id) ON DELETE RESTRICT,\n agent_id TEXT REFERENCES agents(id) ON DELETE SET NULL,\n step_id TEXT REFERENCES steps(id) ON DELETE CASCADE,\n attempt_id TEXT REFERENCES model_attempts(id) ON DELETE CASCADE,\n partition_id TEXT REFERENCES call_partitions(id) ON DELETE CASCADE,\n parent_call_id TEXT REFERENCES calls(id) ON DELETE CASCADE,\n source TEXT NOT NULL CHECK (source IN ('user', 'llm', 'program')),\n capability_id TEXT NOT NULL,\n provider_call_id TEXT,\n call_ordinal INTEGER CHECK (call_ordinal >= 0),\n input_json TEXT NOT NULL,\n effect TEXT NOT NULL CHECK (effect IN ('read_only', 'workspace_write', 'external', 'full')),\n policy TEXT CHECK (policy IN ('read_only', 'workspace_write', 'external', 'ask', 'auto_approve', 'full_access')),\n state TEXT NOT NULL CHECK (state IN ('WAITING', 'QUEUED', 'RUNNING', 'TERMINAL')),\n wait_reason TEXT CHECK (wait_reason IN ('user_input', 'policy_review')),\n outcome TEXT CHECK (outcome IN ('success', 'failed', 'cancelled', 'interrupted')),\n outcome_unknown INTEGER NOT NULL CHECK (outcome_unknown IN (0, 1)),\n auto_review_passed INTEGER CHECK (auto_review_passed IN (0, 1)),\n revision INTEGER NOT NULL CHECK (revision >= 0),\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n UNIQUE(attempt_id, call_ordinal)\n) STRICT;\nCREATE UNIQUE INDEX IF NOT EXISTS calls_by_provider_call ON calls(attempt_id, provider_call_id) WHERE provider_call_id IS NOT NULL;\n\nCREATE TABLE IF NOT EXISTS results (\n id TEXT PRIMARY KEY,\n call_id TEXT NOT NULL UNIQUE REFERENCES calls(id) ON DELETE CASCADE,\n outcome TEXT NOT NULL CHECK (outcome IN ('success', 'failed', 'cancelled', 'interrupted')),\n content_json TEXT NOT NULL,\n truncated INTEGER NOT NULL DEFAULT 0 CHECK (truncated IN (0, 1)),\n error_code TEXT,\n error_message TEXT,\n created_at TEXT NOT NULL\n) STRICT;\n\nCREATE TABLE IF NOT EXISTS artifacts (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n name TEXT NOT NULL,\n media_type TEXT NOT NULL,\n relative_path TEXT NOT NULL,\n sha256 TEXT NOT NULL,\n size_bytes INTEGER NOT NULL CHECK (size_bytes >= 0),\n created_at TEXT NOT NULL\n) STRICT;\nCREATE UNIQUE INDEX IF NOT EXISTS artifact_identity ON artifacts(project_id, sha256, name, media_type);\nCREATE INDEX IF NOT EXISTS artifacts_by_path ON artifacts(relative_path);\n\nCREATE TABLE IF NOT EXISTS result_artifacts (\n result_id TEXT NOT NULL REFERENCES results(id) ON DELETE CASCADE,\n artifact_id TEXT NOT NULL REFERENCES artifacts(id) ON DELETE RESTRICT,\n PRIMARY KEY(result_id, artifact_id)\n) STRICT;\n\n-- No table for write_file/edit_file file history: it belongs to the Executor, which owns the files\n-- and therefore the only authoritative view of what they contained. Core keeps Call semantics and\n-- asks the Executor to revert by call_id. See\n-- docs/architecture/harness-level3/09-file-snapshot-storage-decision.md.\n\nCREATE TABLE IF NOT EXISTS context_turn_groups (\n id TEXT PRIMARY KEY,\n agent_id TEXT NOT NULL REFERENCES agents(id) ON DELETE CASCADE,\n ordinal INTEGER NOT NULL CHECK (ordinal >= 0),\n kind TEXT NOT NULL CHECK (kind IN ('turn', 'compaction', 'included', 'ledger')),\n state TEXT NOT NULL CHECK (state IN ('OPEN', 'COMPLETE', 'ABORTED')),\n revision INTEGER NOT NULL CHECK (revision >= 0),\n created_at TEXT NOT NULL,\n completed_at TEXT,\n UNIQUE(agent_id, ordinal)\n) STRICT;\n\nCREATE TABLE IF NOT EXISTS context_items (\n id TEXT PRIMARY KEY,\n agent_id TEXT NOT NULL REFERENCES agents(id) ON DELETE CASCADE,\n turn_group_id TEXT NOT NULL REFERENCES context_turn_groups(id) ON DELETE CASCADE,\n turn_group_ordinal INTEGER NOT NULL CHECK (turn_group_ordinal >= 0),\n kind TEXT NOT NULL CHECK (kind IN ('message', 'tool_calls', 'result', 'compaction')),\n source_id TEXT NOT NULL,\n role TEXT CHECK (role IN ('system', 'user', 'assistant', 'tool')),\n content TEXT NOT NULL,\n tool_call_id TEXT,\n tool_name TEXT,\n ordinal INTEGER NOT NULL CHECK (ordinal >= 0),\n visible INTEGER NOT NULL CHECK (visible IN (0, 1)),\n locked INTEGER NOT NULL CHECK (locked IN (0, 1)),\n revision INTEGER NOT NULL CHECK (revision >= 0),\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n UNIQUE(agent_id, ordinal),\n UNIQUE(turn_group_id, turn_group_ordinal)\n) STRICT;\n\nCREATE TABLE IF NOT EXISTS context_overrides (\n id TEXT PRIMARY KEY,\n agent_id TEXT NOT NULL REFERENCES agents(id) ON DELETE CASCADE,\n target_kind TEXT NOT NULL CHECK (target_kind IN ('agent', 'message', 'result', 'artifact')),\n target_id TEXT NOT NULL,\n instructions TEXT NOT NULL,\n revision INTEGER NOT NULL CHECK (revision >= 0),\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n UNIQUE(agent_id, target_kind, target_id)\n) STRICT;\n\nCREATE TABLE IF NOT EXISTS projection_decisions (\n id TEXT PRIMARY KEY,\n agent_id TEXT NOT NULL REFERENCES agents(id) ON DELETE CASCADE,\n attempt_id TEXT REFERENCES model_attempts(id) ON DELETE CASCADE,\n stage TEXT NOT NULL,\n source_tokens INTEGER NOT NULL CHECK (source_tokens >= 0),\n projected_tokens INTEGER NOT NULL CHECK (projected_tokens >= 0),\n details_json TEXT NOT NULL,\n created_at TEXT NOT NULL\n) STRICT;\n\nCREATE TABLE IF NOT EXISTS capability_assignments (\n agent_id TEXT NOT NULL REFERENCES agents(id) ON DELETE CASCADE,\n capability_id TEXT NOT NULL,\n policy TEXT NOT NULL CHECK (policy IN ('read_only', 'workspace_write', 'external', 'ask', 'auto_approve', 'full_access')),\n assigned_at TEXT NOT NULL,\n PRIMARY KEY(agent_id, capability_id)\n) STRICT;\n\nCREATE TABLE IF NOT EXISTS capability_loads (\n agent_id TEXT NOT NULL REFERENCES agents(id) ON DELETE CASCADE,\n capability_id TEXT NOT NULL,\n loaded_at TEXT NOT NULL,\n PRIMARY KEY(agent_id, capability_id),\n FOREIGN KEY(agent_id, capability_id) REFERENCES capability_assignments(agent_id, capability_id) ON DELETE CASCADE\n) STRICT;\n\nCREATE TABLE IF NOT EXISTS agent_plans (\n agent_id TEXT PRIMARY KEY REFERENCES agents(id) ON DELETE CASCADE,\n items_json TEXT NOT NULL,\n revision INTEGER NOT NULL CHECK (revision >= 0),\n updated_at TEXT NOT NULL\n) STRICT;\n\nCREATE TABLE IF NOT EXISTS ingress_requests (\n client_id TEXT NOT NULL,\n key TEXT NOT NULL,\n operation TEXT NOT NULL,\n request_digest TEXT NOT NULL,\n response_json TEXT NOT NULL,\n created_at TEXT NOT NULL,\n PRIMARY KEY(client_id, key)\n) STRICT;\n\nCREATE TABLE IF NOT EXISTS side_effect_ledgers (\n id TEXT PRIMARY KEY,\n step_id TEXT NOT NULL REFERENCES steps(id) ON DELETE CASCADE,\n content TEXT NOT NULL,\n created_at TEXT NOT NULL\n) STRICT;\n\nCREATE INDEX IF NOT EXISTS tasks_by_project ON tasks(project_id, archived_at, updated_at DESC);\nCREATE INDEX IF NOT EXISTS sessions_by_task ON sessions(task_id, archived_at, updated_at DESC);\nCREATE INDEX IF NOT EXISTS agents_by_session ON agents(session_id, parent_agent_id, created_at);\nCREATE INDEX IF NOT EXISTS pending_by_agent ON pending_messages(agent_id, ordinal);\nCREATE INDEX IF NOT EXISTS runs_by_agent ON runs(agent_id, created_at DESC);\nCREATE UNIQUE INDEX IF NOT EXISTS one_live_run_per_agent ON runs(agent_id) WHERE state != 'TERMINAL';\nCREATE INDEX IF NOT EXISTS attempts_by_step ON model_attempts(step_id, sequence);\nCREATE INDEX IF NOT EXISTS calls_by_project ON calls(project_id, state, created_at DESC);\nCREATE INDEX IF NOT EXISTS context_by_agent ON context_items(agent_id, ordinal);\nCREATE INDEX IF NOT EXISTS artifacts_by_project ON artifacts(project_id, created_at DESC);\n";
|
|
1
|
+
export declare const schema = "\nPRAGMA foreign_keys = ON;\nPRAGMA journal_mode = WAL;\nPRAGMA synchronous = NORMAL;\nPRAGMA busy_timeout = 5000;\n\nCREATE TABLE IF NOT EXISTS instance (\n id INTEGER PRIMARY KEY CHECK (id = 1),\n epoch TEXT NOT NULL,\n state_revision INTEGER NOT NULL CHECK (state_revision >= 0),\n created_at TEXT NOT NULL\n) STRICT;\n\nCREATE TABLE IF NOT EXISTS projects (\n id TEXT PRIMARY KEY,\n name TEXT NOT NULL UNIQUE,\n archived_at TEXT,\n revision INTEGER NOT NULL CHECK (revision >= 0),\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL\n) STRICT;\n\nCREATE TABLE IF NOT EXISTS workspaces (\n executor_ref TEXT,\n executor_id TEXT NOT NULL DEFAULT 'remote' CHECK (executor_id IN ('local', 'remote')),\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n name TEXT NOT NULL,\n is_default INTEGER NOT NULL CHECK (is_default IN (0, 1)),\n revision INTEGER NOT NULL CHECK (revision >= 0),\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n UNIQUE(project_id, name)\n) STRICT;\nCREATE UNIQUE INDEX IF NOT EXISTS workspace_default ON workspaces(project_id) WHERE is_default = 1;\n\nCREATE TABLE IF NOT EXISTS workspace_paths (\n workspace_id TEXT NOT NULL REFERENCES workspaces(id) ON DELETE CASCADE,\n ordinal INTEGER NOT NULL CHECK (ordinal >= 0),\n path TEXT NOT NULL,\n PRIMARY KEY(workspace_id, ordinal),\n UNIQUE(workspace_id, path)\n) STRICT;\n\nCREATE TABLE IF NOT EXISTS tasks (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n title TEXT NOT NULL,\n archived_at TEXT,\n revision INTEGER NOT NULL CHECK (revision >= 0),\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL\n) STRICT;\n\nCREATE TABLE IF NOT EXISTS sessions (\n id TEXT PRIMARY KEY,\n task_id TEXT NOT NULL REFERENCES tasks(id) ON DELETE CASCADE,\n title TEXT NOT NULL,\n archived_at TEXT,\n revision INTEGER NOT NULL CHECK (revision >= 0),\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL\n) STRICT;\n\nCREATE TABLE IF NOT EXISTS agents (\n id TEXT PRIMARY KEY,\n task_id TEXT NOT NULL REFERENCES tasks(id) ON DELETE CASCADE,\n session_id TEXT NOT NULL REFERENCES sessions(id) ON DELETE CASCADE,\n workspace_id TEXT NOT NULL REFERENCES workspaces(id) ON DELETE RESTRICT,\n parent_agent_id TEXT REFERENCES agents(id) ON DELETE SET NULL,\n name TEXT NOT NULL,\n state TEXT NOT NULL CHECK (state IN ('IDLE', 'RUNNING', 'WAITING', 'STOPPED')),\n model TEXT NOT NULL,\n model_reasoning_effort TEXT NOT NULL,\n policy_preset TEXT NOT NULL,\n context_revision INTEGER NOT NULL CHECK (context_revision >= 0),\n revision INTEGER NOT NULL CHECK (revision >= 0),\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL\n) STRICT;\n\nCREATE TABLE IF NOT EXISTS messages (\n id TEXT PRIMARY KEY,\n agent_id TEXT NOT NULL REFERENCES agents(id) ON DELETE CASCADE,\n source_agent_id TEXT REFERENCES agents(id) ON DELETE SET NULL,\n role TEXT NOT NULL CHECK (role IN ('system', 'user', 'assistant', 'tool')),\n content TEXT NOT NULL,\n metadata_json TEXT,\n created_at TEXT NOT NULL\n) STRICT;\n\nCREATE TABLE IF NOT EXISTS pending_messages (\n id TEXT PRIMARY KEY,\n agent_id TEXT NOT NULL REFERENCES agents(id) ON DELETE CASCADE,\n message_id TEXT NOT NULL REFERENCES messages(id) ON DELETE CASCADE,\n source_agent_id TEXT REFERENCES agents(id) ON DELETE SET NULL,\n content TEXT NOT NULL,\n ordinal INTEGER NOT NULL CHECK (ordinal >= 0),\n revision INTEGER NOT NULL CHECK (revision >= 0),\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n UNIQUE(agent_id, ordinal)\n) STRICT;\n\nCREATE TABLE IF NOT EXISTS runs (\n id TEXT PRIMARY KEY,\n agent_id TEXT NOT NULL REFERENCES agents(id) ON DELETE CASCADE,\n goal_message_ids_json TEXT NOT NULL DEFAULT '[]',\n initial_step_pending INTEGER NOT NULL DEFAULT 0 CHECK (initial_step_pending IN (0, 1)),\n state TEXT NOT NULL CHECK (state IN ('READY', 'RUNNING', 'WAITING', 'TERMINAL')),\n outcome TEXT CHECK (outcome IN ('success', 'failed', 'cancelled', 'interrupted')),\n error_code TEXT,\n revision INTEGER NOT NULL CHECK (revision >= 0),\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL\n) STRICT;\n\nCREATE TABLE IF NOT EXISTS steps (\n id TEXT PRIMARY KEY,\n run_id TEXT NOT NULL REFERENCES runs(id) ON DELETE CASCADE,\n turn_group_id TEXT NOT NULL REFERENCES context_turn_groups(id) ON DELETE RESTRICT,\n ordinal INTEGER NOT NULL CHECK (ordinal >= 0),\n state TEXT NOT NULL CHECK (state IN ('RUNNING', 'WAITING', 'TERMINAL')),\n outcome TEXT CHECK (outcome IN ('success', 'failed', 'cancelled', 'interrupted')),\n error_code TEXT,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n UNIQUE(run_id, ordinal)\n) STRICT;\n\nCREATE TABLE IF NOT EXISTS model_attempts (\n id TEXT PRIMARY KEY,\n agent_id TEXT NOT NULL REFERENCES agents(id) ON DELETE CASCADE,\n step_id TEXT REFERENCES steps(id) ON DELETE CASCADE,\n kind TEXT NOT NULL CHECK (kind IN ('agent', 'compaction')),\n sequence INTEGER NOT NULL CHECK (sequence >= 0),\n model TEXT NOT NULL,\n state TEXT NOT NULL CHECK (state IN ('PREPARED', 'RUNNING', 'TERMINAL')),\n outcome TEXT CHECK (outcome IN ('success', 'failed', 'cancelled', 'interrupted')),\n profile_id TEXT NOT NULL,\n profile_version INTEGER NOT NULL CHECK (profile_version >= 1),\n profile_digest TEXT NOT NULL,\n config_digest TEXT NOT NULL,\n context_revision INTEGER NOT NULL CHECK (context_revision >= 0),\n request_digest TEXT NOT NULL,\n request_json TEXT,\n observation_json TEXT,\n preparation_json TEXT NOT NULL,\n usage_json TEXT,\n error_code TEXT,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n UNIQUE(agent_id, kind, sequence)\n) STRICT;\n\nCREATE TABLE IF NOT EXISTS attempt_capabilities (\n attempt_id TEXT NOT NULL REFERENCES model_attempts(id) ON DELETE CASCADE,\n ordinal INTEGER NOT NULL CHECK (ordinal >= 0),\n capability_id TEXT NOT NULL,\n schema_json TEXT NOT NULL,\n PRIMARY KEY(attempt_id, ordinal),\n UNIQUE(attempt_id, capability_id)\n) STRICT;\n\nCREATE TABLE IF NOT EXISTS attempt_tool_ordinals (\n attempt_id TEXT NOT NULL REFERENCES model_attempts(id) ON DELETE CASCADE,\n ordinal INTEGER NOT NULL CHECK (ordinal >= 0),\n provider_tool_id TEXT,\n complete INTEGER NOT NULL CHECK (complete IN (0, 1)),\n PRIMARY KEY(attempt_id, ordinal)\n) STRICT;\n\nCREATE TABLE IF NOT EXISTS call_partitions (\n id TEXT PRIMARY KEY,\n step_id TEXT NOT NULL REFERENCES steps(id) ON DELETE CASCADE,\n ordinal INTEGER NOT NULL CHECK (ordinal >= 0),\n mode TEXT NOT NULL CHECK (mode IN ('parallel', 'serial')),\n created_at TEXT NOT NULL,\n UNIQUE(step_id, ordinal)\n) STRICT;\n\nCREATE TABLE IF NOT EXISTS calls (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n workspace_id TEXT NOT NULL REFERENCES workspaces(id) ON DELETE RESTRICT,\n agent_id TEXT REFERENCES agents(id) ON DELETE SET NULL,\n step_id TEXT REFERENCES steps(id) ON DELETE CASCADE,\n attempt_id TEXT REFERENCES model_attempts(id) ON DELETE CASCADE,\n partition_id TEXT REFERENCES call_partitions(id) ON DELETE CASCADE,\n parent_call_id TEXT REFERENCES calls(id) ON DELETE CASCADE,\n source TEXT NOT NULL CHECK (source IN ('user', 'llm', 'program')),\n capability_id TEXT NOT NULL,\n provider_call_id TEXT,\n call_ordinal INTEGER CHECK (call_ordinal >= 0),\n input_json TEXT NOT NULL,\n continuation_json TEXT,\n effect TEXT NOT NULL CHECK (effect IN ('read_only', 'workspace_write', 'external', 'full')),\n policy TEXT CHECK (policy IN ('read_only', 'workspace_write', 'external', 'ask', 'auto_approve', 'full_access')),\n state TEXT NOT NULL CHECK (state IN ('WAITING', 'QUEUED', 'RUNNING', 'TERMINAL')),\n wait_reason TEXT CHECK (wait_reason IN ('user_input', 'policy_review')),\n outcome TEXT CHECK (outcome IN ('success', 'failed', 'cancelled', 'interrupted')),\n outcome_unknown INTEGER NOT NULL CHECK (outcome_unknown IN (0, 1)),\n auto_review_passed INTEGER CHECK (auto_review_passed IN (0, 1)),\n auto_review_json TEXT,\n revision INTEGER NOT NULL CHECK (revision >= 0),\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n UNIQUE(attempt_id, call_ordinal)\n) STRICT;\nCREATE UNIQUE INDEX IF NOT EXISTS calls_by_provider_call ON calls(attempt_id, provider_call_id) WHERE provider_call_id IS NOT NULL;\n\nCREATE TABLE IF NOT EXISTS results (\n capture TEXT NOT NULL DEFAULT 'unknown' CHECK (capture IN ('complete', 'partial', 'unknown')),\n stored TEXT NOT NULL DEFAULT 'unknown' CHECK (stored IN ('full', 'unknown')),\n id TEXT PRIMARY KEY,\n call_id TEXT NOT NULL UNIQUE REFERENCES calls(id) ON DELETE CASCADE,\n outcome TEXT NOT NULL CHECK (outcome IN ('success', 'failed', 'cancelled', 'interrupted')),\n content_json TEXT NOT NULL,\n truncated INTEGER NOT NULL DEFAULT 0 CHECK (truncated IN (0, 1)),\n error_code TEXT,\n error_message TEXT,\n created_at TEXT NOT NULL\n) STRICT;\n\nCREATE TABLE IF NOT EXISTS artifacts (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n name TEXT NOT NULL,\n media_type TEXT NOT NULL,\n relative_path TEXT NOT NULL,\n sha256 TEXT NOT NULL,\n size_bytes INTEGER NOT NULL CHECK (size_bytes >= 0),\n created_at TEXT NOT NULL\n) STRICT;\nCREATE UNIQUE INDEX IF NOT EXISTS artifact_identity ON artifacts(project_id, sha256, name, media_type);\nCREATE INDEX IF NOT EXISTS artifacts_by_path ON artifacts(relative_path);\n\nCREATE TABLE IF NOT EXISTS result_artifacts (\n result_id TEXT NOT NULL REFERENCES results(id) ON DELETE CASCADE,\n artifact_id TEXT NOT NULL REFERENCES artifacts(id) ON DELETE RESTRICT,\n PRIMARY KEY(result_id, artifact_id)\n) STRICT;\n\n-- No table for edit_file/patch_file file history: it belongs to the Executor, which owns the files\n-- and therefore the only authoritative view of what they contained. Core keeps Call semantics and\n-- asks the Executor to revert by call_id. See\n-- docs/architecture/harness-level3/09-file-snapshot-storage-decision.md.\n\nCREATE TABLE IF NOT EXISTS context_turn_groups (\n id TEXT PRIMARY KEY,\n agent_id TEXT NOT NULL REFERENCES agents(id) ON DELETE CASCADE,\n ordinal INTEGER NOT NULL CHECK (ordinal >= 0),\n kind TEXT NOT NULL CHECK (kind IN ('turn', 'compaction', 'included', 'ledger')),\n state TEXT NOT NULL CHECK (state IN ('OPEN', 'COMPLETE', 'ABORTED')),\n revision INTEGER NOT NULL CHECK (revision >= 0),\n created_at TEXT NOT NULL,\n completed_at TEXT,\n UNIQUE(agent_id, ordinal)\n) STRICT;\n\nCREATE TABLE IF NOT EXISTS context_items (\n id TEXT PRIMARY KEY,\n agent_id TEXT NOT NULL REFERENCES agents(id) ON DELETE CASCADE,\n turn_group_id TEXT NOT NULL REFERENCES context_turn_groups(id) ON DELETE CASCADE,\n turn_group_ordinal INTEGER NOT NULL CHECK (turn_group_ordinal >= 0),\n kind TEXT NOT NULL CHECK (kind IN ('message', 'tool_calls', 'result', 'compaction')),\n source_id TEXT NOT NULL,\n role TEXT CHECK (role IN ('system', 'user', 'assistant', 'tool')),\n content TEXT NOT NULL,\n tool_call_id TEXT,\n tool_name TEXT,\n ordinal INTEGER NOT NULL CHECK (ordinal >= 0),\n visible INTEGER NOT NULL CHECK (visible IN (0, 1)),\n locked INTEGER NOT NULL CHECK (locked IN (0, 1)),\n revision INTEGER NOT NULL CHECK (revision >= 0),\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n UNIQUE(agent_id, ordinal),\n UNIQUE(turn_group_id, turn_group_ordinal)\n) STRICT;\n\nCREATE TABLE IF NOT EXISTS context_overrides (\n id TEXT PRIMARY KEY,\n agent_id TEXT NOT NULL REFERENCES agents(id) ON DELETE CASCADE,\n target_kind TEXT NOT NULL CHECK (target_kind IN ('agent', 'message', 'result', 'artifact')),\n target_id TEXT NOT NULL,\n instructions TEXT NOT NULL,\n revision INTEGER NOT NULL CHECK (revision >= 0),\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n UNIQUE(agent_id, target_kind, target_id)\n) STRICT;\n\nCREATE TABLE IF NOT EXISTS todo_reminder_state (\n agent_id TEXT PRIMARY KEY REFERENCES agents(id) ON DELETE CASCADE,\n last_context_rowid INTEGER NOT NULL DEFAULT 0,\n pending_tokens INTEGER NOT NULL DEFAULT 0 CHECK (pending_tokens >= 0)\n) STRICT;\n\nCREATE TABLE IF NOT EXISTS working_context_items (\n context_item_id TEXT PRIMARY KEY REFERENCES context_items(id) ON DELETE CASCADE,\n agent_id TEXT NOT NULL REFERENCES agents(id) ON DELETE CASCADE,\n source_revision INTEGER NOT NULL,\n content TEXT NOT NULL,\n snipped INTEGER NOT NULL DEFAULT 0 CHECK (snipped IN (0, 1))\n) STRICT;\nCREATE INDEX IF NOT EXISTS working_context_agent ON working_context_items(agent_id);\n\nCREATE TABLE IF NOT EXISTS working_contexts (\n agent_id TEXT PRIMARY KEY REFERENCES agents(id) ON DELETE CASCADE,\n source_revision INTEGER NOT NULL,\n revision INTEGER NOT NULL,\n digest TEXT NOT NULL,\n prefixes_json TEXT NOT NULL DEFAULT '[]',\n messages_json TEXT,\n request_frame_json TEXT,\n updated_at TEXT NOT NULL\n) STRICT;\n\nCREATE TABLE IF NOT EXISTS context_compactions (\n context_item_id TEXT PRIMARY KEY REFERENCES context_items(id) ON DELETE CASCADE,\n source_revision INTEGER NOT NULL,\n covered_item_ids_json TEXT NOT NULL,\n focus TEXT\n) STRICT;\n\nCREATE TABLE IF NOT EXISTS projection_decisions (\n id TEXT PRIMARY KEY,\n agent_id TEXT NOT NULL REFERENCES agents(id) ON DELETE CASCADE,\n attempt_id TEXT REFERENCES model_attempts(id) ON DELETE CASCADE,\n stage TEXT NOT NULL,\n source_tokens INTEGER NOT NULL CHECK (source_tokens >= 0),\n projected_tokens INTEGER NOT NULL CHECK (projected_tokens >= 0),\n details_json TEXT NOT NULL,\n created_at TEXT NOT NULL\n) STRICT;\n\nCREATE TABLE IF NOT EXISTS capability_assignments (\n agent_id TEXT NOT NULL REFERENCES agents(id) ON DELETE CASCADE,\n capability_id TEXT NOT NULL,\n policy TEXT NOT NULL CHECK (policy IN ('read_only', 'workspace_write', 'external', 'ask', 'auto_approve', 'full_access')),\n assigned_at TEXT NOT NULL,\n PRIMARY KEY(agent_id, capability_id)\n) STRICT;\n\nCREATE TABLE IF NOT EXISTS capability_loads (\n agent_id TEXT NOT NULL REFERENCES agents(id) ON DELETE CASCADE,\n capability_id TEXT NOT NULL,\n loaded_at TEXT NOT NULL,\n PRIMARY KEY(agent_id, capability_id),\n FOREIGN KEY(agent_id, capability_id) REFERENCES capability_assignments(agent_id, capability_id) ON DELETE CASCADE\n) STRICT;\n\nCREATE TABLE IF NOT EXISTS agent_plans (\n agent_id TEXT PRIMARY KEY REFERENCES agents(id) ON DELETE CASCADE,\n items_json TEXT NOT NULL,\n revision INTEGER NOT NULL CHECK (revision >= 0),\n updated_at TEXT NOT NULL\n) STRICT;\n\nCREATE TABLE IF NOT EXISTS ingress_requests (\n client_id TEXT NOT NULL,\n key TEXT NOT NULL,\n operation TEXT NOT NULL,\n request_digest TEXT NOT NULL,\n response_json TEXT NOT NULL,\n created_at TEXT NOT NULL,\n PRIMARY KEY(client_id, key)\n) STRICT;\n\nCREATE TABLE IF NOT EXISTS side_effect_ledgers (\n id TEXT PRIMARY KEY,\n step_id TEXT NOT NULL REFERENCES steps(id) ON DELETE CASCADE,\n content TEXT NOT NULL,\n created_at TEXT NOT NULL\n) STRICT;\n\nCREATE TABLE IF NOT EXISTS purge_cleanups (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id),\n executor_state_id TEXT NOT NULL,\n payload_json TEXT NOT NULL,\n created_at TEXT NOT NULL\n) STRICT;\n\nCREATE INDEX IF NOT EXISTS tasks_by_project ON tasks(project_id, archived_at, updated_at DESC);\nCREATE INDEX IF NOT EXISTS sessions_by_task ON sessions(task_id, archived_at, updated_at DESC);\nCREATE INDEX IF NOT EXISTS agents_by_session ON agents(session_id, parent_agent_id, created_at);\nCREATE INDEX IF NOT EXISTS pending_by_agent ON pending_messages(agent_id, ordinal);\nCREATE INDEX IF NOT EXISTS runs_by_agent ON runs(agent_id, created_at DESC);\nCREATE UNIQUE INDEX IF NOT EXISTS one_live_run_per_agent ON runs(agent_id) WHERE state != 'TERMINAL';\nCREATE INDEX IF NOT EXISTS attempts_by_step ON model_attempts(step_id, sequence);\nCREATE INDEX IF NOT EXISTS calls_by_project ON calls(project_id, state, created_at DESC);\nCREATE INDEX IF NOT EXISTS context_by_agent ON context_items(agent_id, ordinal);\nCREATE INDEX IF NOT EXISTS artifacts_by_project ON artifacts(project_id, created_at DESC);\n";
|
package/dist/store/schema.js
CHANGED
|
@@ -21,6 +21,8 @@ CREATE TABLE IF NOT EXISTS projects (
|
|
|
21
21
|
) STRICT;
|
|
22
22
|
|
|
23
23
|
CREATE TABLE IF NOT EXISTS workspaces (
|
|
24
|
+
executor_ref TEXT,
|
|
25
|
+
executor_id TEXT NOT NULL DEFAULT 'remote' CHECK (executor_id IN ('local', 'remote')),
|
|
24
26
|
id TEXT PRIMARY KEY,
|
|
25
27
|
project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
|
|
26
28
|
name TEXT NOT NULL,
|
|
@@ -141,6 +143,8 @@ CREATE TABLE IF NOT EXISTS model_attempts (
|
|
|
141
143
|
config_digest TEXT NOT NULL,
|
|
142
144
|
context_revision INTEGER NOT NULL CHECK (context_revision >= 0),
|
|
143
145
|
request_digest TEXT NOT NULL,
|
|
146
|
+
request_json TEXT,
|
|
147
|
+
observation_json TEXT,
|
|
144
148
|
preparation_json TEXT NOT NULL,
|
|
145
149
|
usage_json TEXT,
|
|
146
150
|
error_code TEXT,
|
|
@@ -189,6 +193,7 @@ CREATE TABLE IF NOT EXISTS calls (
|
|
|
189
193
|
provider_call_id TEXT,
|
|
190
194
|
call_ordinal INTEGER CHECK (call_ordinal >= 0),
|
|
191
195
|
input_json TEXT NOT NULL,
|
|
196
|
+
continuation_json TEXT,
|
|
192
197
|
effect TEXT NOT NULL CHECK (effect IN ('read_only', 'workspace_write', 'external', 'full')),
|
|
193
198
|
policy TEXT CHECK (policy IN ('read_only', 'workspace_write', 'external', 'ask', 'auto_approve', 'full_access')),
|
|
194
199
|
state TEXT NOT NULL CHECK (state IN ('WAITING', 'QUEUED', 'RUNNING', 'TERMINAL')),
|
|
@@ -196,6 +201,7 @@ CREATE TABLE IF NOT EXISTS calls (
|
|
|
196
201
|
outcome TEXT CHECK (outcome IN ('success', 'failed', 'cancelled', 'interrupted')),
|
|
197
202
|
outcome_unknown INTEGER NOT NULL CHECK (outcome_unknown IN (0, 1)),
|
|
198
203
|
auto_review_passed INTEGER CHECK (auto_review_passed IN (0, 1)),
|
|
204
|
+
auto_review_json TEXT,
|
|
199
205
|
revision INTEGER NOT NULL CHECK (revision >= 0),
|
|
200
206
|
created_at TEXT NOT NULL,
|
|
201
207
|
updated_at TEXT NOT NULL,
|
|
@@ -204,6 +210,8 @@ CREATE TABLE IF NOT EXISTS calls (
|
|
|
204
210
|
CREATE UNIQUE INDEX IF NOT EXISTS calls_by_provider_call ON calls(attempt_id, provider_call_id) WHERE provider_call_id IS NOT NULL;
|
|
205
211
|
|
|
206
212
|
CREATE TABLE IF NOT EXISTS results (
|
|
213
|
+
capture TEXT NOT NULL DEFAULT 'unknown' CHECK (capture IN ('complete', 'partial', 'unknown')),
|
|
214
|
+
stored TEXT NOT NULL DEFAULT 'unknown' CHECK (stored IN ('full', 'unknown')),
|
|
207
215
|
id TEXT PRIMARY KEY,
|
|
208
216
|
call_id TEXT NOT NULL UNIQUE REFERENCES calls(id) ON DELETE CASCADE,
|
|
209
217
|
outcome TEXT NOT NULL CHECK (outcome IN ('success', 'failed', 'cancelled', 'interrupted')),
|
|
@@ -233,7 +241,7 @@ CREATE TABLE IF NOT EXISTS result_artifacts (
|
|
|
233
241
|
PRIMARY KEY(result_id, artifact_id)
|
|
234
242
|
) STRICT;
|
|
235
243
|
|
|
236
|
-
-- No table for
|
|
244
|
+
-- No table for edit_file/patch_file file history: it belongs to the Executor, which owns the files
|
|
237
245
|
-- and therefore the only authoritative view of what they contained. Core keeps Call semantics and
|
|
238
246
|
-- asks the Executor to revert by call_id. See
|
|
239
247
|
-- docs/architecture/harness-level3/09-file-snapshot-storage-decision.md.
|
|
@@ -283,6 +291,39 @@ CREATE TABLE IF NOT EXISTS context_overrides (
|
|
|
283
291
|
UNIQUE(agent_id, target_kind, target_id)
|
|
284
292
|
) STRICT;
|
|
285
293
|
|
|
294
|
+
CREATE TABLE IF NOT EXISTS todo_reminder_state (
|
|
295
|
+
agent_id TEXT PRIMARY KEY REFERENCES agents(id) ON DELETE CASCADE,
|
|
296
|
+
last_context_rowid INTEGER NOT NULL DEFAULT 0,
|
|
297
|
+
pending_tokens INTEGER NOT NULL DEFAULT 0 CHECK (pending_tokens >= 0)
|
|
298
|
+
) STRICT;
|
|
299
|
+
|
|
300
|
+
CREATE TABLE IF NOT EXISTS working_context_items (
|
|
301
|
+
context_item_id TEXT PRIMARY KEY REFERENCES context_items(id) ON DELETE CASCADE,
|
|
302
|
+
agent_id TEXT NOT NULL REFERENCES agents(id) ON DELETE CASCADE,
|
|
303
|
+
source_revision INTEGER NOT NULL,
|
|
304
|
+
content TEXT NOT NULL,
|
|
305
|
+
snipped INTEGER NOT NULL DEFAULT 0 CHECK (snipped IN (0, 1))
|
|
306
|
+
) STRICT;
|
|
307
|
+
CREATE INDEX IF NOT EXISTS working_context_agent ON working_context_items(agent_id);
|
|
308
|
+
|
|
309
|
+
CREATE TABLE IF NOT EXISTS working_contexts (
|
|
310
|
+
agent_id TEXT PRIMARY KEY REFERENCES agents(id) ON DELETE CASCADE,
|
|
311
|
+
source_revision INTEGER NOT NULL,
|
|
312
|
+
revision INTEGER NOT NULL,
|
|
313
|
+
digest TEXT NOT NULL,
|
|
314
|
+
prefixes_json TEXT NOT NULL DEFAULT '[]',
|
|
315
|
+
messages_json TEXT,
|
|
316
|
+
request_frame_json TEXT,
|
|
317
|
+
updated_at TEXT NOT NULL
|
|
318
|
+
) STRICT;
|
|
319
|
+
|
|
320
|
+
CREATE TABLE IF NOT EXISTS context_compactions (
|
|
321
|
+
context_item_id TEXT PRIMARY KEY REFERENCES context_items(id) ON DELETE CASCADE,
|
|
322
|
+
source_revision INTEGER NOT NULL,
|
|
323
|
+
covered_item_ids_json TEXT NOT NULL,
|
|
324
|
+
focus TEXT
|
|
325
|
+
) STRICT;
|
|
326
|
+
|
|
286
327
|
CREATE TABLE IF NOT EXISTS projection_decisions (
|
|
287
328
|
id TEXT PRIMARY KEY,
|
|
288
329
|
agent_id TEXT NOT NULL REFERENCES agents(id) ON DELETE CASCADE,
|
|
@@ -334,6 +375,14 @@ CREATE TABLE IF NOT EXISTS side_effect_ledgers (
|
|
|
334
375
|
created_at TEXT NOT NULL
|
|
335
376
|
) STRICT;
|
|
336
377
|
|
|
378
|
+
CREATE TABLE IF NOT EXISTS purge_cleanups (
|
|
379
|
+
id TEXT PRIMARY KEY,
|
|
380
|
+
project_id TEXT NOT NULL REFERENCES projects(id),
|
|
381
|
+
executor_state_id TEXT NOT NULL,
|
|
382
|
+
payload_json TEXT NOT NULL,
|
|
383
|
+
created_at TEXT NOT NULL
|
|
384
|
+
) STRICT;
|
|
385
|
+
|
|
337
386
|
CREATE INDEX IF NOT EXISTS tasks_by_project ON tasks(project_id, archived_at, updated_at DESC);
|
|
338
387
|
CREATE INDEX IF NOT EXISTS sessions_by_task ON sessions(task_id, archived_at, updated_at DESC);
|
|
339
388
|
CREATE INDEX IF NOT EXISTS agents_by_session ON agents(session_id, parent_agent_id, created_at);
|
package/dist/store/store.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import
|
|
1
|
+
import type { Observability } from '../runtime/observability.js';
|
|
2
|
+
import { type EntityRef, type Json, type ModelMessage, type ModelResponse, type Page } from '../core/domain.js';
|
|
2
3
|
import type { EventBus } from '../runtime/events.js';
|
|
3
4
|
import type { Sqlite } from './database.js';
|
|
5
|
+
import type { AutoReviewResult, ReviewContext } from '../contracts/review.js';
|
|
4
6
|
import type { EventLog } from './event-log.js';
|
|
5
7
|
export type Document = Readonly<Record<string, Json>>;
|
|
6
8
|
interface PageOptions {
|
|
@@ -27,7 +29,10 @@ export interface IngressCommand {
|
|
|
27
29
|
}
|
|
28
30
|
export declare class Store {
|
|
29
31
|
#private;
|
|
30
|
-
|
|
32
|
+
readonly observability?: Observability | undefined;
|
|
33
|
+
/** Persist a model tool batch before reviews or execution can yield control. */
|
|
34
|
+
commitToolBatch(projectId: string, command: () => readonly string[]): readonly string[];
|
|
35
|
+
constructor(database: Sqlite, events: EventBus, eventLog?: EventLog, observability?: Observability | undefined);
|
|
31
36
|
close(): Promise<void>;
|
|
32
37
|
instance(): Document;
|
|
33
38
|
stateRevision(): number;
|
|
@@ -41,7 +46,7 @@ export declare class Store {
|
|
|
41
46
|
listProjects(options: PageOptions, archive?: 'active' | 'archived' | 'all'): Page<Document>;
|
|
42
47
|
defaultProject(): Document | null;
|
|
43
48
|
getProject(projectId: string): Document;
|
|
44
|
-
createProject(name: string, paths: readonly string[]): Document;
|
|
49
|
+
createProject(name: string, paths: readonly string[], executorId?: string): Document;
|
|
45
50
|
updateProject(projectId: string, expectedRevision: number, name: string): Document;
|
|
46
51
|
archiveProject(projectId: string, expectedRevision: number, archived: boolean): Document;
|
|
47
52
|
listWorkspaces(projectId: string): readonly Document[];
|
|
@@ -56,7 +61,7 @@ export declare class Store {
|
|
|
56
61
|
*/
|
|
57
62
|
projectWorkspacePaths(projectId: string, workspaceId: string): readonly string[];
|
|
58
63
|
getWorkspace(projectId: string, workspaceId: string): Document;
|
|
59
|
-
createWorkspace(projectId: string, name: string, paths: readonly string[], makeDefault: boolean): Document;
|
|
64
|
+
createWorkspace(projectId: string, name: string, paths: readonly string[], makeDefault: boolean, executorId?: string): Document;
|
|
60
65
|
updateWorkspace(projectId: string, workspaceId: string, expectedRevision: number, name: string, paths: readonly string[], makeDefault: boolean): Document;
|
|
61
66
|
deleteWorkspace(projectId: string, workspaceId: string, expectedRevision: number): void;
|
|
62
67
|
listTasks(projectId: string, options: PageOptions, archived?: boolean): Page<Document>;
|
|
@@ -75,7 +80,7 @@ export declare class Store {
|
|
|
75
80
|
createTask(projectId: string, title: string): Document;
|
|
76
81
|
updateTask(projectId: string, taskId: string, expectedRevision: number, title: string): Document;
|
|
77
82
|
archiveTask(projectId: string, taskId: string, expectedRevision: number, archived: boolean): Document;
|
|
78
|
-
deleteTask(projectId: string, taskId: string, expectedRevision: number): Document;
|
|
83
|
+
deleteTask(projectId: string, taskId: string, expectedRevision: number, executorStateId: string): Document;
|
|
79
84
|
listSessions(projectId: string, taskId: string, options: PageOptions, archived?: boolean): Page<Document>;
|
|
80
85
|
getSession(projectId: string, sessionId: string): Document;
|
|
81
86
|
/**
|
|
@@ -127,6 +132,10 @@ export declare class Store {
|
|
|
127
132
|
readonly loadedCapabilities: readonly string[];
|
|
128
133
|
readonly forkContext: 'full' | 'compact' | 'none';
|
|
129
134
|
readonly compactSummary?: string;
|
|
135
|
+
readonly compactCoveredItemIds?: readonly string[];
|
|
136
|
+
readonly compactRetainedItemIds?: readonly string[];
|
|
137
|
+
readonly compactFocus?: string;
|
|
138
|
+
readonly expectedParentContextRevision?: number;
|
|
130
139
|
readonly initialPrompt?: string;
|
|
131
140
|
readonly initialMessage?: string;
|
|
132
141
|
readonly ingress?: IngressCommand;
|
|
@@ -146,7 +155,7 @@ export declare class Store {
|
|
|
146
155
|
};
|
|
147
156
|
enqueueSubagentMessage(projectId: string, parentAgentId: string, targetAgentId: string, content: string, ingress: IngressCommand): Document;
|
|
148
157
|
broadcastSubagentMessage(projectId: string, parentAgentId: string, content: string, ingress: IngressCommand): Document;
|
|
149
|
-
waitForSubagent(projectId: string, sourceAgentId: string, targetAgentId: string, timeoutMs: number, signal: AbortSignal): Promise<Document>;
|
|
158
|
+
waitForSubagent(projectId: string, sourceAgentId: string, targetAgentId: string, timeoutMs: number, signal: AbortSignal, afterMessageId?: string): Promise<Document>;
|
|
150
159
|
listPending(projectId: string, agentId: string, options: PageOptions): Page<Document>;
|
|
151
160
|
getPending(projectId: string, pendingId: string): Document;
|
|
152
161
|
updatePending(projectId: string, pendingId: string, expectedRevision: number, content: string): Document;
|
|
@@ -191,7 +200,9 @@ export declare class Store {
|
|
|
191
200
|
}): Document;
|
|
192
201
|
getAttempt(projectId: string, attemptId: string): Document;
|
|
193
202
|
listAttempts(projectId: string, field: 'agent_id' | 'step_id', ownerId: string, options: PageOptions): Page<Document>;
|
|
194
|
-
|
|
203
|
+
latestModelAttempt(projectId: string, agentId: string, kind?: 'agent' | 'compaction', model?: string): Document | null;
|
|
204
|
+
cacheUsage(projectId: string, agentId: string): Document;
|
|
205
|
+
transitionAttempt(projectId: string, attemptId: string, from: string, to: string, outcome?: string | null, usage?: Json | null, errorCode?: string | null, observation?: Json | null): Document;
|
|
195
206
|
recordToolOrdinal(projectId: string, attemptId: string, ordinal: number, providerToolId: string | null, complete: boolean): void;
|
|
196
207
|
createPartition(projectId: string, stepId: string, mode: 'parallel' | 'serial'): Document;
|
|
197
208
|
listPartitions(projectId: string, stepId: string, options: PageOptions): Page<Document>;
|
|
@@ -207,6 +218,7 @@ export declare class Store {
|
|
|
207
218
|
readonly providerCallId?: string;
|
|
208
219
|
readonly callOrdinal?: number;
|
|
209
220
|
readonly arguments: Json;
|
|
221
|
+
readonly prompt?: Json;
|
|
210
222
|
readonly effect: string;
|
|
211
223
|
readonly policy?: string;
|
|
212
224
|
readonly state: 'WAITING' | 'QUEUED';
|
|
@@ -245,10 +257,19 @@ export declare class Store {
|
|
|
245
257
|
readonly call: Document;
|
|
246
258
|
readonly result: Document | null;
|
|
247
259
|
};
|
|
248
|
-
reviewCall(projectId: string, callId: string,
|
|
249
|
-
|
|
260
|
+
reviewCall(projectId: string, callId: string, review: AutoReviewResult): Document;
|
|
261
|
+
autoReviewContext(projectId: string, agentId: string): ReviewContext;
|
|
262
|
+
consumePendingForStep(projectId: string, stepId: string): readonly Document[];
|
|
263
|
+
interruptCall(projectId: string, callId: string, errorCode: string, message: string): Document;
|
|
264
|
+
interruptProjectCalls(projectId: string): void;
|
|
265
|
+
callAdmission(projectId: string, callId: string): 'ready' | 'blocked' | 'inactive';
|
|
266
|
+
startCall(projectId: string, callId: string, validate?: (call: Document) => void): Document;
|
|
267
|
+
failQueuedCall(projectId: string, callId: string, errorCode: string, errorMessage: string | null, content?: Json): {
|
|
268
|
+
readonly call: Document;
|
|
269
|
+
readonly result: Document;
|
|
270
|
+
};
|
|
250
271
|
waitCall(projectId: string, callId: string, prompt: Json): Document;
|
|
251
|
-
completeCall(projectId: string, callId: string, outcome: string, content: Json, errorCode?: string | null, errorMessage?: string | null, artifacts?: readonly string[], truncated?: boolean): {
|
|
272
|
+
completeCall(projectId: string, callId: string, outcome: string, content: Json, errorCode?: string | null, errorMessage?: string | null, artifacts?: readonly string[], truncated?: boolean, capture?: 'complete' | 'partial' | 'unknown', stored?: 'full' | 'unknown'): {
|
|
252
273
|
readonly call: Document;
|
|
253
274
|
readonly result: Document;
|
|
254
275
|
};
|
|
@@ -259,10 +280,9 @@ export declare class Store {
|
|
|
259
280
|
getResult(projectId: string, resultId: string): Document;
|
|
260
281
|
/**
|
|
261
282
|
* 02A `ResultDocument`. One `content_json` column becomes `text` or `structured` according to its
|
|
262
|
-
* JSON type
|
|
263
|
-
*
|
|
264
|
-
*
|
|
265
|
-
* That is why a client reading a large Result has to fall back to `artifact_ids` and ART-01.
|
|
283
|
+
* JSON type. Short results retain their original type; long non-PTC results carry a text preview
|
|
284
|
+
* and full-body Artifact. Earlier results may have null content with only an Artifact reference.
|
|
285
|
+
* Clients reading the full large Result use `artifact_ids` and ART-01.
|
|
266
286
|
*
|
|
267
287
|
* `error_code` stays off the wire here because the documented shape does not carry it; a failed
|
|
268
288
|
* Call reports its code on `CallSummary.error_code`.
|
|
@@ -277,6 +297,14 @@ export declare class Store {
|
|
|
277
297
|
readonly sizeBytes: number;
|
|
278
298
|
}): Document;
|
|
279
299
|
getArtifact(projectId: string, artifactId: string): Document;
|
|
300
|
+
getAgentArtifact(projectId: string, agentId: string, artifactId: string): Document;
|
|
301
|
+
readHistoryItem(projectId: string, agentId: string, contextId: string): Document;
|
|
302
|
+
searchHistory(projectId: string, agentId: string, query: string, after: number, limit: number, scope?: {
|
|
303
|
+
readonly agent_id?: string;
|
|
304
|
+
readonly session_id?: string;
|
|
305
|
+
readonly task_id?: string;
|
|
306
|
+
readonly after_context_item_id?: string;
|
|
307
|
+
}): Document;
|
|
280
308
|
listArtifacts(projectId: string, options: PageOptions): Page<Document>;
|
|
281
309
|
/**
|
|
282
310
|
* 02A `ContextPageQuery.direction`. `backward` walks from the newest item towards the oldest,
|
|
@@ -286,14 +314,24 @@ export declare class Store {
|
|
|
286
314
|
* paged away from the conversation instead of into its history.
|
|
287
315
|
*/
|
|
288
316
|
listContext(projectId: string, agentId: string, options: PageOptions, direction?: 'forward' | 'backward'): Page<Document>;
|
|
289
|
-
contextSource(projectId: string, agentId: string): {
|
|
317
|
+
contextSource(projectId: string, agentId: string, completedOnly?: boolean): {
|
|
290
318
|
readonly agent: Document;
|
|
291
319
|
readonly items: readonly Document[];
|
|
320
|
+
readonly workingItems: readonly Document[];
|
|
321
|
+
readonly unsettledItemIds: readonly string[];
|
|
322
|
+
readonly todo: Document | null;
|
|
292
323
|
readonly overrides: readonly Document[];
|
|
293
324
|
readonly capabilities: readonly Document[];
|
|
294
325
|
};
|
|
295
|
-
|
|
296
|
-
|
|
326
|
+
workingContext(projectId: string, agentId: string): Document;
|
|
327
|
+
saveWorkingContext(projectId: string, agentId: string, sourceRevision: number, edits: readonly {
|
|
328
|
+
readonly id: string;
|
|
329
|
+
readonly content: string;
|
|
330
|
+
}[], messages: Json, prefixes: Json, requestFrame: Json): void;
|
|
331
|
+
compactionSources(projectId: string, contextItemId: string): Document;
|
|
332
|
+
getTodo(projectId: string, agentId: string): Document | null;
|
|
333
|
+
updateTodo(projectId: string, agentId: string, items: Json): Document;
|
|
334
|
+
syncTodoReminder(projectId: string, agentId: string): void;
|
|
297
335
|
getContextItem(projectId: string, contextItemId: string): Document;
|
|
298
336
|
updateContextItem(projectId: string, contextItemId: string, expectedRevision: number, content: string): Document;
|
|
299
337
|
setContextVisibility(projectId: string, agentId: string, turnGroupIds: readonly string[], visible: boolean, expectedContextRevision: number): readonly Document[];
|
|
@@ -307,7 +345,7 @@ export declare class Store {
|
|
|
307
345
|
listProjectionDecisions(projectId: string, agentId: string, options: PageOptions): Page<Document>;
|
|
308
346
|
resetProjection(projectId: string, agentId: string, expectedContextRevision: number, stages?: readonly string[]): Document;
|
|
309
347
|
appendProjectionDecision(projectId: string, agentId: string, attemptId: string | null, stage: string, sourceTokens: number, projectedTokens: number, details: Json): Document;
|
|
310
|
-
compactContext(projectId: string, agentId: string, summary: string,
|
|
348
|
+
compactContext(projectId: string, agentId: string, summary: string, coveredItemIds: readonly string[], expectedContextRevision: number, focus?: string, expectedAgentRevision?: number): Document;
|
|
311
349
|
forkContext(projectId: string, sourceAgentId: string, targetAgentId: string, throughOrdinal: number): readonly Document[];
|
|
312
350
|
createContextFork(projectId: string, sourceAgentId: string, input: {
|
|
313
351
|
readonly throughTurnGroupId: string;
|
|
@@ -316,6 +354,8 @@ export declare class Store {
|
|
|
316
354
|
readonly model: string;
|
|
317
355
|
readonly modelReasoningEffort: string;
|
|
318
356
|
}): Document;
|
|
357
|
+
/** Persist one completed Provider response atomically with its tool batch. */
|
|
358
|
+
appendModelResponse(projectId: string, agentId: string, stepId: string, text: string, calls: NonNullable<ModelMessage['toolCalls']>, response: ModelResponse): Document;
|
|
319
359
|
appendAssistantMessage(projectId: string, agentId: string, stepId: string, content: string): Document;
|
|
320
360
|
appendToolCalls(projectId: string, agentId: string, stepId: string, calls: readonly {
|
|
321
361
|
readonly id: string;
|
|
@@ -338,7 +378,13 @@ export declare class Store {
|
|
|
338
378
|
stepOutput(projectId: string, stepId: string): Document;
|
|
339
379
|
storageStats(): Document;
|
|
340
380
|
exportState(): Json;
|
|
341
|
-
purgeArchived(projectId: string, before: string): Document;
|
|
381
|
+
purgeArchived(projectId: string, before: string, executorStateId: string): Document;
|
|
382
|
+
pendingPurges(projectId: string): readonly Document[];
|
|
383
|
+
completePurge(projectId: string, cleanupId: string): void;
|
|
384
|
+
artifactPathReferenced(relativePath: string): boolean;
|
|
342
385
|
snapshot(projectId: string, maxEntities: number): Document;
|
|
386
|
+
workspaceOwner(workspaceId: string): {
|
|
387
|
+
readonly projectId: string;
|
|
388
|
+
};
|
|
343
389
|
}
|
|
344
390
|
export {};
|