openclaw-scheduler 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/AGENTS.md +302 -0
  2. package/BEST-PRACTICES.md +506 -0
  3. package/CHANGELOG.md +82 -0
  4. package/CODE_OF_CONDUCT.md +22 -0
  5. package/CONTEXT.md +26 -0
  6. package/CONTRIBUTING.md +73 -0
  7. package/IMPLEMENTATION_SPEC.md +170 -0
  8. package/INSTALL-ADDITIONAL-HOST.md +333 -0
  9. package/INSTALL-LINUX.md +419 -0
  10. package/INSTALL-WINDOWS.md +305 -0
  11. package/INSTALL.md +364 -0
  12. package/JOB-QUICK-REF.md +222 -0
  13. package/LICENSE +21 -0
  14. package/QUICK-START.md +256 -0
  15. package/README.md +2170 -0
  16. package/SECURITY.md +34 -0
  17. package/UNINSTALL.md +129 -0
  18. package/UPGRADING.md +436 -0
  19. package/agents.js +67 -0
  20. package/approval.js +107 -0
  21. package/backup.js +390 -0
  22. package/bin/openclaw-scheduler.js +138 -0
  23. package/cli.js +1083 -0
  24. package/db.js +122 -0
  25. package/dispatch/529-recovery.mjs +204 -0
  26. package/dispatch/README.md +372 -0
  27. package/dispatch/config.example.json +24 -0
  28. package/dispatch/deliver-watcher.sh +57 -0
  29. package/dispatch/hooks.mjs +171 -0
  30. package/dispatch/index.mjs +1836 -0
  31. package/dispatch/watcher.mjs +1396 -0
  32. package/dispatch-queue.js +112 -0
  33. package/dispatcher-approvals.js +96 -0
  34. package/dispatcher-delivery.js +43 -0
  35. package/dispatcher-maintenance.js +242 -0
  36. package/dispatcher-shell.js +29 -0
  37. package/dispatcher-strategies.js +1280 -0
  38. package/dispatcher-utils.js +81 -0
  39. package/dispatcher.js +855 -0
  40. package/docs/adr-schedule-ownership.md +73 -0
  41. package/docs/gateway-contract.md +904 -0
  42. package/docs/plans/2026-03-09-fix-typescript-types.md +91 -0
  43. package/docs/plans/2026-03-09-test-coverage-gaps.md +83 -0
  44. package/docs/plans/2026-03-10-dispatcher-refactor.md +801 -0
  45. package/docs/trust-architecture.md +266 -0
  46. package/gateway.js +473 -0
  47. package/idempotency.js +119 -0
  48. package/index.d.ts +864 -0
  49. package/index.js +17 -0
  50. package/jobs.js +1224 -0
  51. package/messages.js +357 -0
  52. package/migrate-consolidate.js +694 -0
  53. package/migrate.js +125 -0
  54. package/package.json +130 -0
  55. package/paths.js +79 -0
  56. package/prompt-context.js +94 -0
  57. package/retrieval.js +176 -0
  58. package/runs.js +270 -0
  59. package/scheduler-schema.js +101 -0
  60. package/schema.sql +480 -0
  61. package/scripts/dispatch-cli-utils.mjs +65 -0
  62. package/scripts/inbox-consumer.mjs +288 -0
  63. package/scripts/stuck-detector.sh +18 -0
  64. package/scripts/stuck-run-detector.mjs +333 -0
  65. package/scripts/telegram-webhook-check.mjs +238 -0
  66. package/setup.mjs +724 -0
  67. package/shell-result.js +214 -0
  68. package/task-tracker.js +300 -0
  69. package/team-adapter.js +335 -0
  70. package/v02-runtime.js +599 -0
package/index.d.ts ADDED
@@ -0,0 +1,864 @@
1
+ export type JsonValue =
2
+ | string
3
+ | number
4
+ | boolean
5
+ | null
6
+ | JsonValue[]
7
+ | { [key: string]: JsonValue };
8
+
9
+ // -- SQLite RunResult returned by write operations --
10
+ export interface SqliteRunResult {
11
+ changes: number;
12
+ lastInsertRowid: number | bigint;
13
+ }
14
+
15
+ // -- Record interfaces matching schema.sql --
16
+
17
+ export interface JobSpec {
18
+ id?: string;
19
+ name: string;
20
+ enabled?: number | boolean;
21
+
22
+ // Schedule
23
+ schedule_kind?: 'cron' | 'at';
24
+ schedule_cron?: string | null;
25
+ schedule_at?: string | null;
26
+ schedule_tz?: string | null;
27
+
28
+ // Execution
29
+ session_target?: 'main' | 'isolated' | 'shell';
30
+ agent_id?: string | null;
31
+
32
+ // Payload
33
+ payload_kind?: 'systemEvent' | 'agentTurn' | 'shellCommand';
34
+ payload_message: string;
35
+ payload_model?: string | null;
36
+ payload_thinking?: string | null;
37
+ payload_timeout_seconds?: number;
38
+ payload_scope?: 'own' | 'global';
39
+ execution_intent?: 'execute' | 'plan';
40
+ execution_read_only?: number | boolean;
41
+
42
+ // Overlap & timeout
43
+ overlap_policy?: 'skip' | 'allow' | 'queue';
44
+ run_timeout_ms: number;
45
+ max_queued_dispatches?: number;
46
+ max_pending_approvals?: number;
47
+ max_trigger_fanout?: number;
48
+
49
+ // Delivery
50
+ delivery_mode?: 'announce' | 'announce-always' | 'none';
51
+ delivery_channel?: string | null;
52
+ delivery_to?: string | null;
53
+ delivery_guarantee?: 'at-most-once' | 'at-least-once';
54
+
55
+ // Workflow chaining
56
+ parent_id?: string | null;
57
+ trigger_on?: 'success' | 'failure' | 'complete' | null;
58
+ trigger_delay_s?: number;
59
+ trigger_condition?: string | null;
60
+
61
+ // Retry
62
+ max_retries?: number;
63
+
64
+ // Metadata
65
+ delete_after_run?: number | boolean;
66
+ ttl_hours?: number | null;
67
+ resource_pool?: string | null;
68
+ job_class?: 'standard' | 'pre_compaction_flush';
69
+
70
+ // HITL approval gates
71
+ approval_required?: number | boolean;
72
+ approval_timeout_s?: number;
73
+ approval_auto?: 'approve' | 'reject';
74
+
75
+ // Context retrieval
76
+ context_retrieval?: 'none' | 'recent' | 'hybrid';
77
+ context_retrieval_limit?: number;
78
+
79
+ // Output handling
80
+ output_store_limit_bytes?: number;
81
+ output_excerpt_limit_bytes?: number;
82
+ output_summary_limit_bytes?: number;
83
+ output_offload_threshold_bytes?: number;
84
+
85
+ // Session continuity
86
+ preferred_session_key?: string | null;
87
+
88
+ // Auth profile override
89
+ auth_profile?: string | null;
90
+
91
+ // Delivery opt-out
92
+ delivery_opt_out_reason?: string | null;
93
+
94
+ // Watchdog monitoring
95
+ job_type?: 'standard' | 'watchdog';
96
+ watchdog_target_label?: string | null;
97
+ watchdog_check_cmd?: string | null;
98
+ watchdog_timeout_min?: number | null;
99
+ watchdog_alert_channel?: string | null;
100
+ watchdog_alert_target?: string | null;
101
+ watchdog_self_destruct?: number | boolean;
102
+ watchdog_started_at?: string | null;
103
+
104
+ // Origin tracking
105
+ origin?: string | null;
106
+
107
+ // Convenience flag (create-time only)
108
+ run_now?: boolean;
109
+
110
+ // v0.2 Identity
111
+ identity_principal?: string | null;
112
+ identity_run_as?: string | null;
113
+ identity_attestation?: string | null;
114
+ identity_ref?: string | null;
115
+ identity_subject_kind?: 'agent' | 'service' | 'workload' | 'user' | 'composite' | 'delegated-agent' | 'unknown' | null;
116
+ identity_subject_principal?: string | null;
117
+ identity_trust_level?: 'untrusted' | 'restricted' | 'supervised' | 'autonomous' | null;
118
+ identity_delegation_mode?: 'none' | 'on-behalf-of' | 'impersonation' | null;
119
+ identity?: string | null;
120
+
121
+ // v0.2 Authorization Proof
122
+ authorization_proof_ref?: string | null;
123
+ authorization_proof?: string | null;
124
+
125
+ // v0.2 Authorization
126
+ authorization_ref?: string | null;
127
+ authorization?: string | null;
128
+
129
+ // v0.2 Evidence
130
+ evidence_ref?: string | null;
131
+ evidence?: string | null;
132
+
133
+ // v0.2 Contract
134
+ contract_required_trust_level?: 'untrusted' | 'restricted' | 'supervised' | 'autonomous' | null;
135
+ contract_trust_enforcement?: 'none' | 'warn' | 'block' | 'advisory' | 'strict' | null;
136
+ contract_sandbox?: string | null;
137
+ contract_allowed_paths?: string | null;
138
+ contract_network?: string | null;
139
+ contract_max_cost_usd?: number | null;
140
+ contract_audit?: string | null;
141
+ child_credential_policy?: 'none' | 'inherit' | 'downscope' | 'independent' | null;
142
+
143
+ [key: string]: unknown;
144
+ }
145
+
146
+ export interface JobRecord extends JobSpec {
147
+ id: string;
148
+ enabled: number;
149
+ schedule_kind: 'cron' | 'at';
150
+ schedule_cron: string | null;
151
+ schedule_at: string | null;
152
+ schedule_tz: string;
153
+ payload_kind: 'systemEvent' | 'agentTurn' | 'shellCommand';
154
+ payload_message: string;
155
+ ttl_hours: number | null;
156
+ auth_profile: string | null;
157
+ delivery_opt_out_reason: string | null;
158
+
159
+ // Scheduling state (denormalized)
160
+ next_run_at?: string | null;
161
+ last_run_at?: string | null;
162
+ last_status?: string | null;
163
+ consecutive_errors?: number;
164
+ queued_count?: number;
165
+
166
+ // Timestamps
167
+ created_at?: string;
168
+ updated_at?: string;
169
+ }
170
+
171
+ export interface RunRecord {
172
+ id: string;
173
+ job_id: string;
174
+ status: string;
175
+
176
+ // Timestamps
177
+ started_at?: string | null;
178
+ finished_at?: string | null;
179
+ duration_ms?: number | null;
180
+ dispatched_at?: string | null;
181
+ last_heartbeat?: string | null;
182
+
183
+ // Session tracking
184
+ session_key?: string | null;
185
+ session_id?: string | null;
186
+
187
+ // Result
188
+ summary?: string | null;
189
+ error_message?: string | null;
190
+ shell_exit_code?: number | null;
191
+ shell_signal?: string | null;
192
+ shell_timed_out?: number | boolean | null;
193
+ shell_stdout?: string | null;
194
+ shell_stderr?: string | null;
195
+ shell_stdout_path?: string | null;
196
+ shell_stderr_path?: string | null;
197
+ shell_stdout_bytes?: number | null;
198
+ shell_stderr_bytes?: number | null;
199
+
200
+ // Timeout
201
+ run_timeout_ms?: number;
202
+
203
+ // Retry tracking
204
+ retry_count?: number;
205
+ retry_of?: string | null;
206
+ triggered_by_run?: string | null;
207
+ dispatch_queue_id?: string | null;
208
+
209
+ // Context & replay
210
+ context_summary?: string | null;
211
+ replay_of?: string | null;
212
+
213
+ // Idempotency
214
+ idempotency_key?: string | null;
215
+
216
+ // v0.2 Outcomes
217
+ identity_resolved?: string | null;
218
+ trust_evaluation?: string | null;
219
+ authorization_decision?: string | null;
220
+ authorization_proof_verification?: string | null;
221
+ evidence_record?: string | null;
222
+ credential_handoff_summary?: string | null;
223
+
224
+ [key: string]: unknown;
225
+ }
226
+
227
+ export interface MessageRecord {
228
+ id: string;
229
+
230
+ // Routing
231
+ from_agent?: string | null;
232
+ to_agent?: string | null;
233
+ team_id?: string | null;
234
+ member_id?: string | null;
235
+ task_id?: string | null;
236
+ reply_to?: string | null;
237
+
238
+ // Content
239
+ kind: string;
240
+ subject?: string | null;
241
+ body: string;
242
+ metadata?: JsonValue | null;
243
+
244
+ // Priority & delivery
245
+ priority?: number;
246
+ channel?: string | null;
247
+ delivery_to?: string | null;
248
+
249
+ // Status
250
+ status?: string | null;
251
+ delivered_at?: string | null;
252
+ read_at?: string | null;
253
+ ack_required?: number;
254
+ ack_at?: string | null;
255
+ delivery_attempts?: number;
256
+ last_error?: string | null;
257
+ team_mapped_at?: string | null;
258
+ expires_at?: string | null;
259
+
260
+ // Metadata
261
+ created_at?: string;
262
+
263
+ // Links
264
+ job_id?: string | null;
265
+ run_id?: string | null;
266
+ owner?: string | null;
267
+
268
+ [key: string]: unknown;
269
+ }
270
+
271
+ export interface ApprovalRecord {
272
+ id: string;
273
+ job_id: string;
274
+ run_id?: string | null;
275
+ dispatch_queue_id?: string | null;
276
+ status: string;
277
+ requested_at?: string;
278
+ resolved_at?: string | null;
279
+ resolved_by?: string | null;
280
+ notes?: string | null;
281
+ [key: string]: unknown;
282
+ }
283
+
284
+ export interface AgentRecord {
285
+ id: string;
286
+ name?: string | null;
287
+ status?: string | null;
288
+ last_seen_at?: string | null;
289
+ session_key?: string | null;
290
+ capabilities?: JsonValue | null;
291
+ delivery_channel?: string | null;
292
+ delivery_to?: string | null;
293
+ brand_name?: string | null;
294
+ created_at?: string;
295
+ [key: string]: unknown;
296
+ }
297
+
298
+ export interface DispatchRecord {
299
+ id: string;
300
+ job_id: string;
301
+ dispatch_kind: 'manual' | 'chain' | 'retry';
302
+ status: string;
303
+ scheduled_for: string;
304
+ source_run_id?: string | null;
305
+ retry_of_run_id?: string | null;
306
+ created_at?: string;
307
+ claimed_at?: string | null;
308
+ processed_at?: string | null;
309
+ [key: string]: unknown;
310
+ }
311
+
312
+ export interface ShellResult {
313
+ status: 'ok' | 'error' | 'timeout';
314
+ summary: string;
315
+ deliveryText: string;
316
+ errorMessage: string | null;
317
+ exitCode: number | null;
318
+ signal: string | null;
319
+ timedOut: boolean;
320
+ stdout: string;
321
+ stderr: string;
322
+ stdoutPath: string | null;
323
+ stderrPath: string | null;
324
+ stdoutBytes: number;
325
+ stderrBytes: number;
326
+ stdoutTruncated: boolean;
327
+ stderrTruncated: boolean;
328
+ contextSummary: Record<string, JsonValue>;
329
+ }
330
+
331
+ /** Partial shell result returned by extractShellResultFromRun (no status/summary/deliveryText/contextSummary). */
332
+ export interface PartialShellResult {
333
+ exitCode: number | null;
334
+ signal: string | null;
335
+ timedOut: boolean;
336
+ stdout: string;
337
+ stderr: string;
338
+ stdoutPath: string | null;
339
+ stderrPath: string | null;
340
+ stdoutBytes: number;
341
+ stderrBytes: number;
342
+ errorMessage: string | null;
343
+ }
344
+
345
+ // -- Parameter option interfaces --
346
+
347
+ export interface SendMessageOpts {
348
+ from_agent: string;
349
+ to_agent: string;
350
+ kind?: string;
351
+ subject?: string;
352
+ body: string;
353
+ metadata?: JsonValue | null;
354
+ priority?: number;
355
+ channel?: string | null;
356
+ expires_at?: string | null;
357
+ reply_to?: string | null;
358
+ team_id?: string | null;
359
+ member_id?: string | null;
360
+ task_id?: string | null;
361
+ job_id?: string | null;
362
+ run_id?: string | null;
363
+ owner?: string | null;
364
+ ack_required?: number | boolean;
365
+ delivery_to?: string | null;
366
+ }
367
+
368
+ export interface CreateRunOpts {
369
+ status?: string;
370
+ run_timeout_ms?: number;
371
+ session_key?: string | null;
372
+ session_id?: string | null;
373
+ context_summary?: string | object | null;
374
+ replay_of?: string | null;
375
+ idempotency_key?: string | null;
376
+ retry_count?: number;
377
+ retry_of?: string | null;
378
+ triggered_by_run?: string | null;
379
+ dispatch_queue_id?: string | null;
380
+ }
381
+
382
+ export interface FinishRunOpts {
383
+ summary?: string | null;
384
+ error_message?: string | null;
385
+ context_summary?: string | object | null;
386
+ shell_exit_code?: number | null;
387
+ shell_signal?: string | null;
388
+ shell_timed_out?: number | boolean | null;
389
+ shell_stdout?: string | null;
390
+ shell_stderr?: string | null;
391
+ shell_stdout_path?: string | null;
392
+ shell_stderr_path?: string | null;
393
+ shell_stdout_bytes?: number | null;
394
+ shell_stderr_bytes?: number | null;
395
+
396
+ // v0.2 Outcomes
397
+ identity_resolved?: string | object | null;
398
+ trust_evaluation?: string | object | null;
399
+ authorization_decision?: string | object | null;
400
+ authorization_proof_verification?: string | object | null;
401
+ evidence_record?: string | object | null;
402
+ credential_handoff_summary?: string | object | null;
403
+ }
404
+
405
+ export interface NormalizeShellOpts {
406
+ runId?: string | null;
407
+ timeoutMs?: number;
408
+ storeLimit?: number;
409
+ excerptLimit?: number;
410
+ summaryLimit?: number;
411
+ offloadThreshold?: number;
412
+ artifactsDir?: string;
413
+ }
414
+
415
+ export interface InboxOpts {
416
+ limit?: number;
417
+ includeRead?: boolean;
418
+ includeDelivered?: boolean;
419
+ teamId?: string;
420
+ memberId?: string;
421
+ taskId?: string;
422
+ }
423
+
424
+ export interface TeamMessagesOpts {
425
+ limit?: number;
426
+ includeRead?: boolean;
427
+ memberId?: string;
428
+ taskId?: string;
429
+ }
430
+
431
+ export interface DbPathParams {
432
+ env?: Record<string, string | undefined>;
433
+ explicitPath?: string;
434
+ moduleDir?: string;
435
+ }
436
+
437
+ export interface ArtifactsDirParams {
438
+ env?: Record<string, string | undefined>;
439
+ explicitPath?: string;
440
+ dbPath?: string;
441
+ }
442
+
443
+ export interface AgentTurnOpts {
444
+ message: string;
445
+ agentId?: string;
446
+ sessionKey?: string;
447
+ model?: string;
448
+ authProfile?: string | null;
449
+ timeoutMs?: number;
450
+ }
451
+
452
+ export interface AgentTurnWithTimeoutOpts {
453
+ message: string;
454
+ agentId?: string;
455
+ sessionKey?: string;
456
+ model?: string;
457
+ authProfile?: string | null;
458
+ idleTimeoutMs?: number;
459
+ pollIntervalMs?: number;
460
+ absoluteTimeoutMs?: number;
461
+ }
462
+
463
+ export interface AgentTurnResult {
464
+ ok: true;
465
+ content: string;
466
+ usage: Record<string, unknown>;
467
+ sessionKey: string;
468
+ raw: Record<string, unknown>;
469
+ }
470
+
471
+ export interface DeliveryResult {
472
+ ok: true;
473
+ parts: number;
474
+ lastResponse: unknown;
475
+ }
476
+
477
+ // -- Module declarations --
478
+
479
+ export const db: {
480
+ setDbPath(path: string): void;
481
+ getDb(): import('better-sqlite3').Database;
482
+ getResolvedDbPath(): string;
483
+ initDb(): Promise<unknown>;
484
+ checkpointWal(): { busy: number; checkpointed: number; log: number } | null;
485
+ closeDb(): void;
486
+ };
487
+
488
+ export const jobs: {
489
+ // Validation
490
+ validateJobSpec(opts: JobSpec, currentJob?: Partial<JobRecord> | null, mode?: 'create' | 'update'): JobSpec;
491
+ validateJobPayload(sessionTarget: string, payloadKind: string): void;
492
+
493
+ // CRUD
494
+ createJob(opts: JobSpec): JobRecord;
495
+ getJob(id: string): JobRecord | undefined;
496
+ listJobs(opts?: { enabledOnly?: boolean }): JobRecord[];
497
+ updateJob(id: string, patch: Partial<JobSpec>): JobRecord | null;
498
+ deleteJob(id: string): void;
499
+
500
+ // At-job helpers
501
+ parseInDuration(duration: string): string;
502
+ AT_JOB_CRON_SENTINEL: string;
503
+
504
+ // Scheduling
505
+ nextRunFromCron(cronExpr: string, tz?: string | null): string | null;
506
+ getDueJobs(): JobRecord[];
507
+ getDueAtJobs(): JobRecord[];
508
+ runJobNow(id: string): (JobRecord & { dispatch_id: string; dispatch_kind: string }) | null;
509
+
510
+ // Chaining
511
+ getTriggeredChildren(parentId: string, status: string): JobRecord[];
512
+ getChildJobs(parentId: string): JobRecord[];
513
+ evalTriggerCondition(condition: string | null, content: string): boolean;
514
+ fireTriggeredChildren(parentId: string, status: string, content: string, parentRunId?: string | null): Array<JobRecord & { dispatch_id: string; scheduled_for: string }>;
515
+ detectCycle(childId: string, parentId: string): void;
516
+ getChainDepth(jobId: string): number;
517
+
518
+ // Queue management
519
+ enqueueJob(jobId: string): { queued: boolean; queued_count: number; limited: boolean };
520
+ dequeueJob(jobId: string): boolean;
521
+ getDispatchBacklogCount(jobId: string): number;
522
+ canEnqueueDispatch(jobId: string, maxQueuedDispatches?: number): boolean;
523
+
524
+ // Retry
525
+ shouldRetry(job: JobRecord, runId: string): boolean;
526
+ scheduleRetry(job: JobRecord, failedRunId: string): {
527
+ retryCount: number;
528
+ delaySec: number;
529
+ retryOf: string;
530
+ dispatch: DispatchRecord | null;
531
+ skipped?: boolean;
532
+ };
533
+
534
+ // Overlap detection
535
+ hasRunningRun(jobId: string): boolean;
536
+ hasRunningRunForPool(poolName: string): boolean;
537
+
538
+ // Lifecycle
539
+ cancelJob(jobId: string, opts?: { cascade?: boolean }): string[];
540
+ pruneExpiredJobs(): number;
541
+ };
542
+
543
+ export const runs: {
544
+ createRun(jobId: string, opts?: CreateRunOpts): RunRecord;
545
+ getRun(id: string): RunRecord | undefined;
546
+ getRunsForJob(jobId: string, limit?: number): RunRecord[];
547
+ finishRun(id: string, status: string, opts?: FinishRunOpts): RunRecord | null;
548
+ updateHeartbeat(id: string): void;
549
+ updateRunSession(id: string, sessionKey: string | null, sessionId: string | null): void;
550
+ getStaleRuns(thresholdSeconds?: number): Array<RunRecord & { job_name: string; job_timeout_ms: number }>;
551
+ getTimedOutRuns(): Array<RunRecord & { job_name: string; job_timeout_ms: number }>;
552
+ getRunningRuns(): Array<RunRecord & { job_name: string; job_timeout_ms: number }>;
553
+ getRunningRunsByPool(poolName: string): Array<RunRecord & { job_name: string }>;
554
+ pruneRuns(keepPerJob?: number): void;
555
+ updateContextSummary(runId: string, summaryObj: unknown): RunRecord | undefined;
556
+ };
557
+
558
+ export const messages: {
559
+ sendMessage(opts: SendMessageOpts): MessageRecord;
560
+ getMessage(id: string): MessageRecord | undefined;
561
+ getInbox(agentId: string, opts?: InboxOpts): MessageRecord[];
562
+ getOutbox(agentId: string, limit?: number): MessageRecord[];
563
+ getThread(messageId: string): MessageRecord[];
564
+ getTeamMessages(teamId: string, opts?: TeamMessagesOpts): MessageRecord[];
565
+ markDelivered(id: string): void;
566
+ markRead(id: string): void;
567
+ markAllRead(agentId: string): SqliteRunResult;
568
+ getUnreadCount(agentId: string): number;
569
+ ackMessage(id: string, actor?: string, detail?: string | null): MessageRecord;
570
+ expireMessages(): SqliteRunResult;
571
+ pruneMessages(keepDays?: number, deliveredKeepDays?: number, systemKeepDays?: number): SqliteRunResult;
572
+ recordMessageAttempt(messageId: string, opts?: { ok?: boolean; actor?: string; error?: string }): MessageRecord | null;
573
+ listMessageReceipts(messageId: string, limit?: number): Array<Record<string, unknown>>;
574
+ };
575
+
576
+ export const approvals: {
577
+ createApproval(jobId: string, runId: string, dispatchQueueId?: string | null): ApprovalRecord;
578
+ getApproval(id: string): ApprovalRecord | undefined;
579
+ getPendingApproval(jobId: string): ApprovalRecord | undefined;
580
+ listPendingApprovals(): Array<ApprovalRecord & { job_name: string }>;
581
+ resolveApproval(id: string, status: string, resolvedBy: string, notes?: string): ApprovalRecord;
582
+ countPendingApprovalsForJob(jobId: string): number;
583
+ getTimedOutApprovals(): Array<ApprovalRecord & { job_name: string; approval_timeout_s: number; approval_auto: string }>;
584
+ pruneApprovals(retentionDays?: number): SqliteRunResult;
585
+ };
586
+
587
+ export const agents: {
588
+ upsertAgent(id: string, opts?: { name?: string; status?: string; session_key?: string | null; capabilities?: JsonValue | null; delivery_channel?: string | null; delivery_to?: string | null; brand_name?: string | null }): AgentRecord;
589
+ getAgent(id: string): AgentRecord | undefined;
590
+ listAgents(): AgentRecord[];
591
+ setAgentStatus(id: string, status: string, sessionKey?: string | null): void;
592
+ touchAgent(id: string): void;
593
+ };
594
+
595
+ export const dispatchQueue: {
596
+ enqueueDispatch(jobId: string, opts?: {
597
+ id?: string;
598
+ kind?: string;
599
+ status?: string;
600
+ scheduled_for?: string;
601
+ source_run_id?: string | null;
602
+ retry_of_run_id?: string | null;
603
+ claimed_at?: string | null;
604
+ processed_at?: string | null;
605
+ }): DispatchRecord;
606
+ getDispatch(id: string): DispatchRecord | null;
607
+ getDueDispatches(limit?: number): Array<DispatchRecord & { job_name: string }>;
608
+ claimDispatch(id: string): DispatchRecord | null;
609
+ releaseDispatch(id: string, scheduledFor?: string | null): DispatchRecord | null;
610
+ setDispatchStatus(id: string, status: string): DispatchRecord;
611
+ listDispatchesForJob(jobId: string, limit?: number): DispatchRecord[];
612
+ };
613
+
614
+ export const gateway: {
615
+ TELEGRAM_MAX_MESSAGE_LENGTH: number;
616
+ runAgentTurn(opts: AgentTurnOpts): Promise<AgentTurnResult>;
617
+ runAgentTurnWithActivityTimeout(opts: AgentTurnWithTimeoutOpts): Promise<AgentTurnResult>;
618
+ sendSystemEvent(text: string, mode?: string): Promise<Record<string, unknown>>;
619
+ invokeGatewayTool(tool: string, args: Record<string, unknown>, sessionKey?: string): Promise<Record<string, unknown>>;
620
+ listSessions(opts?: { activeMinutes?: number; limit?: number; kinds?: string[] }): Promise<Record<string, unknown>>;
621
+ getAllSubAgentSessions(activeMinutes?: number): Promise<Array<Record<string, unknown>>>;
622
+ splitMessageForChannel(channel: string, message: string): string[];
623
+ resolveDeliveryAlias(rawTarget: string): { channel: string; target: string } | null;
624
+ deliverMessage(channel: string, target: string, message: string): Promise<DeliveryResult>;
625
+ checkGatewayHealth(): Promise<boolean>;
626
+ waitForGateway(timeoutMs?: number, intervalMs?: number): Promise<boolean>;
627
+ };
628
+
629
+ export const paths: {
630
+ resolveSchedulerHome(env?: Record<string, string | undefined>): string;
631
+ resolveSchedulerDbPath(params?: DbPathParams): string;
632
+ ensureSchedulerDbParent(dbPath: string): string;
633
+ resolveBackupStagingDir(env?: Record<string, string | undefined>): string;
634
+ resolveArtifactsDir(params?: ArtifactsDirParams): string;
635
+ ensureArtifactsDir(dirPath: string): string;
636
+ };
637
+
638
+ export const promptContext: {
639
+ buildTriggeredRunContext(run: RunRecord, deps?: {
640
+ getRunById?: (id: string) => RunRecord | undefined;
641
+ getJobById?: (id: string) => JobRecord | undefined;
642
+ }): {
643
+ text: string;
644
+ meta: Record<string, unknown>;
645
+ };
646
+ };
647
+
648
+ export const retrieval: {
649
+ getRecentRunSummaries(jobId: string, limit?: number): Array<{
650
+ id: string;
651
+ job_id: string;
652
+ started_at: string;
653
+ finished_at: string | null;
654
+ status: string;
655
+ context_summary: string | null;
656
+ summary: string | null;
657
+ }>;
658
+ searchRunSummaries(jobId: string, query: string, limit?: number): Array<{
659
+ id: string;
660
+ job_id: string;
661
+ started_at: string;
662
+ finished_at: string | null;
663
+ status: string;
664
+ context_summary: string | null;
665
+ summary: string | null;
666
+ _score: number;
667
+ }>;
668
+ buildRetrievalContext(job: JobRecord): string;
669
+ };
670
+
671
+ export const shellResults: {
672
+ DEFAULT_STORE_LIMIT: number;
673
+ DEFAULT_EXCERPT_LIMIT: number;
674
+ DEFAULT_SUMMARY_LIMIT: number;
675
+ DEFAULT_OFFLOAD_THRESHOLD: number;
676
+ normalizeShellResult(result: { stdout?: string; stderr?: string; error?: unknown }, opts?: NormalizeShellOpts): ShellResult;
677
+ extractShellResultFromRun(run: RunRecord): PartialShellResult | null;
678
+ };
679
+
680
+ export const idempotency: {
681
+ generateIdempotencyKey(jobId: string, scheduledTime?: string): string;
682
+ generateChainIdempotencyKey(parentRunId: string, childJobId: string): string;
683
+ generateRunNowIdempotencyKey(jobId: string): string;
684
+ checkIdempotencyKey(key: string): Record<string, unknown> | null;
685
+ getIdempotencyEntry(key: string): Record<string, unknown> | null;
686
+ claimIdempotencyKey(key: string, jobId: string, runId: string, expiresAt: string): boolean;
687
+ releaseIdempotencyKey(key: string): void;
688
+ updateIdempotencyResultHash(key: string, content: string): void;
689
+ listIdempotencyForJob(jobId: string, limit?: number): Array<Record<string, unknown>>;
690
+ forcePruneIdempotency(): number;
691
+ };
692
+
693
+ export interface TaskGroupOpts {
694
+ name: string;
695
+ expectedAgents: string[];
696
+ timeoutS?: number;
697
+ createdBy?: string;
698
+ deliveryChannel?: string | null;
699
+ deliveryTo?: string | null;
700
+ }
701
+
702
+ export interface TaskGroupResult {
703
+ id: string;
704
+ name: string;
705
+ status: string;
706
+ created_at: string;
707
+ created_by: string;
708
+ agents: Array<{ agent_label: string; status: string }>;
709
+ }
710
+
711
+ export interface TaskGroupStatus {
712
+ id: string;
713
+ name: string;
714
+ status: string;
715
+ agents: Array<{
716
+ label: string;
717
+ status: string;
718
+ session_key?: string;
719
+ last_heartbeat?: string;
720
+ duration: number | null;
721
+ exit_message?: string;
722
+ error?: string;
723
+ }>;
724
+ elapsed: number;
725
+ remaining_timeout: number;
726
+ summary?: string;
727
+ delivery_channel: string | null;
728
+ delivery_to: string | null;
729
+ }
730
+
731
+ export const taskTracker: {
732
+ createTaskGroup(opts: TaskGroupOpts): TaskGroupResult;
733
+ getTaskGroup(id: string): Record<string, unknown> | undefined;
734
+ listActiveTaskGroups(): Array<Record<string, unknown>>;
735
+ agentStarted(trackerId: string, agentLabel: string, sessionKey?: string): void;
736
+ registerAgentSession(trackerId: string, agentLabel: string, sessionKey: string): void;
737
+ touchAgentHeartbeat(trackerId: string, agentLabel: string): void;
738
+ agentCompleted(trackerId: string, agentLabel: string, exitMessage?: string): void;
739
+ agentFailed(trackerId: string, agentLabel: string, error?: string): void;
740
+ checkDeadAgents(): Array<{ tracker_id: string; agent_label: string; agent_id: string }>;
741
+ checkGroupCompletion(trackerId: string): Record<string, unknown> | null;
742
+ getTaskGroupStatus(trackerId: string): TaskGroupStatus | null;
743
+ };
744
+
745
+ export interface TeamTaskGateOpts {
746
+ teamId: string;
747
+ taskId: string;
748
+ expectedMembers: string[];
749
+ timeoutS?: number;
750
+ createdBy?: string;
751
+ deliveryChannel?: string | null;
752
+ deliveryTo?: string | null;
753
+ }
754
+
755
+ export const teamAdapter: {
756
+ mapTeamMessages(limit?: number): number;
757
+ listTeamTasks(teamId: string, limit?: number): Array<Record<string, unknown>>;
758
+ listTeamMailboxEvents(teamId: string, opts?: { limit?: number; taskId?: string | null }): Array<Record<string, unknown>>;
759
+ createTeamTaskGate(opts: TeamTaskGateOpts): {
760
+ team_id: string;
761
+ task_id: string;
762
+ gate_status: string;
763
+ tracker_id: string;
764
+ expected_members: string[];
765
+ };
766
+ checkTeamTaskGates(limit?: number): { passed: number; failed: number; pending: number };
767
+ ackTeamMessage(messageId: string, actor?: string, detail?: string | null): Record<string, unknown> | null;
768
+ };
769
+
770
+ export const SCHEDULER_SCHEMAS: {
771
+ jobs: {
772
+ type: string;
773
+ required: string[];
774
+ fields: Record<string, {
775
+ type: string;
776
+ default?: unknown;
777
+ enum?: string[];
778
+ min?: number;
779
+ maxLength?: number;
780
+ [key: string]: unknown;
781
+ }>;
782
+ };
783
+ runs: {
784
+ statuses: string[];
785
+ key_fields: string[];
786
+ };
787
+ approvals: {
788
+ statuses: string[];
789
+ key_fields: string[];
790
+ };
791
+ dispatches: {
792
+ kinds: string[];
793
+ statuses: string[];
794
+ key_fields: string[];
795
+ };
796
+ messages: {
797
+ kinds: string[];
798
+ statuses: string[];
799
+ };
800
+ };
801
+
802
+ // -- v0.2 Runtime result interfaces --
803
+
804
+ export interface ResolvedIdentity {
805
+ provider?: string;
806
+ session?: Record<string, unknown> | null;
807
+ source?: 'provider' | 'provider-error';
808
+ subject_kind: string;
809
+ principal: string | null;
810
+ trust_level: string | null;
811
+ delegation_mode: string | null;
812
+ raw: Record<string, unknown> | null;
813
+ transient?: boolean;
814
+ error?: string;
815
+ }
816
+
817
+ export interface TrustEvaluation {
818
+ effective_level: string | null;
819
+ required_level: string | null;
820
+ decision: 'permit' | 'deny' | 'warn';
821
+ reason: string;
822
+ }
823
+
824
+ export interface AuthorizationProofResult {
825
+ verified: boolean;
826
+ method: string | null;
827
+ ref: string | null;
828
+ source?: 'provider' | 'provider-error';
829
+ provider?: string;
830
+ error?: string;
831
+ }
832
+
833
+ export interface AuthorizationResult {
834
+ decision: 'permit' | 'deny' | 'escalate';
835
+ reason: string;
836
+ ref: string | null;
837
+ source?: 'provider' | 'provider-error';
838
+ provider?: string;
839
+ }
840
+
841
+ export interface EvidenceResult {
842
+ evidence_ref: string | null;
843
+ created_at: string;
844
+ hash: string | null;
845
+ integrity: 'none';
846
+ payload_summary: Record<string, unknown>;
847
+ }
848
+
849
+ export interface CredentialHandoffSummary {
850
+ mode: string | null;
851
+ bindings_count: number;
852
+ cleanup_required: boolean;
853
+ }
854
+
855
+ export const v02Runtime: {
856
+ TRUST_LEVELS: readonly string[];
857
+ compareTrustLevels(a: string | null | undefined, b: string | null | undefined): -1 | 0 | 1;
858
+ resolveIdentity(job: Record<string, unknown>, ctx?: Record<string, unknown>): Promise<ResolvedIdentity | null>;
859
+ evaluateTrust(job: Record<string, unknown>, resolvedIdentity: ResolvedIdentity | null): TrustEvaluation;
860
+ verifyAuthorizationProof(job: Record<string, unknown>, ctx?: Record<string, unknown>): Promise<AuthorizationProofResult | null>;
861
+ evaluateAuthorization(job: Record<string, unknown>, identityResult: ResolvedIdentity | null, trustResult: TrustEvaluation | null, ctx?: Record<string, unknown>): Promise<AuthorizationResult | null>;
862
+ generateEvidence(job: Record<string, unknown>, runResult: Record<string, unknown> | null, outcomes: Record<string, unknown> | null): EvidenceResult | null;
863
+ summarizeCredentialHandoff(job: Record<string, unknown>): CredentialHandoffSummary | null;
864
+ };