@harness-engineering/orchestrator 0.9.2 → 0.11.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/dist/index.d.mts +123 -4
- package/dist/index.d.ts +123 -4
- package/dist/index.js +1017 -70
- package/dist/index.mjs +1005 -46
- package/package.json +8 -7
package/dist/index.d.mts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import * as _harness_engineering_types from '@harness-engineering/types';
|
|
2
2
|
import { Issue, AgentEvent, WorkflowConfig, TokenUsage, ConcernSignal, ScopeTier, EscalationConfig, IssueRoutingDecision, Result, WorkflowDefinition, BackendDef, RoutingConfig, WorkspaceConfig, HooksConfig, AgentBackend, SessionStartParams, AgentSession, AgentError, TurnParams, TurnResult, CheckScriptDefinition, OutputRetentionConfig, RoutingDecision, RoutingUseCase, ContainerConfig, SecretConfig, AgentConfig, LocalModelStatus, CustomTaskDefinition, MaintenanceConfig, TokenScope, AuthToken, AuthTokenPublic, IndexedFileKind, SessionSearchResult, ReindexStats, SessionSummarizationConfig, SessionSummary, SessionSummaryMeta, SessionsConfig, GatewayEvent, NotificationEnvelope, NotificationDeliveryResult, NotificationSinkConfig, NotificationsConfig } from '@harness-engineering/types';
|
|
3
|
-
import { IssueTrackerClient, Issue as Issue$1, TrackerConfig, eventSourcing, CacheMetricsRecorder, ArchiveHooks, SkillProposal, ProposalGateFinding } from '@harness-engineering/core';
|
|
3
|
+
import { IssueTrackerClient, Issue as Issue$1, TrackerConfig, eventSourcing, CacheMetricsRecorder, ArchiveHooks, SkillProposal, ProposalGateFinding, SkillKind } from '@harness-engineering/core';
|
|
4
4
|
import { EnrichedSpec, ComplexityScore, SimulationResult, IntelligencePipeline, WeightedRecommendation, AnalysisProvider } from '@harness-engineering/intelligence';
|
|
5
5
|
import { GraphStore } from '@harness-engineering/graph';
|
|
6
6
|
import { execFile } from 'node:child_process';
|
|
7
7
|
import { EventEmitter } from 'node:events';
|
|
8
|
+
import { PoolStateProvider, SchedulerTimerHandle } from '@harness-engineering/local-models';
|
|
8
9
|
import { z } from 'zod';
|
|
9
10
|
|
|
10
11
|
/**
|
|
@@ -1697,6 +1698,45 @@ declare class Orchestrator extends EventEmitter {
|
|
|
1697
1698
|
* so this map is the single source of truth post-migration.
|
|
1698
1699
|
*/
|
|
1699
1700
|
private localResolvers;
|
|
1701
|
+
/** Phase 4 (D5): pool-state port shared by all local/pi resolvers. Null when LMLM disabled. */
|
|
1702
|
+
private poolStateProvider;
|
|
1703
|
+
private poolStateStore;
|
|
1704
|
+
/**
|
|
1705
|
+
* LMLM Phase 6: live model pool + its installer. Constructed only when
|
|
1706
|
+
* `localModels.enabled` and a real `PoolStateStore` exists (not a test
|
|
1707
|
+
* override). Exposed to the server via `getModelPool()`, which retires the
|
|
1708
|
+
* proposals-route 501 stub for `kind: 'model'` approve/reject. Null when LMLM
|
|
1709
|
+
* is disabled. `PoolManager` reads `store.snapshot()` lazily, so constructing
|
|
1710
|
+
* before `store.load()` (in initLocalModelAndPipeline) is safe.
|
|
1711
|
+
*/
|
|
1712
|
+
private modelPool;
|
|
1713
|
+
private modelInstaller;
|
|
1714
|
+
/**
|
|
1715
|
+
* S1 drain re-entrancy guard (P7-SUG-DRAIN-REENTRANCY). `drainDeferredEvictions`
|
|
1716
|
+
* is fired fire-and-forget from `emitWorkerExit` (and, since P7-SUG-DRAIN-LIVENESS,
|
|
1717
|
+
* piggybacked on each refresh tick). Two overlapping drains would both read the
|
|
1718
|
+
* same `listPendingEvictions()` snapshot, both re-check `isLocalModelInUse`, and
|
|
1719
|
+
* both `await pool.evict` the SAME name — double-calling the installer and
|
|
1720
|
+
* broadcasting a duplicate `evict_completed` frame. The single-threaded event
|
|
1721
|
+
* loop makes a plain boolean sufficient: a drain that arrives while one is
|
|
1722
|
+
* running returns early rather than double-processing.
|
|
1723
|
+
*/
|
|
1724
|
+
private draining;
|
|
1725
|
+
/**
|
|
1726
|
+
* LMLM Phase 6: single per-instance background refresh scheduler. Started in
|
|
1727
|
+
* `initLocalModelAndPipeline` when the pool exists; stopped in `stop()`. Null
|
|
1728
|
+
* when LMLM is disabled. Exposed to the server via `getRefreshScheduler()`.
|
|
1729
|
+
*/
|
|
1730
|
+
private refreshScheduler;
|
|
1731
|
+
/**
|
|
1732
|
+
* LMLM Phase 7: the hardware-aware recommender bound at scheduler start. Reused
|
|
1733
|
+
* by `GET /api/v1/local-models/recommendations`. Null when LMLM is disabled (no
|
|
1734
|
+
* pool → scheduler never armed). Ranks the (currently empty) candidate set —
|
|
1735
|
+
* see the Phase 2 candidate-parser gap noted on `startRefreshScheduler`.
|
|
1736
|
+
*/
|
|
1737
|
+
private modelRecommender;
|
|
1738
|
+
/** Test seam: injected timer/clock for the scheduler so no real 24h timer runs. */
|
|
1739
|
+
private readonly schedulerTimerOverride;
|
|
1700
1740
|
/**
|
|
1701
1741
|
* Spec B Phase 3: skill catalog (name + cognitiveMode) read once at
|
|
1702
1742
|
* construction from `projectRoot/agents/skills/`. Consulted by
|
|
@@ -1765,6 +1805,14 @@ declare class Orchestrator extends EventEmitter {
|
|
|
1765
1805
|
tracker?: IssueTrackerClient;
|
|
1766
1806
|
backend?: AgentBackend;
|
|
1767
1807
|
execFileFn?: ExecFileFn$1;
|
|
1808
|
+
poolState?: PoolStateProvider;
|
|
1809
|
+
/** LMLM Phase 6 test seam: inject the RefreshScheduler timer/clock. */
|
|
1810
|
+
schedulerTimer?: {
|
|
1811
|
+
setTimer?: (cb: () => void, delayMs: number) => SchedulerTimerHandle;
|
|
1812
|
+
clearTimer?: (handle: SchedulerTimerHandle) => void;
|
|
1813
|
+
now?: () => number;
|
|
1814
|
+
random?: () => number;
|
|
1815
|
+
};
|
|
1768
1816
|
});
|
|
1769
1817
|
/**
|
|
1770
1818
|
* Phase 5: construct the OTLP/HTTP trace exporter and wire telemetry fanout.
|
|
@@ -1784,6 +1832,29 @@ declare class Orchestrator extends EventEmitter {
|
|
|
1784
1832
|
* with its backendName + endpoint from the config.
|
|
1785
1833
|
*/
|
|
1786
1834
|
private buildLocalModelStatuses;
|
|
1835
|
+
/**
|
|
1836
|
+
* S1 conservative in-use probe (ADR 0060). Returns `true` when ANY agent run
|
|
1837
|
+
* is live AND `ollamaName` is a currently-resolved (or last-detected) local
|
|
1838
|
+
* model — i.e. an agent could be routing inference to it right now.
|
|
1839
|
+
*
|
|
1840
|
+
* This signal is AGENT-RUN-COARSE, not per-request: `state.running` is keyed
|
|
1841
|
+
* by GitHub issue (spawned agent runs), NOT by inference call, and no
|
|
1842
|
+
* per-model request counter exists today. The probe therefore MAY OVER-DEFER
|
|
1843
|
+
* (a swap waits until the pool is idle). Over-deferral is exactly S1's
|
|
1844
|
+
* intended safe failure — never yank a model mid-request; occasionally wait
|
|
1845
|
+
* longer than strictly necessary. A fine-grained per-request signal is an
|
|
1846
|
+
* explicit deferred gap (ADR 0060).
|
|
1847
|
+
*/
|
|
1848
|
+
private isLocalModelInUse;
|
|
1849
|
+
/**
|
|
1850
|
+
* S1 drain (ADR 0060): complete any eviction that was DEFERRED because its
|
|
1851
|
+
* target was in use, now that the probe reports it idle. Best-effort — called
|
|
1852
|
+
* from the run-completion path; it never blocks dispatch and swallows
|
|
1853
|
+
* per-model errors (a failed or still-busy evict stays pending for the next
|
|
1854
|
+
* drain). `pendingEviction` is a transient overlay, so a missed drain simply
|
|
1855
|
+
* leaves the flag set until the next completion re-checks it.
|
|
1856
|
+
*/
|
|
1857
|
+
private drainDeferredEvictions;
|
|
1787
1858
|
private createTracker;
|
|
1788
1859
|
/**
|
|
1789
1860
|
* Creates a TaskRunner for the maintenance scheduler.
|
|
@@ -1914,6 +1985,40 @@ declare class Orchestrator extends EventEmitter {
|
|
|
1914
1985
|
* before constructing the intelligence pipeline. Subscribes the dashboard
|
|
1915
1986
|
* broadcast stub to status changes. Called exactly once from start().
|
|
1916
1987
|
*/
|
|
1988
|
+
/**
|
|
1989
|
+
* LMLM Phase 6: construct the live `PoolManager` (Ollama installer + the
|
|
1990
|
+
* loaded pool-state store) and stash it for `getModelPool()`. Defensive
|
|
1991
|
+
* config fallbacks: `ollamaEndpoint → http://localhost:11434`. The pool reads
|
|
1992
|
+
* `store.snapshot()` lazily, so this runs safely at construction time before
|
|
1993
|
+
* `store.load()`.
|
|
1994
|
+
*/
|
|
1995
|
+
private initModelPool;
|
|
1996
|
+
/**
|
|
1997
|
+
* LMLM Phase 7 wiring: apply the operator's configured pool bounds (disk
|
|
1998
|
+
* budget + org/family allowlist) from `localModels.pool` to the live pool.
|
|
1999
|
+
* Called after `PoolStateStore.load()` so config wins over persisted bounds
|
|
2000
|
+
* (D2, declarative precedence). No-op when the pool is null (LMLM disabled)
|
|
2001
|
+
* or no `pool` block is configured, so it is safe to call unconditionally
|
|
2002
|
+
* on the startup path.
|
|
2003
|
+
*/
|
|
2004
|
+
private applyConfiguredPoolBounds;
|
|
2005
|
+
/**
|
|
2006
|
+
* LMLM Phase 6: arm the single background refresh scheduler over the live
|
|
2007
|
+
* pool. No-op when LMLM is disabled (`modelPool` null). Each tick runs
|
|
2008
|
+
* hardware→recommend→reconcile(D12 drift)→diff→emit→score-writeback.
|
|
2009
|
+
*
|
|
2010
|
+
* NOTE (deferred): the recommender is seeded with an empty candidate set —
|
|
2011
|
+
* Phase 2's live-HF→RankerCandidate parser was never built, so autonomous
|
|
2012
|
+
* swap-proposal discovery is out of scope here (flagged concern). The tick
|
|
2013
|
+
* still performs F10 drift reconciliation, O1 logging, and re-ranks/dedups
|
|
2014
|
+
* whatever candidates are supplied — the wiring is complete and candidate
|
|
2015
|
+
* breadth is the only piece deferred to the Phase 2 recommender.
|
|
2016
|
+
*/
|
|
2017
|
+
private startRefreshScheduler;
|
|
2018
|
+
/** Resolve the hardware profile for a refresh tick (operator override wins). */
|
|
2019
|
+
private detectLmlmHardware;
|
|
2020
|
+
/** Map the on-disk model-proposal queue to F7 dedup pairs (open→pending, rejected→rejected). */
|
|
2021
|
+
private lmlmDedupSource;
|
|
1917
2022
|
private initLocalModelAndPipeline;
|
|
1918
2023
|
/**
|
|
1919
2024
|
* Starts the polling loop and the internal HTTP server.
|
|
@@ -2337,6 +2442,13 @@ interface LocalModelResolverOptions {
|
|
|
2337
2442
|
apiKey?: string;
|
|
2338
2443
|
/** Normalized candidate list (already turned from string|string[] into string[]). */
|
|
2339
2444
|
configured: string[];
|
|
2445
|
+
/**
|
|
2446
|
+
* Phase 4 (D5): optional read-only pool-state port. When provided, the
|
|
2447
|
+
* candidate list derives from pool entries (currentScore desc → ollamaName)
|
|
2448
|
+
* instead of `configured`. When absent (default), behavior is byte-identical
|
|
2449
|
+
* to the pre-Phase-4 resolver.
|
|
2450
|
+
*/
|
|
2451
|
+
poolState?: PoolStateProvider;
|
|
2340
2452
|
/** Probe cadence in ms; default 30_000, minimum 1_000. */
|
|
2341
2453
|
probeIntervalMs?: number;
|
|
2342
2454
|
/**
|
|
@@ -2367,6 +2479,7 @@ declare class LocalModelResolver {
|
|
|
2367
2479
|
private readonly endpoint;
|
|
2368
2480
|
private readonly apiKey?;
|
|
2369
2481
|
private readonly configured;
|
|
2482
|
+
private readonly poolState?;
|
|
2370
2483
|
private readonly probeIntervalMs;
|
|
2371
2484
|
private readonly fetchModels;
|
|
2372
2485
|
private readonly logger;
|
|
@@ -2391,6 +2504,12 @@ declare class LocalModelResolver {
|
|
|
2391
2504
|
constructor(opts: LocalModelResolverOptions);
|
|
2392
2505
|
resolveModel(): string | null;
|
|
2393
2506
|
getStatus(): LocalModelStatus;
|
|
2507
|
+
/**
|
|
2508
|
+
* Effective candidate list. With a poolState port present the list derives
|
|
2509
|
+
* from pool entries (currentScore desc → ollamaName); otherwise the static
|
|
2510
|
+
* `configured` list is returned unchanged (byte-identical to pre-Phase-4).
|
|
2511
|
+
*/
|
|
2512
|
+
private candidates;
|
|
2394
2513
|
onStatusChange(handler: (status: LocalModelStatus) => void): () => void;
|
|
2395
2514
|
probe(): Promise<LocalModelStatus>;
|
|
2396
2515
|
private runProbe;
|
|
@@ -3520,7 +3639,7 @@ declare function promote(projectPath: string, proposalId: string, decidedBy: str
|
|
|
3520
3639
|
*/
|
|
3521
3640
|
interface ProposalCreatedData {
|
|
3522
3641
|
id: string;
|
|
3523
|
-
kind:
|
|
3642
|
+
kind: SkillKind;
|
|
3524
3643
|
name: string;
|
|
3525
3644
|
targetSkill?: string;
|
|
3526
3645
|
proposedBy: string;
|
|
@@ -3528,14 +3647,14 @@ interface ProposalCreatedData {
|
|
|
3528
3647
|
}
|
|
3529
3648
|
interface ProposalApprovedData {
|
|
3530
3649
|
id: string;
|
|
3531
|
-
kind:
|
|
3650
|
+
kind: SkillKind;
|
|
3532
3651
|
name: string;
|
|
3533
3652
|
targetSkill?: string;
|
|
3534
3653
|
decidedBy: string;
|
|
3535
3654
|
}
|
|
3536
3655
|
interface ProposalRejectedData {
|
|
3537
3656
|
id: string;
|
|
3538
|
-
kind:
|
|
3657
|
+
kind: SkillKind;
|
|
3539
3658
|
name: string;
|
|
3540
3659
|
decidedBy: string;
|
|
3541
3660
|
reason: string;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import * as _harness_engineering_types from '@harness-engineering/types';
|
|
2
2
|
import { Issue, AgentEvent, WorkflowConfig, TokenUsage, ConcernSignal, ScopeTier, EscalationConfig, IssueRoutingDecision, Result, WorkflowDefinition, BackendDef, RoutingConfig, WorkspaceConfig, HooksConfig, AgentBackend, SessionStartParams, AgentSession, AgentError, TurnParams, TurnResult, CheckScriptDefinition, OutputRetentionConfig, RoutingDecision, RoutingUseCase, ContainerConfig, SecretConfig, AgentConfig, LocalModelStatus, CustomTaskDefinition, MaintenanceConfig, TokenScope, AuthToken, AuthTokenPublic, IndexedFileKind, SessionSearchResult, ReindexStats, SessionSummarizationConfig, SessionSummary, SessionSummaryMeta, SessionsConfig, GatewayEvent, NotificationEnvelope, NotificationDeliveryResult, NotificationSinkConfig, NotificationsConfig } from '@harness-engineering/types';
|
|
3
|
-
import { IssueTrackerClient, Issue as Issue$1, TrackerConfig, eventSourcing, CacheMetricsRecorder, ArchiveHooks, SkillProposal, ProposalGateFinding } from '@harness-engineering/core';
|
|
3
|
+
import { IssueTrackerClient, Issue as Issue$1, TrackerConfig, eventSourcing, CacheMetricsRecorder, ArchiveHooks, SkillProposal, ProposalGateFinding, SkillKind } from '@harness-engineering/core';
|
|
4
4
|
import { EnrichedSpec, ComplexityScore, SimulationResult, IntelligencePipeline, WeightedRecommendation, AnalysisProvider } from '@harness-engineering/intelligence';
|
|
5
5
|
import { GraphStore } from '@harness-engineering/graph';
|
|
6
6
|
import { execFile } from 'node:child_process';
|
|
7
7
|
import { EventEmitter } from 'node:events';
|
|
8
|
+
import { PoolStateProvider, SchedulerTimerHandle } from '@harness-engineering/local-models';
|
|
8
9
|
import { z } from 'zod';
|
|
9
10
|
|
|
10
11
|
/**
|
|
@@ -1697,6 +1698,45 @@ declare class Orchestrator extends EventEmitter {
|
|
|
1697
1698
|
* so this map is the single source of truth post-migration.
|
|
1698
1699
|
*/
|
|
1699
1700
|
private localResolvers;
|
|
1701
|
+
/** Phase 4 (D5): pool-state port shared by all local/pi resolvers. Null when LMLM disabled. */
|
|
1702
|
+
private poolStateProvider;
|
|
1703
|
+
private poolStateStore;
|
|
1704
|
+
/**
|
|
1705
|
+
* LMLM Phase 6: live model pool + its installer. Constructed only when
|
|
1706
|
+
* `localModels.enabled` and a real `PoolStateStore` exists (not a test
|
|
1707
|
+
* override). Exposed to the server via `getModelPool()`, which retires the
|
|
1708
|
+
* proposals-route 501 stub for `kind: 'model'` approve/reject. Null when LMLM
|
|
1709
|
+
* is disabled. `PoolManager` reads `store.snapshot()` lazily, so constructing
|
|
1710
|
+
* before `store.load()` (in initLocalModelAndPipeline) is safe.
|
|
1711
|
+
*/
|
|
1712
|
+
private modelPool;
|
|
1713
|
+
private modelInstaller;
|
|
1714
|
+
/**
|
|
1715
|
+
* S1 drain re-entrancy guard (P7-SUG-DRAIN-REENTRANCY). `drainDeferredEvictions`
|
|
1716
|
+
* is fired fire-and-forget from `emitWorkerExit` (and, since P7-SUG-DRAIN-LIVENESS,
|
|
1717
|
+
* piggybacked on each refresh tick). Two overlapping drains would both read the
|
|
1718
|
+
* same `listPendingEvictions()` snapshot, both re-check `isLocalModelInUse`, and
|
|
1719
|
+
* both `await pool.evict` the SAME name — double-calling the installer and
|
|
1720
|
+
* broadcasting a duplicate `evict_completed` frame. The single-threaded event
|
|
1721
|
+
* loop makes a plain boolean sufficient: a drain that arrives while one is
|
|
1722
|
+
* running returns early rather than double-processing.
|
|
1723
|
+
*/
|
|
1724
|
+
private draining;
|
|
1725
|
+
/**
|
|
1726
|
+
* LMLM Phase 6: single per-instance background refresh scheduler. Started in
|
|
1727
|
+
* `initLocalModelAndPipeline` when the pool exists; stopped in `stop()`. Null
|
|
1728
|
+
* when LMLM is disabled. Exposed to the server via `getRefreshScheduler()`.
|
|
1729
|
+
*/
|
|
1730
|
+
private refreshScheduler;
|
|
1731
|
+
/**
|
|
1732
|
+
* LMLM Phase 7: the hardware-aware recommender bound at scheduler start. Reused
|
|
1733
|
+
* by `GET /api/v1/local-models/recommendations`. Null when LMLM is disabled (no
|
|
1734
|
+
* pool → scheduler never armed). Ranks the (currently empty) candidate set —
|
|
1735
|
+
* see the Phase 2 candidate-parser gap noted on `startRefreshScheduler`.
|
|
1736
|
+
*/
|
|
1737
|
+
private modelRecommender;
|
|
1738
|
+
/** Test seam: injected timer/clock for the scheduler so no real 24h timer runs. */
|
|
1739
|
+
private readonly schedulerTimerOverride;
|
|
1700
1740
|
/**
|
|
1701
1741
|
* Spec B Phase 3: skill catalog (name + cognitiveMode) read once at
|
|
1702
1742
|
* construction from `projectRoot/agents/skills/`. Consulted by
|
|
@@ -1765,6 +1805,14 @@ declare class Orchestrator extends EventEmitter {
|
|
|
1765
1805
|
tracker?: IssueTrackerClient;
|
|
1766
1806
|
backend?: AgentBackend;
|
|
1767
1807
|
execFileFn?: ExecFileFn$1;
|
|
1808
|
+
poolState?: PoolStateProvider;
|
|
1809
|
+
/** LMLM Phase 6 test seam: inject the RefreshScheduler timer/clock. */
|
|
1810
|
+
schedulerTimer?: {
|
|
1811
|
+
setTimer?: (cb: () => void, delayMs: number) => SchedulerTimerHandle;
|
|
1812
|
+
clearTimer?: (handle: SchedulerTimerHandle) => void;
|
|
1813
|
+
now?: () => number;
|
|
1814
|
+
random?: () => number;
|
|
1815
|
+
};
|
|
1768
1816
|
});
|
|
1769
1817
|
/**
|
|
1770
1818
|
* Phase 5: construct the OTLP/HTTP trace exporter and wire telemetry fanout.
|
|
@@ -1784,6 +1832,29 @@ declare class Orchestrator extends EventEmitter {
|
|
|
1784
1832
|
* with its backendName + endpoint from the config.
|
|
1785
1833
|
*/
|
|
1786
1834
|
private buildLocalModelStatuses;
|
|
1835
|
+
/**
|
|
1836
|
+
* S1 conservative in-use probe (ADR 0060). Returns `true` when ANY agent run
|
|
1837
|
+
* is live AND `ollamaName` is a currently-resolved (or last-detected) local
|
|
1838
|
+
* model — i.e. an agent could be routing inference to it right now.
|
|
1839
|
+
*
|
|
1840
|
+
* This signal is AGENT-RUN-COARSE, not per-request: `state.running` is keyed
|
|
1841
|
+
* by GitHub issue (spawned agent runs), NOT by inference call, and no
|
|
1842
|
+
* per-model request counter exists today. The probe therefore MAY OVER-DEFER
|
|
1843
|
+
* (a swap waits until the pool is idle). Over-deferral is exactly S1's
|
|
1844
|
+
* intended safe failure — never yank a model mid-request; occasionally wait
|
|
1845
|
+
* longer than strictly necessary. A fine-grained per-request signal is an
|
|
1846
|
+
* explicit deferred gap (ADR 0060).
|
|
1847
|
+
*/
|
|
1848
|
+
private isLocalModelInUse;
|
|
1849
|
+
/**
|
|
1850
|
+
* S1 drain (ADR 0060): complete any eviction that was DEFERRED because its
|
|
1851
|
+
* target was in use, now that the probe reports it idle. Best-effort — called
|
|
1852
|
+
* from the run-completion path; it never blocks dispatch and swallows
|
|
1853
|
+
* per-model errors (a failed or still-busy evict stays pending for the next
|
|
1854
|
+
* drain). `pendingEviction` is a transient overlay, so a missed drain simply
|
|
1855
|
+
* leaves the flag set until the next completion re-checks it.
|
|
1856
|
+
*/
|
|
1857
|
+
private drainDeferredEvictions;
|
|
1787
1858
|
private createTracker;
|
|
1788
1859
|
/**
|
|
1789
1860
|
* Creates a TaskRunner for the maintenance scheduler.
|
|
@@ -1914,6 +1985,40 @@ declare class Orchestrator extends EventEmitter {
|
|
|
1914
1985
|
* before constructing the intelligence pipeline. Subscribes the dashboard
|
|
1915
1986
|
* broadcast stub to status changes. Called exactly once from start().
|
|
1916
1987
|
*/
|
|
1988
|
+
/**
|
|
1989
|
+
* LMLM Phase 6: construct the live `PoolManager` (Ollama installer + the
|
|
1990
|
+
* loaded pool-state store) and stash it for `getModelPool()`. Defensive
|
|
1991
|
+
* config fallbacks: `ollamaEndpoint → http://localhost:11434`. The pool reads
|
|
1992
|
+
* `store.snapshot()` lazily, so this runs safely at construction time before
|
|
1993
|
+
* `store.load()`.
|
|
1994
|
+
*/
|
|
1995
|
+
private initModelPool;
|
|
1996
|
+
/**
|
|
1997
|
+
* LMLM Phase 7 wiring: apply the operator's configured pool bounds (disk
|
|
1998
|
+
* budget + org/family allowlist) from `localModels.pool` to the live pool.
|
|
1999
|
+
* Called after `PoolStateStore.load()` so config wins over persisted bounds
|
|
2000
|
+
* (D2, declarative precedence). No-op when the pool is null (LMLM disabled)
|
|
2001
|
+
* or no `pool` block is configured, so it is safe to call unconditionally
|
|
2002
|
+
* on the startup path.
|
|
2003
|
+
*/
|
|
2004
|
+
private applyConfiguredPoolBounds;
|
|
2005
|
+
/**
|
|
2006
|
+
* LMLM Phase 6: arm the single background refresh scheduler over the live
|
|
2007
|
+
* pool. No-op when LMLM is disabled (`modelPool` null). Each tick runs
|
|
2008
|
+
* hardware→recommend→reconcile(D12 drift)→diff→emit→score-writeback.
|
|
2009
|
+
*
|
|
2010
|
+
* NOTE (deferred): the recommender is seeded with an empty candidate set —
|
|
2011
|
+
* Phase 2's live-HF→RankerCandidate parser was never built, so autonomous
|
|
2012
|
+
* swap-proposal discovery is out of scope here (flagged concern). The tick
|
|
2013
|
+
* still performs F10 drift reconciliation, O1 logging, and re-ranks/dedups
|
|
2014
|
+
* whatever candidates are supplied — the wiring is complete and candidate
|
|
2015
|
+
* breadth is the only piece deferred to the Phase 2 recommender.
|
|
2016
|
+
*/
|
|
2017
|
+
private startRefreshScheduler;
|
|
2018
|
+
/** Resolve the hardware profile for a refresh tick (operator override wins). */
|
|
2019
|
+
private detectLmlmHardware;
|
|
2020
|
+
/** Map the on-disk model-proposal queue to F7 dedup pairs (open→pending, rejected→rejected). */
|
|
2021
|
+
private lmlmDedupSource;
|
|
1917
2022
|
private initLocalModelAndPipeline;
|
|
1918
2023
|
/**
|
|
1919
2024
|
* Starts the polling loop and the internal HTTP server.
|
|
@@ -2337,6 +2442,13 @@ interface LocalModelResolverOptions {
|
|
|
2337
2442
|
apiKey?: string;
|
|
2338
2443
|
/** Normalized candidate list (already turned from string|string[] into string[]). */
|
|
2339
2444
|
configured: string[];
|
|
2445
|
+
/**
|
|
2446
|
+
* Phase 4 (D5): optional read-only pool-state port. When provided, the
|
|
2447
|
+
* candidate list derives from pool entries (currentScore desc → ollamaName)
|
|
2448
|
+
* instead of `configured`. When absent (default), behavior is byte-identical
|
|
2449
|
+
* to the pre-Phase-4 resolver.
|
|
2450
|
+
*/
|
|
2451
|
+
poolState?: PoolStateProvider;
|
|
2340
2452
|
/** Probe cadence in ms; default 30_000, minimum 1_000. */
|
|
2341
2453
|
probeIntervalMs?: number;
|
|
2342
2454
|
/**
|
|
@@ -2367,6 +2479,7 @@ declare class LocalModelResolver {
|
|
|
2367
2479
|
private readonly endpoint;
|
|
2368
2480
|
private readonly apiKey?;
|
|
2369
2481
|
private readonly configured;
|
|
2482
|
+
private readonly poolState?;
|
|
2370
2483
|
private readonly probeIntervalMs;
|
|
2371
2484
|
private readonly fetchModels;
|
|
2372
2485
|
private readonly logger;
|
|
@@ -2391,6 +2504,12 @@ declare class LocalModelResolver {
|
|
|
2391
2504
|
constructor(opts: LocalModelResolverOptions);
|
|
2392
2505
|
resolveModel(): string | null;
|
|
2393
2506
|
getStatus(): LocalModelStatus;
|
|
2507
|
+
/**
|
|
2508
|
+
* Effective candidate list. With a poolState port present the list derives
|
|
2509
|
+
* from pool entries (currentScore desc → ollamaName); otherwise the static
|
|
2510
|
+
* `configured` list is returned unchanged (byte-identical to pre-Phase-4).
|
|
2511
|
+
*/
|
|
2512
|
+
private candidates;
|
|
2394
2513
|
onStatusChange(handler: (status: LocalModelStatus) => void): () => void;
|
|
2395
2514
|
probe(): Promise<LocalModelStatus>;
|
|
2396
2515
|
private runProbe;
|
|
@@ -3520,7 +3639,7 @@ declare function promote(projectPath: string, proposalId: string, decidedBy: str
|
|
|
3520
3639
|
*/
|
|
3521
3640
|
interface ProposalCreatedData {
|
|
3522
3641
|
id: string;
|
|
3523
|
-
kind:
|
|
3642
|
+
kind: SkillKind;
|
|
3524
3643
|
name: string;
|
|
3525
3644
|
targetSkill?: string;
|
|
3526
3645
|
proposedBy: string;
|
|
@@ -3528,14 +3647,14 @@ interface ProposalCreatedData {
|
|
|
3528
3647
|
}
|
|
3529
3648
|
interface ProposalApprovedData {
|
|
3530
3649
|
id: string;
|
|
3531
|
-
kind:
|
|
3650
|
+
kind: SkillKind;
|
|
3532
3651
|
name: string;
|
|
3533
3652
|
targetSkill?: string;
|
|
3534
3653
|
decidedBy: string;
|
|
3535
3654
|
}
|
|
3536
3655
|
interface ProposalRejectedData {
|
|
3537
3656
|
id: string;
|
|
3538
|
-
kind:
|
|
3657
|
+
kind: SkillKind;
|
|
3539
3658
|
name: string;
|
|
3540
3659
|
decidedBy: string;
|
|
3541
3660
|
reason: string;
|