10xgraph-client 1.0.0-rc.2 → 1.0.0-rc.3
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/CHANGELOG.md +39 -0
- package/README.md +169 -225
- package/dist/cjs/client.d.ts +55 -19
- package/dist/cjs/endpoints/forgetMemories.d.ts +3 -1
- package/dist/cjs/endpoints/listMemories.d.ts +3 -0
- package/dist/cjs/endpoints/me.d.ts +25 -0
- package/dist/cjs/endpoints/searchMemory.d.ts +3 -1
- package/dist/cjs/endpoints/tasks.d.ts +95 -0
- package/dist/cjs/endpoints/threads.d.ts +3 -0
- package/dist/cjs/filters.d.ts +27 -0
- package/dist/cjs/index.d.ts +3 -1
- package/dist/cjs/message.d.ts +3 -0
- package/dist/client.d.ts +55 -19
- package/dist/client.d.ts.map +1 -1
- package/dist/endpoints/forgetMemories.d.ts +3 -1
- package/dist/endpoints/forgetMemories.d.ts.map +1 -1
- package/dist/endpoints/listMemories.d.ts +3 -0
- package/dist/endpoints/listMemories.d.ts.map +1 -1
- package/dist/endpoints/me.d.ts +26 -0
- package/dist/endpoints/me.d.ts.map +1 -0
- package/dist/endpoints/searchMemory.d.ts +3 -1
- package/dist/endpoints/searchMemory.d.ts.map +1 -1
- package/dist/endpoints/tasks.d.ts +96 -0
- package/dist/endpoints/tasks.d.ts.map +1 -0
- package/dist/endpoints/threads.d.ts +3 -0
- package/dist/endpoints/threads.d.ts.map +1 -1
- package/dist/filters.d.ts +28 -0
- package/dist/filters.d.ts.map +1 -0
- package/dist/index.cjs +3 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1217 -1122
- package/dist/index.js.map +1 -1
- package/dist/message.d.ts +3 -0
- package/dist/message.d.ts.map +1 -1
- package/dist/tools.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/client.ts +107 -42
- package/src/endpoints/forgetMemories.ts +10 -2
- package/src/endpoints/listMemories.ts +6 -0
- package/src/endpoints/me.ts +71 -0
- package/src/endpoints/searchMemory.ts +3 -1
- package/src/endpoints/tasks.ts +170 -0
- package/src/endpoints/threads.ts +10 -0
- package/src/filters.ts +32 -0
- package/src/index.ts +9 -1
- package/src/message.ts +4 -0
- package/src/tools.ts +13 -5
- package/dist/cjs/endpoints/addThreadMessages.d.ts +0 -25
- package/dist/endpoints/addThreadMessages.d.ts +0 -26
- package/dist/endpoints/addThreadMessages.d.ts.map +0 -1
- package/src/endpoints/addThreadMessages.ts +0 -88
package/CHANGELOG.md
CHANGED
|
@@ -26,6 +26,45 @@ project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
|
26
26
|
|
|
27
27
|
---
|
|
28
28
|
|
|
29
|
+
## [1.0.0-rc.3] - 2026-11-11
|
|
30
|
+
|
|
31
|
+
The third release candidate of `10xgraph-client` 1.0. Use it with `10xgraph-api` 1.0.0rc6. New
|
|
32
|
+
response fields are typed optional, so the client still works against older servers; a
|
|
33
|
+
`ToolResultBlock.name` sent to an older server is ignored there.
|
|
34
|
+
|
|
35
|
+
### Added
|
|
36
|
+
|
|
37
|
+
- `ToolResultBlock.name?: string`: the name of the tool that produced the result. The server sets it on results from `10xgraph` 1.0.0rc6 or later; older results have none. Results the client builds for client-side tools (`ToolExecutor`: success, thrown error, unknown tool, rejected arguments, duplicate call id) set it too.
|
|
38
|
+
- `me()` for `GET /v1/me` of `10xgraph-api`: who the caller is and what they may do. `data` is
|
|
39
|
+
`{ user_id, tenant, roles, permissions, reach }` (`reach` is `own`, `tenant` or `all`; `permissions` is
|
|
40
|
+
`['*']` for an unrestricted identity) or `{ auth: 'off' }` when the server runs without auth. New exported
|
|
41
|
+
types and helper: `MeResponse`, `MeData`, `MeIdentity`, `MeAuthOff`, `MeReach`, `isAuthOff`. Needs a
|
|
42
|
+
`10xgraph-api` with RBAC.
|
|
43
|
+
- Background task methods for the `/v1/tasks` routes of `10xgraph-api`: `runTask(name, { args, kwargs })`,
|
|
44
|
+
`scheduleTask(name, { args, kwargs, schedule })`, `getTask(id)`, `rescheduleTask(scheduleId, schedule)`
|
|
45
|
+
and `cancelTask(id)`. `schedule` is exactly one of `{ cron }`, `{ at }` or `{ every }` (seconds); the
|
|
46
|
+
client does not validate it, the server answers 422. New exported types: `TaskStatus`, `TaskSchedule`,
|
|
47
|
+
`TaskRecord`, `ScheduleRecord`, `TaskCallOptions`, `RunTaskResponse`, `ScheduleTaskRequest`,
|
|
48
|
+
`ScheduleTaskResponse`, `GetTaskResponse`, `RescheduleTaskResponse`, `CancelTaskResponse`. Needs a
|
|
49
|
+
`10xgraph-api` with background tasks.
|
|
50
|
+
- Filter support. `threads()` takes `filters` (sent as a JSON `filters` query parameter);
|
|
51
|
+
`searchMemory()`, `listMemories()` and `forgetMemories()` take `filters` in the request body.
|
|
52
|
+
A filter is `{ column: value }` (equality) or `{ column: { op: value } }` with the operators
|
|
53
|
+
`eq`, `ne`, `in`, `nin`, `like`, `ilike`, `is_null`, `gt`, `gte`, `lt`, `lte`. New exported
|
|
54
|
+
types: `Filters`, `FilterCondition`, `FilterOperator`, `FilterScalar`. `listMemories()` gains
|
|
55
|
+
`filters`. The client does not validate columns; the server answers 422. Needs a `10xgraph-api`
|
|
56
|
+
with filter support.
|
|
57
|
+
|
|
58
|
+
### Changed
|
|
59
|
+
|
|
60
|
+
- `forgetMemories()` now throws a `TenxGraphError` subclass on a failed request (`ValidationError`
|
|
61
|
+
for 422, with the server message) instead of a plain `Error`. When the response has no JSON
|
|
62
|
+
error body the message is still `Forget memories failed: <status> <statusText>`.
|
|
63
|
+
|
|
64
|
+
### Removed
|
|
65
|
+
|
|
66
|
+
- `addThreadMessages` and its `AddThreadMessages*` types. The `POST /v1/threads/{thread_id}/messages` route was removed from `10xgraph-api`, so the method had nothing to call. Send messages through `invoke` or `stream`, and use `updateThreadMessageFeedback` for feedback.
|
|
67
|
+
|
|
29
68
|
## [1.0.0-rc.2] - 2026-10-30
|
|
30
69
|
|
|
31
70
|
The second release candidate of `10xgraph-client` 1.0, aligned with `10xgraph` and `10xgraph-api`
|
package/README.md
CHANGED
|
@@ -4,306 +4,240 @@
|
|
|
4
4
|
[](https://www.typescriptlang.org/)
|
|
5
5
|
[](https://opensource.org/licenses/MIT)
|
|
6
6
|
|
|
7
|
-
The TypeScript client for
|
|
8
|
-
|
|
7
|
+
The typed TypeScript client for 10xGraph, infrastructure for AI applications. It talks to the
|
|
8
|
+
`10xgraph-api` server from any frontend or Node app: invoke, stream, threads, memory, files,
|
|
9
|
+
background tasks, remote tools and realtime audio.
|
|
9
10
|
|
|
10
|
-
10xGraph
|
|
11
|
+
> 10xGraph is open-source, self-hosted infrastructure for AI applications. You write the agents, tools and tasks; 10xGraph runs them behind an API server with authentication, role-based access, tenant isolation, durable state in Postgres and Redis, background jobs, metrics and tracing, and generates Docker and Kubernetes deploy files. MIT licensed, by 10xScale. Formerly Agentflow.
|
|
11
12
|
|
|
12
|
-
> **Coming from `@10xscale/agentflow-client`?** This is the same client under its new name.
|
|
13
|
-
>
|
|
13
|
+
> **Coming from `@10xscale/agentflow-client`?** This is the same client under its new name. Change
|
|
14
|
+
> the import and you are done; the old `AgentFlow*` names still work until 2.0. See
|
|
14
15
|
> [Migrating from `@10xscale/agentflow-client`](#migrating-from-10xscaleagentflow-client).
|
|
15
16
|
|
|
16
|
-
##
|
|
17
|
-
|
|
18
|
-
- **Simple API**: one client class with a method per server endpoint
|
|
19
|
-
- **Streaming**: HTTP and WebSocket streaming for chat UIs
|
|
20
|
-
- **Tool execution**: run browser-side tools locally, with recursion handling
|
|
21
|
-
- **State management**: dynamic state schema with validation
|
|
22
|
-
- **Realtime audio**: WebSocket audio-to-audio via `/v1/graph/live`
|
|
23
|
-
- **TypeScript first**: full type definitions, dual ESM + CJS
|
|
24
|
-
|
|
25
|
-
## Installation
|
|
17
|
+
## Install
|
|
26
18
|
|
|
27
19
|
```bash
|
|
28
20
|
npm install 10xgraph-client
|
|
29
|
-
# or
|
|
30
|
-
yarn add 10xgraph-client
|
|
31
|
-
# or
|
|
32
|
-
pnpm add 10xgraph-client
|
|
21
|
+
# or: yarn add 10xgraph-client / pnpm add 10xgraph-client
|
|
33
22
|
```
|
|
34
23
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
From 1.0, match `major.minor` across `10xgraph`, `10xgraph-api` and `10xgraph-client`; patch
|
|
38
|
-
versions are independent (a patch is only a bug or security fix). Before 1.0, pick versions by
|
|
39
|
-
this table:
|
|
40
|
-
|
|
41
|
-
| `10xgraph-client` (npm) | API server | Core framework |
|
|
42
|
-
| -------------------------------------- | ------------------------------------------------- | ------------------------------ |
|
|
43
|
-
| 1.0.x | `10xgraph-api` 1.0.x | `10xgraph` 1.0.x |
|
|
44
|
-
| 0.6.x | `10xgraph-api` >= 0.7.0 | `10xgraph` >= 0.10.0 |
|
|
45
|
-
| `@10xscale/agentflow-client` 0.5.x | `10xscale-agentflow-cli` >= 0.6.0, `10xgraph-api` | `10xscale-agentflow` >= 0.10.0 |
|
|
46
|
-
| `@10xscale/agentflow-client` 0.3-0.4.x | `10xscale-agentflow-cli` >= 0.5.0 | `10xscale-agentflow` >= 0.9.0 |
|
|
24
|
+
Node 20 or newer. It uses the global `fetch`, ships ESM and CJS with types, and works with any
|
|
25
|
+
frontend framework. There are no React hooks; call the client from your own state code.
|
|
47
26
|
|
|
48
|
-
The client
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
is upgraded.
|
|
27
|
+
The client talks to a `10xgraph-api` server, so run one first. Match `major.minor` across
|
|
28
|
+
`10xgraph`, `10xgraph-api` and `10xgraph-client` (patch versions are independent). WebSocket auth
|
|
29
|
+
(`wsStream()` and `realtime()`) uses the `10xgraph-bearer` subprotocol, which needs `10xgraph-api`
|
|
30
|
+
1.0. See [Run the server](https://10xgraph.com/docs/server/run-the-server).
|
|
53
31
|
|
|
54
|
-
##
|
|
55
|
-
|
|
56
|
-
### Basic usage
|
|
32
|
+
## Quickstart
|
|
57
33
|
|
|
58
34
|
```typescript
|
|
59
35
|
import { TenxGraphClient, Message } from '10xgraph-client';
|
|
60
36
|
|
|
61
37
|
const client = new TenxGraphClient({
|
|
62
38
|
baseUrl: 'http://localhost:8000',
|
|
63
|
-
authToken:
|
|
64
|
-
debug: true, // optional
|
|
39
|
+
authToken: token, // a bearer token for the signed-in user
|
|
65
40
|
});
|
|
66
41
|
|
|
67
|
-
|
|
68
|
-
|
|
42
|
+
// Request and response. Remote tools run automatically during invoke.
|
|
43
|
+
const result = await client.invoke(
|
|
44
|
+
[Message.text_message('Where is my order 1042?', 'user')],
|
|
45
|
+
{ config: { thread_id: 'support-1042' } }
|
|
46
|
+
);
|
|
69
47
|
console.log(result.messages);
|
|
48
|
+
|
|
49
|
+
// Server-sent events
|
|
50
|
+
for await (const chunk of client.stream([Message.text_message('And the refund status?', 'user')], {
|
|
51
|
+
config: { thread_id: 'support-1042' },
|
|
52
|
+
})) {
|
|
53
|
+
if (chunk.event === 'message') console.log(chunk.message?.content);
|
|
54
|
+
}
|
|
70
55
|
```
|
|
71
56
|
|
|
72
|
-
|
|
57
|
+
`stream()` returns an async generator of `StreamChunk`. `wsStream()` takes the same arguments and
|
|
58
|
+
streams over a WebSocket. Both accept `initial_state`, `config`, `recursion_limit`, `on_busy`
|
|
59
|
+
(`'wait' | 'cancel'`), `resume` with `interrupt_id`, `response_granularity` and `signal` (an
|
|
60
|
+
`AbortSignal` that cancels the request). A 409 throws `ConflictError` and is not retried.
|
|
73
61
|
|
|
74
|
-
|
|
62
|
+
To answer a human-in-the-loop interrupt, read it from a chunk and resume the thread:
|
|
75
63
|
|
|
76
64
|
```typescript
|
|
77
|
-
import {
|
|
65
|
+
import { getInterrupt, approveInterrupt, rejectInterrupt } from '10xgraph-client';
|
|
78
66
|
|
|
79
|
-
const
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
67
|
+
const interrupt = getInterrupt(chunk); // null when the chunk carries none
|
|
68
|
+
if (interrupt) {
|
|
69
|
+
await client.invoke([], { config: { thread_id }, ...approveInterrupt(interrupt) });
|
|
70
|
+
// or ...rejectInterrupt(interrupt)
|
|
71
|
+
}
|
|
72
|
+
```
|
|
83
73
|
|
|
84
|
-
|
|
85
|
-
baseUrl: 'https://api.example.com',
|
|
86
|
-
auth: basicAuth('service-user', 'service-password'),
|
|
87
|
-
});
|
|
74
|
+
## What the client covers
|
|
88
75
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
76
|
+
| Area | Methods |
|
|
77
|
+
| --- | --- |
|
|
78
|
+
| Runs | `invoke`, `stream`, `wsStream`, `stopGraph` |
|
|
79
|
+
| Identity and server | `ping`, `me`, `graph`, `graphTools`, `graphStateSchema`, `observability` |
|
|
80
|
+
| Threads and messages | `threads`, `threadDetails`, `threadMessages`, `singleMessage`, `deleteMessage`, `updateThreadMessageFeedback`, `deleteThread` |
|
|
81
|
+
| Thread state | `threadState`, `updateThreadState`, `clearThreadState` |
|
|
82
|
+
| Memory store | `storeMemory`, `searchMemory`, `getMemory`, `updateMemory`, `deleteMemory`, `listMemories`, `forgetMemories` |
|
|
83
|
+
| Files | `uploadFile`, `getFile`, `listFiles`, `getFileInfo`, `getFileAccessUrl`, `deleteFile`, `getMultimodalConfig` |
|
|
84
|
+
| Background tasks | `runTask`, `scheduleTask`, `getTask`, `rescheduleTask`, `cancelTask` |
|
|
85
|
+
| Remote tools | `registerTool`, `registerToolHandler` |
|
|
86
|
+
| Realtime audio | `realtime` |
|
|
93
87
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
});
|
|
98
|
-
```
|
|
88
|
+
Every method that does not return a stream accepts a per-call `options` argument with an
|
|
89
|
+
`AbortSignal`. The full list with types is in the
|
|
90
|
+
[`TenxGraphClient` reference](https://10xgraph.com/docs/reference/client/client).
|
|
99
91
|
|
|
100
|
-
###
|
|
92
|
+
### Threads, memory and files
|
|
101
93
|
|
|
102
94
|
```typescript
|
|
103
|
-
const
|
|
95
|
+
const page = await client.threads({ limit: 20 });
|
|
96
|
+
const messages = await client.threadMessages('support-1042', { limit: 50 });
|
|
104
97
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
}
|
|
109
|
-
}
|
|
98
|
+
const upload = await client.uploadFile(file);
|
|
99
|
+
const msg = Message.withFile('Summarize this document', upload.data.file_id, upload.data.mime_type);
|
|
100
|
+
const accessUrl = await client.getFileAccessUrl(upload.data.file_id);
|
|
110
101
|
```
|
|
111
102
|
|
|
112
|
-
|
|
103
|
+
### Background tasks
|
|
113
104
|
|
|
114
|
-
|
|
105
|
+
Tasks marked `http=True` on the server can be started and read from the client:
|
|
115
106
|
|
|
116
|
-
```
|
|
117
|
-
|
|
107
|
+
```typescript
|
|
108
|
+
const { data } = await client.runTask('web_add', { kwargs: { a: 1, b: 2 } });
|
|
109
|
+
const task = await client.getTask(data.task_id);
|
|
110
|
+
```
|
|
118
111
|
|
|
119
|
-
|
|
112
|
+
`scheduleTask` takes a `schedule` with exactly one of `cron`, `at` or `every`; the server answers
|
|
113
|
+
501 when it has no Redis. See [Background tasks](https://10xgraph.com/docs/server/background-tasks).
|
|
120
114
|
|
|
121
|
-
|
|
122
|
-
{ model: 'gemini-3.8-live', modalities: 'AUDIO' },
|
|
123
|
-
{ reconnect: { maxAttempts: 5 } }
|
|
124
|
-
);
|
|
115
|
+
## Authentication and secure frontends
|
|
125
116
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
session.on('tool_call', (e) => console.log('tool', e.name, e.args));
|
|
129
|
-
session.on('error', (e) => console.error(e.message));
|
|
117
|
+
```typescript
|
|
118
|
+
import { TenxGraphClient, basicAuth, headerAuth } from '10xgraph-client';
|
|
130
119
|
|
|
131
|
-
|
|
132
|
-
session.
|
|
133
|
-
|
|
134
|
-
|
|
120
|
+
new TenxGraphClient({ baseUrl, authToken: token }); // bearer token
|
|
121
|
+
new TenxGraphClient({ baseUrl, authToken: () => session.accessToken }); // called before each request
|
|
122
|
+
new TenxGraphClient({ baseUrl, auth: basicAuth('service-user', 'service-password') });
|
|
123
|
+
new TenxGraphClient({ baseUrl, auth: headerAuth('X-API-Key', apiKey) });
|
|
124
|
+
new TenxGraphClient({ baseUrl, credentials: 'include' }); // cookie sessions
|
|
135
125
|
```
|
|
136
126
|
|
|
137
|
-
|
|
138
|
-
|
|
127
|
+
`setAuthToken(token)` swaps the token on a live client and `clearAuth()` removes it.
|
|
128
|
+
|
|
129
|
+
- The server decides who the caller is and what they may read. The client only carries the
|
|
130
|
+
identity. Roles, tenant columns and ownership are enforced on the server.
|
|
131
|
+
- Anything in a browser bundle is readable by the person using it, including `NEXT_PUBLIC_*`
|
|
132
|
+
variables. Never put a shared API key, a signing secret or a service credential in frontend code.
|
|
133
|
+
Use a server-side proxy that holds the secret, or give each signed-in user a short-lived token.
|
|
134
|
+
- Browsers cannot set headers on a WebSocket. For `wsStream()` and `realtime()` the client sends
|
|
135
|
+
the token as the second entry of the `Sec-WebSocket-Protocol` list, after the `10xgraph-bearer`
|
|
136
|
+
sentinel (`WS_BEARER_SUBPROTOCOL`). The token never goes in the URL.
|
|
137
|
+
- In Node versions without a global `WebSocket` (before 21), pass an implementation:
|
|
139
138
|
|
|
140
|
-
```
|
|
139
|
+
```typescript
|
|
141
140
|
import WebSocket from 'ws';
|
|
142
141
|
const client = new TenxGraphClient({ baseUrl, authToken, webSocketImpl: WebSocket });
|
|
143
142
|
```
|
|
144
143
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
```typescript
|
|
148
|
-
const upload = await client.uploadFile(file);
|
|
149
|
-
|
|
150
|
-
// Best URL for rendering/downloading in the UI.
|
|
151
|
-
// Cloud-backed deployments typically return a signed URL here.
|
|
152
|
-
const accessUrl = upload.data.direct_url ?? upload.data.url;
|
|
144
|
+
More in [Secure your frontend](https://10xgraph.com/docs/client/secure-your-frontend) and the
|
|
145
|
+
[security model](https://10xgraph.com/docs/production/security-model).
|
|
153
146
|
|
|
154
|
-
|
|
155
|
-
const fileUrl = await client.getFileAccessUrl(upload.data.file_id);
|
|
147
|
+
## Remote tools
|
|
156
148
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
### Tool registration
|
|
161
|
-
|
|
162
|
-
**Important:** remote tools (registered client-side) should **only** be used for browser-level APIs
|
|
163
|
-
like `localStorage` or `navigator.geolocation`. For most operations (database queries, external API
|
|
164
|
-
calls, calculations), define your tools in the Python backend instead. See
|
|
165
|
-
[Remote tools](https://10xgraph.com/docs/client/remote-tools) for details.
|
|
149
|
+
Remote tools run in the user's browser, for browser-only APIs such as `localStorage` or
|
|
150
|
+
`navigator.geolocation`. Database queries, external API calls and calculations belong in tools on
|
|
151
|
+
the server.
|
|
166
152
|
|
|
167
153
|
```typescript
|
|
168
|
-
//
|
|
169
|
-
client.registerToolHandler('
|
|
170
|
-
|
|
154
|
+
// The matching schema must be declared in the server's 10xgraph.json.
|
|
155
|
+
client.registerToolHandler('get_location', async () => {
|
|
156
|
+
const pos = await new Promise<GeolocationPosition>((resolve, reject) =>
|
|
157
|
+
navigator.geolocation.getCurrentPosition(resolve, reject)
|
|
158
|
+
);
|
|
159
|
+
return { lat: pos.coords.latitude, lon: pos.coords.longitude };
|
|
171
160
|
});
|
|
172
161
|
|
|
173
|
-
//
|
|
174
|
-
const result = await client.invoke([Message.text_message('
|
|
162
|
+
// The server asks for the tool during the run; the client runs it and sends the result back.
|
|
163
|
+
const result = await client.invoke([Message.text_message('Find a store near me', 'user')]);
|
|
175
164
|
```
|
|
176
165
|
|
|
177
|
-
|
|
166
|
+
Model-facing metadata is declared on the server, never by an untrusted client:
|
|
178
167
|
|
|
179
168
|
```json
|
|
180
169
|
{
|
|
181
170
|
"remote_tools": [
|
|
182
171
|
{
|
|
183
172
|
"node": "assistant",
|
|
184
|
-
"name": "
|
|
185
|
-
"description": "Get
|
|
186
|
-
"parameters": {
|
|
187
|
-
"type": "object",
|
|
188
|
-
"properties": { "location": { "type": "string" } },
|
|
189
|
-
"required": ["location"]
|
|
190
|
-
}
|
|
173
|
+
"name": "get_location",
|
|
174
|
+
"description": "Get the user's current coordinates",
|
|
175
|
+
"parameters": { "type": "object", "properties": {} }
|
|
191
176
|
}
|
|
192
177
|
]
|
|
193
178
|
}
|
|
194
179
|
```
|
|
195
180
|
|
|
196
|
-
No client setup call is required or available.
|
|
197
|
-
|
|
198
|
-
## Documentation
|
|
199
|
-
|
|
200
|
-
Full documentation lives at **[10xgraph.com/docs](https://10xgraph.com/docs/client)**.
|
|
201
|
-
|
|
202
|
-
### Guides
|
|
203
|
-
|
|
204
|
-
- **[Create a client](https://10xgraph.com/docs/client/create-client)**: setup and first request
|
|
205
|
-
- **[Invoke an agent](https://10xgraph.com/docs/client/invoke-agent)**: request/response with tool execution
|
|
206
|
-
- **[Stream responses](https://10xgraph.com/docs/client/stream-responses)**: real-time streaming
|
|
207
|
-
- **[Remote tools](https://10xgraph.com/docs/client/remote-tools)**: when to use client-side tools
|
|
208
|
-
- **[Realtime audio](https://10xgraph.com/docs/client/realtime-audio)**: the `/v1/graph/live` session
|
|
209
|
-
- **[Error handling](https://10xgraph.com/docs/client/error-handling)**: error classes and recovery
|
|
210
|
-
|
|
211
|
-
### Reference
|
|
212
|
-
|
|
213
|
-
- **[`TenxGraphClient`](https://10xgraph.com/docs/reference/client/client)**: constructor config and every method
|
|
214
|
-
- **[`Message` and content blocks](https://10xgraph.com/docs/reference/client/message)**
|
|
215
|
-
- **[Auth](https://10xgraph.com/docs/reference/client/auth)** and **[Errors](https://10xgraph.com/docs/reference/client/errors)**
|
|
216
|
-
- **[Troubleshooting](https://10xgraph.com/docs/troubleshooting/client)**: common issues and solutions
|
|
217
|
-
|
|
218
|
-
## Key APIs
|
|
181
|
+
No client setup call is required or available. See
|
|
182
|
+
[Remote tools](https://10xgraph.com/docs/client/remote-tools).
|
|
219
183
|
|
|
220
|
-
|
|
184
|
+
## Realtime audio
|
|
221
185
|
|
|
222
|
-
|
|
186
|
+
Transport only: you stream PCM16 in and get PCM16 out, and wire microphone capture and playback
|
|
187
|
+
yourself.
|
|
223
188
|
|
|
224
189
|
```typescript
|
|
225
|
-
const
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
```
|
|
230
|
-
|
|
231
|
-
Optional: `on_busy: 'wait' | 'cancel'` controls what happens when the thread already has an active
|
|
232
|
-
run, and `resume` with `interrupt_id` answers an open interrupt. A 409 throws `ConflictError`
|
|
233
|
-
(not retried automatically).
|
|
234
|
-
|
|
235
|
-
### `stream()`: real-time streaming
|
|
236
|
-
|
|
237
|
-
```typescript
|
|
238
|
-
const stream = client.stream(messages);
|
|
239
|
-
for await (const chunk of stream) {
|
|
240
|
-
// Process chunks in real-time
|
|
241
|
-
}
|
|
242
|
-
```
|
|
243
|
-
|
|
244
|
-
### `graphStateSchema()`: dynamic schema
|
|
190
|
+
const session = client.realtime(
|
|
191
|
+
{ model: 'gemini-3.8-live', modalities: 'AUDIO' },
|
|
192
|
+
{ reconnect: { maxAttempts: 5 } }
|
|
193
|
+
);
|
|
245
194
|
|
|
246
|
-
|
|
195
|
+
session.on('audio', (pcm16, sampleRate) => playback(pcm16, sampleRate)); // PCM16 @ 24 kHz
|
|
196
|
+
session.on('output_transcript', (e) => console.log(e.text));
|
|
197
|
+
session.on('tool_call', (e) => console.log('tool', e.name, e.args));
|
|
198
|
+
session.on('error', (e) => console.error(e.message));
|
|
247
199
|
|
|
248
|
-
|
|
249
|
-
|
|
200
|
+
await session.ready; // socket open and init sent
|
|
201
|
+
session.sendAudio(micChunk); // PCM16 @ 16 kHz (Uint8Array | ArrayBuffer)
|
|
202
|
+
// push-to-talk: session.activityStart() / session.activityEnd()
|
|
203
|
+
session.close(); // graceful end; disables reconnect
|
|
250
204
|
```
|
|
251
205
|
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
List the tools the graph's tool nodes expose, grouped by node. Each tool is tagged with its
|
|
255
|
-
source (`local`, `mcp`, or `remote`):
|
|
256
|
-
|
|
257
|
-
```typescript
|
|
258
|
-
const { data } = await client.graphTools();
|
|
259
|
-
// data.nodes[].tools[] -> { name, description, source, parameters }
|
|
260
|
-
```
|
|
206
|
+
The server honours `model` only when it lists it in `websocket.realtime_models`. See
|
|
207
|
+
[Realtime audio](https://10xgraph.com/docs/client/realtime-audio).
|
|
261
208
|
|
|
262
|
-
|
|
209
|
+
## Errors
|
|
263
210
|
|
|
264
|
-
|
|
265
|
-
latest run:
|
|
211
|
+
Every failure is a `TenxGraphError` or a subclass, so `instanceof` works:
|
|
266
212
|
|
|
267
213
|
```typescript
|
|
268
|
-
|
|
269
|
-
|
|
214
|
+
import { TenxGraphError, AuthenticationError, RateLimitError, ConflictError } from '10xgraph-client';
|
|
215
|
+
|
|
216
|
+
try {
|
|
217
|
+
await client.invoke(messages);
|
|
218
|
+
} catch (err) {
|
|
219
|
+
if (err instanceof RateLimitError) {
|
|
220
|
+
await sleep((err.retryAfterSeconds ?? 1) * 1000); // set when the server sends a hint
|
|
221
|
+
} else if (err instanceof AuthenticationError) {
|
|
222
|
+
// refresh the token
|
|
223
|
+
} else if (err instanceof TenxGraphError) {
|
|
224
|
+
console.error(err.statusCode, err.errorCode, err.requestId, err.message);
|
|
225
|
+
} else {
|
|
226
|
+
throw err;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
270
229
|
```
|
|
271
230
|
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
- **[invoke-example.ts](examples/invoke-example.ts)**: basic invoke with tool execution
|
|
277
|
-
- **[stream-example.ts](examples/stream-example.ts)**: streaming responses
|
|
278
|
-
- **[state-schema-examples.ts](examples/state-schema-examples.ts)**: form generation and validation
|
|
279
|
-
|
|
280
|
-
## Architecture
|
|
281
|
-
|
|
282
|
-
```
|
|
283
|
-
┌──────────────────────┐
|
|
284
|
-
│ Your application │
|
|
285
|
-
└──────────┬───────────┘
|
|
286
|
-
│ TenxGraphClient
|
|
287
|
-
▼
|
|
288
|
-
┌──────────────────────┐
|
|
289
|
-
│ 10xgraph-client │ <- this library
|
|
290
|
-
│ client, tools, │
|
|
291
|
-
│ messages │
|
|
292
|
-
└──────────┬───────────┘
|
|
293
|
-
│ HTTP/HTTPS + WebSocket
|
|
294
|
-
▼
|
|
295
|
-
┌──────────────────────┐
|
|
296
|
-
│ 10xgraph-api │ <- your backend
|
|
297
|
-
│ (10xgraph api) │
|
|
298
|
-
└──────────────────────┘
|
|
299
|
-
```
|
|
231
|
+
Other subclasses include `PermissionError`, `NotFoundError`, `ValidationError`, `ServerError`,
|
|
232
|
+
`RequestTimeoutError`, `NetworkError`, `WebSocketError` and `StreamError`. See
|
|
233
|
+
[Error handling](https://10xgraph.com/docs/client/error-handling).
|
|
300
234
|
|
|
301
235
|
## Configuration
|
|
302
236
|
|
|
303
237
|
```typescript
|
|
304
238
|
const client = new TenxGraphClient({
|
|
305
239
|
baseUrl: string, // Required: API base URL
|
|
306
|
-
authToken?: string,
|
|
240
|
+
authToken?: string | (() => string | null | undefined), // Optional: bearer token or getter
|
|
307
241
|
auth?: TenxGraphAuth, // Optional: bearer/basic/custom header auth
|
|
308
242
|
headers?: HeadersInit, // Optional: extra headers for every request
|
|
309
243
|
credentials?: RequestCredentials, // Optional: cookie/session auth
|
|
@@ -313,6 +247,18 @@ const client = new TenxGraphClient({
|
|
|
313
247
|
});
|
|
314
248
|
```
|
|
315
249
|
|
|
250
|
+
## One stack, backend to frontend
|
|
251
|
+
|
|
252
|
+
| Layer | Package | What it is |
|
|
253
|
+
| --- | --- | --- |
|
|
254
|
+
| Core | [`10xgraph`](https://github.com/10xGraph/10xGraph) (PyPI, import `tenxgraph`) | Graphs, agents, tools, state, storage |
|
|
255
|
+
| Server | [`10xgraph-api`](https://github.com/10xGraph/10xgraph-api) (PyPI, command `10xgraph`) | API server, auth, jobs, deploy files |
|
|
256
|
+
| Client | `10xgraph-client` (this package) | Typed TypeScript client |
|
|
257
|
+
| Docs | [10xgraph.com/docs/client](https://10xgraph.com/docs/client) | Guides and reference |
|
|
258
|
+
|
|
259
|
+
Start a local server with `10xgraph dev`. For a Next.js or React app see
|
|
260
|
+
[Next.js and React](https://10xgraph.com/docs/client/nextjs-and-react).
|
|
261
|
+
|
|
316
262
|
## Migrating from `@10xscale/agentflow-client`
|
|
317
263
|
|
|
318
264
|
The project was renamed from Agentflow to **10xGraph** because "Agentflow" is shared by several
|
|
@@ -331,7 +277,7 @@ Steps:
|
|
|
331
277
|
|
|
332
278
|
1. `npm uninstall @10xscale/agentflow-client && npm install 10xgraph-client`
|
|
333
279
|
2. Replace `'@10xscale/agentflow-client'` with `'10xgraph-client'` in your imports.
|
|
334
|
-
3. Upgrade the server to `10xgraph-api`
|
|
280
|
+
3. Upgrade the server to `10xgraph-api` 1.0 if you use `wsStream()` or `realtime()`.
|
|
335
281
|
4. Optionally rename `AgentFlow*` identifiers to `TenxGraph*`. The old names are exported as
|
|
336
282
|
deprecated aliases of the same classes and types, so `instanceof AgentFlowError` keeps working.
|
|
337
283
|
They are removed in 2.0.
|
|
@@ -344,28 +290,26 @@ One observable difference: errors now report `error.name === 'TenxGraphError'` i
|
|
|
344
290
|
Ships dual ESM + CJS with types. `import` resolves `dist/index.js` (ESM); `require` resolves
|
|
345
291
|
`dist/index.cjs`. Tree-shakeable (`"sideEffects": false`).
|
|
346
292
|
|
|
347
|
-
## Testing
|
|
348
|
-
|
|
349
|
-
```bash
|
|
350
|
-
npm test # watch mode
|
|
351
|
-
npm run test:run # run once
|
|
352
|
-
npm run build # build the library
|
|
353
|
-
```
|
|
354
|
-
|
|
355
293
|
## TypeScript support
|
|
356
294
|
|
|
357
295
|
```typescript
|
|
358
296
|
import type {
|
|
359
|
-
|
|
360
|
-
Message,
|
|
297
|
+
TenxGraphConfig,
|
|
361
298
|
ToolRegistration,
|
|
362
299
|
InvokeResult,
|
|
363
300
|
StreamChunk,
|
|
364
301
|
AgentState,
|
|
365
|
-
AgentStateSchema,
|
|
366
302
|
} from '10xgraph-client';
|
|
367
303
|
```
|
|
368
304
|
|
|
305
|
+
## Testing
|
|
306
|
+
|
|
307
|
+
```bash
|
|
308
|
+
npm test # watch mode
|
|
309
|
+
npm run test:run # run once
|
|
310
|
+
npm run build # build the library
|
|
311
|
+
```
|
|
312
|
+
|
|
369
313
|
## Contributing
|
|
370
314
|
|
|
371
315
|
**Be the first community contributor on this wall.**
|