@smooai/smooth-operator-core 0.23.0 → 1.7.0

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.
Files changed (2) hide show
  1. package/README.md +59 -11
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -15,11 +15,13 @@
15
15
 
16
16
  ---
17
17
 
18
- > The TypeScript sibling of the [Rust reference engine](https://github.com/SmooAI/smooth-operator-core). Agents, tools, knowledge/RAG, memory, checkpointing, human-in-the-loop, cost budgets, and workflows — as one embeddable npm package. It's the engine, not a notebook demo.
18
+ > ### The agent brain you can point at production — right in your Node process.
19
+ >
20
+ > Most agent frameworks hand the model a pile of tools and hope. This one gives you the loop **and the brakes**: draw hard lines the model can never cross, then let it run.
19
21
 
20
- `@smooai/smooth-operator-core` is the **native TypeScript implementation** of the Smoo AI agent engine — the in-process observe→think→act loop that powers [**lom.smoo.ai**](https://lom.smoo.ai). It's a sibling of the [Rust reference engine](https://github.com/SmooAI/smooth-operator-core) and one of the [polyglot set](https://github.com/SmooAI/smooth-operator-core/blob/main/docs/Polyglot-Engines.md) (Rust, TypeScript, Python, Go, C#/.NET) whose behavior is held at parity by a shared eval suite.
22
+ `@smooai/smooth-operator-core` is the agent engine itself, in-process — an observe→think→act loop over any OpenAI-compatible client, with typed tools, streaming, checkpointing, cost budgets, and a permission gate you control. Not a client to a remote server: the agent *is* your process.
21
23
 
22
- It's a library, not a client to a remote server: it *is* the agent, running in your Node process. Every surface is covered by **fast, offline tests** built on a deterministic `MockLlmProvider`, so the loop is verified — not vibe-coded.
24
+ It's the native TypeScript port of the [Rust reference engine](https://github.com/SmooAI/smooth-operator-core) — one of five siblings (Rust, TypeScript, Python, Go, C#/.NET) that share one wire spec and one eval suite. **The same agent brain, the same guarantees, wherever your stack already lives.** Every surface is covered by fast, offline tests on a deterministic `MockLlmProvider`, so the loop is verified — not vibe-coded.
23
25
 
24
26
  ## Install
25
27
 
@@ -29,19 +31,34 @@ npm install @smooai/smooth-operator-core
29
31
 
30
32
  ## Quickstart
31
33
 
32
- A complete agent — no credentials needed — using the deterministic mock provider the engine's own tests run on:
34
+ A complete agent with one tool — no credentials needed — using the deterministic mock provider the engine's own tests run on. The mock is scripted to call the tool, then answer:
33
35
 
34
36
  ```ts
35
- import { SmoothAgent, MockLlmProvider } from '@smooai/smooth-operator-core';
36
-
37
- const provider = new MockLlmProvider().pushText('the answer is 42');
38
- const agent = new SmoothAgent(provider, { instructions: 'You are a helpful assistant' });
39
-
40
- const response = await agent.run('what is the answer?');
37
+ import { SmoothAgent, MockLlmProvider, type Tool } from '@smooai/smooth-operator-core';
38
+
39
+ const getWeather: Tool = {
40
+ name: 'get_weather',
41
+ description: 'Get the current weather for a city',
42
+ parameters: { type: 'object', properties: { city: { type: 'string' } }, required: ['city'] },
43
+ async execute(args) {
44
+ return `Weather in ${args.city}: 72F, sunny`;
45
+ },
46
+ };
47
+
48
+ const provider = new MockLlmProvider()
49
+ .pushToolCall('call_1', 'get_weather', JSON.stringify({ city: 'Tokyo' }))
50
+ .pushText("It's 72F and sunny in Tokyo.");
51
+
52
+ const agent = new SmoothAgent(provider, {
53
+ instructions: 'You are a helpful assistant',
54
+ tools: [getWeather],
55
+ });
56
+
57
+ const response = await agent.run("what's the weather in Tokyo?");
41
58
  console.log(response.text);
42
59
  ```
43
60
 
44
- `SmoothAgent`'s constructor takes a `ChatClientLike` (the `MockLlmProvider` implements it — swap in any OpenAI-compatible client) and an `AgentOptions` object. `run` returns an `AgentRunResponse` whose `text` is the final answer.
61
+ `SmoothAgent`'s constructor takes a `ChatClientLike` (the `MockLlmProvider` implements it — swap in any OpenAI-compatible client) and an `AgentOptions` object. A `Tool` is a `{ name, description, parameters, execute }` object. `run` returns an `AgentRunResponse` whose `text` is the final answer.
45
62
 
46
63
  ## Features
47
64
 
@@ -57,6 +74,7 @@ The full parity surface — every engine in the [polyglot set](https://github.co
57
74
  - **Rerank** — `LexicalReranker` reranks retrieved hits before injection.
58
75
  - **Sub-agents / delegation** — `delegateTool` spawns child agents for sub-tasks.
59
76
  - **Cast + clearance** — `Cast`, `Clearance`, `makeRole` for per-role tool-access policy.
77
+ - **Permissions + deny-policy** — a tool-call gate (`AutoMode`: ask / accept-edits / deny-unmatched / bypass) with hard circuit-breakers (`rm -rf /`, credential paths, pipe-to-shell, dangerous domains), a persisted allow-list, and a consumer `DenyPolicy` — declarative TOML rules plus semantic predicates for what strings can't express.
60
78
  - **Human-in-the-loop gate** — `HumanGate` requires approval before designated tool calls run.
61
79
  - **Conversation thread** — `SmoothAgentThread` carries a conversation across multiple `run` calls.
62
80
  - **`LlmProvider` seam + `MockLlmProvider`** — inject any OpenAI-compatible client; the record/replay mock drives the offline tests.
@@ -66,6 +84,36 @@ The full parity surface — every engine in the [polyglot set](https://github.co
66
84
  - **Retry / backoff** — retry transient model-call failures with exponential backoff.
67
85
  - **Streaming** — stream incremental text, tool calls, and tool results as the turn runs.
68
86
 
87
+ ## Permissions & deny-policy — lines the agent can't cross
88
+
89
+ This is what makes an agent safe to point at real infrastructure: **you** decide what it can never do, and no prompt or model mistake talks it out of that. Every tool call passes through a gate. `AutoMode` sets the posture — read-only calls **allow**, mutating calls **ask**, dangerous calls **deny** — and hard circuit-breakers (`rm -rf /`, credential paths, pipe-to-shell, dangerous domains) fire in every mode, `Bypass` included. Attach a `DenyPolicy` on top: declarative TOML rules for the lines you can name, semantic predicates for the ones you can't. A match is a hard deny no stored grant and no mode can waive.
90
+
91
+ ```ts
92
+ import { SmoothAgent, AutoMode, DenyPolicy, type DenyPredicate } from '@smooai/smooth-operator-core';
93
+
94
+ // Declarative rules (TOML): never the prod AWS profile, never a prod host.
95
+ const policy = DenyPolicy.fromToml(`
96
+ schema_version = 1
97
+ [bash]
98
+ deny_patterns = ["aws * --profile prod"]
99
+ [network]
100
+ deny_hosts = ["*.prod.internal"]
101
+ `);
102
+
103
+ // Predicate for what strings can't express — return a reason to deny, or undefined to allow.
104
+ const denyDbWriter: DenyPredicate = (call) =>
105
+ call.name === 'db_query' && /writer/.test(JSON.stringify(call.arguments))
106
+ ? 'DB writer endpoint is off-limits — reads go to the replica'
107
+ : undefined;
108
+
109
+ const agent = new SmoothAgent(provider, {
110
+ instructions: 'You are a careful assistant',
111
+ tools: [getWeather],
112
+ permissionMode: AutoMode.Ask, // read allow · mutate ask · dangerous deny
113
+ denyPolicy: policy.withPredicate(denyDbWriter),
114
+ });
115
+ ```
116
+
69
117
  ## Streaming
70
118
 
71
119
  `runStream` is an async generator over a `StreamEvent` tagged union (discriminated on `type`): `text` deltas as the model produces them, each `tool_call` before dispatch, each `tool_result` after it finishes, and a terminal `done` event carrying the same response `run` would have returned.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@smooai/smooth-operator-core",
3
- "version": "0.23.0",
3
+ "version": "1.7.0",
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",