@hilbras/omninode 1.0.0 → 2.0.0-alpha.2

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.ts CHANGED
@@ -172,6 +172,11 @@ interface ChatResponse {
172
172
  /** Verbatim provider response body for advanced consumers. */
173
173
  raw?: unknown;
174
174
  }
175
+ /**
176
+ * Model-backed chat used by the planner layer. Lives in the neutral types
177
+ * layer so adapters (e.g. planner) never depend on engine modules.
178
+ */
179
+ type ChatFn = (model: string, messages: ChatMessage[]) => Promise<string>;
175
180
 
176
181
  /**
177
182
  * Memory abstraction. Remembera is the preferred Hilbras integration, but the
@@ -224,7 +229,27 @@ interface ModelInfo {
224
229
 
225
230
  /** Task system: every operation becomes a Task (§13). */
226
231
 
227
- type TaskStatus = "created" | "queued" | "running" | "waiting" | "completed" | "failed" | "cancelled";
232
+ /**
233
+ * Execution states (v2 Phase 2, roadmap §6.1).
234
+ *
235
+ * The crucial distinction: `unknown` means "we cannot prove the outcome" —
236
+ * e.g. a process timeout after the agent may already have performed side
237
+ * effects. It is deliberately NOT `failed`: retrying blindly could duplicate
238
+ * work, and reporting failure would be a lie. Resolve it explicitly with
239
+ * `task retry` (which starts a fresh execution) or by inspecting artifacts.
240
+ */
241
+ type TaskStatus = "created" | "queued" | "running" | "waiting" | "completed" | "failed" | "timed_out" | "cancelled" | "unknown" | "partially_completed";
242
+ /** States from which no further automatic transition happens. */
243
+ declare const TERMINAL_TASK_STATUSES: readonly TaskStatus[];
244
+ /** One execution attempt (roadmap §6.5 identity: task + attempt + execution id). */
245
+ interface ExecutionRecord {
246
+ executionId: string;
247
+ attempt: number;
248
+ startedAt: string;
249
+ finishedAt: string;
250
+ outcome: "completed" | "failed" | "timed_out" | "unknown" | "cancelled";
251
+ error?: string;
252
+ }
228
253
  interface TaskContext {
229
254
  project?: string;
230
255
  /** Paths or globs relevant to the task. */
@@ -257,6 +282,12 @@ interface Task {
257
282
  status: TaskStatus;
258
283
  createdAt: string;
259
284
  updatedAt: string;
285
+ /** Number of engine.run attempts so far (0 = never executed). */
286
+ attempt: number;
287
+ /** Error from the most recent failed/unknown attempt. */
288
+ lastError?: string;
289
+ /** Recent execution attempts, newest last, bounded in length. */
290
+ executions?: ExecutionRecord[];
260
291
  result?: TaskResult;
261
292
  }
262
293
 
@@ -287,7 +318,12 @@ interface PipelineDefinition {
287
318
  role?: string;
288
319
  steps: PipelineStep[];
289
320
  }
290
- type PipelineRunStatus = "pending" | "running" | "completed" | "failed" | "cancelled";
321
+ /**
322
+ * Run status. "partial" means the run finished but some step outcome was
323
+ * incomplete or unprovable (partial fan-out, unknown task state) — the
324
+ * authoritative detail always lives in `stepRuns`/`taskRuns`.
325
+ */
326
+ type PipelineRunStatus = "pending" | "running" | "completed" | "failed" | "partial" | "cancelled";
291
327
  interface PipelineStepRun {
292
328
  stepId: string;
293
329
  status: TaskStatus;
@@ -1625,6 +1661,13 @@ declare class OmniHilbrasProvider extends OpenAICompatibleProvider {
1625
1661
  connect(registry?: ModelRegistry): Promise<OmniHilbrasConnectionResult>;
1626
1662
  }
1627
1663
 
1664
+ /**
1665
+ * Builds the child environment. By default the agent inherits the full
1666
+ * environment; with `inheritEnv: false` it receives only PATH plus the
1667
+ * explicitly configured variables — useful to avoid leaking OmniNode's
1668
+ * own secrets (e.g. provider API keys) into third-party agents.
1669
+ */
1670
+ declare function buildChildEnv(config: AgentConfig): NodeJS.ProcessEnv;
1628
1671
  declare function composeTaskText(input: AgentTaskInput): string;
1629
1672
  declare class ProcessAgent implements IAgent {
1630
1673
  readonly config: AgentConfig;
@@ -1668,6 +1711,41 @@ declare class RoleRegistry {
1668
1711
  /** Builds a role registry from the project configuration. */
1669
1712
  declare function buildRoleRegistry(config: AppConfig): RoleRegistry;
1670
1713
 
1714
+ interface JsonDocument<T> {
1715
+ /** Bumped when the persisted shape changes in a breaking way (v2 Phase 12). */
1716
+ schemaVersion?: number;
1717
+ items: T[];
1718
+ }
1719
+ interface JsonFileStoreOptions {
1720
+ directory?: string;
1721
+ fileName: string;
1722
+ schemaVersion?: number;
1723
+ /** Called when a persisted file cannot be parsed. */
1724
+ onCorrupt?: (path: string, error: unknown) => void;
1725
+ }
1726
+ declare class JsonFileStore<T> {
1727
+ private readonly filePath;
1728
+ private readonly schemaVersion;
1729
+ private readonly onCorrupt?;
1730
+ private readonly log;
1731
+ private queue;
1732
+ constructor(options: JsonFileStoreOptions);
1733
+ get path(): string;
1734
+ /** All items, or [] when missing/corrupt. */
1735
+ protected readAll(): Promise<T[]>;
1736
+ protected writeAll(items: T[]): Promise<void>;
1737
+ /** Serializes an async operation against this file. */
1738
+ protected synchronized<R>(operation: () => Promise<R>): Promise<R>;
1739
+ /** Read-modify-write helper: applies `mutate` to the current items. */
1740
+ protected mutate<R>(mutate: (items: T[]) => Promise<[T[], R]> | [T[], R]): Promise<R>;
1741
+ }
1742
+
1743
+ /**
1744
+ * Task persistence (§4.1 — execution state). The store is replaceable
1745
+ * (§2 — Modular); the default implementation is a local JSON file so
1746
+ * OmniNode stays local-first (§25).
1747
+ */
1748
+
1671
1749
  interface TaskStoreFilter {
1672
1750
  status?: TaskStatus;
1673
1751
  project?: string;
@@ -1677,20 +1755,11 @@ interface TaskStore {
1677
1755
  get(id: string): Promise<Task | undefined>;
1678
1756
  list(filter?: TaskStoreFilter): Promise<Task[]>;
1679
1757
  }
1680
- declare class FileTaskStore implements TaskStore {
1681
- private readonly filePath;
1682
- /**
1683
- * Read-modify-write operations are serialized: parallel pipeline tasks
1684
- * would otherwise race on the JSON file (last writer wins).
1685
- */
1686
- private queue;
1758
+ declare class FileTaskStore extends JsonFileStore<Task> implements TaskStore {
1687
1759
  constructor(directory?: string);
1688
1760
  save(task: Task): Promise<void>;
1689
1761
  get(id: string): Promise<Task | undefined>;
1690
1762
  list(filter?: TaskStoreFilter): Promise<Task[]>;
1691
- private synchronized;
1692
- private load;
1693
- private write;
1694
1763
  }
1695
1764
 
1696
1765
  type AuditAction = "task.created" | "task.queued" | "task.running" | "task.completed" | "task.failed" | "task.cancelled" | "task.retry" | "pipeline.run.started" | "pipeline.run.finished" | "plan.generated" | "memory.context.gathered" | "memory.outcome.recorded";
@@ -1715,18 +1784,20 @@ declare class FileAuditLog implements AuditSink {
1715
1784
  recent(limit?: number): Promise<AuditEvent[]>;
1716
1785
  }
1717
1786
 
1787
+ /**
1788
+ * Local file-based memory provider: the default implementation so persistent
1789
+ * memory works out of the box, locally (§25), with no external service.
1790
+ * Relevance is scored by keyword overlap and tag matches — deterministic and
1791
+ * dependency-free.
1792
+ */
1793
+
1718
1794
  declare function keywords(text: string): Set<string>;
1719
- declare class LocalMemoryProvider implements IMemoryProvider {
1795
+ declare class LocalMemoryProvider extends JsonFileStore<MemoryEntry> implements IMemoryProvider {
1720
1796
  readonly name = "local";
1721
- private readonly filePath;
1722
- private queue;
1723
1797
  constructor(directory?: string);
1724
1798
  query(query: MemoryQuery): Promise<MemoryEntry[]>;
1725
1799
  write(entry: MemoryEntry): Promise<void>;
1726
1800
  count(): Promise<number>;
1727
- private synchronized;
1728
- private load;
1729
- private saveAll;
1730
1801
  }
1731
1802
 
1732
1803
  interface RememberaConfig {
@@ -1783,6 +1854,12 @@ interface CreateTaskInput {
1783
1854
  agent?: string;
1784
1855
  context?: TaskContext;
1785
1856
  }
1857
+ interface RunTaskOptions {
1858
+ /** Total attempts (1 = no automatic retry). Retries apply to retryable errors only. */
1859
+ maxAttempts?: number;
1860
+ /** Linear backoff base in ms: waits backoffMs × attempt between attempts. */
1861
+ retryBackoffMs?: number;
1862
+ }
1786
1863
  interface TaskEngineOptions {
1787
1864
  agents: AgentRegistry;
1788
1865
  roles: RoleRegistry;
@@ -1800,10 +1877,12 @@ declare class TaskEngine {
1800
1877
  get store(): TaskStore;
1801
1878
  create(input: CreateTaskInput): Promise<Task>;
1802
1879
  queue(id: string): Promise<Task>;
1803
- /** Runs the task through its assigned agent and records the result. */
1804
- run(id: string): Promise<Task>;
1880
+ /** Runs the task through its assigned agent and records the result.
1881
+ * `maxAttempts` enables bounded automatic retries of *retryable* errors
1882
+ * with linear backoff; unknown/timed_out outcomes are never auto-retried. */
1883
+ run(id: string, options?: RunTaskOptions): Promise<Task>;
1805
1884
  cancel(id: string): Promise<Task>;
1806
- /** Error recovery (§27 Phase 9): reset a failed/cancelled task so it can run again. */
1885
+ /** Error recovery: reset a failed/cancelled/unknown/timed_out task so it can run again. */
1807
1886
  retry(id: string): Promise<Task>;
1808
1887
  get(id: string): Promise<Task | undefined>;
1809
1888
  list(filter?: TaskStoreFilter): Promise<Task[]>;
@@ -1816,6 +1895,11 @@ declare class TaskEngine {
1816
1895
 
1817
1896
  declare function createTaskEngine(config: AppConfig, log?: Logger, directory?: string): TaskEngine;
1818
1897
 
1898
+ /**
1899
+ * Report persistence (§16 — report storage). Same replaceable-store and
1900
+ * serialized-write patterns as the other local stores.
1901
+ */
1902
+
1819
1903
  interface ReportFilter {
1820
1904
  taskId?: string;
1821
1905
  agent?: string;
@@ -1830,18 +1914,20 @@ interface ReportStore {
1830
1914
  getCombined(id: string): Promise<CombinedReport | undefined>;
1831
1915
  listCombined(filter?: CombinedReportFilter): Promise<CombinedReport[]>;
1832
1916
  }
1833
- declare class FileReportStore implements ReportStore {
1834
- private readonly filePath;
1835
- private queue;
1917
+ type StoreEntry = {
1918
+ kind: "report";
1919
+ report: Report;
1920
+ } | {
1921
+ kind: "combined";
1922
+ combined: CombinedReport;
1923
+ };
1924
+ declare class FileReportStore extends JsonFileStore<StoreEntry> implements ReportStore {
1836
1925
  constructor(directory?: string);
1837
1926
  saveReports(reports: Report[]): Promise<void>;
1838
1927
  listReports(filter?: ReportFilter): Promise<Report[]>;
1839
1928
  saveCombined(combined: CombinedReport): Promise<void>;
1840
1929
  getCombined(id: string): Promise<CombinedReport | undefined>;
1841
1930
  listCombined(filter?: CombinedReportFilter): Promise<CombinedReport[]>;
1842
- private synchronized;
1843
- private load;
1844
- private write;
1845
1931
  }
1846
1932
 
1847
1933
  /**
@@ -1909,6 +1995,50 @@ interface IPlanner {
1909
1995
  plan(request: PlanRequest): Promise<Plan>;
1910
1996
  }
1911
1997
 
1998
+ /**
1999
+ * Planner context builder (§18): assembles everything the planner needs —
2000
+ * the objective, the combined findings from the AI reports (with source
2001
+ * attribution), relevant memory and the role definition — into one
2002
+ * structured text.
2003
+ */
2004
+
2005
+ declare function buildPlannerContext(request: PlanRequest): string;
2006
+
2007
+ declare class HeuristicPlanner implements IPlanner {
2008
+ readonly name = "heuristic";
2009
+ plan(request: PlanRequest): Promise<Plan>;
2010
+ }
2011
+
2012
+ interface ModelPlannerOptions {
2013
+ model: string;
2014
+ chat: ChatFn;
2015
+ /** Extra instruction appended to the system prompt. */
2016
+ instruction?: string;
2017
+ /** Used when the model output is unparseable (or the call fails, if tolerateErrors). */
2018
+ fallback?: IPlanner;
2019
+ log?: Logger;
2020
+ }
2021
+ declare class ModelPlanner implements IPlanner {
2022
+ private readonly options;
2023
+ readonly name = "model";
2024
+ private readonly log;
2025
+ constructor(options: ModelPlannerOptions);
2026
+ plan(request: PlanRequest): Promise<Plan>;
2027
+ private degrade;
2028
+ }
2029
+ /** Extracts and validates the plan JSON from arbitrary model output. */
2030
+ declare function parsePlanJson(text: string): {
2031
+ summary: string;
2032
+ steps: PlanStep[];
2033
+ risks?: string[];
2034
+ notes?: string[];
2035
+ } | undefined;
2036
+
2037
+ /**
2038
+ * Plan persistence (§27 Phase 8 — planner result storage). Same
2039
+ * replaceable-store pattern as the other local stores.
2040
+ */
2041
+
1912
2042
  interface PlanFilter {
1913
2043
  pipelineRunId?: string;
1914
2044
  taskId?: string;
@@ -1918,6 +2048,19 @@ interface PlanStore {
1918
2048
  get(id: string): Promise<Plan | undefined>;
1919
2049
  list(filter?: PlanFilter): Promise<Plan[]>;
1920
2050
  }
2051
+ declare class FilePlanStore extends JsonFileStore<Plan> implements PlanStore {
2052
+ constructor(directory?: string);
2053
+ save(plan: Plan): Promise<void>;
2054
+ get(id: string): Promise<Plan | undefined>;
2055
+ list(filter?: PlanFilter): Promise<Plan[]>;
2056
+ }
2057
+
2058
+ declare function buildPlanner(plannerConfig: AppConfig["project"]["planner"], chat: ChatFn, log?: Logger): IPlanner | undefined;
2059
+
2060
+ /**
2061
+ * Pipeline run persistence (§27 Phase 5 — pipeline state). Same
2062
+ * replaceable-store pattern as the task store, local-first JSON file.
2063
+ */
1921
2064
 
1922
2065
  interface PipelineRunFilter {
1923
2066
  pipelineId?: string;
@@ -1928,19 +2071,13 @@ interface PipelineRunStore {
1928
2071
  get(id: string): Promise<PipelineRun | undefined>;
1929
2072
  list(filter?: PipelineRunFilter): Promise<PipelineRun[]>;
1930
2073
  }
1931
- declare class FilePipelineRunStore implements PipelineRunStore {
1932
- private readonly filePath;
1933
- private queue;
2074
+ declare class FilePipelineRunStore extends JsonFileStore<PipelineRun> implements PipelineRunStore {
1934
2075
  constructor(directory?: string);
1935
2076
  save(run: PipelineRun): Promise<void>;
1936
2077
  get(id: string): Promise<PipelineRun | undefined>;
1937
2078
  list(filter?: PipelineRunFilter): Promise<PipelineRun[]>;
1938
- private synchronized;
1939
- private load;
1940
- private write;
1941
2079
  }
1942
2080
 
1943
- type ChatFn = (modelRef: string, messages: ChatMessage[]) => Promise<string>;
1944
2081
  interface PipelineEngineOptions {
1945
2082
  tasks: TaskEngine;
1946
2083
  agents: AgentRegistry;
@@ -1994,6 +2131,25 @@ declare function createDefaultChatFn(providers: AppConfig["project"]["providers"
1994
2131
 
1995
2132
  declare function buildPipelineEngine(config: AppConfig, log?: Logger): PipelineEngine;
1996
2133
 
1997
- declare const OMNINODE_VERSION = "1.0.0";
2134
+ /**
2135
+ * Persistence layer (v2 Phase 1): one entry point to every local store.
2136
+ *
2137
+ * All stores are interfaces with a local JSON default
2138
+ * (TaskStore, PipelineRunStore, ReportStore, PlanStore, IMemoryProvider,
2139
+ * AuditSink) — see docs/API.md for the inventory and stability status.
2140
+ */
2141
+
2142
+ /** Bundles every store for a single project directory. */
2143
+ declare class ProjectStores {
2144
+ readonly tasks: FileTaskStore;
2145
+ readonly pipelineRuns: FilePipelineRunStore;
2146
+ readonly reports: FileReportStore;
2147
+ readonly plans: FilePlanStore;
2148
+ readonly memory: LocalMemoryProvider;
2149
+ readonly audit: FileAuditLog;
2150
+ constructor(directory?: string);
2151
+ }
2152
+
2153
+ declare const OMNINODE_VERSION = "2.0.0-alpha.2";
1998
2154
 
1999
- export { type AgentConfig, type AgentConfigYaml, AgentError, type AgentInfo, type AgentInputMode, type AgentIntegrationType, AgentRegistry, type AgentStatus, type AgentTaskInput, type AgentTaskOutput, type AgentToNodeMessage, type AggregateOptions, type AggregatedFinding, type AggregatedRecommendation, type AppConfig, type AppConfigYaml, type AuditAction, type AuditEvent, type AuditSink, type ChatFn, type ChatMessage, type ChatRequest, type ChatResponse, type ChatRole, type ChatUsage, type CombinedMeta, type CombinedReport, type CombinedReportFilter, type Confidence, ConfigError, ConsoleLogSink, type CreateTaskInput, type DiscoveryResult, type EnvelopeMeta, type ExtractionMeta, FileAuditLog, FilePipelineRunStore, FileReportStore, FileTaskStore, type Finding, type FindingSeverity, type FindingSource, type HttpRequestOptions, type HttpResponse, type IAgent, type IChatProvider, type IMemoryProvider, type IProvider, type LoadConfigOptions, LocalMemoryProvider, type LogLevel, type LogSink, Logger, type LoggerOptions, type MemoryContextQuery, type MemoryEntry, MemoryError, type MemoryProviderConfig, type MemoryQuery, type MemoryScope, MemoryService, type MessageEnvelope, type ModelCapabilities, type ModelFilter, type ModelInfo, ModelRegistry, type ModelStatus, type NodeToAgentMessage, OMNINODE_VERSION, OPENAI_COMPATIBLE_TYPES, type OmniHilbrasConnectionResult, OmniHilbrasProvider, OmniNodeError, type OmniNodeErrorCode, type OmniNodeErrorOptions, OpenAICompatibleProvider, type PipelineConfigYaml, type PipelineDefinition, PipelineEngine, type PipelineEngineOptions, PipelineError, type PipelineRun, type PipelineRunFilter, type PipelineRunStatus, type PipelineRunStore, type PipelineStep, type PipelineStepCondition, type PipelineStepConfigYaml, type PipelineStepKind, type PipelineStepRun, type Plan, type PlanStep, type PlannerConfigYaml, PlannerError, ProcessAgent, type Project, type ProjectConfigYaml, ProtocolError, type ProviderConfig, type ProviderConfigYaml, ProviderError, type ProviderHealth, type ProviderStatus, type ProviderType, type RememberaConfig, RememberaMemoryProvider, type Report, type ReportFilter, ReportService, type ReportStore, type RoleConfigYaml, type RoleDefinition, RoleRegistry, type RunPipelineOptions, type Task, type TaskContext, TaskEngine, type TaskEngineOptions, TaskError, type TaskResult, type TaskStatus, type TaskStore, type TaskStoreFilter, type WritableLike, agentConfigSchema, aggregateReports, appConfigSchema, authHeaders, buildAgentRegistry, buildPipelineEngine, buildRoleRegistry, composeTaskText, createAgent, createDefaultChatFn, createMemoryProvider, createProvider, createTaskEngine, defaultProjectConfigYaml, expandEnvRefs, extractReportFromText, findConfigFile, isOmniNodeError, keywords, loadConfig, logger, pipelineConfigSchema, pipelineStepConfigSchema, plannerConfigSchema, projectConfigSchema, providerConfigSchema, registryKey, requestJson, resolveApiKey, roleConfigSchema, similar };
2155
+ export { type AgentConfig, type AgentConfigYaml, AgentError, type AgentInfo, type AgentInputMode, type AgentIntegrationType, AgentRegistry, type AgentStatus, type AgentTaskInput, type AgentTaskOutput, type AgentToNodeMessage, type AggregateOptions, type AggregatedFinding, type AggregatedRecommendation, type AppConfig, type AppConfigYaml, type AuditAction, type AuditEvent, type AuditSink, type ChatFn, type ChatMessage, type ChatRequest, type ChatResponse, type ChatRole, type ChatUsage, type CombinedMeta, type CombinedReport, type CombinedReportFilter, type Confidence, ConfigError, ConsoleLogSink, type CreateTaskInput, type DiscoveryResult, type EnvelopeMeta, type ExecutionRecord, type ExtractionMeta, FileAuditLog, FilePipelineRunStore, FilePlanStore, FileReportStore, FileTaskStore, type Finding, type FindingSeverity, type FindingSource, HeuristicPlanner, type HttpRequestOptions, type HttpResponse, type IAgent, type IChatProvider, type IMemoryProvider, type IPlanner, type IProvider, type JsonDocument, JsonFileStore, type JsonFileStoreOptions, type LoadConfigOptions, LocalMemoryProvider, type LogLevel, type LogSink, Logger, type LoggerOptions, type MemoryContextQuery, type MemoryEntry, MemoryError, type MemoryProviderConfig, type MemoryQuery, type MemoryScope, MemoryService, type MessageEnvelope, type ModelCapabilities, type ModelFilter, type ModelInfo, ModelPlanner, ModelRegistry, type ModelStatus, type NodeToAgentMessage, OMNINODE_VERSION, OPENAI_COMPATIBLE_TYPES, type OmniHilbrasConnectionResult, OmniHilbrasProvider, OmniNodeError, type OmniNodeErrorCode, type OmniNodeErrorOptions, OpenAICompatibleProvider, type PipelineConfigYaml, type PipelineDefinition, PipelineEngine, type PipelineEngineOptions, PipelineError, type PipelineRun, type PipelineRunFilter, type PipelineRunStatus, type PipelineRunStore, type PipelineStep, type PipelineStepCondition, type PipelineStepConfigYaml, type PipelineStepKind, type PipelineStepRun, type Plan, type PlanFilter, type PlanRequest, type PlanStep, type PlanStore, type PlannerConfigYaml, PlannerError, ProcessAgent, type Project, type ProjectConfigYaml, ProjectStores, ProtocolError, type ProviderConfig, type ProviderConfigYaml, ProviderError, type ProviderHealth, type ProviderStatus, type ProviderType, type RememberaConfig, RememberaMemoryProvider, type Report, type ReportFilter, ReportService, type ReportStore, type RoleConfigYaml, type RoleDefinition, RoleRegistry, type RunPipelineOptions, TERMINAL_TASK_STATUSES, type Task, type TaskContext, TaskEngine, type TaskEngineOptions, TaskError, type TaskResult, type TaskStatus, type TaskStore, type TaskStoreFilter, type WritableLike, agentConfigSchema, aggregateReports, appConfigSchema, authHeaders, buildAgentRegistry, buildChildEnv, buildPipelineEngine, buildPlanner, buildPlannerContext, buildRoleRegistry, composeTaskText, createAgent, createDefaultChatFn, createMemoryProvider, createProvider, createTaskEngine, defaultProjectConfigYaml, expandEnvRefs, extractReportFromText, findConfigFile, isOmniNodeError, keywords, loadConfig, logger, parsePlanJson, pipelineConfigSchema, pipelineStepConfigSchema, plannerConfigSchema, projectConfigSchema, providerConfigSchema, registryKey, requestJson, resolveApiKey, roleConfigSchema, similar };