@pasko70/pibo 1.9.13 → 1.10.1
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 +183 -183
- package/context/codex-base-prompt.md +148 -148
- package/context/compute-worker.md +23 -23
- package/context/pibo-compaction-prompt.md +100 -100
- package/context/pibo-native-tooling.md +18 -18
- package/context/pibo-system-prompt.md +77 -77
- package/dist/apps/chat/agent-profiles.js +2 -2
- package/dist/apps/chat/agent-store.js +263 -250
- package/dist/apps/chat/chat-request-normalizers.js +17 -0
- package/dist/apps/chat/data/chat-data-mappers.js +2 -0
- package/dist/apps/chat/data/project-service.js +168 -168
- package/dist/apps/chat/data/read-state-service.js +18 -18
- package/dist/apps/chat/data/session-query-service.js +25 -25
- package/dist/apps/chat/data/timeline-query-service.js +19 -19
- package/dist/apps/chat/loop-api.js +181 -0
- package/dist/apps/chat/static-assets.js +854 -854
- package/dist/apps/chat/web-app.js +36 -16
- package/dist/apps/chat/workflow-manual-trigger-runtime.js +149 -46
- package/dist/apps/chat/workflow-persistence.js +255 -255
- package/dist/apps/chat-ui/assets/{dist-BZ2eTC4f.js → dist-3Sts0Afa.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-BHa-kcGl.js → dist-4NlLjLs7.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-yCYNNb5d.js → dist-BA6mhAec.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-D811wJeV.js → dist-BPl-fzRB.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-Dq4GxJi3.js → dist-BPnn9e2B.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-CzE6k3F3.js → dist-BpfBSMzK.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-CnVsqwSG.js → dist-Cvx5M97R.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-WyXdYl-w.js → dist-DnXWNQRm.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-BNMu92bb.js → dist-hU-2oAb6.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-BCB6zezO.js → dist-r31x5Fcc.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-HqTN67dc.js → dist-uF6UXzI7.js} +1 -1
- package/dist/apps/chat-ui/assets/index-CaTGYBOS.js +173 -0
- package/dist/apps/chat-ui/assets/{index-C0x9nEcf.css → index-al8DeEjA.css} +1 -1
- package/dist/apps/chat-ui/index.html +18 -18
- package/dist/apps/chat-ui/manifest.webmanifest +25 -25
- package/dist/apps/chat-ui/sw.js +47 -47
- package/dist/apps/chat-vscode-web/assets/index-CK4SMZuu.js +41 -0
- package/dist/apps/chat-vscode-web/index.html +13 -13
- package/dist/apps/cli-ui/cliSessionsCommand.js +23 -23
- package/dist/apps/context-files-ui/index.html +11 -11
- package/dist/cli-session/localSessionSource.js +34 -12
- package/dist/cli.js +61 -44
- package/dist/compute/cli.js +54 -54
- package/dist/compute/resource-health.js +35 -2
- package/dist/core/events.js +6 -1
- package/dist/core/routed-session.js +97 -5
- package/dist/core/runtime.js +6 -1
- package/dist/core/session-router.js +27 -8
- package/dist/cron/cli.js +15 -15
- package/dist/cron/store.js +49 -49
- package/dist/data/cli.js +23 -23
- package/dist/data/event-log.js +23 -23
- package/dist/data/ingest-service.js +3 -1
- package/dist/data/message-store.js +27 -27
- package/dist/data/navigation-store.js +9 -9
- package/dist/data/observation-store.js +4 -4
- package/dist/data/payload-store.js +17 -17
- package/dist/data/schema.js +433 -433
- package/dist/data/session-store.js +4 -4
- package/dist/data/telemetry-queries.js +54 -54
- package/dist/data/telemetry.js +197 -197
- package/dist/debug/events.js +12 -12
- package/dist/debug/failures.js +6 -6
- package/dist/debug/index.js +231 -227
- package/dist/debug/messages.js +6 -6
- package/dist/debug/pty.js +124 -124
- package/dist/debug/session.js +29 -29
- package/dist/debug/tools.js +5 -5
- package/dist/debug/trace.js +42 -7
- package/dist/debug/web-snapshot-browser-scripts.js +294 -294
- package/dist/debug/web-streaming-browser-library.js +925 -925
- package/dist/debug/web-streaming-browser-scripts.js +232 -232
- package/dist/debug/web-streaming-provider-telemetry.js +4 -4
- package/dist/debug/web.js +93 -93
- package/dist/gateway/cli.js +19 -19
- package/dist/gateway/server.js +4 -2
- package/dist/gateway/web.js +2 -2
- package/dist/index.js +1 -0
- package/dist/loops/accounting.js +19 -0
- package/dist/loops/channel.js +8 -0
- package/dist/loops/cli.js +224 -0
- package/dist/loops/plugin.js +16 -0
- package/dist/loops/prompts.js +86 -0
- package/dist/loops/service.js +446 -0
- package/dist/loops/stopping.js +170 -0
- package/dist/loops/store.js +642 -0
- package/dist/loops/templates.js +232 -0
- package/dist/loops/tools.js +184 -0
- package/dist/loops/types.js +1 -0
- package/dist/mcp/config-command.js +53 -53
- package/dist/mcp/index.js +21 -21
- package/dist/mcp/registry.js +11 -11
- package/dist/pi-packages/cli.js +11 -11
- package/dist/plugins/builtin.js +8 -0
- package/dist/plugins/context-files-store.js +110 -110
- package/dist/plugins/context-files.js +4 -4
- package/dist/plugins/registry.js +23 -12
- package/dist/ralph/cli.js +18 -18
- package/dist/ralph/templates.js +140 -140
- package/dist/reliability/store.js +256 -229
- package/dist/runs/lifecycle.js +59 -0
- package/dist/runs/registry.js +47 -1
- package/dist/runs/tools.js +31 -13
- package/dist/session-ui/terminalRows.js +66 -2
- package/dist/sessions/pibo-data-store.js +16 -16
- package/dist/sessions/sqlite-store.js +53 -53
- package/dist/setup/cli.js +58 -58
- package/dist/shared/trace-async-agent-runs.js +4 -4
- package/dist/shared/trace-event-projection.js +59 -19
- package/dist/shared/trace-nodes.js +5 -0
- package/dist/shared/trace-page-merge.js +15 -0
- package/dist/shared/trace-run-notifications.js +3 -1
- package/dist/signals/projector.js +6 -2
- package/dist/tools/agent-browser-wrapper.js +80 -80
- package/dist/tools/browser-pool.js +50 -0
- package/dist/tools/browser-use-cdp.js +12 -12
- package/dist/tools/browser-use-leases.js +12 -8
- package/dist/tools/browser-use-wrapper.js +762 -762
- package/dist/tools/guides.js +596 -538
- package/dist/tools/index.js +123 -99
- package/dist/tools/registry.js +21 -3
- package/dist/tools/runtime/node-worker-source.js +205 -205
- package/dist/tools/runtime/python-worker-source.js +177 -177
- package/dist/vscode/cli.js +9 -9
- package/dist/web-annotations/cdp.js +900 -900
- package/dist/web-annotations/store.js +96 -96
- package/docs/README.md +23 -23
- package/docs/ops/install-developer-host.md +112 -112
- package/docs/ops/install-user-host.md +96 -96
- package/docs/ops/upgrade-user-to-developer-host.md +69 -69
- package/docs/ops/vscode-extension-release.md +160 -160
- package/package.json +99 -95
- package/skills/builtin/graphify/SKILL.md +52 -52
- package/skills/builtin/loop/SKILL.md +78 -0
- package/skills/builtin/pi-agent-harness/SKILL.md +319 -319
- package/skills/builtin/pi-agent-harness/agents/openai.yaml +4 -4
- package/skills/builtin/pibo-docker-system/SKILL.md +170 -170
- package/skills/builtin/pibo-spec-writing/SKILL.md +330 -330
- package/skills/builtin/prd/SKILL.md +143 -143
- package/skills/builtin/ralph-loop/SKILL.md +361 -359
- package/skills/builtin/ralph-prd-json/SKILL.md +123 -123
- package/skills/builtin/skill-creator/LICENSE.txt +201 -201
- package/skills/builtin/skill-creator/SKILL.md +513 -513
- package/skills/builtin/skill-creator/agents/analyzer.md +274 -274
- package/skills/builtin/skill-creator/agents/comparator.md +202 -202
- package/skills/builtin/skill-creator/agents/grader.md +223 -223
- package/skills/builtin/skill-creator/assets/eval_review.html +146 -146
- package/skills/builtin/skill-creator/eval-viewer/generate_review.py +471 -471
- package/skills/builtin/skill-creator/eval-viewer/viewer.html +1325 -1325
- package/skills/builtin/skill-creator/references/schemas.md +430 -430
- package/skills/builtin/skill-creator/scripts/aggregate_benchmark.py +401 -401
- package/skills/builtin/skill-creator/scripts/generate_report.py +326 -326
- package/skills/builtin/skill-creator/scripts/improve_description.py +247 -247
- package/skills/builtin/skill-creator/scripts/package_skill.py +136 -136
- package/skills/builtin/skill-creator/scripts/quick_validate.py +102 -102
- package/skills/builtin/skill-creator/scripts/run_eval.py +310 -310
- package/skills/builtin/skill-creator/scripts/run_loop.py +328 -328
- package/skills/builtin/skill-creator/scripts/utils.py +47 -47
- package/skills/builtin/web-annotations/SKILL.md +93 -93
- package/src/mcp/LICENSE.mcp-cli +21 -21
- package/dist/apps/chat-ui/assets/index-DwHJfmiF.js +0 -173
- package/dist/apps/chat-vscode-web/assets/index-BAMxIaI_.js +0 -41
- package/dist/apps/vscode-artifacts/latest.vsix +0 -0
- package/dist/apps/vscode-artifacts/pibo-vscode-ext-1.9.13.vsix +0 -0
|
@@ -30,6 +30,11 @@ function migratePiboRunControllerColumn(db) {
|
|
|
30
30
|
db.exec("DROP INDEX IF EXISTS idx_pibo_runs_" + ["o", "wner_updated"].join(""));
|
|
31
31
|
db.exec(`ALTER TABLE pibo_runs RENAME COLUMN ${legacyColumn} TO controller_pibo_session_id`);
|
|
32
32
|
}
|
|
33
|
+
function ensurePiboRunColumn(db, name, definition) {
|
|
34
|
+
const columns = sqliteTableColumns(db, "pibo_runs");
|
|
35
|
+
if (!columns.has(name))
|
|
36
|
+
db.exec(`ALTER TABLE pibo_runs ADD COLUMN ${name} ${definition}`);
|
|
37
|
+
}
|
|
33
38
|
export class PiboReliabilityStore {
|
|
34
39
|
db;
|
|
35
40
|
appendEventStatement;
|
|
@@ -46,105 +51,113 @@ export class PiboReliabilityStore {
|
|
|
46
51
|
if (resolvedPath !== ":memory:")
|
|
47
52
|
this.db.exec("PRAGMA journal_mode = WAL");
|
|
48
53
|
migratePiboRunControllerColumn(this.db);
|
|
49
|
-
this.db.exec(`
|
|
50
|
-
CREATE TABLE IF NOT EXISTS pibo_event_stream (
|
|
51
|
-
stream_id INTEGER PRIMARY KEY,
|
|
52
|
-
topic TEXT NOT NULL,
|
|
53
|
-
key TEXT,
|
|
54
|
-
event_id TEXT NOT NULL,
|
|
55
|
-
idempotency_key TEXT,
|
|
56
|
-
created_at TEXT NOT NULL,
|
|
57
|
-
retention_class TEXT NOT NULL,
|
|
58
|
-
payload_json TEXT NOT NULL
|
|
59
|
-
);
|
|
60
|
-
CREATE UNIQUE INDEX IF NOT EXISTS idx_pibo_event_stream_event
|
|
61
|
-
ON pibo_event_stream(topic, event_id);
|
|
62
|
-
CREATE UNIQUE INDEX IF NOT EXISTS idx_pibo_event_stream_idempotency
|
|
63
|
-
ON pibo_event_stream(topic, idempotency_key)
|
|
64
|
-
WHERE idempotency_key IS NOT NULL;
|
|
65
|
-
CREATE INDEX IF NOT EXISTS idx_pibo_event_stream_topic_stream
|
|
66
|
-
ON pibo_event_stream(topic, stream_id);
|
|
67
|
-
|
|
68
|
-
CREATE TABLE IF NOT EXISTS pibo_event_consumers (
|
|
69
|
-
consumer TEXT NOT NULL,
|
|
70
|
-
topic TEXT NOT NULL,
|
|
71
|
-
last_stream_id INTEGER NOT NULL,
|
|
72
|
-
updated_at TEXT NOT NULL,
|
|
73
|
-
PRIMARY KEY(consumer, topic)
|
|
74
|
-
);
|
|
75
|
-
|
|
76
|
-
CREATE TABLE IF NOT EXISTS pibo_jobs (
|
|
77
|
-
job_id TEXT PRIMARY KEY,
|
|
78
|
-
queue TEXT NOT NULL,
|
|
79
|
-
state TEXT NOT NULL,
|
|
80
|
-
payload_json TEXT NOT NULL,
|
|
81
|
-
run_at TEXT NOT NULL,
|
|
82
|
-
priority INTEGER NOT NULL DEFAULT 0,
|
|
83
|
-
worker_id TEXT,
|
|
84
|
-
claim_expires_at TEXT,
|
|
85
|
-
attempts INTEGER NOT NULL DEFAULT 0,
|
|
86
|
-
max_attempts INTEGER NOT NULL DEFAULT 1,
|
|
87
|
-
idempotency_key TEXT,
|
|
88
|
-
created_at TEXT NOT NULL,
|
|
89
|
-
updated_at TEXT NOT NULL,
|
|
90
|
-
expires_at TEXT,
|
|
91
|
-
last_error TEXT
|
|
92
|
-
);
|
|
93
|
-
CREATE UNIQUE INDEX IF NOT EXISTS idx_pibo_jobs_idempotency
|
|
94
|
-
ON pibo_jobs(queue, idempotency_key)
|
|
95
|
-
WHERE idempotency_key IS NOT NULL;
|
|
96
|
-
CREATE INDEX IF NOT EXISTS idx_pibo_jobs_live_claim
|
|
97
|
-
ON pibo_jobs(queue, state, run_at, priority DESC, created_at)
|
|
98
|
-
WHERE state = 'pending';
|
|
99
|
-
CREATE INDEX IF NOT EXISTS idx_pibo_jobs_expired_claim
|
|
100
|
-
ON pibo_jobs(queue, state, claim_expires_at, priority DESC, created_at)
|
|
101
|
-
WHERE state = 'running';
|
|
102
|
-
|
|
103
|
-
CREATE TABLE IF NOT EXISTS pibo_dead_jobs (
|
|
104
|
-
job_id TEXT PRIMARY KEY,
|
|
105
|
-
queue TEXT NOT NULL,
|
|
106
|
-
payload_json TEXT NOT NULL,
|
|
107
|
-
attempts INTEGER NOT NULL,
|
|
108
|
-
max_attempts INTEGER NOT NULL,
|
|
109
|
-
idempotency_key TEXT,
|
|
110
|
-
created_at TEXT NOT NULL,
|
|
111
|
-
updated_at TEXT NOT NULL,
|
|
112
|
-
expires_at TEXT,
|
|
113
|
-
last_error TEXT,
|
|
114
|
-
dead_at TEXT NOT NULL,
|
|
115
|
-
dead_reason TEXT NOT NULL
|
|
116
|
-
);
|
|
117
|
-
CREATE INDEX IF NOT EXISTS idx_pibo_dead_jobs_queue_dead_at
|
|
118
|
-
ON pibo_dead_jobs(queue, dead_at);
|
|
119
|
-
|
|
120
|
-
CREATE TABLE IF NOT EXISTS pibo_runs (
|
|
121
|
-
run_id TEXT PRIMARY KEY,
|
|
122
|
-
kind TEXT NOT NULL,
|
|
123
|
-
controller_pibo_session_id TEXT NOT NULL,
|
|
124
|
-
status TEXT NOT NULL,
|
|
125
|
-
completion_policy TEXT NOT NULL,
|
|
126
|
-
consumed INTEGER NOT NULL DEFAULT 0,
|
|
127
|
-
tool_name TEXT NOT NULL,
|
|
128
|
-
summary TEXT,
|
|
129
|
-
result_json TEXT,
|
|
130
|
-
error TEXT,
|
|
131
|
-
notified_status TEXT,
|
|
132
|
-
acknowledged_status TEXT,
|
|
133
|
-
created_at TEXT NOT NULL,
|
|
134
|
-
updated_at TEXT NOT NULL,
|
|
135
|
-
completed_at TEXT,
|
|
136
|
-
job_id TEXT,
|
|
137
|
-
retryable INTEGER NOT NULL DEFAULT 0,
|
|
138
|
-
max_attempts INTEGER NOT NULL DEFAULT 1
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
54
|
+
this.db.exec(`
|
|
55
|
+
CREATE TABLE IF NOT EXISTS pibo_event_stream (
|
|
56
|
+
stream_id INTEGER PRIMARY KEY,
|
|
57
|
+
topic TEXT NOT NULL,
|
|
58
|
+
key TEXT,
|
|
59
|
+
event_id TEXT NOT NULL,
|
|
60
|
+
idempotency_key TEXT,
|
|
61
|
+
created_at TEXT NOT NULL,
|
|
62
|
+
retention_class TEXT NOT NULL,
|
|
63
|
+
payload_json TEXT NOT NULL
|
|
64
|
+
);
|
|
65
|
+
CREATE UNIQUE INDEX IF NOT EXISTS idx_pibo_event_stream_event
|
|
66
|
+
ON pibo_event_stream(topic, event_id);
|
|
67
|
+
CREATE UNIQUE INDEX IF NOT EXISTS idx_pibo_event_stream_idempotency
|
|
68
|
+
ON pibo_event_stream(topic, idempotency_key)
|
|
69
|
+
WHERE idempotency_key IS NOT NULL;
|
|
70
|
+
CREATE INDEX IF NOT EXISTS idx_pibo_event_stream_topic_stream
|
|
71
|
+
ON pibo_event_stream(topic, stream_id);
|
|
72
|
+
|
|
73
|
+
CREATE TABLE IF NOT EXISTS pibo_event_consumers (
|
|
74
|
+
consumer TEXT NOT NULL,
|
|
75
|
+
topic TEXT NOT NULL,
|
|
76
|
+
last_stream_id INTEGER NOT NULL,
|
|
77
|
+
updated_at TEXT NOT NULL,
|
|
78
|
+
PRIMARY KEY(consumer, topic)
|
|
79
|
+
);
|
|
80
|
+
|
|
81
|
+
CREATE TABLE IF NOT EXISTS pibo_jobs (
|
|
82
|
+
job_id TEXT PRIMARY KEY,
|
|
83
|
+
queue TEXT NOT NULL,
|
|
84
|
+
state TEXT NOT NULL,
|
|
85
|
+
payload_json TEXT NOT NULL,
|
|
86
|
+
run_at TEXT NOT NULL,
|
|
87
|
+
priority INTEGER NOT NULL DEFAULT 0,
|
|
88
|
+
worker_id TEXT,
|
|
89
|
+
claim_expires_at TEXT,
|
|
90
|
+
attempts INTEGER NOT NULL DEFAULT 0,
|
|
91
|
+
max_attempts INTEGER NOT NULL DEFAULT 1,
|
|
92
|
+
idempotency_key TEXT,
|
|
93
|
+
created_at TEXT NOT NULL,
|
|
94
|
+
updated_at TEXT NOT NULL,
|
|
95
|
+
expires_at TEXT,
|
|
96
|
+
last_error TEXT
|
|
97
|
+
);
|
|
98
|
+
CREATE UNIQUE INDEX IF NOT EXISTS idx_pibo_jobs_idempotency
|
|
99
|
+
ON pibo_jobs(queue, idempotency_key)
|
|
100
|
+
WHERE idempotency_key IS NOT NULL;
|
|
101
|
+
CREATE INDEX IF NOT EXISTS idx_pibo_jobs_live_claim
|
|
102
|
+
ON pibo_jobs(queue, state, run_at, priority DESC, created_at)
|
|
103
|
+
WHERE state = 'pending';
|
|
104
|
+
CREATE INDEX IF NOT EXISTS idx_pibo_jobs_expired_claim
|
|
105
|
+
ON pibo_jobs(queue, state, claim_expires_at, priority DESC, created_at)
|
|
106
|
+
WHERE state = 'running';
|
|
107
|
+
|
|
108
|
+
CREATE TABLE IF NOT EXISTS pibo_dead_jobs (
|
|
109
|
+
job_id TEXT PRIMARY KEY,
|
|
110
|
+
queue TEXT NOT NULL,
|
|
111
|
+
payload_json TEXT NOT NULL,
|
|
112
|
+
attempts INTEGER NOT NULL,
|
|
113
|
+
max_attempts INTEGER NOT NULL,
|
|
114
|
+
idempotency_key TEXT,
|
|
115
|
+
created_at TEXT NOT NULL,
|
|
116
|
+
updated_at TEXT NOT NULL,
|
|
117
|
+
expires_at TEXT,
|
|
118
|
+
last_error TEXT,
|
|
119
|
+
dead_at TEXT NOT NULL,
|
|
120
|
+
dead_reason TEXT NOT NULL
|
|
121
|
+
);
|
|
122
|
+
CREATE INDEX IF NOT EXISTS idx_pibo_dead_jobs_queue_dead_at
|
|
123
|
+
ON pibo_dead_jobs(queue, dead_at);
|
|
124
|
+
|
|
125
|
+
CREATE TABLE IF NOT EXISTS pibo_runs (
|
|
126
|
+
run_id TEXT PRIMARY KEY,
|
|
127
|
+
kind TEXT NOT NULL,
|
|
128
|
+
controller_pibo_session_id TEXT NOT NULL,
|
|
129
|
+
status TEXT NOT NULL,
|
|
130
|
+
completion_policy TEXT NOT NULL,
|
|
131
|
+
consumed INTEGER NOT NULL DEFAULT 0,
|
|
132
|
+
tool_name TEXT NOT NULL,
|
|
133
|
+
summary TEXT,
|
|
134
|
+
result_json TEXT,
|
|
135
|
+
error TEXT,
|
|
136
|
+
notified_status TEXT,
|
|
137
|
+
acknowledged_status TEXT,
|
|
138
|
+
created_at TEXT NOT NULL,
|
|
139
|
+
updated_at TEXT NOT NULL,
|
|
140
|
+
completed_at TEXT,
|
|
141
|
+
job_id TEXT,
|
|
142
|
+
retryable INTEGER NOT NULL DEFAULT 0,
|
|
143
|
+
max_attempts INTEGER NOT NULL DEFAULT 1,
|
|
144
|
+
timeout_ms INTEGER,
|
|
145
|
+
timeout_at TEXT,
|
|
146
|
+
timeout_phase TEXT,
|
|
147
|
+
service_warning TEXT
|
|
148
|
+
);
|
|
149
|
+
CREATE INDEX IF NOT EXISTS idx_pibo_runs_controller_updated
|
|
150
|
+
ON pibo_runs(controller_pibo_session_id, updated_at);
|
|
151
|
+
CREATE INDEX IF NOT EXISTS idx_pibo_runs_status
|
|
152
|
+
ON pibo_runs(status);
|
|
144
153
|
`);
|
|
145
|
-
this.
|
|
146
|
-
|
|
147
|
-
|
|
154
|
+
ensurePiboRunColumn(this.db, "timeout_ms", "INTEGER");
|
|
155
|
+
ensurePiboRunColumn(this.db, "timeout_at", "TEXT");
|
|
156
|
+
ensurePiboRunColumn(this.db, "timeout_phase", "TEXT");
|
|
157
|
+
ensurePiboRunColumn(this.db, "service_warning", "TEXT");
|
|
158
|
+
this.appendEventStatement = this.db.prepare(`
|
|
159
|
+
INSERT INTO pibo_event_stream (topic, key, event_id, idempotency_key, created_at, retention_class, payload_json)
|
|
160
|
+
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
148
161
|
`);
|
|
149
162
|
this.getEventByStreamIdStatement = this.db.prepare("SELECT * FROM pibo_event_stream WHERE stream_id = ?");
|
|
150
163
|
this.getEventByTopicEventIdStatement = this.db.prepare("SELECT * FROM pibo_event_stream WHERE topic = ? AND event_id = ?");
|
|
@@ -202,12 +215,12 @@ export class PiboReliabilityStore {
|
|
|
202
215
|
}
|
|
203
216
|
const where = clauses.length ? `WHERE ${clauses.join(" AND ")}` : "";
|
|
204
217
|
const rows = this.db
|
|
205
|
-
.prepare(`
|
|
206
|
-
SELECT topic, key, retention_class, COUNT(*) AS count
|
|
207
|
-
FROM pibo_event_stream
|
|
208
|
-
${where}
|
|
209
|
-
GROUP BY topic, key, retention_class
|
|
210
|
-
ORDER BY topic, key, retention_class
|
|
218
|
+
.prepare(`
|
|
219
|
+
SELECT topic, key, retention_class, COUNT(*) AS count
|
|
220
|
+
FROM pibo_event_stream
|
|
221
|
+
${where}
|
|
222
|
+
GROUP BY topic, key, retention_class
|
|
223
|
+
ORDER BY topic, key, retention_class
|
|
211
224
|
`)
|
|
212
225
|
.all(...values);
|
|
213
226
|
return rows.map((row) => ({
|
|
@@ -223,12 +236,12 @@ export class PiboReliabilityStore {
|
|
|
223
236
|
}
|
|
224
237
|
saveConsumerOffset(topic, consumer, streamId) {
|
|
225
238
|
this.db
|
|
226
|
-
.prepare(`
|
|
227
|
-
INSERT INTO pibo_event_consumers (consumer, topic, last_stream_id, updated_at)
|
|
228
|
-
VALUES (?, ?, ?, ?)
|
|
229
|
-
ON CONFLICT(consumer, topic) DO UPDATE SET
|
|
230
|
-
last_stream_id = MAX(pibo_event_consumers.last_stream_id, excluded.last_stream_id),
|
|
231
|
-
updated_at = excluded.updated_at
|
|
239
|
+
.prepare(`
|
|
240
|
+
INSERT INTO pibo_event_consumers (consumer, topic, last_stream_id, updated_at)
|
|
241
|
+
VALUES (?, ?, ?, ?)
|
|
242
|
+
ON CONFLICT(consumer, topic) DO UPDATE SET
|
|
243
|
+
last_stream_id = MAX(pibo_event_consumers.last_stream_id, excluded.last_stream_id),
|
|
244
|
+
updated_at = excluded.updated_at
|
|
232
245
|
`)
|
|
233
246
|
.run(consumer, topic, streamId, now());
|
|
234
247
|
}
|
|
@@ -260,23 +273,23 @@ export class PiboReliabilityStore {
|
|
|
260
273
|
values.push(input.beforeStreamId);
|
|
261
274
|
}
|
|
262
275
|
if (!input.destructive) {
|
|
263
|
-
clauses.push(`
|
|
264
|
-
stream_id <= COALESCE(
|
|
265
|
-
(SELECT MIN(last_stream_id) FROM pibo_event_consumers WHERE pibo_event_consumers.topic = pibo_event_stream.topic),
|
|
266
|
-
stream_id
|
|
267
|
-
)
|
|
276
|
+
clauses.push(`
|
|
277
|
+
stream_id <= COALESCE(
|
|
278
|
+
(SELECT MIN(last_stream_id) FROM pibo_event_consumers WHERE pibo_event_consumers.topic = pibo_event_stream.topic),
|
|
279
|
+
stream_id
|
|
280
|
+
)
|
|
268
281
|
`);
|
|
269
282
|
}
|
|
270
283
|
const where = clauses.length ? `WHERE ${clauses.join(" AND ")}` : "";
|
|
271
284
|
const result = this.db
|
|
272
|
-
.prepare(`
|
|
273
|
-
DELETE FROM pibo_event_stream
|
|
274
|
-
WHERE stream_id IN (
|
|
275
|
-
SELECT stream_id FROM pibo_event_stream
|
|
276
|
-
${where}
|
|
277
|
-
ORDER BY stream_id ASC
|
|
278
|
-
LIMIT ${clampLimit(input.limit, 500)}
|
|
279
|
-
)
|
|
285
|
+
.prepare(`
|
|
286
|
+
DELETE FROM pibo_event_stream
|
|
287
|
+
WHERE stream_id IN (
|
|
288
|
+
SELECT stream_id FROM pibo_event_stream
|
|
289
|
+
${where}
|
|
290
|
+
ORDER BY stream_id ASC
|
|
291
|
+
LIMIT ${clampLimit(input.limit, 500)}
|
|
292
|
+
)
|
|
280
293
|
`)
|
|
281
294
|
.run(...values);
|
|
282
295
|
return Number(result.changes ?? 0);
|
|
@@ -285,11 +298,11 @@ export class PiboReliabilityStore {
|
|
|
285
298
|
const timestamp = now();
|
|
286
299
|
const jobId = input.jobId ?? `job_${randomUUID()}`;
|
|
287
300
|
const result = this.db
|
|
288
|
-
.prepare(`
|
|
289
|
-
INSERT OR IGNORE INTO pibo_jobs (
|
|
290
|
-
job_id, queue, state, payload_json, run_at, priority, worker_id, claim_expires_at,
|
|
291
|
-
attempts, max_attempts, idempotency_key, created_at, updated_at, expires_at, last_error
|
|
292
|
-
) VALUES (?, ?, 'pending', ?, ?, ?, NULL, NULL, 0, ?, ?, ?, ?, ?, NULL)
|
|
301
|
+
.prepare(`
|
|
302
|
+
INSERT OR IGNORE INTO pibo_jobs (
|
|
303
|
+
job_id, queue, state, payload_json, run_at, priority, worker_id, claim_expires_at,
|
|
304
|
+
attempts, max_attempts, idempotency_key, created_at, updated_at, expires_at, last_error
|
|
305
|
+
) VALUES (?, ?, 'pending', ?, ?, ?, NULL, NULL, 0, ?, ?, ?, ?, ?, NULL)
|
|
293
306
|
`)
|
|
294
307
|
.run(jobId, input.queue, json(input.payload), input.runAt ?? timestamp, input.priority ?? 0, Math.max(1, input.maxAttempts ?? 1), input.idempotencyKey ?? null, timestamp, timestamp, input.expiresAt ?? null);
|
|
295
308
|
if (Number(result.changes ?? 0) === 0 && input.idempotencyKey) {
|
|
@@ -313,20 +326,20 @@ export class PiboReliabilityStore {
|
|
|
313
326
|
}
|
|
314
327
|
this.moveExpiredJobs(timestamp);
|
|
315
328
|
const rows = this.db
|
|
316
|
-
.prepare(`
|
|
317
|
-
UPDATE pibo_jobs
|
|
318
|
-
SET state = 'running',
|
|
319
|
-
worker_id = ?,
|
|
320
|
-
claim_expires_at = ?,
|
|
321
|
-
attempts = attempts + 1,
|
|
322
|
-
updated_at = ?
|
|
323
|
-
WHERE job_id IN (
|
|
324
|
-
SELECT job_id FROM pibo_jobs
|
|
325
|
-
WHERE ${clauses.join(" AND ")}
|
|
326
|
-
ORDER BY priority DESC, run_at ASC, created_at ASC
|
|
327
|
-
LIMIT ?
|
|
328
|
-
)
|
|
329
|
-
RETURNING *
|
|
329
|
+
.prepare(`
|
|
330
|
+
UPDATE pibo_jobs
|
|
331
|
+
SET state = 'running',
|
|
332
|
+
worker_id = ?,
|
|
333
|
+
claim_expires_at = ?,
|
|
334
|
+
attempts = attempts + 1,
|
|
335
|
+
updated_at = ?
|
|
336
|
+
WHERE job_id IN (
|
|
337
|
+
SELECT job_id FROM pibo_jobs
|
|
338
|
+
WHERE ${clauses.join(" AND ")}
|
|
339
|
+
ORDER BY priority DESC, run_at ASC, created_at ASC
|
|
340
|
+
LIMIT ?
|
|
341
|
+
)
|
|
342
|
+
RETURNING *
|
|
330
343
|
`)
|
|
331
344
|
.all(workerId, claimExpiresAt, timestamp, ...values, clampLimit(limit));
|
|
332
345
|
return rows.map(jobFromRow);
|
|
@@ -335,18 +348,18 @@ export class PiboReliabilityStore {
|
|
|
335
348
|
const timestamp = now();
|
|
336
349
|
const claimExpiresAt = new Date(Date.now() + visibilityTimeoutMs).toISOString();
|
|
337
350
|
const row = this.db
|
|
338
|
-
.prepare(`
|
|
339
|
-
UPDATE pibo_jobs
|
|
340
|
-
SET state = 'running',
|
|
341
|
-
worker_id = ?,
|
|
342
|
-
claim_expires_at = ?,
|
|
343
|
-
attempts = attempts + 1,
|
|
344
|
-
updated_at = ?
|
|
345
|
-
WHERE job_id = ?
|
|
346
|
-
AND state = 'pending'
|
|
347
|
-
AND run_at <= ?
|
|
348
|
-
AND (expires_at IS NULL OR expires_at > ?)
|
|
349
|
-
RETURNING *
|
|
351
|
+
.prepare(`
|
|
352
|
+
UPDATE pibo_jobs
|
|
353
|
+
SET state = 'running',
|
|
354
|
+
worker_id = ?,
|
|
355
|
+
claim_expires_at = ?,
|
|
356
|
+
attempts = attempts + 1,
|
|
357
|
+
updated_at = ?
|
|
358
|
+
WHERE job_id = ?
|
|
359
|
+
AND state = 'pending'
|
|
360
|
+
AND run_at <= ?
|
|
361
|
+
AND (expires_at IS NULL OR expires_at > ?)
|
|
362
|
+
RETURNING *
|
|
350
363
|
`)
|
|
351
364
|
.get(workerId, claimExpiresAt, timestamp, jobId, timestamp, timestamp);
|
|
352
365
|
return row ? jobFromRow(row) : undefined;
|
|
@@ -354,13 +367,13 @@ export class PiboReliabilityStore {
|
|
|
354
367
|
ack(jobId, workerId) {
|
|
355
368
|
const timestamp = now();
|
|
356
369
|
const result = this.db
|
|
357
|
-
.prepare(`
|
|
358
|
-
DELETE FROM pibo_jobs
|
|
359
|
-
WHERE job_id = ?
|
|
360
|
-
AND state = 'running'
|
|
361
|
-
AND worker_id = ?
|
|
362
|
-
AND claim_expires_at IS NOT NULL
|
|
363
|
-
AND claim_expires_at > ?
|
|
370
|
+
.prepare(`
|
|
371
|
+
DELETE FROM pibo_jobs
|
|
372
|
+
WHERE job_id = ?
|
|
373
|
+
AND state = 'running'
|
|
374
|
+
AND worker_id = ?
|
|
375
|
+
AND claim_expires_at IS NOT NULL
|
|
376
|
+
AND claim_expires_at > ?
|
|
364
377
|
`)
|
|
365
378
|
.run(jobId, workerId, timestamp);
|
|
366
379
|
return Number(result.changes ?? 0) > 0;
|
|
@@ -378,15 +391,15 @@ export class PiboReliabilityStore {
|
|
|
378
391
|
const delayMs = input.delayMs ?? retryDelayMs(job.attempts, input);
|
|
379
392
|
const runAt = new Date(asDate(input.now).getTime() + delayMs).toISOString();
|
|
380
393
|
this.db
|
|
381
|
-
.prepare(`
|
|
382
|
-
UPDATE pibo_jobs
|
|
383
|
-
SET state = 'pending',
|
|
384
|
-
worker_id = NULL,
|
|
385
|
-
claim_expires_at = NULL,
|
|
386
|
-
run_at = ?,
|
|
387
|
-
updated_at = ?,
|
|
388
|
-
last_error = ?
|
|
389
|
-
WHERE job_id = ?
|
|
394
|
+
.prepare(`
|
|
395
|
+
UPDATE pibo_jobs
|
|
396
|
+
SET state = 'pending',
|
|
397
|
+
worker_id = NULL,
|
|
398
|
+
claim_expires_at = NULL,
|
|
399
|
+
run_at = ?,
|
|
400
|
+
updated_at = ?,
|
|
401
|
+
last_error = ?
|
|
402
|
+
WHERE job_id = ?
|
|
390
403
|
`)
|
|
391
404
|
.run(runAt, timestamp, input.error ?? null, jobId);
|
|
392
405
|
return true;
|
|
@@ -403,14 +416,14 @@ export class PiboReliabilityStore {
|
|
|
403
416
|
const timestamp = now();
|
|
404
417
|
const claimExpiresAt = new Date(Date.now() + Math.max(1, extendMs)).toISOString();
|
|
405
418
|
const result = this.db
|
|
406
|
-
.prepare(`
|
|
407
|
-
UPDATE pibo_jobs
|
|
408
|
-
SET claim_expires_at = ?, updated_at = ?
|
|
409
|
-
WHERE job_id = ?
|
|
410
|
-
AND state = 'running'
|
|
411
|
-
AND worker_id = ?
|
|
412
|
-
AND claim_expires_at IS NOT NULL
|
|
413
|
-
AND claim_expires_at > ?
|
|
419
|
+
.prepare(`
|
|
420
|
+
UPDATE pibo_jobs
|
|
421
|
+
SET claim_expires_at = ?, updated_at = ?
|
|
422
|
+
WHERE job_id = ?
|
|
423
|
+
AND state = 'running'
|
|
424
|
+
AND worker_id = ?
|
|
425
|
+
AND claim_expires_at IS NOT NULL
|
|
426
|
+
AND claim_expires_at > ?
|
|
414
427
|
`)
|
|
415
428
|
.run(claimExpiresAt, timestamp, jobId, workerId, timestamp);
|
|
416
429
|
return Number(result.changes ?? 0) > 0;
|
|
@@ -466,6 +479,7 @@ export class PiboReliabilityStore {
|
|
|
466
479
|
const timestamp = now();
|
|
467
480
|
const runId = input.runId ?? `run_${randomUUID()}`;
|
|
468
481
|
const maxAttempts = Math.max(1, input.maxAttempts ?? 1);
|
|
482
|
+
const timeoutAt = input.timeoutMs === undefined ? undefined : new Date(Date.parse(timestamp) + input.timeoutMs).toISOString();
|
|
469
483
|
const job = this.enqueue({
|
|
470
484
|
queue: "runs",
|
|
471
485
|
payload: {
|
|
@@ -473,18 +487,19 @@ export class PiboReliabilityStore {
|
|
|
473
487
|
controllerPiboSessionId: input.controllerPiboSessionId,
|
|
474
488
|
toolName: input.toolName,
|
|
475
489
|
params: input.params,
|
|
490
|
+
timeoutMs: input.timeoutMs,
|
|
476
491
|
},
|
|
477
492
|
maxAttempts,
|
|
478
493
|
});
|
|
479
494
|
this.db
|
|
480
|
-
.prepare(`
|
|
481
|
-
INSERT INTO pibo_runs (
|
|
482
|
-
run_id, kind, controller_pibo_session_id, status, completion_policy, consumed, tool_name,
|
|
483
|
-
summary, result_json, error, notified_status, acknowledged_status, created_at, updated_at,
|
|
484
|
-
completed_at, job_id, retryable, max_attempts
|
|
485
|
-
) VALUES (?, 'tool', ?, 'running', ?, 0, ?, ?, NULL, NULL, NULL, NULL, ?, ?, NULL, ?, ?, ?)
|
|
495
|
+
.prepare(`
|
|
496
|
+
INSERT INTO pibo_runs (
|
|
497
|
+
run_id, kind, controller_pibo_session_id, status, completion_policy, consumed, tool_name,
|
|
498
|
+
summary, result_json, error, notified_status, acknowledged_status, created_at, updated_at,
|
|
499
|
+
completed_at, job_id, retryable, max_attempts, timeout_ms, timeout_at, timeout_phase, service_warning
|
|
500
|
+
) VALUES (?, 'tool', ?, 'running', ?, 0, ?, ?, NULL, NULL, NULL, NULL, ?, ?, NULL, ?, ?, ?, ?, ?, NULL, ?)
|
|
486
501
|
`)
|
|
487
|
-
.run(runId, input.controllerPiboSessionId, input.completionPolicy, input.toolName, `${input.toolName} run is running.`, timestamp, timestamp, job.jobId, input.retryable ? 1 : 0, maxAttempts);
|
|
502
|
+
.run(runId, input.controllerPiboSessionId, input.completionPolicy, input.toolName, `${input.toolName} run is running.`, timestamp, timestamp, job.jobId, input.retryable ? 1 : 0, maxAttempts, input.timeoutMs ?? null, timeoutAt ?? null, input.serviceWarning ?? null);
|
|
488
503
|
this.claimJob(job.jobId, `run-registry:${process.pid}`, 24 * 60 * 60 * 1000);
|
|
489
504
|
return this.requireRun(runId);
|
|
490
505
|
}
|
|
@@ -494,24 +509,28 @@ export class PiboReliabilityStore {
|
|
|
494
509
|
return undefined;
|
|
495
510
|
const next = { ...existing, ...patch, updatedAt: patch.updatedAt ?? now() };
|
|
496
511
|
this.db
|
|
497
|
-
.prepare(`
|
|
498
|
-
UPDATE pibo_runs SET
|
|
499
|
-
status = ?,
|
|
500
|
-
completion_policy = ?,
|
|
501
|
-
consumed = ?,
|
|
502
|
-
summary = ?,
|
|
503
|
-
result_json = ?,
|
|
504
|
-
error = ?,
|
|
505
|
-
notified_status = ?,
|
|
506
|
-
acknowledged_status = ?,
|
|
507
|
-
updated_at = ?,
|
|
508
|
-
completed_at = ?,
|
|
509
|
-
job_id = ?,
|
|
510
|
-
retryable = ?,
|
|
511
|
-
max_attempts =
|
|
512
|
-
|
|
512
|
+
.prepare(`
|
|
513
|
+
UPDATE pibo_runs SET
|
|
514
|
+
status = ?,
|
|
515
|
+
completion_policy = ?,
|
|
516
|
+
consumed = ?,
|
|
517
|
+
summary = ?,
|
|
518
|
+
result_json = ?,
|
|
519
|
+
error = ?,
|
|
520
|
+
notified_status = ?,
|
|
521
|
+
acknowledged_status = ?,
|
|
522
|
+
updated_at = ?,
|
|
523
|
+
completed_at = ?,
|
|
524
|
+
job_id = ?,
|
|
525
|
+
retryable = ?,
|
|
526
|
+
max_attempts = ?,
|
|
527
|
+
timeout_ms = ?,
|
|
528
|
+
timeout_at = ?,
|
|
529
|
+
timeout_phase = ?,
|
|
530
|
+
service_warning = ?
|
|
531
|
+
WHERE run_id = ?
|
|
513
532
|
`)
|
|
514
|
-
.run(next.status, next.completionPolicy, next.consumed ? 1 : 0, next.summary ?? null, next.result ? JSON.stringify(next.result) : null, next.error ?? null, next.notifiedStatus ?? null, next.acknowledgedStatus ?? null, next.updatedAt, next.completedAt ?? null, next.jobId ?? null, next.retryable ? 1 : 0, next.maxAttempts, runId);
|
|
533
|
+
.run(next.status, next.completionPolicy, next.consumed ? 1 : 0, next.summary ?? null, next.result ? JSON.stringify(next.result) : null, next.error ?? null, next.notifiedStatus ?? null, next.acknowledgedStatus ?? null, next.updatedAt, next.completedAt ?? null, next.jobId ?? null, next.retryable ? 1 : 0, next.maxAttempts, next.timeoutMs ?? null, next.timeoutAt ?? null, next.timeoutPhase ?? null, next.serviceWarning ?? null, runId);
|
|
515
534
|
return this.requireRun(runId);
|
|
516
535
|
}
|
|
517
536
|
getRun(runId) {
|
|
@@ -535,7 +554,7 @@ export class PiboReliabilityStore {
|
|
|
535
554
|
}
|
|
536
555
|
pruneRuns(input) {
|
|
537
556
|
const rows = this.db
|
|
538
|
-
.prepare("SELECT * FROM pibo_runs WHERE status IN ('completed', 'failed', 'cancelled') AND completed_at IS NOT NULL")
|
|
557
|
+
.prepare("SELECT * FROM pibo_runs WHERE status IN ('completed', 'failed', 'timed_out', 'cancelled') AND completed_at IS NOT NULL")
|
|
539
558
|
.all();
|
|
540
559
|
const ids = rows
|
|
541
560
|
.map(runFromRow)
|
|
@@ -619,13 +638,13 @@ export class PiboReliabilityStore {
|
|
|
619
638
|
}
|
|
620
639
|
getLiveWorkerJob(jobId, workerId, timestamp) {
|
|
621
640
|
return this.db
|
|
622
|
-
.prepare(`
|
|
623
|
-
SELECT * FROM pibo_jobs
|
|
624
|
-
WHERE job_id = ?
|
|
625
|
-
AND state = 'running'
|
|
626
|
-
AND worker_id = ?
|
|
627
|
-
AND claim_expires_at IS NOT NULL
|
|
628
|
-
AND claim_expires_at > ?
|
|
641
|
+
.prepare(`
|
|
642
|
+
SELECT * FROM pibo_jobs
|
|
643
|
+
WHERE job_id = ?
|
|
644
|
+
AND state = 'running'
|
|
645
|
+
AND worker_id = ?
|
|
646
|
+
AND claim_expires_at IS NOT NULL
|
|
647
|
+
AND claim_expires_at > ?
|
|
629
648
|
`)
|
|
630
649
|
.get(jobId, workerId, timestamp);
|
|
631
650
|
}
|
|
@@ -636,26 +655,26 @@ export class PiboReliabilityStore {
|
|
|
636
655
|
}
|
|
637
656
|
hasUnexpiredJobClaim(jobId, timestamp) {
|
|
638
657
|
const row = this.db
|
|
639
|
-
.prepare(`
|
|
640
|
-
SELECT job_id FROM pibo_jobs
|
|
641
|
-
WHERE job_id = ?
|
|
642
|
-
AND state = 'running'
|
|
643
|
-
AND claim_expires_at IS NOT NULL
|
|
644
|
-
AND claim_expires_at > ?
|
|
658
|
+
.prepare(`
|
|
659
|
+
SELECT job_id FROM pibo_jobs
|
|
660
|
+
WHERE job_id = ?
|
|
661
|
+
AND state = 'running'
|
|
662
|
+
AND claim_expires_at IS NOT NULL
|
|
663
|
+
AND claim_expires_at > ?
|
|
645
664
|
`)
|
|
646
665
|
.get(jobId, timestamp);
|
|
647
666
|
return row !== undefined;
|
|
648
667
|
}
|
|
649
668
|
releaseJobForRetry(jobId, timestamp) {
|
|
650
669
|
this.db
|
|
651
|
-
.prepare(`
|
|
652
|
-
UPDATE pibo_jobs
|
|
653
|
-
SET state = 'pending',
|
|
654
|
-
worker_id = NULL,
|
|
655
|
-
claim_expires_at = NULL,
|
|
656
|
-
run_at = ?,
|
|
657
|
-
updated_at = ?
|
|
658
|
-
WHERE job_id = ?
|
|
670
|
+
.prepare(`
|
|
671
|
+
UPDATE pibo_jobs
|
|
672
|
+
SET state = 'pending',
|
|
673
|
+
worker_id = NULL,
|
|
674
|
+
claim_expires_at = NULL,
|
|
675
|
+
run_at = ?,
|
|
676
|
+
updated_at = ?
|
|
677
|
+
WHERE job_id = ?
|
|
659
678
|
`)
|
|
660
679
|
.run(timestamp, timestamp, jobId);
|
|
661
680
|
}
|
|
@@ -666,11 +685,11 @@ export class PiboReliabilityStore {
|
|
|
666
685
|
}
|
|
667
686
|
moveJobToDead(row, error, reason, timestamp) {
|
|
668
687
|
this.db
|
|
669
|
-
.prepare(`
|
|
670
|
-
INSERT OR REPLACE INTO pibo_dead_jobs (
|
|
671
|
-
job_id, queue, payload_json, attempts, max_attempts, idempotency_key, created_at,
|
|
672
|
-
updated_at, expires_at, last_error, dead_at, dead_reason
|
|
673
|
-
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
688
|
+
.prepare(`
|
|
689
|
+
INSERT OR REPLACE INTO pibo_dead_jobs (
|
|
690
|
+
job_id, queue, payload_json, attempts, max_attempts, idempotency_key, created_at,
|
|
691
|
+
updated_at, expires_at, last_error, dead_at, dead_reason
|
|
692
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
674
693
|
`)
|
|
675
694
|
.run(row.job_id, row.queue, row.payload_json, row.attempts, row.max_attempts, row.idempotency_key, row.created_at, timestamp, row.expires_at, error, timestamp, reason);
|
|
676
695
|
this.db.prepare("DELETE FROM pibo_jobs WHERE job_id = ?").run(row.job_id);
|
|
@@ -760,6 +779,14 @@ function runFromRow(row) {
|
|
|
760
779
|
output.completedAt = row.completed_at;
|
|
761
780
|
if (row.job_id)
|
|
762
781
|
output.jobId = row.job_id;
|
|
782
|
+
if (row.timeout_ms !== null)
|
|
783
|
+
output.timeoutMs = row.timeout_ms;
|
|
784
|
+
if (row.timeout_at)
|
|
785
|
+
output.timeoutAt = row.timeout_at;
|
|
786
|
+
if (row.timeout_phase === "startup" || row.timeout_phase === "lifetime")
|
|
787
|
+
output.timeoutPhase = row.timeout_phase;
|
|
788
|
+
if (row.service_warning)
|
|
789
|
+
output.serviceWarning = row.service_warning;
|
|
763
790
|
return output;
|
|
764
791
|
}
|
|
765
792
|
function retryDelayMs(attempts, input) {
|