@smooai/smooth-operator 0.1.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.
- package/LICENSE +21 -0
- package/README.md +157 -0
- package/dist/client.d.ts +148 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +359 -0
- package/dist/client.js.map +1 -0
- package/dist/generated/types.d.ts +1273 -0
- package/dist/generated/types.d.ts.map +1 -0
- package/dist/generated/types.js +9 -0
- package/dist/generated/types.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +19 -0
- package/dist/index.js.map +1 -0
- package/dist/transport.d.ts +70 -0
- package/dist/transport.d.ts.map +1 -0
- package/dist/transport.js +167 -0
- package/dist/transport.js.map +1 -0
- package/dist/types.d.ts +74 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +49 -0
- package/dist/types.js.map +1 -0
- package/dist/validate.d.ts +52 -0
- package/dist/validate.d.ts.map +1 -0
- package/dist/validate.js +133 -0
- package/dist/validate.js.map +1 -0
- package/package.json +65 -0
- package/src/client.ts +435 -0
- package/src/generated/types.ts +1358 -0
- package/src/index.ts +31 -0
- package/src/transport.ts +194 -0
- package/src/types.ts +184 -0
- package/src/validate.ts +158 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Smoo AI
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
<p align="center"><img src="../assets/smooth-logo.svg" alt="Smooth" width="360" /></p>
|
|
2
|
+
|
|
3
|
+
<p align="center"><strong><code>@smooai/smooth-operator</code></strong> — the Lambda-native TypeScript client for the smooth-operator protocol. Streaming agent turns, HITL resume, fully typed.</p>
|
|
4
|
+
|
|
5
|
+
<p align="center">
|
|
6
|
+
<a href="../LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue.svg" alt="MIT License" /></a>
|
|
7
|
+
<img src="https://img.shields.io/badge/tests-16%20passing-success" alt="16 tests passing" />
|
|
8
|
+
<img src="https://img.shields.io/badge/serverless%20%C2%B7%20polyglot%20%C2%B7%20TDD-6f42c1" alt="serverless · polyglot · TDD" />
|
|
9
|
+
<a href="https://lom.smoo.ai"><img src="https://img.shields.io/badge/hosted-lom.smoo.ai-0aa" alt="lom.smoo.ai" /></a>
|
|
10
|
+
</p>
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## What is this?
|
|
15
|
+
|
|
16
|
+
The **native TypeScript client** for the [smooth-operator](../docs/PROTOCOL.md) WebSocket protocol — and the one the [smooai monorepo dogfoods](https://github.com/SmooAI/smooth-operator). Types are **generated** from the language-neutral JSON Schemas in [`../spec`](../spec) (and committed, so consumers don't need the generator), with an ergonomic layer — discriminated unions + type guards — on top. It's Lambda-native and transport-injectable, so it runs in a browser, on Node, or inside a Lambda handler unchanged.
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## 30-second quickstart
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
pnpm add @smooai/smooth-operator # npm publish pending — use a workspace / file: dep today
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Requires Node ≥ 22, ESM only. Until the package is published, depend on it from a
|
|
27
|
+
sibling checkout (`"@smooai/smooth-operator": "workspace:*"` in a pnpm workspace, or
|
|
28
|
+
`"file:../smooth-operator/typescript"`).
|
|
29
|
+
|
|
30
|
+
```ts
|
|
31
|
+
import { SmoothAgentClient } from '@smooai/smooth-operator';
|
|
32
|
+
|
|
33
|
+
const client = new SmoothAgentClient({ url: 'ws://127.0.0.1:8787/ws' });
|
|
34
|
+
await client.connect();
|
|
35
|
+
|
|
36
|
+
const session = await client.createConversationSession({ agentId, userName: 'Alice' });
|
|
37
|
+
const turn = client.sendMessage({ sessionId: session.sessionId, message: 'How long is your return window?' });
|
|
38
|
+
|
|
39
|
+
const final = await turn; // EventualResponse — cost, tokens, messageId
|
|
40
|
+
console.log(final.data.payload.messageId);
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
(Point `url` at your own [`smooth-operator-server`](../rust/README.md), or at the hosted endpoint.)
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## Watch it stream
|
|
48
|
+
|
|
49
|
+
`sendMessage` returns a `MessageTurn` that is **both** an async-iterable of events **and** awaitable for the authoritative terminal state. Iterate tokens as they arrive; `await` the same handle for the final response.
|
|
50
|
+
|
|
51
|
+
```ts
|
|
52
|
+
const turn = client.sendMessage({ sessionId: session.sessionId, message: 'Where is my order?' });
|
|
53
|
+
|
|
54
|
+
for await (const ev of turn) {
|
|
55
|
+
if (ev.type === 'stream_chunk') console.error(` ↳ node: ${ev.node}`); // workflow node boundary
|
|
56
|
+
if (ev.type === 'stream_token') process.stdout.write(ev.token ?? ''); // tokens, live
|
|
57
|
+
if (ev.type === 'write_confirmation_required') {
|
|
58
|
+
// HITL: a tool wants to write. Approve, and the resumed stream flows back into THIS turn.
|
|
59
|
+
client.confirmToolAction({ sessionId: session.sessionId, requestId: turn.requestId, approved: true });
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const final = await turn; // EventualResponse — the authoritative terminal state
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
```mermaid
|
|
67
|
+
sequenceDiagram
|
|
68
|
+
participant App
|
|
69
|
+
participant C as SmoothAgentClient
|
|
70
|
+
participant S as Service
|
|
71
|
+
App->>C: sendMessage(...)
|
|
72
|
+
C->>S: { action: send_message }
|
|
73
|
+
S-->>C: immediate_response (202)
|
|
74
|
+
S-->>C: stream_token "Our" "return" "window" …
|
|
75
|
+
S-->>C: stream_chunk { node: response_gen }
|
|
76
|
+
S-->>C: eventual_response (200)
|
|
77
|
+
C-->>App: for-await yields events · await resolves final
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## Transport injection
|
|
83
|
+
|
|
84
|
+
The client never touches a real socket directly — it talks to an injectable `Transport`. The default uses the global `WebSocket`. On Node, inject the `ws` package; in tests, inject a mock — which is how the conformance suite exercises real client code (correlation, parsing, HITL routing) without a network.
|
|
85
|
+
|
|
86
|
+
```ts
|
|
87
|
+
import WebSocket from 'ws';
|
|
88
|
+
new SmoothAgentClient({ url, webSocketFactory: (u) => new WebSocket(u) });
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Runtime validation (optional, Node-only)
|
|
92
|
+
|
|
93
|
+
```ts
|
|
94
|
+
import { ProtocolValidator } from '@smooai/smooth-operator';
|
|
95
|
+
const v = await ProtocolValidator.load();
|
|
96
|
+
v.validateEvent(incomingEvent); // { valid, errors } — ajv-compiled from the spec schemas
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
## Polyglot — one spec, five clients
|
|
102
|
+
|
|
103
|
+
This is one of five native clients generated from the same protocol. Need C# / Microsoft.Extensions.AI? The **`IChatClient` facade** lives in the [.NET client](../dotnet/README.md) (it's a .NET-ecosystem feature). This TypeScript package is the native streaming client.
|
|
104
|
+
|
|
105
|
+
```mermaid
|
|
106
|
+
flowchart LR
|
|
107
|
+
SPEC["spec/ (JSON Schema)"] --> TS["TypeScript<br/>@smooai/smooth-operator"]
|
|
108
|
+
SPEC --> GO["Go"]
|
|
109
|
+
SPEC --> NET[".NET (+ MEAI IChatClient facade)"]
|
|
110
|
+
SPEC --> PY["Python"]
|
|
111
|
+
SPEC --> RS["Rust"]
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
---
|
|
115
|
+
|
|
116
|
+
## Test-driven by default
|
|
117
|
+
|
|
118
|
+
> **Nothing here is vibe-coded — it's verified against a real LLM gateway.**
|
|
119
|
+
|
|
120
|
+
```mermaid
|
|
121
|
+
flowchart TD
|
|
122
|
+
J["🎯 LLM-as-judge quality evals (Rust harness)"]
|
|
123
|
+
E["🌐 Live cross-language E2E — this client boots the real server + drives a real claude-haiku-4-5 turn"]
|
|
124
|
+
C["🧪 Conformance fixtures (shared across all 5 clients)"]
|
|
125
|
+
U["⚡ Unit + type-level tests (discrimination, guards, correlation)"]
|
|
126
|
+
J --> E --> C --> U
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
**16 tests** cover the conformance fixtures, the client (with a mock transport so real parsing/correlation/HITL run), and type-level checks. In the **live cross-language E2E**, this client boots a real `smooth-operator-server` subprocess (KB seeded), drives a real `claude-haiku-4-5` turn over WebSocket, and asserts ≥1 streamed event, a knowledge-grounded "17", and per-session memory.
|
|
130
|
+
|
|
131
|
+
**The proof story:** an LLM-as-judge scored a multi-turn answer **1/5** (the runtime forgot turn 1's context); the failing eval drove a per-session-memory fix; **it now scores 5/5** — a regression a substring test would have missed. See [`docs/EVALS.md`](../docs/EVALS.md).
|
|
132
|
+
|
|
133
|
+
Live tests are **gated, never silently skipped**: they run with `SMOOTH_AGENT_E2E=1` + `SMOOAI_GATEWAY_KEY` and skip cleanly otherwise.
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
pnpm test # conformance + client + type-level — no creds
|
|
137
|
+
pnpm test:e2e # live cross-language E2E (needs gateway key)
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
## Scripts
|
|
141
|
+
|
|
142
|
+
| Script | Purpose |
|
|
143
|
+
| --- | --- |
|
|
144
|
+
| `pnpm generate` | Regenerate `src/generated/types.ts` from `../spec`. |
|
|
145
|
+
| `pnpm build` | `tsc` → `dist/`. |
|
|
146
|
+
| `pnpm typecheck` | Type-check `src/` + `test/` without emitting. |
|
|
147
|
+
| `pnpm test` | Vitest (conformance + client + type-level). |
|
|
148
|
+
|
|
149
|
+
The generated types are committed; CI runs `pnpm generate` + `git diff --exit-code` to catch schemas that changed without a regenerate.
|
|
150
|
+
|
|
151
|
+
## Smoo-powered or bring-your-own
|
|
152
|
+
|
|
153
|
+
Point the client at the hosted **[lom.smoo.ai](https://lom.smoo.ai)** endpoint, or at your own self-hosted `smooth-operator-server` (AWS Lambda or k8s) — same protocol, same client, same code.
|
|
154
|
+
|
|
155
|
+
## License
|
|
156
|
+
|
|
157
|
+
MIT © 2026 Smoo AI
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SmoothAgentClient — a minimal, idiomatic, transport-agnostic client for the
|
|
3
|
+
* smooth-operator WebSocket protocol.
|
|
4
|
+
*
|
|
5
|
+
* Design goals
|
|
6
|
+
* ------------
|
|
7
|
+
* - **Transport-agnostic.** The client never touches a real socket directly; it
|
|
8
|
+
* talks to an injectable {@link Transport}. The default ({@link WebSocketTransport})
|
|
9
|
+
* uses the global `WebSocket`, but tests inject a mock and Node can inject `ws`.
|
|
10
|
+
* - **Request/response correlation by `requestId`.** Every action gets a generated
|
|
11
|
+
* `requestId`; the client routes incoming events back to the originating call.
|
|
12
|
+
* - **Streaming as an async iterator.** `sendMessage` returns a {@link MessageTurn}
|
|
13
|
+
* that is both awaitable (resolves with the terminal `eventual_response`) and
|
|
14
|
+
* async-iterable (yields each `stream_token` / `stream_chunk` / HITL event in
|
|
15
|
+
* order). This models the `stream_token`/`stream_chunk` → `eventual_response`
|
|
16
|
+
* flow without forcing a callback style on the caller.
|
|
17
|
+
* - **No live server required.** Correctness is fully unit-testable with a mock
|
|
18
|
+
* transport (see `test/client.test.ts`).
|
|
19
|
+
*/
|
|
20
|
+
import { type Transport, type WebSocketFactory } from './transport.js';
|
|
21
|
+
import type { CreateConversationSessionRequest, CreateConversationSessionResponse, EventualResponse, GetMessagesRequest, GetMessagesResponse, GetSessionRequest, GetSessionResponse, SendMessageRequest, ServerEvent } from './types.js';
|
|
22
|
+
export interface SmoothAgentClientOptions {
|
|
23
|
+
/** WebSocket URL, e.g. `wss://realtime.prod.smooth-agent.dev`. */
|
|
24
|
+
url: string;
|
|
25
|
+
/** Inject a transport (for tests / non-browser runtimes). Defaults to a WebSocket transport. */
|
|
26
|
+
transport?: Transport;
|
|
27
|
+
/** Inject a WebSocket factory used by the default transport (e.g. the `ws` package on Node). */
|
|
28
|
+
webSocketFactory?: WebSocketFactory;
|
|
29
|
+
/** Generate request IDs. Defaults to `crypto.randomUUID()` with a `req-` prefix. */
|
|
30
|
+
generateRequestId?: () => string;
|
|
31
|
+
/** Per-request timeout in ms for non-streaming actions. Default 30000. */
|
|
32
|
+
requestTimeout?: number;
|
|
33
|
+
/**
|
|
34
|
+
* Overall timeout in ms for a streaming `sendMessage` turn: if the server accepts
|
|
35
|
+
* the message but never emits a terminal `eventual_response` / `error`, the turn
|
|
36
|
+
* rejects with a {@link TurnTimeoutError} instead of hanging forever. Default
|
|
37
|
+
* 120000. Set to 0 (or a negative number) to disable.
|
|
38
|
+
*/
|
|
39
|
+
turnTimeout?: number;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* A streaming turn that received no terminal `eventual_response` / `error` within the
|
|
43
|
+
* configured {@link SmoothAgentClientOptions.turnTimeout}. The turn rejects with this
|
|
44
|
+
* and its async iteration throws it, so a stuck server can never hang the caller.
|
|
45
|
+
*/
|
|
46
|
+
export declare class TurnTimeoutError extends Error {
|
|
47
|
+
readonly requestId: string;
|
|
48
|
+
constructor(requestId: string, ms: number);
|
|
49
|
+
}
|
|
50
|
+
/** A protocol-level error event surfaced as a throwable. */
|
|
51
|
+
export declare class ProtocolError extends Error {
|
|
52
|
+
readonly code: string;
|
|
53
|
+
readonly requestId?: string;
|
|
54
|
+
constructor(code: string, message: string, requestId?: string);
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* A streaming message turn. Await it for the terminal {@link EventualResponse},
|
|
58
|
+
* or async-iterate it to receive every intermediate event in arrival order.
|
|
59
|
+
*
|
|
60
|
+
* ```ts
|
|
61
|
+
* const turn = client.sendMessage({ sessionId, message: 'hi' });
|
|
62
|
+
* for await (const ev of turn) {
|
|
63
|
+
* if (ev.type === 'stream_token') process.stdout.write(ev.token ?? '');
|
|
64
|
+
* }
|
|
65
|
+
* const final = await turn; // EventualResponse
|
|
66
|
+
* ```
|
|
67
|
+
*/
|
|
68
|
+
export declare class MessageTurn implements AsyncIterable<ServerEvent>, PromiseLike<EventualResponse> {
|
|
69
|
+
/** The requestId this turn is correlated on. */
|
|
70
|
+
readonly requestId: string;
|
|
71
|
+
private readonly queue;
|
|
72
|
+
private waiter;
|
|
73
|
+
private done;
|
|
74
|
+
private finalEvent;
|
|
75
|
+
private error;
|
|
76
|
+
private readonly settled;
|
|
77
|
+
private settle;
|
|
78
|
+
private fail;
|
|
79
|
+
private readonly onClose;
|
|
80
|
+
private timeoutTimer;
|
|
81
|
+
constructor(requestId: string, onClose: () => void, turnTimeout?: number);
|
|
82
|
+
/** Feed an event into the turn (called by the client's dispatcher). */
|
|
83
|
+
push(event: ServerEvent): void;
|
|
84
|
+
/** Force-close the turn (e.g. on disconnect) with an error. */
|
|
85
|
+
abort(err: unknown): void;
|
|
86
|
+
private deliver;
|
|
87
|
+
private finish;
|
|
88
|
+
[Symbol.asyncIterator](): AsyncIterator<ServerEvent>;
|
|
89
|
+
then<TResult1 = EventualResponse, TResult2 = never>(onfulfilled?: ((value: EventualResponse) => TResult1 | PromiseLike<TResult1>) | null, onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null): PromiseLike<TResult1 | TResult2>;
|
|
90
|
+
}
|
|
91
|
+
export declare class SmoothAgentClient {
|
|
92
|
+
private readonly transport;
|
|
93
|
+
private readonly generateRequestId;
|
|
94
|
+
private readonly requestTimeout;
|
|
95
|
+
private readonly turnTimeout;
|
|
96
|
+
/** requestId → single-response waiter (create_session, get_session, ping, …). */
|
|
97
|
+
private readonly pending;
|
|
98
|
+
/** requestId → active streaming turn (send_message, and HITL resumes). */
|
|
99
|
+
private readonly turns;
|
|
100
|
+
/** Unsolicited-event listeners (keepalive, server-push). */
|
|
101
|
+
private readonly listeners;
|
|
102
|
+
private unsubscribe;
|
|
103
|
+
constructor(options: SmoothAgentClientOptions);
|
|
104
|
+
/** Open the underlying transport. */
|
|
105
|
+
connect(): Promise<void>;
|
|
106
|
+
/** Close the transport and reject all in-flight work. */
|
|
107
|
+
disconnect(reason?: string): void;
|
|
108
|
+
/** Subscribe to unsolicited / uncorrelated server events (e.g. keepalive). */
|
|
109
|
+
onEvent(listener: (event: ServerEvent) => void): () => void;
|
|
110
|
+
/** Start a new conversation session. Resolves with the session descriptor. */
|
|
111
|
+
createConversationSession(req: Omit<CreateConversationSessionRequest, 'action' | 'requestId'>): Promise<CreateConversationSessionResponse>;
|
|
112
|
+
/** Fetch a session snapshot by ID. */
|
|
113
|
+
getSession(req: Omit<GetSessionRequest, 'action' | 'requestId'>): Promise<GetSessionResponse>;
|
|
114
|
+
/** Fetch a page of conversation messages. */
|
|
115
|
+
getMessages(req: Omit<GetMessagesRequest, 'action' | 'requestId'>): Promise<GetMessagesResponse>;
|
|
116
|
+
/** Keepalive ping. Resolves with the server timestamp from the `pong` event. */
|
|
117
|
+
ping(): Promise<number>;
|
|
118
|
+
/**
|
|
119
|
+
* Submit a user message and return a {@link MessageTurn}: await it for the
|
|
120
|
+
* terminal `eventual_response`, or async-iterate it for the streaming events.
|
|
121
|
+
*/
|
|
122
|
+
sendMessage(req: Omit<SendMessageRequest, 'action' | 'requestId'>): MessageTurn;
|
|
123
|
+
/**
|
|
124
|
+
* Approve or reject a pending tool write, resuming the paused turn identified
|
|
125
|
+
* by `requestId`. The resumed streaming events flow back into the original
|
|
126
|
+
* {@link MessageTurn} for that `requestId`.
|
|
127
|
+
*/
|
|
128
|
+
confirmToolAction(req: {
|
|
129
|
+
sessionId: string;
|
|
130
|
+
requestId: string;
|
|
131
|
+
approved: boolean;
|
|
132
|
+
}): void;
|
|
133
|
+
/**
|
|
134
|
+
* Submit an OTP code, resuming the paused turn identified by `requestId`.
|
|
135
|
+
* The resumed streaming events flow back into the original {@link MessageTurn}.
|
|
136
|
+
*/
|
|
137
|
+
verifyOtp(req: {
|
|
138
|
+
sessionId: string;
|
|
139
|
+
requestId: string;
|
|
140
|
+
code: string;
|
|
141
|
+
}): void;
|
|
142
|
+
/** Send an action that expects a single correlated response event. */
|
|
143
|
+
private request;
|
|
144
|
+
/** Parse and route an incoming frame to the right consumer. */
|
|
145
|
+
private handleFrame;
|
|
146
|
+
private failAll;
|
|
147
|
+
}
|
|
148
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|