@smooai/smooth-operator-core 0.9.0 → 0.10.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/agent.d.ts +276 -0
- package/dist/agent.d.ts.map +1 -0
- package/dist/agent.js +450 -0
- package/dist/agent.js.map +1 -0
- package/dist/cast.d.ts +81 -0
- package/dist/cast.d.ts.map +1 -0
- package/dist/cast.js +103 -0
- package/dist/cast.js.map +1 -0
- package/dist/checkpoint.d.ts +25 -0
- package/dist/checkpoint.d.ts.map +1 -0
- package/dist/checkpoint.js +23 -0
- package/dist/checkpoint.js.map +1 -0
- package/dist/compaction.d.ts +21 -0
- package/dist/compaction.d.ts.map +1 -0
- package/dist/compaction.js +50 -0
- package/dist/compaction.js.map +1 -0
- package/dist/cost.d.ts +34 -0
- package/dist/cost.d.ts.map +1 -0
- package/dist/cost.js +42 -0
- package/dist/cost.js.map +1 -0
- package/dist/extension/host.d.ts +199 -0
- package/dist/extension/host.d.ts.map +1 -0
- package/dist/extension/host.js +502 -0
- package/dist/extension/host.js.map +1 -0
- package/dist/extension/index.d.ts +36 -0
- package/dist/extension/index.d.ts.map +1 -0
- package/dist/extension/index.js +37 -0
- package/dist/extension/index.js.map +1 -0
- package/dist/extension/manifest.d.ts +111 -0
- package/dist/extension/manifest.d.ts.map +1 -0
- package/dist/extension/manifest.js +190 -0
- package/dist/extension/manifest.js.map +1 -0
- package/dist/extension/process.d.ts +118 -0
- package/dist/extension/process.d.ts.map +1 -0
- package/dist/extension/process.js +352 -0
- package/dist/extension/process.js.map +1 -0
- package/dist/extension/protocol.d.ts +254 -0
- package/dist/extension/protocol.d.ts.map +1 -0
- package/dist/extension/protocol.js +127 -0
- package/dist/extension/protocol.js.map +1 -0
- package/dist/extension/tool_proxy.d.ts +34 -0
- package/dist/extension/tool_proxy.d.ts.map +1 -0
- package/dist/extension/tool_proxy.js +48 -0
- package/dist/extension/tool_proxy.js.map +1 -0
- package/dist/humanGate.d.ts +44 -0
- package/dist/humanGate.d.ts.map +1 -0
- package/dist/humanGate.js +30 -0
- package/dist/humanGate.js.map +1 -0
- package/dist/index.d.ts +32 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +21 -0
- package/dist/index.js.map +1 -0
- package/dist/knowledge.d.ts +30 -0
- package/dist/knowledge.d.ts.map +1 -0
- package/dist/knowledge.js +43 -0
- package/dist/knowledge.js.map +1 -0
- package/dist/llmProvider.d.ts +106 -0
- package/dist/llmProvider.d.ts.map +1 -0
- package/dist/llmProvider.js +160 -0
- package/dist/llmProvider.js.map +1 -0
- package/dist/memory.d.ts +23 -0
- package/dist/memory.d.ts.map +1 -0
- package/dist/memory.js +40 -0
- package/dist/memory.js.map +1 -0
- package/dist/rerank.d.ts +27 -0
- package/dist/rerank.d.ts.map +1 -0
- package/dist/rerank.js +45 -0
- package/dist/rerank.js.map +1 -0
- package/dist/thread.d.ts +43 -0
- package/dist/thread.d.ts.map +1 -0
- package/dist/thread.js +60 -0
- package/dist/thread.js.map +1 -0
- package/dist/toolSearch.d.ts +55 -0
- package/dist/toolSearch.d.ts.map +1 -0
- package/dist/toolSearch.js +110 -0
- package/dist/toolSearch.js.map +1 -0
- package/dist/vector.d.ts +36 -0
- package/dist/vector.d.ts.map +1 -0
- package/dist/vector.js +75 -0
- package/dist/vector.js.map +1 -0
- package/dist/workflow.d.ts +62 -0
- package/dist/workflow.d.ts.map +1 -0
- package/dist/workflow.js +109 -0
- package/dist/workflow.js.map +1 -0
- package/package.json +1 -1
package/dist/vector.d.ts
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vector knowledge — embedding-backed semantic retrieval.
|
|
3
|
+
*
|
|
4
|
+
* Phase-1 sibling of the reference engines' vector store. `VectorKnowledge` embeds
|
|
5
|
+
* documents and queries and retrieves by cosine similarity, satisfying the same
|
|
6
|
+
* {@link Knowledge} interface as the lexical retriever (so the agent accepts
|
|
7
|
+
* either). The `Embedder` is pluggable: the default `HashEmbedder` is deterministic
|
|
8
|
+
* and offline (feature-hashed bag-of-words) — good for tests and a zero-dependency
|
|
9
|
+
* default — while a gateway embedder drops in behind the same interface for true
|
|
10
|
+
* semantics.
|
|
11
|
+
*/
|
|
12
|
+
import type { Knowledge, KnowledgeHit } from './knowledge.js';
|
|
13
|
+
/** A small deterministic non-cryptographic hash (FNV-1a, 32-bit). */
|
|
14
|
+
export declare function hashToken(token: string): number;
|
|
15
|
+
export interface Embedder {
|
|
16
|
+
embed(text: string): number[];
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Deterministic, offline feature-hashing embedder. Hashes each token into one of
|
|
20
|
+
* `dim` buckets (signed) and L2-normalizes. No learned semantics, but a real
|
|
21
|
+
* vector with cosine geometry — docs sharing tokens land near each other.
|
|
22
|
+
*/
|
|
23
|
+
export declare class HashEmbedder implements Embedder {
|
|
24
|
+
private readonly dim;
|
|
25
|
+
constructor(dim?: number);
|
|
26
|
+
embed(text: string): number[];
|
|
27
|
+
}
|
|
28
|
+
/** An embedding-backed knowledge store with cosine-similarity retrieval. */
|
|
29
|
+
export declare class VectorKnowledge implements Knowledge {
|
|
30
|
+
private readonly embedder;
|
|
31
|
+
private readonly docs;
|
|
32
|
+
constructor(embedder?: Embedder);
|
|
33
|
+
ingest(content: string, source: string): void;
|
|
34
|
+
query(query: string, topK?: number): KnowledgeHit[];
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=vector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vector.d.ts","sourceRoot":"","sources":["../src/vector.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAM9D,qEAAqE;AACrE,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAO/C;AAED,MAAM,WAAW,QAAQ;IACrB,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;CACjC;AAED;;;;GAIG;AACH,qBAAa,YAAa,YAAW,QAAQ;IAC7B,OAAO,CAAC,QAAQ,CAAC,GAAG;gBAAH,GAAG,SAAM;IAItC,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE;CAWhC;AAQD,4EAA4E;AAC5E,qBAAa,eAAgB,YAAW,SAAS;IAGjC,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAFrC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAiE;gBAEzD,QAAQ,GAAE,QAA6B;IAEpE,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAI7C,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,SAAI,GAAG,YAAY,EAAE;CASjD"}
|
package/dist/vector.js
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vector knowledge — embedding-backed semantic retrieval.
|
|
3
|
+
*
|
|
4
|
+
* Phase-1 sibling of the reference engines' vector store. `VectorKnowledge` embeds
|
|
5
|
+
* documents and queries and retrieves by cosine similarity, satisfying the same
|
|
6
|
+
* {@link Knowledge} interface as the lexical retriever (so the agent accepts
|
|
7
|
+
* either). The `Embedder` is pluggable: the default `HashEmbedder` is deterministic
|
|
8
|
+
* and offline (feature-hashed bag-of-words) — good for tests and a zero-dependency
|
|
9
|
+
* default — while a gateway embedder drops in behind the same interface for true
|
|
10
|
+
* semantics.
|
|
11
|
+
*/
|
|
12
|
+
function tokens(text) {
|
|
13
|
+
return text.toLowerCase().match(/[a-z0-9]+/g) ?? [];
|
|
14
|
+
}
|
|
15
|
+
/** A small deterministic non-cryptographic hash (FNV-1a, 32-bit). */
|
|
16
|
+
export function hashToken(token) {
|
|
17
|
+
let h = 0x811c9dc5;
|
|
18
|
+
for (let i = 0; i < token.length; i++) {
|
|
19
|
+
h ^= token.charCodeAt(i) & 0xff;
|
|
20
|
+
h = Math.imul(h, 0x01000193) >>> 0;
|
|
21
|
+
}
|
|
22
|
+
return h >>> 0;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Deterministic, offline feature-hashing embedder. Hashes each token into one of
|
|
26
|
+
* `dim` buckets (signed) and L2-normalizes. No learned semantics, but a real
|
|
27
|
+
* vector with cosine geometry — docs sharing tokens land near each other.
|
|
28
|
+
*/
|
|
29
|
+
export class HashEmbedder {
|
|
30
|
+
dim;
|
|
31
|
+
constructor(dim = 256) {
|
|
32
|
+
this.dim = dim;
|
|
33
|
+
if (dim <= 0)
|
|
34
|
+
throw new Error('dim must be positive');
|
|
35
|
+
}
|
|
36
|
+
embed(text) {
|
|
37
|
+
const vec = new Array(this.dim).fill(0);
|
|
38
|
+
for (const tok of tokens(text)) {
|
|
39
|
+
const h = hashToken(tok);
|
|
40
|
+
const bucket = h % this.dim;
|
|
41
|
+
const sign = (h >>> 31) & 1 ? -1 : 1;
|
|
42
|
+
vec[bucket] += sign;
|
|
43
|
+
}
|
|
44
|
+
const norm = Math.sqrt(vec.reduce((s, v) => s + v * v, 0));
|
|
45
|
+
return norm > 0 ? vec.map((v) => v / norm) : vec;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
function cosine(a, b) {
|
|
49
|
+
let s = 0;
|
|
50
|
+
for (let i = 0; i < a.length; i++)
|
|
51
|
+
s += a[i] * b[i]; // both L2-normalized
|
|
52
|
+
return s;
|
|
53
|
+
}
|
|
54
|
+
/** An embedding-backed knowledge store with cosine-similarity retrieval. */
|
|
55
|
+
export class VectorKnowledge {
|
|
56
|
+
embedder;
|
|
57
|
+
docs = [];
|
|
58
|
+
constructor(embedder = new HashEmbedder()) {
|
|
59
|
+
this.embedder = embedder;
|
|
60
|
+
}
|
|
61
|
+
ingest(content, source) {
|
|
62
|
+
this.docs.push({ emb: this.embedder.embed(content), content, source });
|
|
63
|
+
}
|
|
64
|
+
query(query, topK = 4) {
|
|
65
|
+
if (topK <= 0 || this.docs.length === 0)
|
|
66
|
+
return [];
|
|
67
|
+
const q = this.embedder.embed(query);
|
|
68
|
+
return this.docs
|
|
69
|
+
.map((d) => ({ content: d.content, source: d.source, score: cosine(q, d.emb) }))
|
|
70
|
+
.filter((h) => h.score > 0)
|
|
71
|
+
.sort((a, b) => b.score - a.score)
|
|
72
|
+
.slice(0, topK);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=vector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vector.js","sourceRoot":"","sources":["../src/vector.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LangGraph-inspired typed workflow graph with conditional edges.
|
|
3
|
+
*
|
|
4
|
+
* Phase-3 sibling of the reference engine's workflow primitive. A `Workflow<S>`
|
|
5
|
+
* is a state machine: **nodes** transform a typed state value and **edges** —
|
|
6
|
+
* static or **conditional** — determine the next node to execute. The runner
|
|
7
|
+
* starts at the entry node, applies each node then follows its outgoing edge,
|
|
8
|
+
* until it reaches the `END` sentinel (or a node with no outgoing edge), then
|
|
9
|
+
* returns the final state.
|
|
10
|
+
*
|
|
11
|
+
* Nodes may be sync or async; the runner awaits their results. A `maxSteps` cap
|
|
12
|
+
* bounds execution so an intentional or accidental cycle can't loop forever.
|
|
13
|
+
*
|
|
14
|
+
* Standalone module — it does not touch the agent loop. The point is the seam: a
|
|
15
|
+
* multi-step orchestration (parse → guardrails → retrieve → compose → …) drops in
|
|
16
|
+
* as a graph of named nodes with the routing made explicit.
|
|
17
|
+
*/
|
|
18
|
+
/** Sentinel a conditional router can return to signal termination. */
|
|
19
|
+
export declare const END: "__end__";
|
|
20
|
+
/** A node transforms state into a new state; may be sync or async. */
|
|
21
|
+
export type NodeFn<S> = (state: S) => S | Promise<S>;
|
|
22
|
+
/** A conditional router inspects state and returns the next node name (or `END`). */
|
|
23
|
+
export type Router<S> = (state: S) => string;
|
|
24
|
+
/** Thrown when a workflow is misconfigured or exceeds its step limit. */
|
|
25
|
+
export declare class WorkflowError extends Error {
|
|
26
|
+
constructor(message: string);
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* A typed workflow graph: named nodes connected by static/conditional edges.
|
|
30
|
+
*
|
|
31
|
+
* Build with `addNode`, `addEdge` / `addConditionalEdge`, `setEntry`, and
|
|
32
|
+
* `setEnd`; the builder methods return `this` so they chain. `run` executes the
|
|
33
|
+
* graph from the entry node.
|
|
34
|
+
*/
|
|
35
|
+
export declare class Workflow<S> {
|
|
36
|
+
private readonly maxSteps;
|
|
37
|
+
private readonly nodes;
|
|
38
|
+
private readonly edges;
|
|
39
|
+
private entry;
|
|
40
|
+
constructor(maxSteps?: number);
|
|
41
|
+
/** Register a node `func` under `name` (used to reference it in edges). */
|
|
42
|
+
addNode(name: string, func: NodeFn<S>): this;
|
|
43
|
+
/** Add a static edge `from` → `to`. */
|
|
44
|
+
addEdge(from: string, to: string): this;
|
|
45
|
+
/**
|
|
46
|
+
* Add a conditional edge whose `router` picks the next node at runtime. The
|
|
47
|
+
* router returns the target node name, or `END` to terminate the workflow.
|
|
48
|
+
*/
|
|
49
|
+
addConditionalEdge(from: string, router: Router<S>): this;
|
|
50
|
+
/** Set the entry node (first node to execute). */
|
|
51
|
+
setEntry(name: string): this;
|
|
52
|
+
/** Mark `from` as terminal — reaching it ends the workflow. */
|
|
53
|
+
setEnd(from: string): this;
|
|
54
|
+
/**
|
|
55
|
+
* Execute the workflow from the entry node, returning the final state.
|
|
56
|
+
*
|
|
57
|
+
* Throws {@link WorkflowError} if no entry node was set, a referenced node
|
|
58
|
+
* does not exist, or the `maxSteps` cap is exceeded (e.g. an unbroken cycle).
|
|
59
|
+
*/
|
|
60
|
+
run(initialState: S): Promise<S>;
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=workflow.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workflow.d.ts","sourceRoot":"","sources":["../src/workflow.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,sEAAsE;AACtE,eAAO,MAAM,GAAG,EAAG,SAAkB,CAAC;AAEtC,sEAAsE;AACtE,MAAM,MAAM,MAAM,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;AAErD,qFAAqF;AACrF,MAAM,MAAM,MAAM,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,KAAK,MAAM,CAAC;AAE7C,yEAAyE;AACzE,qBAAa,aAAc,SAAQ,KAAK;gBACxB,OAAO,EAAE,MAAM;CAI9B;AAKD;;;;;;GAMG;AACH,qBAAa,QAAQ,CAAC,CAAC;IAKP,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAJrC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAgC;IACtD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA8B;IACpD,OAAO,CAAC,KAAK,CAAqB;gBAEL,QAAQ,SAAM;IAE3C,2EAA2E;IAC3E,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,GAAG,IAAI;IAK5C,uCAAuC;IACvC,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,IAAI;IAKvC;;;OAGG;IACH,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,GAAG,IAAI;IAKzD,kDAAkD;IAClD,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAK5B,+DAA+D;IAC/D,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAK1B;;;;;OAKG;IACG,GAAG,CAAC,YAAY,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;CAmCzC"}
|
package/dist/workflow.js
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LangGraph-inspired typed workflow graph with conditional edges.
|
|
3
|
+
*
|
|
4
|
+
* Phase-3 sibling of the reference engine's workflow primitive. A `Workflow<S>`
|
|
5
|
+
* is a state machine: **nodes** transform a typed state value and **edges** —
|
|
6
|
+
* static or **conditional** — determine the next node to execute. The runner
|
|
7
|
+
* starts at the entry node, applies each node then follows its outgoing edge,
|
|
8
|
+
* until it reaches the `END` sentinel (or a node with no outgoing edge), then
|
|
9
|
+
* returns the final state.
|
|
10
|
+
*
|
|
11
|
+
* Nodes may be sync or async; the runner awaits their results. A `maxSteps` cap
|
|
12
|
+
* bounds execution so an intentional or accidental cycle can't loop forever.
|
|
13
|
+
*
|
|
14
|
+
* Standalone module — it does not touch the agent loop. The point is the seam: a
|
|
15
|
+
* multi-step orchestration (parse → guardrails → retrieve → compose → …) drops in
|
|
16
|
+
* as a graph of named nodes with the routing made explicit.
|
|
17
|
+
*/
|
|
18
|
+
/** Sentinel a conditional router can return to signal termination. */
|
|
19
|
+
export const END = '__end__';
|
|
20
|
+
/** Thrown when a workflow is misconfigured or exceeds its step limit. */
|
|
21
|
+
export class WorkflowError extends Error {
|
|
22
|
+
constructor(message) {
|
|
23
|
+
super(message);
|
|
24
|
+
this.name = 'WorkflowError';
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* A typed workflow graph: named nodes connected by static/conditional edges.
|
|
29
|
+
*
|
|
30
|
+
* Build with `addNode`, `addEdge` / `addConditionalEdge`, `setEntry`, and
|
|
31
|
+
* `setEnd`; the builder methods return `this` so they chain. `run` executes the
|
|
32
|
+
* graph from the entry node.
|
|
33
|
+
*/
|
|
34
|
+
export class Workflow {
|
|
35
|
+
maxSteps;
|
|
36
|
+
nodes = new Map();
|
|
37
|
+
edges = new Map();
|
|
38
|
+
entry;
|
|
39
|
+
constructor(maxSteps = 100) {
|
|
40
|
+
this.maxSteps = maxSteps;
|
|
41
|
+
}
|
|
42
|
+
/** Register a node `func` under `name` (used to reference it in edges). */
|
|
43
|
+
addNode(name, func) {
|
|
44
|
+
this.nodes.set(name, func);
|
|
45
|
+
return this;
|
|
46
|
+
}
|
|
47
|
+
/** Add a static edge `from` → `to`. */
|
|
48
|
+
addEdge(from, to) {
|
|
49
|
+
this.edges.set(from, { kind: 'node', to });
|
|
50
|
+
return this;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Add a conditional edge whose `router` picks the next node at runtime. The
|
|
54
|
+
* router returns the target node name, or `END` to terminate the workflow.
|
|
55
|
+
*/
|
|
56
|
+
addConditionalEdge(from, router) {
|
|
57
|
+
this.edges.set(from, { kind: 'conditional', router });
|
|
58
|
+
return this;
|
|
59
|
+
}
|
|
60
|
+
/** Set the entry node (first node to execute). */
|
|
61
|
+
setEntry(name) {
|
|
62
|
+
this.entry = name;
|
|
63
|
+
return this;
|
|
64
|
+
}
|
|
65
|
+
/** Mark `from` as terminal — reaching it ends the workflow. */
|
|
66
|
+
setEnd(from) {
|
|
67
|
+
this.edges.set(from, { kind: 'end' });
|
|
68
|
+
return this;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Execute the workflow from the entry node, returning the final state.
|
|
72
|
+
*
|
|
73
|
+
* Throws {@link WorkflowError} if no entry node was set, a referenced node
|
|
74
|
+
* does not exist, or the `maxSteps` cap is exceeded (e.g. an unbroken cycle).
|
|
75
|
+
*/
|
|
76
|
+
async run(initialState) {
|
|
77
|
+
if (this.entry === undefined) {
|
|
78
|
+
throw new WorkflowError('workflow has no entry node — call setEntry()');
|
|
79
|
+
}
|
|
80
|
+
if (!this.nodes.has(this.entry)) {
|
|
81
|
+
throw new WorkflowError(`entry node '${this.entry}' not found in registered nodes`);
|
|
82
|
+
}
|
|
83
|
+
let state = initialState;
|
|
84
|
+
let current = this.entry;
|
|
85
|
+
for (let step = 0; step < this.maxSteps; step++) {
|
|
86
|
+
const node = this.nodes.get(current);
|
|
87
|
+
if (node === undefined) {
|
|
88
|
+
throw new WorkflowError(`node '${current}' not found in workflow`);
|
|
89
|
+
}
|
|
90
|
+
state = await node(state);
|
|
91
|
+
const edge = this.edges.get(current);
|
|
92
|
+
if (edge === undefined || edge.kind === 'end') {
|
|
93
|
+
// No outgoing edge, or an explicit END — terminate.
|
|
94
|
+
return state;
|
|
95
|
+
}
|
|
96
|
+
if (edge.kind === 'conditional') {
|
|
97
|
+
const target = edge.router(state);
|
|
98
|
+
if (target === END)
|
|
99
|
+
return state;
|
|
100
|
+
current = target;
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
current = edge.to;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
throw new WorkflowError(`workflow exceeded maxSteps (${this.maxSteps}) — possible infinite loop`);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
//# sourceMappingURL=workflow.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workflow.js","sourceRoot":"","sources":["../src/workflow.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@smooai/smooth-operator-core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.1",
|
|
4
4
|
"description": "Native TypeScript implementation of the smooth-operator agent engine — an in-process, OpenAI-compatible agentic tool-calling loop with knowledge grounding. The TypeScript sibling of the Rust reference engine, the C# core, and the Python core.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|