@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 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: SkillProposal['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: SkillProposal['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: SkillProposal['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: SkillProposal['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: SkillProposal['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: SkillProposal['kind'];
3657
+ kind: SkillKind;
3539
3658
  name: string;
3540
3659
  decidedBy: string;
3541
3660
  reason: string;