@karmaniverous/jeeves-meta 0.11.3 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -1
- package/dist/cli/jeeves-meta/index.js +4134 -8352
- package/dist/index.d.ts +449 -346
- package/dist/index.js +9984 -9007
- package/package.json +4 -3
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
+
import { Command } from 'commander';
|
|
3
|
+
import { JeevesComponentDescriptor } from '@karmaniverous/jeeves';
|
|
2
4
|
import pino, { Logger } from 'pino';
|
|
3
5
|
import * as fastify from 'fastify';
|
|
4
6
|
import { FastifyInstance, FastifyBaseLogger } from 'fastify';
|
|
@@ -32,6 +34,160 @@ declare function listArchiveFiles(metaPath: string): string[];
|
|
|
32
34
|
*/
|
|
33
35
|
declare function pruneArchive(metaPath: string, maxArchive: number): Promise<number>;
|
|
34
36
|
|
|
37
|
+
/**
|
|
38
|
+
* Per-cycle context package computed by the orchestrator.
|
|
39
|
+
*
|
|
40
|
+
* Shared inputs that multiple subprocesses need are computed once
|
|
41
|
+
* and serialized into each subprocess's task prompt.
|
|
42
|
+
*
|
|
43
|
+
* @module interfaces/MetaContext
|
|
44
|
+
*/
|
|
45
|
+
/**
|
|
46
|
+
* Context package for a single synthesis cycle.
|
|
47
|
+
*
|
|
48
|
+
* The orchestrator computes this once per cycle from the meta path,
|
|
49
|
+
* ownership tree, watcher walk results, and filesystem reads.
|
|
50
|
+
*/
|
|
51
|
+
interface MetaContext {
|
|
52
|
+
/** Absolute path to the .meta directory. */
|
|
53
|
+
path: string;
|
|
54
|
+
/** All files in scope (absolute paths). */
|
|
55
|
+
scopeFiles: string[];
|
|
56
|
+
/** Files changed since _generatedAt (absolute paths). */
|
|
57
|
+
deltaFiles: string[];
|
|
58
|
+
/** Child _content outputs, keyed by relative path. */
|
|
59
|
+
childMetas: Record<string, unknown>;
|
|
60
|
+
/** Cross-referenced meta _content outputs, keyed by owner path. */
|
|
61
|
+
crossRefMetas: Record<string, unknown>;
|
|
62
|
+
/** _content from the last cycle, or null on first run. */
|
|
63
|
+
previousContent: string | null;
|
|
64
|
+
/** _feedback from the last cycle, or null on first run. */
|
|
65
|
+
previousFeedback: string | null;
|
|
66
|
+
/** Current _steer value, or null if unset. */
|
|
67
|
+
steer: string | null;
|
|
68
|
+
/** _state from the last cycle, or null on first run. */
|
|
69
|
+
previousState: unknown;
|
|
70
|
+
/** Archive snapshot file paths (for steer change detection, etc.). */
|
|
71
|
+
archives: string[];
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Pluggable executor interface for LLM subprocess invocation.
|
|
76
|
+
*
|
|
77
|
+
* @module interfaces/MetaExecutor
|
|
78
|
+
*/
|
|
79
|
+
/** Options for spawning a synthesis subprocess. */
|
|
80
|
+
interface MetaSpawnOptions {
|
|
81
|
+
/** Model override for this subprocess. */
|
|
82
|
+
model?: string;
|
|
83
|
+
/** Timeout in seconds. */
|
|
84
|
+
timeout?: number;
|
|
85
|
+
/** Label for the spawned session. */
|
|
86
|
+
label?: string;
|
|
87
|
+
/** Thinking level (e.g. "low", "medium", "high"). */
|
|
88
|
+
thinking?: string;
|
|
89
|
+
}
|
|
90
|
+
/** Result of a spawn call, including optional token usage. */
|
|
91
|
+
interface MetaSpawnResult {
|
|
92
|
+
/** Subprocess output text. */
|
|
93
|
+
output: string;
|
|
94
|
+
/** Token count for this call, if available from the executor. */
|
|
95
|
+
tokens?: number;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Interface for spawning synthesis subprocesses.
|
|
99
|
+
*
|
|
100
|
+
* The executor abstracts the LLM invocation mechanism. The orchestrator
|
|
101
|
+
* calls spawn() sequentially for architect, builder, and critic steps.
|
|
102
|
+
* Each call blocks until the subprocess completes and returns its result.
|
|
103
|
+
*/
|
|
104
|
+
interface MetaExecutor {
|
|
105
|
+
/**
|
|
106
|
+
* Spawn a subprocess with the given task prompt.
|
|
107
|
+
*
|
|
108
|
+
* @param task - Full task prompt for the subprocess.
|
|
109
|
+
* @param options - Optional model and timeout overrides.
|
|
110
|
+
* @returns The subprocess result with output and optional token count.
|
|
111
|
+
*/
|
|
112
|
+
spawn(task: string, options?: MetaSpawnOptions): Promise<MetaSpawnResult>;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Abstraction over the jeeves-watcher HTTP API.
|
|
117
|
+
*
|
|
118
|
+
* The service uses this for filesystem enumeration (POST /walk),
|
|
119
|
+
* virtual rule registration (POST /rules/register), and archive reads
|
|
120
|
+
* via filter-only point scans (POST /scan).
|
|
121
|
+
*
|
|
122
|
+
* @module interfaces/WatcherClient
|
|
123
|
+
*/
|
|
124
|
+
/** An inference rule to register with the watcher. */
|
|
125
|
+
interface InferenceRuleSpec {
|
|
126
|
+
/** Rule name. */
|
|
127
|
+
name: string;
|
|
128
|
+
/** Rule description. */
|
|
129
|
+
description: string;
|
|
130
|
+
/** JSON Schema match criteria. */
|
|
131
|
+
match: Record<string, unknown>;
|
|
132
|
+
/** Schema array with set keywords. */
|
|
133
|
+
schema: unknown[];
|
|
134
|
+
/** Declarative render config. */
|
|
135
|
+
render?: Record<string, unknown>;
|
|
136
|
+
/** Handlebars template name. */
|
|
137
|
+
template?: string;
|
|
138
|
+
/** Render output format. */
|
|
139
|
+
renderAs?: string;
|
|
140
|
+
}
|
|
141
|
+
/** Request shape for watcher scan queries. */
|
|
142
|
+
interface WatcherScanRequest {
|
|
143
|
+
filter: Record<string, unknown>;
|
|
144
|
+
limit?: number;
|
|
145
|
+
cursor?: string;
|
|
146
|
+
fields?: string[];
|
|
147
|
+
countOnly?: boolean;
|
|
148
|
+
}
|
|
149
|
+
/** A single point returned from watcher scan. */
|
|
150
|
+
interface WatcherScanPoint {
|
|
151
|
+
id?: string | number;
|
|
152
|
+
payload?: Record<string, unknown>;
|
|
153
|
+
}
|
|
154
|
+
/** Response shape for watcher scan queries. */
|
|
155
|
+
interface WatcherScanResult {
|
|
156
|
+
points: WatcherScanPoint[];
|
|
157
|
+
cursor: string | null;
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Interface for watcher HTTP operations.
|
|
161
|
+
*
|
|
162
|
+
* Implementations handle retry with backoff internally.
|
|
163
|
+
*/
|
|
164
|
+
interface WatcherClient {
|
|
165
|
+
/**
|
|
166
|
+
* Register virtual inference rules with the watcher.
|
|
167
|
+
*
|
|
168
|
+
* @param source - Source identifier (e.g. 'jeeves-meta').
|
|
169
|
+
* @param rules - Array of inference rules to register.
|
|
170
|
+
*/
|
|
171
|
+
registerRules(source: string, rules: InferenceRuleSpec[]): Promise<void>;
|
|
172
|
+
/**
|
|
173
|
+
* Walk filesystem using glob patterns.
|
|
174
|
+
*
|
|
175
|
+
* @param globs - Array of glob patterns to match against.
|
|
176
|
+
* @returns Promise resolving to array of matching file paths.
|
|
177
|
+
*/
|
|
178
|
+
walk(globs: string[]): Promise<string[]>;
|
|
179
|
+
/**
|
|
180
|
+
* Run a filter-only point scan against the watcher index.
|
|
181
|
+
*
|
|
182
|
+
* Optional so narrow test doubles do not need to implement archive-read
|
|
183
|
+
* support unless a test exercises that path.
|
|
184
|
+
*
|
|
185
|
+
* @param request - Scan filter, pagination, and projection options.
|
|
186
|
+
* @returns Matching points and the next cursor.
|
|
187
|
+
*/
|
|
188
|
+
scan?(request: WatcherScanRequest): Promise<WatcherScanResult>;
|
|
189
|
+
}
|
|
190
|
+
|
|
35
191
|
/**
|
|
36
192
|
* Zod schema for jeeves-meta service configuration.
|
|
37
193
|
*
|
|
@@ -210,156 +366,329 @@ declare const SERVICE_NAME = "jeeves-meta";
|
|
|
210
366
|
declare const SERVICE_VERSION: string;
|
|
211
367
|
|
|
212
368
|
/**
|
|
213
|
-
*
|
|
369
|
+
* Custom CLI commands for the jeeves-meta service.
|
|
214
370
|
*
|
|
215
|
-
*
|
|
371
|
+
* Registered via `descriptor.customCliCommands` and added to the
|
|
372
|
+
* standard service CLI produced by `createServiceCli`.
|
|
216
373
|
*
|
|
217
|
-
* @module
|
|
374
|
+
* @module customCliCommands
|
|
218
375
|
*/
|
|
219
376
|
|
|
377
|
+
/** Register all custom meta commands on the parent program. */
|
|
378
|
+
declare function registerCustomCliCommands(program: Command): void;
|
|
379
|
+
|
|
220
380
|
/**
|
|
221
|
-
*
|
|
381
|
+
* Single-threaded synthesis queue with priority support and deduplication.
|
|
222
382
|
*
|
|
223
|
-
*
|
|
224
|
-
*
|
|
225
|
-
*
|
|
383
|
+
* The scheduler enqueues the stalest candidate each tick. HTTP-triggered
|
|
384
|
+
* synthesis requests get priority (inserted at front). A path appears at
|
|
385
|
+
* most once in the queue; re-triggering returns the current position.
|
|
386
|
+
*
|
|
387
|
+
* @module queue
|
|
226
388
|
*/
|
|
227
|
-
|
|
389
|
+
|
|
390
|
+
/** A queued synthesis work item. */
|
|
391
|
+
interface QueueItem {
|
|
392
|
+
path: string;
|
|
393
|
+
priority: boolean;
|
|
394
|
+
enqueuedAt: string;
|
|
395
|
+
}
|
|
396
|
+
/** Result returned by {@link SynthesisQueue.enqueue}. */
|
|
397
|
+
interface EnqueueResult {
|
|
398
|
+
position: number;
|
|
399
|
+
alreadyQueued: boolean;
|
|
400
|
+
}
|
|
401
|
+
/** Snapshot of queue state for the /status endpoint. */
|
|
402
|
+
interface QueueState {
|
|
403
|
+
depth: number;
|
|
404
|
+
items: Array<{
|
|
405
|
+
path: string;
|
|
406
|
+
priority: boolean;
|
|
407
|
+
enqueuedAt: string;
|
|
408
|
+
}>;
|
|
409
|
+
}
|
|
228
410
|
/**
|
|
229
|
-
*
|
|
230
|
-
*
|
|
231
|
-
* Resolves \@file: references for defaultArchitect and defaultCritic,
|
|
232
|
-
* and substitutes environment-variable placeholders throughout.
|
|
411
|
+
* Single-threaded synthesis queue.
|
|
233
412
|
*
|
|
234
|
-
*
|
|
235
|
-
*
|
|
413
|
+
* Only one synthesis runs at a time. Priority items are inserted at the
|
|
414
|
+
* front of the queue. Duplicate paths are rejected with their current
|
|
415
|
+
* position returned.
|
|
236
416
|
*/
|
|
237
|
-
declare
|
|
417
|
+
declare class SynthesisQueue {
|
|
418
|
+
private queue;
|
|
419
|
+
private currentItem;
|
|
420
|
+
private processing;
|
|
421
|
+
private logger;
|
|
422
|
+
private onEnqueueCallback;
|
|
423
|
+
/**
|
|
424
|
+
* Create a new SynthesisQueue.
|
|
425
|
+
*
|
|
426
|
+
* @param logger - Pino logger instance.
|
|
427
|
+
*/
|
|
428
|
+
constructor(logger: Logger);
|
|
429
|
+
/**
|
|
430
|
+
* Set a callback to invoke when a new (non-duplicate) item is enqueued.
|
|
431
|
+
*/
|
|
432
|
+
onEnqueue(callback: () => void): void;
|
|
433
|
+
/**
|
|
434
|
+
* Add a path to the synthesis queue.
|
|
435
|
+
*
|
|
436
|
+
* @param path - Meta path to synthesize.
|
|
437
|
+
* @param priority - If true, insert at front of queue.
|
|
438
|
+
* @returns Position and whether the path was already queued.
|
|
439
|
+
*/
|
|
440
|
+
enqueue(path: string, priority?: boolean): EnqueueResult;
|
|
441
|
+
/**
|
|
442
|
+
* Remove and return the next item from the queue.
|
|
443
|
+
*
|
|
444
|
+
* @returns The next QueueItem, or undefined if the queue is empty.
|
|
445
|
+
*/
|
|
446
|
+
dequeue(): QueueItem | undefined;
|
|
447
|
+
/** Mark the currently-running synthesis as complete. */
|
|
448
|
+
complete(): void;
|
|
449
|
+
/** Number of items waiting in the queue (excludes current). */
|
|
450
|
+
get depth(): number;
|
|
451
|
+
/** The item currently being synthesized, or null. */
|
|
452
|
+
get current(): QueueItem | null;
|
|
453
|
+
/** A shallow copy of the queued items. */
|
|
454
|
+
get items(): QueueItem[];
|
|
455
|
+
/** A shallow copy of the pending items (alias for items). */
|
|
456
|
+
get pending(): QueueItem[];
|
|
457
|
+
/**
|
|
458
|
+
* Remove all pending items from the queue.
|
|
459
|
+
*
|
|
460
|
+
* Does not affect the currently-running item.
|
|
461
|
+
*
|
|
462
|
+
* @returns The number of items removed.
|
|
463
|
+
*/
|
|
464
|
+
clear(): number;
|
|
465
|
+
/**
|
|
466
|
+
* Check whether a path is in the queue or currently being synthesized.
|
|
467
|
+
*
|
|
468
|
+
* @param path - Meta path to look up.
|
|
469
|
+
* @returns True if the path is queued or currently running.
|
|
470
|
+
*/
|
|
471
|
+
has(path: string): boolean;
|
|
472
|
+
/**
|
|
473
|
+
* Get the 0-indexed position of a path in the queue.
|
|
474
|
+
*
|
|
475
|
+
* @param path - Meta path to look up.
|
|
476
|
+
* @returns Position index, or null if not found in the queue.
|
|
477
|
+
*/
|
|
478
|
+
getPosition(path: string): number | null;
|
|
479
|
+
/**
|
|
480
|
+
* Return a snapshot of queue state for the /status endpoint.
|
|
481
|
+
*
|
|
482
|
+
* @returns Queue depth and item list.
|
|
483
|
+
*/
|
|
484
|
+
getState(): QueueState;
|
|
485
|
+
/**
|
|
486
|
+
* Process queued items one at a time until the queue is empty.
|
|
487
|
+
*
|
|
488
|
+
* Re-entry is prevented: if already processing, the call returns
|
|
489
|
+
* immediately. Errors are logged and do not block subsequent items.
|
|
490
|
+
*
|
|
491
|
+
* @param synthesizeFn - Async function that performs synthesis for a path.
|
|
492
|
+
*/
|
|
493
|
+
processQueue(synthesizeFn: (path: string) => Promise<void>): Promise<void>;
|
|
494
|
+
}
|
|
238
495
|
|
|
239
496
|
/**
|
|
240
|
-
*
|
|
497
|
+
* Virtual rule registration with jeeves-watcher.
|
|
241
498
|
*
|
|
242
|
-
*
|
|
243
|
-
*
|
|
499
|
+
* Service registers inference rules at startup (with retry) and
|
|
500
|
+
* re-registers opportunistically when watcher restart is detected.
|
|
244
501
|
*
|
|
245
|
-
* @module
|
|
502
|
+
* @module rules
|
|
246
503
|
*/
|
|
504
|
+
|
|
247
505
|
/**
|
|
248
|
-
*
|
|
506
|
+
* Manages virtual rule registration with watcher.
|
|
249
507
|
*
|
|
250
|
-
*
|
|
251
|
-
*
|
|
508
|
+
* - Registers at startup with exponential retry
|
|
509
|
+
* - Tracks watcher uptime for restart detection
|
|
510
|
+
* - Re-registers opportunistically when uptime decreases
|
|
252
511
|
*/
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
/**
|
|
261
|
-
|
|
262
|
-
/**
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
archives: string[];
|
|
512
|
+
declare class RuleRegistrar {
|
|
513
|
+
private readonly config;
|
|
514
|
+
private readonly logger;
|
|
515
|
+
private readonly watcherClient;
|
|
516
|
+
private lastWatcherUptime;
|
|
517
|
+
private registered;
|
|
518
|
+
constructor(config: MetaConfig, logger: Logger, watcher: WatcherClient);
|
|
519
|
+
/** Whether rules have been successfully registered. */
|
|
520
|
+
get isRegistered(): boolean;
|
|
521
|
+
/**
|
|
522
|
+
* Register rules with watcher. Retries with exponential backoff.
|
|
523
|
+
* Non-blocking — logs errors but never throws.
|
|
524
|
+
*/
|
|
525
|
+
register(): Promise<void>;
|
|
526
|
+
/**
|
|
527
|
+
* Check watcher uptime and re-register if it decreased (restart detected).
|
|
528
|
+
*
|
|
529
|
+
* @param currentUptime - Current watcher uptime in seconds.
|
|
530
|
+
*/
|
|
531
|
+
checkAndReregister(currentUptime: number): Promise<void>;
|
|
274
532
|
}
|
|
275
533
|
|
|
276
534
|
/**
|
|
277
|
-
*
|
|
535
|
+
* HTTP implementation of the WatcherClient interface.
|
|
278
536
|
*
|
|
279
|
-
*
|
|
537
|
+
* Talks to jeeves-watcher's POST /walk and POST /rules/register endpoints
|
|
538
|
+
* with retry and exponential backoff.
|
|
539
|
+
*
|
|
540
|
+
* @module watcher-client/HttpWatcherClient
|
|
280
541
|
*/
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
542
|
+
|
|
543
|
+
/** Options for creating an HttpWatcherClient. */
|
|
544
|
+
interface HttpWatcherClientOptions {
|
|
545
|
+
/** Base URL for the watcher service (e.g. "http://localhost:1936"). */
|
|
546
|
+
baseUrl: string;
|
|
547
|
+
/** Maximum retry attempts for transient failures. Default: 3. */
|
|
548
|
+
maxRetries?: number;
|
|
549
|
+
/** Base delay in ms for exponential backoff. Default: 1000. */
|
|
550
|
+
backoffBaseMs?: number;
|
|
551
|
+
/** Multiplier for backoff. Default: 4 (1s, 4s, 16s). */
|
|
552
|
+
backoffFactor?: number;
|
|
553
|
+
/** Per-request timeout in ms. Default: 10000. */
|
|
554
|
+
timeoutMs?: number;
|
|
291
555
|
}
|
|
292
|
-
/**
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
556
|
+
/**
|
|
557
|
+
* HTTP-based WatcherClient implementation with retry.
|
|
558
|
+
*/
|
|
559
|
+
declare class HttpWatcherClient implements WatcherClient {
|
|
560
|
+
private readonly baseUrl;
|
|
561
|
+
private readonly maxRetries;
|
|
562
|
+
private readonly backoffBaseMs;
|
|
563
|
+
private readonly backoffFactor;
|
|
564
|
+
private readonly timeoutMs;
|
|
565
|
+
constructor(options: HttpWatcherClientOptions);
|
|
566
|
+
/** POST JSON with retry. */
|
|
567
|
+
private post;
|
|
568
|
+
registerRules(source: string, rules: InferenceRuleSpec[]): Promise<void>;
|
|
569
|
+
walk(globs: string[]): Promise<string[]>;
|
|
570
|
+
scan(request: WatcherScanRequest): Promise<WatcherScanResult>;
|
|
298
571
|
}
|
|
572
|
+
|
|
299
573
|
/**
|
|
300
|
-
*
|
|
574
|
+
* Croner-based scheduler that discovers the stalest meta candidate each tick
|
|
575
|
+
* and enqueues it for synthesis.
|
|
301
576
|
*
|
|
302
|
-
*
|
|
303
|
-
* calls spawn() sequentially for architect, builder, and critic steps.
|
|
304
|
-
* Each call blocks until the subprocess completes and returns its result.
|
|
577
|
+
* @module scheduler
|
|
305
578
|
*/
|
|
306
|
-
|
|
579
|
+
|
|
580
|
+
/**
|
|
581
|
+
* Periodic scheduler that discovers stale meta candidates and enqueues them.
|
|
582
|
+
*
|
|
583
|
+
* Supports adaptive backoff when no candidates are found and hot-reloadable
|
|
584
|
+
* cron expressions via {@link Scheduler.updateSchedule}.
|
|
585
|
+
*/
|
|
586
|
+
declare class Scheduler {
|
|
587
|
+
private job;
|
|
588
|
+
private backoffMultiplier;
|
|
589
|
+
private tickCount;
|
|
590
|
+
private readonly config;
|
|
591
|
+
private readonly queue;
|
|
592
|
+
private readonly logger;
|
|
593
|
+
private readonly watcher;
|
|
594
|
+
private registrar;
|
|
595
|
+
private currentExpression;
|
|
596
|
+
constructor(config: ServiceConfig, queue: SynthesisQueue, logger: Logger, watcher: HttpWatcherClient);
|
|
597
|
+
/** Set the rule registrar for watcher restart detection. */
|
|
598
|
+
setRegistrar(registrar: RuleRegistrar): void;
|
|
599
|
+
/** Start the cron job. */
|
|
600
|
+
start(): void;
|
|
601
|
+
/** Stop the cron job. */
|
|
602
|
+
stop(): void;
|
|
603
|
+
/** Hot-reload the cron schedule expression. */
|
|
604
|
+
updateSchedule(expression: string): void;
|
|
605
|
+
/** Reset backoff multiplier (call after successful synthesis). */
|
|
606
|
+
resetBackoff(): void;
|
|
607
|
+
/** Whether the scheduler is currently running. */
|
|
608
|
+
get isRunning(): boolean;
|
|
609
|
+
/** Next scheduled tick time, or null if not running. */
|
|
610
|
+
get nextRunAt(): Date | null;
|
|
307
611
|
/**
|
|
308
|
-
*
|
|
612
|
+
* Single tick: discover stalest candidate and enqueue it.
|
|
309
613
|
*
|
|
310
|
-
*
|
|
311
|
-
*
|
|
312
|
-
* @returns The subprocess result with output and optional token count.
|
|
614
|
+
* Skips if the queue is currently processing. Applies adaptive backoff
|
|
615
|
+
* when no candidates are found.
|
|
313
616
|
*/
|
|
314
|
-
|
|
617
|
+
private tick;
|
|
618
|
+
/**
|
|
619
|
+
* Discover the stalest meta candidate via watcher.
|
|
620
|
+
*/
|
|
621
|
+
private discoverStalest;
|
|
315
622
|
}
|
|
316
623
|
|
|
317
624
|
/**
|
|
318
|
-
*
|
|
625
|
+
* Shared live config hot-reload support.
|
|
319
626
|
*
|
|
320
|
-
*
|
|
321
|
-
*
|
|
627
|
+
* Used by both file-watch reloads in bootstrap and POST /config/apply
|
|
628
|
+
* via the component descriptor's onConfigApply callback.
|
|
322
629
|
*
|
|
323
|
-
* @module
|
|
630
|
+
* @module configHotReload
|
|
324
631
|
*/
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
632
|
+
|
|
633
|
+
/**
|
|
634
|
+
* Fields that require a service restart to take effect.
|
|
635
|
+
*
|
|
636
|
+
* Shared between the descriptor's `onConfigApply` and the file-watcher
|
|
637
|
+
* hot-reload in `bootstrap.ts`.
|
|
638
|
+
*/
|
|
639
|
+
declare const RESTART_REQUIRED_FIELDS: readonly ["port", "host", "watcherUrl", "gatewayUrl", "gatewayApiKey", "defaultArchitect", "defaultCritic"];
|
|
640
|
+
|
|
641
|
+
/**
|
|
642
|
+
* Load and resolve jeeves-meta service config.
|
|
643
|
+
*
|
|
644
|
+
* Supports \@file: indirection and environment-variable substitution (dollar-brace pattern).
|
|
645
|
+
*
|
|
646
|
+
* @module configLoader
|
|
647
|
+
*/
|
|
648
|
+
|
|
649
|
+
/**
|
|
650
|
+
* Migrate legacy config path to the new canonical location.
|
|
651
|
+
*
|
|
652
|
+
* If the old path `{configRoot}/jeeves-meta.config.json` exists and the new
|
|
653
|
+
* path `{configRoot}/jeeves-meta/config.json` does NOT exist, copies the file
|
|
654
|
+
* to the new location and logs a warning.
|
|
655
|
+
*
|
|
656
|
+
* @param configRoot - Root directory for configuration files.
|
|
657
|
+
* @param warn - Optional callback for logging the migration warning.
|
|
658
|
+
*/
|
|
659
|
+
declare function migrateConfigPath(configRoot: string, warn?: (msg: string) => void): void;
|
|
660
|
+
/**
|
|
661
|
+
* Resolve config path from --config flag or JEEVES_META_CONFIG env var.
|
|
662
|
+
*
|
|
663
|
+
* @param args - CLI arguments (process.argv.slice(2)).
|
|
664
|
+
* @returns Resolved config path.
|
|
665
|
+
* @throws If no config path found.
|
|
666
|
+
*/
|
|
667
|
+
declare function resolveConfigPath(args: string[]): string;
|
|
668
|
+
/**
|
|
669
|
+
* Load service config from a JSON file.
|
|
670
|
+
*
|
|
671
|
+
* Resolves \@file: references for defaultArchitect and defaultCritic,
|
|
672
|
+
* and substitutes environment-variable placeholders throughout.
|
|
673
|
+
*
|
|
674
|
+
* @param configPath - Path to config JSON file.
|
|
675
|
+
* @returns Validated ServiceConfig.
|
|
676
|
+
*/
|
|
677
|
+
declare function loadServiceConfig(configPath: string): ServiceConfig;
|
|
678
|
+
|
|
342
679
|
/**
|
|
343
|
-
*
|
|
680
|
+
* Jeeves component descriptor for jeeves-meta.
|
|
344
681
|
*
|
|
345
|
-
*
|
|
682
|
+
* Single source of truth consumed by the service CLI, plugin writer, and
|
|
683
|
+
* config-apply pipeline.
|
|
684
|
+
*
|
|
685
|
+
* @module descriptor
|
|
346
686
|
*/
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
* @param rules - Array of inference rules to register.
|
|
353
|
-
*/
|
|
354
|
-
registerRules(source: string, rules: InferenceRuleSpec[]): Promise<void>;
|
|
355
|
-
/**
|
|
356
|
-
* Walk filesystem using glob patterns.
|
|
357
|
-
*
|
|
358
|
-
* @param globs - Array of glob patterns to match against.
|
|
359
|
-
* @returns Promise resolving to array of matching file paths.
|
|
360
|
-
*/
|
|
361
|
-
walk(globs: string[]): Promise<string[]>;
|
|
362
|
-
}
|
|
687
|
+
|
|
688
|
+
/**
|
|
689
|
+
* Parsed jeeves-meta component descriptor.
|
|
690
|
+
*/
|
|
691
|
+
declare const metaDescriptor: JeevesComponentDescriptor;
|
|
363
692
|
|
|
364
693
|
/**
|
|
365
694
|
* Types for meta discovery and ownership tree.
|
|
@@ -731,11 +1060,16 @@ declare class GatewayExecutor implements MetaExecutor {
|
|
|
731
1060
|
private readonly apiKey;
|
|
732
1061
|
private readonly pollIntervalMs;
|
|
733
1062
|
private readonly workspaceDir;
|
|
1063
|
+
private controller;
|
|
734
1064
|
constructor(options?: GatewayExecutorOptions);
|
|
1065
|
+
/** Remove a temp output file if it exists. */
|
|
1066
|
+
private cleanupOutputFile;
|
|
735
1067
|
/** Invoke a gateway tool via the /tools/invoke HTTP endpoint. */
|
|
736
1068
|
private invoke;
|
|
737
1069
|
/** Look up totalTokens for a session via sessions_list. */
|
|
738
1070
|
private getSessionTokens;
|
|
1071
|
+
/** Abort the currently running spawn, if any. */
|
|
1072
|
+
abort(): void;
|
|
739
1073
|
spawn(task: string, options?: MetaSpawnOptions): Promise<MetaSpawnResult>;
|
|
740
1074
|
}
|
|
741
1075
|
|
|
@@ -1065,239 +1399,6 @@ declare function isArchitectTriggered(meta: MetaJson, structureChanged: boolean,
|
|
|
1065
1399
|
*/
|
|
1066
1400
|
declare function hasSteerChanged(currentSteer: string | undefined, archiveSteer: string | undefined, hasArchive: boolean): boolean;
|
|
1067
1401
|
|
|
1068
|
-
/**
|
|
1069
|
-
* Single-threaded synthesis queue with priority support and deduplication.
|
|
1070
|
-
*
|
|
1071
|
-
* The scheduler enqueues the stalest candidate each tick. HTTP-triggered
|
|
1072
|
-
* synthesis requests get priority (inserted at front). A path appears at
|
|
1073
|
-
* most once in the queue; re-triggering returns the current position.
|
|
1074
|
-
*
|
|
1075
|
-
* @module queue
|
|
1076
|
-
*/
|
|
1077
|
-
|
|
1078
|
-
/** A queued synthesis work item. */
|
|
1079
|
-
interface QueueItem {
|
|
1080
|
-
path: string;
|
|
1081
|
-
priority: boolean;
|
|
1082
|
-
enqueuedAt: string;
|
|
1083
|
-
}
|
|
1084
|
-
/** Result returned by {@link SynthesisQueue.enqueue}. */
|
|
1085
|
-
interface EnqueueResult {
|
|
1086
|
-
position: number;
|
|
1087
|
-
alreadyQueued: boolean;
|
|
1088
|
-
}
|
|
1089
|
-
/** Snapshot of queue state for the /status endpoint. */
|
|
1090
|
-
interface QueueState {
|
|
1091
|
-
depth: number;
|
|
1092
|
-
items: Array<{
|
|
1093
|
-
path: string;
|
|
1094
|
-
priority: boolean;
|
|
1095
|
-
enqueuedAt: string;
|
|
1096
|
-
}>;
|
|
1097
|
-
}
|
|
1098
|
-
/**
|
|
1099
|
-
* Single-threaded synthesis queue.
|
|
1100
|
-
*
|
|
1101
|
-
* Only one synthesis runs at a time. Priority items are inserted at the
|
|
1102
|
-
* front of the queue. Duplicate paths are rejected with their current
|
|
1103
|
-
* position returned.
|
|
1104
|
-
*/
|
|
1105
|
-
declare class SynthesisQueue {
|
|
1106
|
-
private queue;
|
|
1107
|
-
private currentItem;
|
|
1108
|
-
private processing;
|
|
1109
|
-
private logger;
|
|
1110
|
-
private onEnqueueCallback;
|
|
1111
|
-
/**
|
|
1112
|
-
* Create a new SynthesisQueue.
|
|
1113
|
-
*
|
|
1114
|
-
* @param logger - Pino logger instance.
|
|
1115
|
-
*/
|
|
1116
|
-
constructor(logger: Logger);
|
|
1117
|
-
/**
|
|
1118
|
-
* Set a callback to invoke when a new (non-duplicate) item is enqueued.
|
|
1119
|
-
*/
|
|
1120
|
-
onEnqueue(callback: () => void): void;
|
|
1121
|
-
/**
|
|
1122
|
-
* Add a path to the synthesis queue.
|
|
1123
|
-
*
|
|
1124
|
-
* @param path - Meta path to synthesize.
|
|
1125
|
-
* @param priority - If true, insert at front of queue.
|
|
1126
|
-
* @returns Position and whether the path was already queued.
|
|
1127
|
-
*/
|
|
1128
|
-
enqueue(path: string, priority?: boolean): EnqueueResult;
|
|
1129
|
-
/**
|
|
1130
|
-
* Remove and return the next item from the queue.
|
|
1131
|
-
*
|
|
1132
|
-
* @returns The next QueueItem, or undefined if the queue is empty.
|
|
1133
|
-
*/
|
|
1134
|
-
dequeue(): QueueItem | undefined;
|
|
1135
|
-
/** Mark the currently-running synthesis as complete. */
|
|
1136
|
-
complete(): void;
|
|
1137
|
-
/** Number of items waiting in the queue (excludes current). */
|
|
1138
|
-
get depth(): number;
|
|
1139
|
-
/** The item currently being synthesized, or null. */
|
|
1140
|
-
get current(): QueueItem | null;
|
|
1141
|
-
/** A shallow copy of the queued items. */
|
|
1142
|
-
get items(): QueueItem[];
|
|
1143
|
-
/**
|
|
1144
|
-
* Check whether a path is in the queue or currently being synthesized.
|
|
1145
|
-
*
|
|
1146
|
-
* @param path - Meta path to look up.
|
|
1147
|
-
* @returns True if the path is queued or currently running.
|
|
1148
|
-
*/
|
|
1149
|
-
has(path: string): boolean;
|
|
1150
|
-
/**
|
|
1151
|
-
* Get the 0-indexed position of a path in the queue.
|
|
1152
|
-
*
|
|
1153
|
-
* @param path - Meta path to look up.
|
|
1154
|
-
* @returns Position index, or null if not found in the queue.
|
|
1155
|
-
*/
|
|
1156
|
-
getPosition(path: string): number | null;
|
|
1157
|
-
/**
|
|
1158
|
-
* Return a snapshot of queue state for the /status endpoint.
|
|
1159
|
-
*
|
|
1160
|
-
* @returns Queue depth and item list.
|
|
1161
|
-
*/
|
|
1162
|
-
getState(): QueueState;
|
|
1163
|
-
/**
|
|
1164
|
-
* Process queued items one at a time until the queue is empty.
|
|
1165
|
-
*
|
|
1166
|
-
* Re-entry is prevented: if already processing, the call returns
|
|
1167
|
-
* immediately. Errors are logged and do not block subsequent items.
|
|
1168
|
-
*
|
|
1169
|
-
* @param synthesizeFn - Async function that performs synthesis for a path.
|
|
1170
|
-
*/
|
|
1171
|
-
processQueue(synthesizeFn: (path: string) => Promise<void>): Promise<void>;
|
|
1172
|
-
}
|
|
1173
|
-
|
|
1174
|
-
/**
|
|
1175
|
-
* Virtual rule registration with jeeves-watcher.
|
|
1176
|
-
*
|
|
1177
|
-
* Service registers inference rules at startup (with retry) and
|
|
1178
|
-
* re-registers opportunistically when watcher restart is detected.
|
|
1179
|
-
*
|
|
1180
|
-
* @module rules
|
|
1181
|
-
*/
|
|
1182
|
-
|
|
1183
|
-
/**
|
|
1184
|
-
* Manages virtual rule registration with watcher.
|
|
1185
|
-
*
|
|
1186
|
-
* - Registers at startup with exponential retry
|
|
1187
|
-
* - Tracks watcher uptime for restart detection
|
|
1188
|
-
* - Re-registers opportunistically when uptime decreases
|
|
1189
|
-
*/
|
|
1190
|
-
declare class RuleRegistrar {
|
|
1191
|
-
private readonly config;
|
|
1192
|
-
private readonly logger;
|
|
1193
|
-
private readonly watcherClient;
|
|
1194
|
-
private lastWatcherUptime;
|
|
1195
|
-
private registered;
|
|
1196
|
-
constructor(config: MetaConfig, logger: Logger, watcher: WatcherClient);
|
|
1197
|
-
/** Whether rules have been successfully registered. */
|
|
1198
|
-
get isRegistered(): boolean;
|
|
1199
|
-
/**
|
|
1200
|
-
* Register rules with watcher. Retries with exponential backoff.
|
|
1201
|
-
* Non-blocking — logs errors but never throws.
|
|
1202
|
-
*/
|
|
1203
|
-
register(): Promise<void>;
|
|
1204
|
-
/**
|
|
1205
|
-
* Check watcher uptime and re-register if it decreased (restart detected).
|
|
1206
|
-
*
|
|
1207
|
-
* @param currentUptime - Current watcher uptime in seconds.
|
|
1208
|
-
*/
|
|
1209
|
-
checkAndReregister(currentUptime: number): Promise<void>;
|
|
1210
|
-
}
|
|
1211
|
-
|
|
1212
|
-
/**
|
|
1213
|
-
* HTTP implementation of the WatcherClient interface.
|
|
1214
|
-
*
|
|
1215
|
-
* Talks to jeeves-watcher's POST /walk and POST /rules/register endpoints
|
|
1216
|
-
* with retry and exponential backoff.
|
|
1217
|
-
*
|
|
1218
|
-
* @module watcher-client/HttpWatcherClient
|
|
1219
|
-
*/
|
|
1220
|
-
|
|
1221
|
-
/** Options for creating an HttpWatcherClient. */
|
|
1222
|
-
interface HttpWatcherClientOptions {
|
|
1223
|
-
/** Base URL for the watcher service (e.g. "http://localhost:1936"). */
|
|
1224
|
-
baseUrl: string;
|
|
1225
|
-
/** Maximum retry attempts for transient failures. Default: 3. */
|
|
1226
|
-
maxRetries?: number;
|
|
1227
|
-
/** Base delay in ms for exponential backoff. Default: 1000. */
|
|
1228
|
-
backoffBaseMs?: number;
|
|
1229
|
-
/** Multiplier for backoff. Default: 4 (1s, 4s, 16s). */
|
|
1230
|
-
backoffFactor?: number;
|
|
1231
|
-
/** Per-request timeout in ms. Default: 10000. */
|
|
1232
|
-
timeoutMs?: number;
|
|
1233
|
-
}
|
|
1234
|
-
/**
|
|
1235
|
-
* HTTP-based WatcherClient implementation with retry.
|
|
1236
|
-
*/
|
|
1237
|
-
declare class HttpWatcherClient implements WatcherClient {
|
|
1238
|
-
private readonly baseUrl;
|
|
1239
|
-
private readonly maxRetries;
|
|
1240
|
-
private readonly backoffBaseMs;
|
|
1241
|
-
private readonly backoffFactor;
|
|
1242
|
-
private readonly timeoutMs;
|
|
1243
|
-
constructor(options: HttpWatcherClientOptions);
|
|
1244
|
-
/** POST JSON with retry. */
|
|
1245
|
-
private post;
|
|
1246
|
-
registerRules(source: string, rules: InferenceRuleSpec[]): Promise<void>;
|
|
1247
|
-
walk(globs: string[]): Promise<string[]>;
|
|
1248
|
-
}
|
|
1249
|
-
|
|
1250
|
-
/**
|
|
1251
|
-
* Croner-based scheduler that discovers the stalest meta candidate each tick
|
|
1252
|
-
* and enqueues it for synthesis.
|
|
1253
|
-
*
|
|
1254
|
-
* @module scheduler
|
|
1255
|
-
*/
|
|
1256
|
-
|
|
1257
|
-
/**
|
|
1258
|
-
* Periodic scheduler that discovers stale meta candidates and enqueues them.
|
|
1259
|
-
*
|
|
1260
|
-
* Supports adaptive backoff when no candidates are found and hot-reloadable
|
|
1261
|
-
* cron expressions via {@link Scheduler.updateSchedule}.
|
|
1262
|
-
*/
|
|
1263
|
-
declare class Scheduler {
|
|
1264
|
-
private job;
|
|
1265
|
-
private backoffMultiplier;
|
|
1266
|
-
private tickCount;
|
|
1267
|
-
private readonly config;
|
|
1268
|
-
private readonly queue;
|
|
1269
|
-
private readonly logger;
|
|
1270
|
-
private readonly watcher;
|
|
1271
|
-
private registrar;
|
|
1272
|
-
private currentExpression;
|
|
1273
|
-
constructor(config: ServiceConfig, queue: SynthesisQueue, logger: Logger, watcher: HttpWatcherClient);
|
|
1274
|
-
/** Set the rule registrar for watcher restart detection. */
|
|
1275
|
-
setRegistrar(registrar: RuleRegistrar): void;
|
|
1276
|
-
/** Start the cron job. */
|
|
1277
|
-
start(): void;
|
|
1278
|
-
/** Stop the cron job. */
|
|
1279
|
-
stop(): void;
|
|
1280
|
-
/** Hot-reload the cron schedule expression. */
|
|
1281
|
-
updateSchedule(expression: string): void;
|
|
1282
|
-
/** Reset backoff multiplier (call after successful synthesis). */
|
|
1283
|
-
resetBackoff(): void;
|
|
1284
|
-
/** Whether the scheduler is currently running. */
|
|
1285
|
-
get isRunning(): boolean;
|
|
1286
|
-
/** Next scheduled tick time, or null if not running. */
|
|
1287
|
-
get nextRunAt(): Date | null;
|
|
1288
|
-
/**
|
|
1289
|
-
* Single tick: discover stalest candidate and enqueue it.
|
|
1290
|
-
*
|
|
1291
|
-
* Skips if the queue is currently processing. Applies adaptive backoff
|
|
1292
|
-
* when no candidates are found.
|
|
1293
|
-
*/
|
|
1294
|
-
private tick;
|
|
1295
|
-
/**
|
|
1296
|
-
* Discover the stalest meta candidate via watcher.
|
|
1297
|
-
*/
|
|
1298
|
-
private discoverStalest;
|
|
1299
|
-
}
|
|
1300
|
-
|
|
1301
1402
|
/**
|
|
1302
1403
|
* Route registration for jeeves-meta service.
|
|
1303
1404
|
*
|
|
@@ -1317,11 +1418,13 @@ interface RouteDeps {
|
|
|
1317
1418
|
config: ServiceConfig;
|
|
1318
1419
|
logger: Logger;
|
|
1319
1420
|
queue: SynthesisQueue;
|
|
1320
|
-
watcher:
|
|
1421
|
+
watcher: WatcherClient;
|
|
1321
1422
|
scheduler: Scheduler | null;
|
|
1322
1423
|
stats: ServiceStats;
|
|
1323
1424
|
/** Rule registrar for reporting registration state in /status. */
|
|
1324
1425
|
registrar?: RuleRegistrar;
|
|
1426
|
+
/** Executor instance for abort support. */
|
|
1427
|
+
executor?: Pick<GatewayExecutor, 'abort'>;
|
|
1325
1428
|
/** Set to true during graceful shutdown. */
|
|
1326
1429
|
shuttingDown?: boolean;
|
|
1327
1430
|
}
|
|
@@ -1416,5 +1519,5 @@ declare function registerShutdownHandlers(deps: ShutdownDeps): void;
|
|
|
1416
1519
|
*/
|
|
1417
1520
|
declare function startService(config: ServiceConfig, configPath?: string): Promise<void>;
|
|
1418
1521
|
|
|
1419
|
-
export { DEFAULT_PORT, DEFAULT_PORT_STR, GatewayExecutor, HttpWatcherClient, ProgressReporter, RuleRegistrar, SERVICE_NAME, SERVICE_VERSION, Scheduler, SynthesisQueue, acquireLock, actualStaleness, buildArchitectTask, buildBuilderTask, buildContextPackage, buildCriticTask, buildOwnershipTree, cleanupStaleLocks, computeEffectiveStaleness, computeEma, computeStructureHash, createLogger, createServer, createSnapshot, discoverMetas, filterInScope, findNode, formatProgressEvent, getScopePrefix, hasSteerChanged, isArchitectTriggered, isLocked, isStale, listArchiveFiles, listMetas, loadServiceConfig, mergeAndWrite, metaConfigSchema, metaErrorSchema, metaJsonSchema, normalizePath, orchestrate, parseArchitectOutput, parseBuilderOutput, parseCriticOutput, pruneArchive, readLatestArchive, readLockState, registerRoutes, registerShutdownHandlers, releaseLock, resolveConfigPath, resolveMetaDir, selectCandidate, serviceConfigSchema, sleep, startService, toMetaError, verifyRuleApplication };
|
|
1420
|
-
export type { BuilderOutput, EnqueueResult, GatewayExecutorOptions, HttpWatcherClientOptions, InferenceRuleSpec, LockState, LoggerConfig, MergeOptions, MetaConfig, MetaContext, MetaEntry, MetaError, MetaExecutor, MetaJson, MetaListResult, MetaListSummary, MetaNode, MetaSpawnOptions, MetaSpawnResult, MinimalLogger, OrchestrateResult, OwnershipTree, ProgressCallback, ProgressEvent, ProgressPhase, ProgressReporterConfig, QueueItem, QueueState, RouteDeps, ServerOptions, ServiceConfig, ServiceStats, StalenessCandidate, WatcherClient };
|
|
1522
|
+
export { DEFAULT_PORT, DEFAULT_PORT_STR, GatewayExecutor, HttpWatcherClient, ProgressReporter, RESTART_REQUIRED_FIELDS, RuleRegistrar, SERVICE_NAME, SERVICE_VERSION, Scheduler, SynthesisQueue, acquireLock, actualStaleness, buildArchitectTask, buildBuilderTask, buildContextPackage, buildCriticTask, buildOwnershipTree, cleanupStaleLocks, computeEffectiveStaleness, computeEma, computeStructureHash, createLogger, createServer, createSnapshot, discoverMetas, filterInScope, findNode, formatProgressEvent, getScopePrefix, hasSteerChanged, isArchitectTriggered, isLocked, isStale, listArchiveFiles, listMetas, loadServiceConfig, mergeAndWrite, metaConfigSchema, metaDescriptor, metaErrorSchema, metaJsonSchema, migrateConfigPath, normalizePath, orchestrate, parseArchitectOutput, parseBuilderOutput, parseCriticOutput, pruneArchive, readLatestArchive, readLockState, registerCustomCliCommands, registerRoutes, registerShutdownHandlers, releaseLock, resolveConfigPath, resolveMetaDir, selectCandidate, serviceConfigSchema, sleep, startService, toMetaError, verifyRuleApplication };
|
|
1523
|
+
export type { BuilderOutput, EnqueueResult, GatewayExecutorOptions, HttpWatcherClientOptions, InferenceRuleSpec, LockState, LoggerConfig, MergeOptions, MetaConfig, MetaContext, MetaEntry, MetaError, MetaExecutor, MetaJson, MetaListResult, MetaListSummary, MetaNode, MetaSpawnOptions, MetaSpawnResult, MinimalLogger, OrchestrateResult, OwnershipTree, ProgressCallback, ProgressEvent, ProgressPhase, ProgressReporterConfig, QueueItem, QueueState, RouteDeps, ServerOptions, ServiceConfig, ServiceStats, StalenessCandidate, WatcherClient, WatcherScanPoint, WatcherScanRequest, WatcherScanResult };
|