e789c7bb34
Phase 1 of RFC #308: Stateful Sense refactor. - SenseComputeFn<S> now takes state and returns { state, workflow } - SenseModule<S> exports compute + initialState (no more table) - Removed: Signal type, ComputeResult, RoutedSenseOutput, routeSenseComputeOutput, retention/DEFAULT_SENSE_SIGNAL_RETENTION - Updated isSenseInfo (removed lastSignalTimestamp) Refs #308, closes #309
@uncaged/nerve-core
Shared types and configuration parser for the nerve observation engine.
What's Inside
- Type definitions —
Signal,SenseConfig,SenseInfo,WorkflowConfig,NerveConfig, and related types - Config parser —
parseNerveConfig(yaml)validates and parsesnerve.yamlintoNerveConfig(rejects reflex entries that declare aworkflowkey; reflexes only schedule senses) - Sense → workflow routing —
parseWorkflowTrigger,routeSenseComputeOutput, and typesWorkflowTrigger,RoutedSenseOutput - Daemon IPC protocol — request/response types (
DaemonIpcRequest,DaemonIpcResponse, …) andparseDaemonIpcRequestfor newline-delimited JSON on the CLI ↔ daemon socket - Workflow automaton types —
START/ENDsentinel constants,WorkflowMessage,StartStep,RoleStep,ModeratorContext(start+steps; emptystepson first moderator call),Moderator(singlecontextargument),WorkflowDefinition,Role,RoleResult, plusDEFAULT_ENGINE_MAX_ROUNDS - Result type —
Result<T>withok()/err()helpers for explicit error handling (no thrown exceptions for parse paths)
Usage
import { parseNerveConfig, ok, err } from "@uncaged/nerve-core";
import type { NerveConfig, Signal, Result } from "@uncaged/nerve-core";
const result: Result<NerveConfig> = parseNerveConfig(yamlString);
if (result.ok) {
console.log(result.value.senses);
}
Sense return → signal vs workflow
import { parseWorkflowTrigger, routeSenseComputeOutput } from "@uncaged/nerve-core";
const directive = parseWorkflowTrigger({
name: "my-workflow",
maxRounds: 8,
prompt: "Hello from sense",
dryRun: false,
});
if (directive.ok) {
console.log(directive.value.name, directive.value.maxRounds, directive.value.prompt);
}
const route = routeSenseComputeOutput({
signal: { metric: 42 },
workflow: {
name: "my-workflow",
maxRounds: 8,
prompt: "Run now",
dryRun: false,
},
});
if (route.ok && route.value.workflow !== null) {
console.log(route.value.workflow);
} else if (route.ok) {
console.log(route.value.signal);
}
Duration Format
Config fields like throttle, timeout, and interval accept human-readable durations:
5s— 5 seconds10m— 10 minutes1h— 1 hour
Install
pnpm add @uncaged/nerve-core
License
MIT