@iicp/client 0.7.12 → 0.7.35
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/README.md +120 -19
- package/dist/backends/anthropic.d.ts +40 -0
- package/dist/backends/anthropic.d.ts.map +1 -0
- package/dist/backends/anthropic.js +205 -0
- package/dist/backends/anthropic.js.map +1 -0
- package/dist/backends/index.d.ts +1 -1
- package/dist/backends/index.d.ts.map +1 -1
- package/dist/backends/index.js +3 -1
- package/dist/backends/index.js.map +1 -1
- package/dist/cip_policy.d.ts +9 -0
- package/dist/cip_policy.d.ts.map +1 -1
- package/dist/cip_policy.js +13 -0
- package/dist/cip_policy.js.map +1 -1
- package/dist/cli.d.ts +24 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +205 -35
- package/dist/cli.js.map +1 -1
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +122 -36
- package/dist/client.js.map +1 -1
- package/dist/confidentiality.d.ts +14 -0
- package/dist/confidentiality.d.ts.map +1 -0
- package/dist/confidentiality.js +104 -0
- package/dist/confidentiality.js.map +1 -0
- package/dist/delegation.d.ts +40 -0
- package/dist/delegation.d.ts.map +1 -0
- package/dist/delegation.js +76 -0
- package/dist/delegation.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/instance_lock.d.ts +11 -0
- package/dist/instance_lock.d.ts.map +1 -0
- package/dist/instance_lock.js +86 -0
- package/dist/instance_lock.js.map +1 -0
- package/dist/node.d.ts +48 -0
- package/dist/node.d.ts.map +1 -1
- package/dist/node.js +0 -0
- package/dist/node.js.map +1 -1
- package/dist/node_log.d.ts +5 -0
- package/dist/node_log.d.ts.map +1 -0
- package/dist/node_log.js +69 -0
- package/dist/node_log.js.map +1 -0
- package/dist/qualify.js +2 -2
- package/dist/qualify.js.map +1 -1
- package/dist/types.d.ts +10 -1
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
[](https://github.com/RobLe3/iicp-client-typescript/actions/workflows/ci.yml)
|
|
4
4
|
[](LICENSE)
|
|
5
5
|
[](https://iicp.network/spec)
|
|
6
|
-
[](https://www.npmjs.com/package/@iicp/client)
|
|
7
7
|
|
|
8
8
|
Official TypeScript client library for the [IICP protocol](https://iicp.network) — route AI agent tasks by intent across a self-organising mesh of provider nodes. No central broker. No hardcoded endpoints.
|
|
9
9
|
|
|
@@ -18,9 +18,9 @@ urn:iicp:intent:llm:chat:v1 → discover → select → submit
|
|
|
18
18
|
## Install
|
|
19
19
|
|
|
20
20
|
```bash
|
|
21
|
-
npm install iicp
|
|
22
|
-
# yarn add iicp
|
|
23
|
-
# pnpm add iicp
|
|
21
|
+
npm install @iicp/client
|
|
22
|
+
# yarn add @iicp/client
|
|
23
|
+
# pnpm add @iicp/client
|
|
24
24
|
```
|
|
25
25
|
|
|
26
26
|
> **Upgrade note (0.5.3)** — if you operate a node and use the native IICP
|
|
@@ -31,12 +31,26 @@ npm install iicp-client
|
|
|
31
31
|
|
|
32
32
|
---
|
|
33
33
|
|
|
34
|
+
## Architecture — consumer or provider?
|
|
35
|
+
|
|
36
|
+
This SDK covers **both** sides of the IICP protocol:
|
|
37
|
+
|
|
38
|
+
| Role | What you do | Class |
|
|
39
|
+
|------|-------------|-------|
|
|
40
|
+
| **Consumer** | Send AI tasks to the mesh; discover and submit | `IicpClient` |
|
|
41
|
+
| **Provider** | Run a node, register with the directory, serve tasks | `IicpNode` |
|
|
42
|
+
|
|
43
|
+
Consumer and provider can run in the same process. For production provider nodes backed by Ollama/vLLM, see [iicp.network/docs/node-setup](https://iicp.network/docs/node-setup).
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
34
47
|
## Quickstart
|
|
35
48
|
|
|
36
49
|
```typescript
|
|
37
|
-
import { IicpClient } from "iicp
|
|
50
|
+
import { IicpClient } from "@iicp/client";
|
|
38
51
|
|
|
39
|
-
|
|
52
|
+
// directory_url defaults to https://iicp.network/api
|
|
53
|
+
const client = new IicpClient();
|
|
40
54
|
|
|
41
55
|
// chat() discovers, selects the best node, and submits in one call
|
|
42
56
|
const response = await client.chat(
|
|
@@ -62,19 +76,19 @@ const result = await client.submit({
|
|
|
62
76
|
## Configuration
|
|
63
77
|
|
|
64
78
|
```typescript
|
|
65
|
-
import { IicpClient } from "iicp
|
|
79
|
+
import { IicpClient } from "@iicp/client";
|
|
66
80
|
|
|
67
81
|
const client = new IicpClient({
|
|
68
|
-
directory_url : "https://iicp.network", // IICP directory
|
|
69
|
-
timeout_ms : 30_000,
|
|
70
|
-
region : "eu-central",
|
|
71
|
-
api_token : "your-token",
|
|
82
|
+
directory_url : "https://iicp.network/api", // IICP directory
|
|
83
|
+
timeout_ms : 30_000, // max 120 000 (SDK-04)
|
|
84
|
+
region : "eu-central", // prefer nodes in region
|
|
85
|
+
api_token : "your-token", // optional auth token
|
|
72
86
|
});
|
|
73
87
|
```
|
|
74
88
|
|
|
75
89
|
| Option | Default | Description |
|
|
76
90
|
|--------|---------|-------------|
|
|
77
|
-
| `directory_url` | `"https://iicp.network"` | IICP directory endpoint |
|
|
91
|
+
| `directory_url` | `"https://iicp.network/api"` | IICP directory endpoint |
|
|
78
92
|
| `timeout_ms` | `30000` | Request timeout — max 120 000 ms |
|
|
79
93
|
| `region` | `undefined` | Preferred node region |
|
|
80
94
|
| `api_token` | `undefined` | Bearer token for authenticated nodes |
|
|
@@ -85,10 +99,10 @@ const client = new IicpClient({
|
|
|
85
99
|
|
|
86
100
|
```typescript
|
|
87
101
|
const nodes = await client.discover("urn:iicp:intent:llm:chat:v1", {
|
|
88
|
-
region : "eu-central",
|
|
89
|
-
|
|
90
|
-
min_reputation: 0.7,
|
|
91
|
-
limit : 5,
|
|
102
|
+
region : "eu-central", // prefer nodes in this region
|
|
103
|
+
qos : "interactive", // quality-of-service hint
|
|
104
|
+
min_reputation: 0.7, // floor on directory reputation
|
|
105
|
+
limit : 5, // capped at 50
|
|
92
106
|
});
|
|
93
107
|
```
|
|
94
108
|
|
|
@@ -97,7 +111,7 @@ const nodes = await client.discover("urn:iicp:intent:llm:chat:v1", {
|
|
|
97
111
|
## Error handling
|
|
98
112
|
|
|
99
113
|
```typescript
|
|
100
|
-
import { IicpClient, IicpError } from "iicp
|
|
114
|
+
import { IicpClient, IicpError } from "@iicp/client";
|
|
101
115
|
|
|
102
116
|
const client = new IicpClient();
|
|
103
117
|
try {
|
|
@@ -116,7 +130,7 @@ Error codes match the [IICP error reference](https://iicp.network/docs/error-ref
|
|
|
116
130
|
## Serving as a provider node
|
|
117
131
|
|
|
118
132
|
```typescript
|
|
119
|
-
import { IicpNode } from "iicp
|
|
133
|
+
import { IicpNode } from "@iicp/client";
|
|
120
134
|
|
|
121
135
|
const node = new IicpNode({
|
|
122
136
|
nodeId : "my-node-001",
|
|
@@ -134,6 +148,93 @@ const stop = node.serve(async (task) => {
|
|
|
134
148
|
process.on("SIGINT", () => { stop(); });
|
|
135
149
|
```
|
|
136
150
|
|
|
151
|
+
### Run a node from the CLI
|
|
152
|
+
|
|
153
|
+
Installing the package puts an `iicp-node` binary on your `PATH`. The CLI wires
|
|
154
|
+
up NAT detection, registration, heartbeats and a backend handler for you:
|
|
155
|
+
|
|
156
|
+
```bash
|
|
157
|
+
# Ollama on the default port — only --model is required
|
|
158
|
+
iicp-node serve --model qwen2.5:0.5b
|
|
159
|
+
|
|
160
|
+
# An OpenAI-compatible backend (LM Studio, vLLM, hosted gateway)
|
|
161
|
+
iicp-node serve \
|
|
162
|
+
--model phi3:mini \
|
|
163
|
+
--backend-url http://localhost:1234 \
|
|
164
|
+
--backend-api-key "$BACKEND_API_KEY"
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
Every flag has an environment-variable equivalent (shown by `iicp-node --help`):
|
|
168
|
+
`--model` / `IICP_BACKEND_MODEL`, `--backend-url` / `IICP_BACKEND_URL`,
|
|
169
|
+
`--backend-type` / `IICP_BACKEND_TYPE`, `--backend-api-key` / `IICP_BACKEND_API_KEY`,
|
|
170
|
+
`--directory-url` / `IICP_DIRECTORY_URL` (default `https://iicp.network/api`),
|
|
171
|
+
`--port` / `IICP_PORT` (default 9484).
|
|
172
|
+
|
|
173
|
+
### Backend types
|
|
174
|
+
|
|
175
|
+
`--backend-type` (or the `getBackendHandler(type, opts)` factory) selects how the
|
|
176
|
+
node talks to your model server. All backends present an identical `llm:chat:v1`
|
|
177
|
+
surface to IICP clients:
|
|
178
|
+
|
|
179
|
+
| `--backend-type` | Handler export | Speaks | Default base URL |
|
|
180
|
+
|------------------|----------------|--------|------------------|
|
|
181
|
+
| `openai_compat` *(default)* | `openaiCompatHandler` | OpenAI `/v1/*` dialect (Ollama, LM Studio, OpenAI) | `http://localhost:11434/v1` |
|
|
182
|
+
| `vllm` | `vllmHandler` | OpenAI dialect, tuned for vLLM | `http://localhost:8000/v1` |
|
|
183
|
+
| `llamacpp` | `llamacppHandler` | OpenAI dialect, tuned for llama.cpp server | `http://localhost:8080/v1` |
|
|
184
|
+
| `anthropic` | `anthropicHandler` | Anthropic Messages API (`POST /v1/messages`) — first-class Claude | `https://api.anthropic.com/v1` |
|
|
185
|
+
|
|
186
|
+
#### Native Anthropic backend (v0.7.35+)
|
|
187
|
+
|
|
188
|
+
The `anthropic` backend speaks the Anthropic **Messages API** directly rather than
|
|
189
|
+
going through the OpenAI-compat shim. It translates an IICP `llm:chat:v1` task into a
|
|
190
|
+
Messages request — hoisting `system` messages to the top-level `system` field, setting
|
|
191
|
+
the required `max_tokens` (default 4096), mapping `image_url` content parts to
|
|
192
|
+
Anthropic image blocks — and maps the response back to the OpenAI chat-completion
|
|
193
|
+
shape, so a Claude-backed node is indistinguishable from an Ollama/vLLM node to any
|
|
194
|
+
client. The API key is sent as the `x-api-key` header (not a Bearer token).
|
|
195
|
+
|
|
196
|
+
```bash
|
|
197
|
+
# Serve Claude to the mesh. --backend-type anthropic defaults --backend-url to
|
|
198
|
+
# https://api.anthropic.com, so you only supply the key and model.
|
|
199
|
+
iicp-node serve \
|
|
200
|
+
--backend-type anthropic \
|
|
201
|
+
--backend-api-key "$ANTHROPIC_API_KEY" \
|
|
202
|
+
--model claude-opus-4-8
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
In code:
|
|
206
|
+
|
|
207
|
+
```typescript
|
|
208
|
+
import { IicpNode, anthropicHandler } from "@iicp/client";
|
|
209
|
+
|
|
210
|
+
const node = new IicpNode({
|
|
211
|
+
nodeId : "claude-node-001",
|
|
212
|
+
endpoint: "http://my.public.host:8020",
|
|
213
|
+
intent : "urn:iicp:intent:llm:chat:v1",
|
|
214
|
+
model : "claude-opus-4-8",
|
|
215
|
+
});
|
|
216
|
+
const handler = anthropicHandler({
|
|
217
|
+
apiKey: process.env.ANTHROPIC_API_KEY,
|
|
218
|
+
model : "claude-opus-4-8",
|
|
219
|
+
// baseUrl defaults to https://api.anthropic.com/v1
|
|
220
|
+
});
|
|
221
|
+
const token = await node.register();
|
|
222
|
+
node.serve(handler, { port: 8020, nodeToken: token });
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
### Multimodal capabilities — vision and audio
|
|
226
|
+
|
|
227
|
+
When a node registers, the SDK derives the `input_modalities` it advertises from the
|
|
228
|
+
model name (`buildCapabilities` / `modalitiesForModel`). Every model serves `text`;
|
|
229
|
+
in addition:
|
|
230
|
+
|
|
231
|
+
- **image** (vision) — model name contains `vl`, `vision`, `llava`, or `omni`
|
|
232
|
+
- **audio** — model name contains `audio`, `voxtral`, or `omni`
|
|
233
|
+
|
|
234
|
+
A node serving several models advertises one capability entry per
|
|
235
|
+
`(intent, input_modalities)` group, so consumers can pick the right model for a
|
|
236
|
+
multimodal task via discover.
|
|
237
|
+
|
|
137
238
|
### Listen port — default 9484, auto-increment (v0.7.5+)
|
|
138
239
|
|
|
139
240
|
The official IICP port **9484** is the default listen port (`IICP_PORT`, `--port`).
|
|
@@ -227,7 +328,7 @@ Conformance tier: `iicp:sdk:v1` (spec S.14) · [Request a badge](https://iicp.ne
|
|
|
227
328
|
```bash
|
|
228
329
|
npm install # install deps
|
|
229
330
|
npm run typecheck # tsc strict
|
|
230
|
-
npm test #
|
|
331
|
+
npm test # 224 unit tests
|
|
231
332
|
npm run build # emit to dist/
|
|
232
333
|
```
|
|
233
334
|
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Native Anthropic Messages-API backend helper.
|
|
3
|
+
*
|
|
4
|
+
* Unlike openai_compat/vllm/llamacpp (which share the OpenAI `/v1/*` dialect via
|
|
5
|
+
* buildOpenAiDialectHandler), Anthropic speaks the Messages API (`POST /v1/messages`):
|
|
6
|
+
* a top-level `system` string instead of a system-role message, `x-api-key` +
|
|
7
|
+
* `anthropic-version` headers instead of a bearer token, a REQUIRED `max_tokens`, and
|
|
8
|
+
* `content` blocks instead of OpenAI's `message.content`.
|
|
9
|
+
*
|
|
10
|
+
* This handler translates an IICP `llm:chat:v1` task (OpenAI chat shape) → an Anthropic
|
|
11
|
+
* Messages request, then translates the response BACK to the OpenAI chat-completion
|
|
12
|
+
* shape — so a Claude-backed node looks identical to an Ollama/vLLM node to any IICP
|
|
13
|
+
* client. First-class Claude support (prompt caching, native content blocks) without
|
|
14
|
+
* the OpenAI-compat shim (which strips audio + disables caching).
|
|
15
|
+
*
|
|
16
|
+
* Capability roadmap C1 (reports/capability-gaps-implementation-plan-2026-06-03.md;
|
|
17
|
+
* research #414). No new dependency — uses built-in fetch.
|
|
18
|
+
*/
|
|
19
|
+
import { type BackendHandler } from "./base.js";
|
|
20
|
+
export interface AnthropicOptions {
|
|
21
|
+
/** Anthropic API root. Default `https://api.anthropic.com/v1`. */
|
|
22
|
+
baseUrl?: string;
|
|
23
|
+
/** Claude model id (e.g. `claude-opus-4-8`). If unset, taken from task payload. */
|
|
24
|
+
model?: string;
|
|
25
|
+
/** Anthropic API key → sent as `x-api-key` (reuses #5 backend api-key support). */
|
|
26
|
+
apiKey?: string;
|
|
27
|
+
/** Per-request HTTP timeout in milliseconds. Default 30000. */
|
|
28
|
+
timeoutMs?: number;
|
|
29
|
+
/** Value for the required `anthropic-version` header. */
|
|
30
|
+
anthropicVersion?: string;
|
|
31
|
+
/** `max_tokens` sent when the task omits it (Anthropic requires the field). */
|
|
32
|
+
defaultMaxTokens?: number;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Build a TaskHandler that proxies `llm:chat:v1` CALLs to the Anthropic Messages API.
|
|
36
|
+
* Only chat is supported (Anthropic has no completion/embedding endpoint). Success →
|
|
37
|
+
* `{ result: <OpenAI-shaped JSON> }`; failure → `{ error_code, error_message }`.
|
|
38
|
+
*/
|
|
39
|
+
export declare function anthropicHandler(opts?: AnthropicOptions): BackendHandler;
|
|
40
|
+
//# sourceMappingURL=anthropic.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"anthropic.d.ts","sourceRoot":"","sources":["../../src/backends/anthropic.ts"],"names":[],"mappings":"AACA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,KAAK,cAAc,EAAiD,MAAM,WAAW,CAAC;AAM/F,MAAM,WAAW,gBAAgB;IAC/B,kEAAkE;IAClE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,mFAAmF;IACnF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,mFAAmF;IACnF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,+DAA+D;IAC/D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,yDAAyD;IACzD,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,+EAA+E;IAC/E,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AA+GD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,GAAE,gBAAqB,GAAG,cAAc,CAqE5E"}
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
/**
|
|
4
|
+
* Native Anthropic Messages-API backend helper.
|
|
5
|
+
*
|
|
6
|
+
* Unlike openai_compat/vllm/llamacpp (which share the OpenAI `/v1/*` dialect via
|
|
7
|
+
* buildOpenAiDialectHandler), Anthropic speaks the Messages API (`POST /v1/messages`):
|
|
8
|
+
* a top-level `system` string instead of a system-role message, `x-api-key` +
|
|
9
|
+
* `anthropic-version` headers instead of a bearer token, a REQUIRED `max_tokens`, and
|
|
10
|
+
* `content` blocks instead of OpenAI's `message.content`.
|
|
11
|
+
*
|
|
12
|
+
* This handler translates an IICP `llm:chat:v1` task (OpenAI chat shape) → an Anthropic
|
|
13
|
+
* Messages request, then translates the response BACK to the OpenAI chat-completion
|
|
14
|
+
* shape — so a Claude-backed node looks identical to an Ollama/vLLM node to any IICP
|
|
15
|
+
* client. First-class Claude support (prompt caching, native content blocks) without
|
|
16
|
+
* the OpenAI-compat shim (which strips audio + disables caching).
|
|
17
|
+
*
|
|
18
|
+
* Capability roadmap C1 (reports/capability-gaps-implementation-plan-2026-06-03.md;
|
|
19
|
+
* research #414). No new dependency — uses built-in fetch.
|
|
20
|
+
*/
|
|
21
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
|
+
exports.anthropicHandler = anthropicHandler;
|
|
23
|
+
const CHAT_INTENT = "urn:iicp:intent:llm:chat:v1";
|
|
24
|
+
const DEFAULT_ANTHROPIC_VERSION = "2023-06-01";
|
|
25
|
+
const DEFAULT_MAX_TOKENS = 4096;
|
|
26
|
+
/** Translate one OpenAI message `content` into Anthropic content. */
|
|
27
|
+
function toAnthropicContent(content) {
|
|
28
|
+
if (typeof content === "string")
|
|
29
|
+
return content;
|
|
30
|
+
if (!Array.isArray(content))
|
|
31
|
+
return content;
|
|
32
|
+
const blocks = [];
|
|
33
|
+
for (const partRaw of content) {
|
|
34
|
+
if (typeof partRaw !== "object" || partRaw === null)
|
|
35
|
+
continue;
|
|
36
|
+
const part = partRaw;
|
|
37
|
+
if (part.type === "text") {
|
|
38
|
+
blocks.push({ type: "text", text: part.text ?? "" });
|
|
39
|
+
}
|
|
40
|
+
else if (part.type === "image_url") {
|
|
41
|
+
const url = part.image_url?.url ?? "";
|
|
42
|
+
if (url.startsWith("data:")) {
|
|
43
|
+
const comma = url.indexOf(",");
|
|
44
|
+
if (comma < 0)
|
|
45
|
+
continue;
|
|
46
|
+
const header = url.slice(0, comma);
|
|
47
|
+
const b64 = url.slice(comma + 1);
|
|
48
|
+
const mediaType = header.slice("data:".length).split(";")[0] || "image/png";
|
|
49
|
+
blocks.push({ type: "image", source: { type: "base64", media_type: mediaType, data: b64 } });
|
|
50
|
+
}
|
|
51
|
+
else if (url) {
|
|
52
|
+
blocks.push({ type: "image", source: { type: "url", url } });
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
// unknown parts dropped
|
|
56
|
+
}
|
|
57
|
+
return blocks;
|
|
58
|
+
}
|
|
59
|
+
/** Translate an OpenAI chat payload → an Anthropic Messages request body. */
|
|
60
|
+
function toAnthropicRequest(payload, model, defaultMaxTokens) {
|
|
61
|
+
const body = {};
|
|
62
|
+
body.model = payload.model ?? model;
|
|
63
|
+
const systemParts = [];
|
|
64
|
+
const messages = [];
|
|
65
|
+
const inMsgs = Array.isArray(payload.messages) ? payload.messages : [];
|
|
66
|
+
for (const msgRaw of inMsgs) {
|
|
67
|
+
if (typeof msgRaw !== "object" || msgRaw === null)
|
|
68
|
+
continue;
|
|
69
|
+
const msg = msgRaw;
|
|
70
|
+
if (msg.role === "system") {
|
|
71
|
+
if (typeof msg.content === "string")
|
|
72
|
+
systemParts.push(msg.content);
|
|
73
|
+
else if (Array.isArray(msg.content)) {
|
|
74
|
+
for (const p of msg.content) {
|
|
75
|
+
if (typeof p === "object" && p !== null && p.type === "text") {
|
|
76
|
+
systemParts.push(p.text ?? "");
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
messages.push({ role: msg.role, content: toAnthropicContent(msg.content) });
|
|
83
|
+
}
|
|
84
|
+
body.messages = messages;
|
|
85
|
+
const sys = systemParts.filter((s) => s).join("\n\n");
|
|
86
|
+
if (sys)
|
|
87
|
+
body.system = sys;
|
|
88
|
+
const mt = payload.max_tokens;
|
|
89
|
+
body.max_tokens = mt && mt > 0 ? mt : defaultMaxTokens;
|
|
90
|
+
if (payload.temperature !== undefined)
|
|
91
|
+
body.temperature = payload.temperature;
|
|
92
|
+
if (payload.top_p !== undefined)
|
|
93
|
+
body.top_p = payload.top_p;
|
|
94
|
+
const stop = payload.stop;
|
|
95
|
+
if (stop !== undefined && stop !== null) {
|
|
96
|
+
body.stop_sequences = typeof stop === "string" ? [stop] : stop;
|
|
97
|
+
}
|
|
98
|
+
return body;
|
|
99
|
+
}
|
|
100
|
+
const STOP_REASON_TO_FINISH = {
|
|
101
|
+
end_turn: "stop",
|
|
102
|
+
stop_sequence: "stop",
|
|
103
|
+
max_tokens: "length",
|
|
104
|
+
tool_use: "tool_calls",
|
|
105
|
+
};
|
|
106
|
+
/** Translate an Anthropic Messages response → the OpenAI chat-completion shape. */
|
|
107
|
+
function toOpenAiResponse(data) {
|
|
108
|
+
const content = Array.isArray(data.content) ? data.content : [];
|
|
109
|
+
const text = content
|
|
110
|
+
.filter((b) => typeof b === "object" && b !== null && b.type === "text")
|
|
111
|
+
.map((b) => b.text ?? "")
|
|
112
|
+
.join("");
|
|
113
|
+
const usage = data.usage ?? {};
|
|
114
|
+
const promptTokens = usage.input_tokens ?? 0;
|
|
115
|
+
const completionTokens = usage.output_tokens ?? 0;
|
|
116
|
+
return {
|
|
117
|
+
id: data.id ?? "",
|
|
118
|
+
object: "chat.completion",
|
|
119
|
+
model: data.model ?? "",
|
|
120
|
+
choices: [
|
|
121
|
+
{
|
|
122
|
+
index: 0,
|
|
123
|
+
message: { role: "assistant", content: text },
|
|
124
|
+
finish_reason: STOP_REASON_TO_FINISH[data.stop_reason] ?? "stop",
|
|
125
|
+
},
|
|
126
|
+
],
|
|
127
|
+
usage: {
|
|
128
|
+
prompt_tokens: promptTokens,
|
|
129
|
+
completion_tokens: completionTokens,
|
|
130
|
+
total_tokens: promptTokens + completionTokens,
|
|
131
|
+
},
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Build a TaskHandler that proxies `llm:chat:v1` CALLs to the Anthropic Messages API.
|
|
136
|
+
* Only chat is supported (Anthropic has no completion/embedding endpoint). Success →
|
|
137
|
+
* `{ result: <OpenAI-shaped JSON> }`; failure → `{ error_code, error_message }`.
|
|
138
|
+
*/
|
|
139
|
+
function anthropicHandler(opts = {}) {
|
|
140
|
+
const baseUrl = (opts.baseUrl ?? "https://api.anthropic.com/v1").replace(/\/$/, "");
|
|
141
|
+
const model = opts.model;
|
|
142
|
+
const apiKey = opts.apiKey ?? "";
|
|
143
|
+
const timeoutMs = opts.timeoutMs ?? 30000;
|
|
144
|
+
const anthropicVersion = opts.anthropicVersion ?? DEFAULT_ANTHROPIC_VERSION;
|
|
145
|
+
const defaultMaxTokens = opts.defaultMaxTokens ?? DEFAULT_MAX_TOKENS;
|
|
146
|
+
const headers = {
|
|
147
|
+
"Content-Type": "application/json",
|
|
148
|
+
"anthropic-version": anthropicVersion,
|
|
149
|
+
};
|
|
150
|
+
if (apiKey)
|
|
151
|
+
headers["x-api-key"] = apiKey;
|
|
152
|
+
return async function handler(task) {
|
|
153
|
+
const intent = String(task.intent ?? "");
|
|
154
|
+
if (intent !== CHAT_INTENT) {
|
|
155
|
+
return {
|
|
156
|
+
error_code: 400,
|
|
157
|
+
error_message: `anthropic: unsupported intent ${JSON.stringify(intent)}; the Messages API serves only ${CHAT_INTENT}`,
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
const payload = task.payload;
|
|
161
|
+
if (payload !== undefined && payload !== null && (typeof payload !== "object" || Array.isArray(payload))) {
|
|
162
|
+
return { error_code: 400, error_message: `anthropic: task.payload must be a dict, got ${typeof payload}` };
|
|
163
|
+
}
|
|
164
|
+
const body = toAnthropicRequest(payload ?? {}, model, defaultMaxTokens);
|
|
165
|
+
if (!body.model) {
|
|
166
|
+
return {
|
|
167
|
+
error_code: 400,
|
|
168
|
+
error_message: "anthropic: no model — pass `model` to the backend factory or include `model` in the task payload",
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
const ctrl = new AbortController();
|
|
172
|
+
const t = setTimeout(() => ctrl.abort(), timeoutMs);
|
|
173
|
+
let resp;
|
|
174
|
+
try {
|
|
175
|
+
resp = await fetch(`${baseUrl}/messages`, {
|
|
176
|
+
method: "POST",
|
|
177
|
+
headers,
|
|
178
|
+
body: JSON.stringify(body),
|
|
179
|
+
signal: ctrl.signal,
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
catch (exc) {
|
|
183
|
+
clearTimeout(t);
|
|
184
|
+
if (ctrl.signal.aborted)
|
|
185
|
+
return { error_code: 408, error_message: "anthropic: backend timed out" };
|
|
186
|
+
const msg = exc instanceof Error ? exc.message : String(exc);
|
|
187
|
+
return { error_code: 502, error_message: `anthropic: HTTP transport error: ${msg}` };
|
|
188
|
+
}
|
|
189
|
+
clearTimeout(t);
|
|
190
|
+
if (!resp.ok) {
|
|
191
|
+
const text = await resp.text().catch(() => "");
|
|
192
|
+
return { error_code: resp.status, error_message: `anthropic: upstream ${resp.status}: ${text.slice(0, 512)}` };
|
|
193
|
+
}
|
|
194
|
+
let data;
|
|
195
|
+
try {
|
|
196
|
+
data = await resp.json();
|
|
197
|
+
}
|
|
198
|
+
catch (exc) {
|
|
199
|
+
const msg = exc instanceof Error ? exc.message : String(exc);
|
|
200
|
+
return { error_code: 502, error_message: `anthropic: upstream returned non-JSON: ${msg}` };
|
|
201
|
+
}
|
|
202
|
+
return { result: toOpenAiResponse(data) };
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
//# sourceMappingURL=anthropic.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"anthropic.js","sourceRoot":"","sources":["../../src/backends/anthropic.ts"],"names":[],"mappings":"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"}
|
package/dist/backends/index.d.ts
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* `--backend-type` flag).
|
|
7
7
|
*/
|
|
8
8
|
import { type BackendHandler, type BackendOptions } from "./base.js";
|
|
9
|
-
export declare const BACKEND_TYPES: readonly ["openai_compat", "vllm", "llamacpp"];
|
|
9
|
+
export declare const BACKEND_TYPES: readonly ["openai_compat", "vllm", "llamacpp", "anthropic"];
|
|
10
10
|
export type BackendType = (typeof BACKEND_TYPES)[number];
|
|
11
11
|
/** Return a backend handler by name. Throws on an unknown type. */
|
|
12
12
|
export declare function getBackendHandler(backendType: string, opts?: BackendOptions): BackendHandler;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/backends/index.ts"],"names":[],"mappings":"AACA;;;;;;GAMG;AAEH,OAAO,EAAE,KAAK,cAAc,EAAE,KAAK,cAAc,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/backends/index.ts"],"names":[],"mappings":"AACA;;;;;;GAMG;AAEH,OAAO,EAAE,KAAK,cAAc,EAAE,KAAK,cAAc,EAAE,MAAM,WAAW,CAAC;AAMrE,eAAO,MAAM,aAAa,6DAA8D,CAAC;AACzF,MAAM,MAAM,WAAW,GAAG,CAAC,OAAO,aAAa,CAAC,CAAC,MAAM,CAAC,CAAC;AASzD,mEAAmE;AACnE,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,GAAE,cAAmB,GAAG,cAAc,CAQhG"}
|
package/dist/backends/index.js
CHANGED
|
@@ -13,11 +13,13 @@ exports.getBackendHandler = getBackendHandler;
|
|
|
13
13
|
const openai_compat_js_1 = require("./openai_compat.js");
|
|
14
14
|
const vllm_js_1 = require("./vllm.js");
|
|
15
15
|
const llamacpp_js_1 = require("./llamacpp.js");
|
|
16
|
-
|
|
16
|
+
const anthropic_js_1 = require("./anthropic.js");
|
|
17
|
+
exports.BACKEND_TYPES = ["openai_compat", "vllm", "llamacpp", "anthropic"];
|
|
17
18
|
const FACTORIES = {
|
|
18
19
|
openai_compat: openai_compat_js_1.openaiCompatHandler,
|
|
19
20
|
vllm: vllm_js_1.vllmHandler,
|
|
20
21
|
llamacpp: llamacpp_js_1.llamacppHandler,
|
|
22
|
+
anthropic: anthropic_js_1.anthropicHandler,
|
|
21
23
|
};
|
|
22
24
|
/** Return a backend handler by name. Throws on an unknown type. */
|
|
23
25
|
function getBackendHandler(backendType, opts = {}) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/backends/index.ts"],"names":[],"mappings":";AAAA,sCAAsC;AACtC;;;;;;GAMG;;;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/backends/index.ts"],"names":[],"mappings":";AAAA,sCAAsC;AACtC;;;;;;GAMG;;;AAmBH,8CAQC;AAxBD,yDAAyD;AACzD,uCAAwC;AACxC,+CAAgD;AAChD,iDAAkD;AAErC,QAAA,aAAa,GAAG,CAAC,eAAe,EAAE,MAAM,EAAE,UAAU,EAAE,WAAW,CAAU,CAAC;AAGzF,MAAM,SAAS,GAAkE;IAC/E,aAAa,EAAE,sCAAmB;IAClC,IAAI,EAAE,qBAAW;IACjB,QAAQ,EAAE,6BAAe;IACzB,SAAS,EAAE,+BAAgB;CAC5B,CAAC;AAEF,mEAAmE;AACnE,SAAgB,iBAAiB,CAAC,WAAmB,EAAE,OAAuB,EAAE;IAC9E,MAAM,OAAO,GAAG,SAAS,CAAC,WAA0B,CAAC,CAAC;IACtD,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CACb,wBAAwB,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,mBAAmB,IAAI,CAAC,SAAS,CAAC,qBAAa,CAAC,EAAE,CACtG,CAAC;IACJ,CAAC;IACD,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC;AACvB,CAAC"}
|
package/dist/cip_policy.d.ts
CHANGED
|
@@ -16,6 +16,8 @@ export interface CooperativeInferencePolicyOptions {
|
|
|
16
16
|
/** Bounded to [1, 60000]ms. */
|
|
17
17
|
maxWorkerTimeoutMs?: number;
|
|
18
18
|
maxConcurrentRemote?: number;
|
|
19
|
+
/** #403 — allow tool-execution-domain intents (default false). */
|
|
20
|
+
allowToolExecution?: boolean;
|
|
19
21
|
}
|
|
20
22
|
/** Safe-by-default CIP policy with the S.12 §2.2 capacity gate built-in. */
|
|
21
23
|
export declare class CooperativeInferencePolicy {
|
|
@@ -25,8 +27,15 @@ export declare class CooperativeInferencePolicy {
|
|
|
25
27
|
readonly maxReplicas: number;
|
|
26
28
|
readonly maxWorkerTimeoutMs: number;
|
|
27
29
|
readonly maxConcurrentRemote: number;
|
|
30
|
+
readonly allowToolExecution: boolean;
|
|
28
31
|
private _inFlight;
|
|
29
32
|
constructor(opts?: CooperativeInferencePolicyOptions);
|
|
33
|
+
/**
|
|
34
|
+
* #403 — per-task admission: reject tool-execution-domain intents unless the
|
|
35
|
+
* operator opted in via allowToolExecution. Mirrors the adapter cip_gate.
|
|
36
|
+
* Intent URN form: urn:iicp:intent:<domain>:... — domain is segment index 3.
|
|
37
|
+
*/
|
|
38
|
+
permitsIntent(intent: string): boolean;
|
|
30
39
|
/** CIP-W01: returns true if this node may act as a CIP coordinator. */
|
|
31
40
|
checkCoordinator(): boolean;
|
|
32
41
|
/** CIP-W02: returns true if this node may accept CIP worker tasks. */
|
package/dist/cip_policy.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cip_policy.d.ts","sourceRoot":"","sources":["../src/cip_policy.ts"],"names":[],"mappings":"AACA;;;;;;;;;GASG;AAEH,MAAM,WAAW,iCAAiC;IAChD,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,+BAA+B;IAC/B,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED,4EAA4E;AAC5E,qBAAa,0BAA0B;IACrC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,gBAAgB,EAAE,OAAO,CAAC;IACnC,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;IAC9B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,mBAAmB,EAAE,MAAM,CAAC;IACrC,OAAO,CAAC,SAAS,CAAK;gBAEV,IAAI,GAAE,iCAAsC;
|
|
1
|
+
{"version":3,"file":"cip_policy.d.ts","sourceRoot":"","sources":["../src/cip_policy.ts"],"names":[],"mappings":"AACA;;;;;;;;;GASG;AAEH,MAAM,WAAW,iCAAiC;IAChD,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,+BAA+B;IAC/B,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,kEAAkE;IAClE,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAED,4EAA4E;AAC5E,qBAAa,0BAA0B;IACrC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,gBAAgB,EAAE,OAAO,CAAC;IACnC,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;IAC9B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,mBAAmB,EAAE,MAAM,CAAC;IACrC,QAAQ,CAAC,kBAAkB,EAAE,OAAO,CAAC;IACrC,OAAO,CAAC,SAAS,CAAK;gBAEV,IAAI,GAAE,iCAAsC;IAWxD;;;;OAIG;IACH,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO;IAKtC,uEAAuE;IACvE,gBAAgB,IAAI,OAAO;IAI3B,sEAAsE;IACtE,WAAW,IAAI,OAAO;IAItB;;;;;OAKG;IACH,iBAAiB,IAAI,OAAO;IAM5B,uDAAuD;IACvD,cAAc,IAAI,IAAI;IAItB;;;;OAIG;IACH,qBAAqB,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;CAOjD;AAMD,uFAAuF;AACvF,wBAAgB,YAAY,IAAI,0BAA0B,CAEzD;AAED,gFAAgF;AAChF,wBAAgB,kBAAkB,CAChC,IAAI,GAAE,iCAAsC,GAC3C,0BAA0B,CAG5B"}
|
package/dist/cip_policy.js
CHANGED
|
@@ -22,6 +22,7 @@ class CooperativeInferencePolicy {
|
|
|
22
22
|
maxReplicas;
|
|
23
23
|
maxWorkerTimeoutMs;
|
|
24
24
|
maxConcurrentRemote;
|
|
25
|
+
allowToolExecution;
|
|
25
26
|
_inFlight = 0;
|
|
26
27
|
constructor(opts = {}) {
|
|
27
28
|
this.enabled = opts.enabled ?? false;
|
|
@@ -30,6 +31,17 @@ class CooperativeInferencePolicy {
|
|
|
30
31
|
this.maxReplicas = Math.max(1, opts.maxReplicas ?? 3);
|
|
31
32
|
this.maxWorkerTimeoutMs = Math.max(1, Math.min(60_000, opts.maxWorkerTimeoutMs ?? 30_000));
|
|
32
33
|
this.maxConcurrentRemote = Math.max(1, opts.maxConcurrentRemote ?? 2);
|
|
34
|
+
// #403 — per-task admission: tool-execution intents rejected unless opted in.
|
|
35
|
+
this.allowToolExecution = opts.allowToolExecution ?? false;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* #403 — per-task admission: reject tool-execution-domain intents unless the
|
|
39
|
+
* operator opted in via allowToolExecution. Mirrors the adapter cip_gate.
|
|
40
|
+
* Intent URN form: urn:iicp:intent:<domain>:... — domain is segment index 3.
|
|
41
|
+
*/
|
|
42
|
+
permitsIntent(intent) {
|
|
43
|
+
const domain = intent.split(":")[3] ?? "";
|
|
44
|
+
return this.allowToolExecution || domain !== "tool";
|
|
33
45
|
}
|
|
34
46
|
/** CIP-W01: returns true if this node may act as a CIP coordinator. */
|
|
35
47
|
checkCoordinator() {
|
|
@@ -66,6 +78,7 @@ class CooperativeInferencePolicy {
|
|
|
66
78
|
return {};
|
|
67
79
|
return {
|
|
68
80
|
allow_remote_inference: this.allowWorker,
|
|
81
|
+
allow_tool_execution: this.allowToolExecution,
|
|
69
82
|
};
|
|
70
83
|
}
|
|
71
84
|
}
|
package/dist/cip_policy.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cip_policy.js","sourceRoot":"","sources":["../src/cip_policy.ts"],"names":[],"mappings":";AAAA,sCAAsC;AACtC;;;;;;;;;GASG;;;
|
|
1
|
+
{"version":3,"file":"cip_policy.js","sourceRoot":"","sources":["../src/cip_policy.ts"],"names":[],"mappings":";AAAA,sCAAsC;AACtC;;;;;;;;;GASG;;;AA4FH,oCAEC;AAGD,gDAKC;AAxFD,4EAA4E;AAC5E,MAAa,0BAA0B;IAC5B,OAAO,CAAU;IACjB,gBAAgB,CAAU;IAC1B,WAAW,CAAU;IACrB,WAAW,CAAS;IACpB,kBAAkB,CAAS;IAC3B,mBAAmB,CAAS;IAC5B,kBAAkB,CAAU;IAC7B,SAAS,GAAG,CAAC,CAAC;IAEtB,YAAY,OAA0C,EAAE;QACtD,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,KAAK,CAAC;QACrC,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC,gBAAgB,IAAI,KAAK,CAAC;QACvD,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,WAAW,IAAI,KAAK,CAAC;QAC7C,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,WAAW,IAAI,CAAC,CAAC,CAAC;QACtD,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,kBAAkB,IAAI,MAAM,CAAC,CAAC,CAAC;QAC3F,IAAI,CAAC,mBAAmB,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,mBAAmB,IAAI,CAAC,CAAC,CAAC;QACtE,8EAA8E;QAC9E,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC,kBAAkB,IAAI,KAAK,CAAC;IAC7D,CAAC;IAED;;;;OAIG;IACH,aAAa,CAAC,MAAc;QAC1B,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC1C,OAAO,IAAI,CAAC,kBAAkB,IAAI,MAAM,KAAK,MAAM,CAAC;IACtD,CAAC;IAED,uEAAuE;IACvE,gBAAgB;QACd,OAAO,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,gBAAgB,CAAC;IAC/C,CAAC;IAED,sEAAsE;IACtE,WAAW;QACT,OAAO,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,WAAW,CAAC;IAC1C,CAAC;IAED;;;;;OAKG;IACH,iBAAiB;QACf,IAAI,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,mBAAmB;YAAE,OAAO,KAAK,CAAC;QAC7D,IAAI,CAAC,SAAS,IAAI,CAAC,CAAC;QACpB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,uDAAuD;IACvD,cAAc;QACZ,IAAI,IAAI,CAAC,SAAS,GAAG,CAAC;YAAE,IAAI,CAAC,SAAS,IAAI,CAAC,CAAC;IAC9C,CAAC;IAED;;;;OAIG;IACH,qBAAqB;QACnB,IAAI,CAAC,IAAI,CAAC,OAAO;YAAE,OAAO,EAAE,CAAC;QAC7B,OAAO;YACL,sBAAsB,EAAE,IAAI,CAAC,WAAW;YACxC,oBAAoB,EAAE,IAAI,CAAC,kBAAkB;SAC9C,CAAC;IACJ,CAAC;CACF;AAtED,gEAsEC;AAED,4EAA4E;AAE5E,IAAI,OAAO,GAA+B,IAAI,0BAA0B,EAAE,CAAC;AAE3E,uFAAuF;AACvF,SAAgB,YAAY;IAC1B,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,gFAAgF;AAChF,SAAgB,kBAAkB,CAChC,OAA0C,EAAE;IAE5C,OAAO,GAAG,IAAI,0BAA0B,CAAC,IAAI,CAAC,CAAC;IAC/C,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
package/dist/cli.d.ts
CHANGED
|
@@ -1,3 +1,27 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import { type NodeIdentity } from "./identity.js";
|
|
3
|
+
export interface ServeOpts {
|
|
4
|
+
backendUrl: string;
|
|
5
|
+
backendType: string;
|
|
6
|
+
/** #5 — Bearer key for an auth-requiring OpenAI-compat backend (LM Studio, hosted). Empty = none. */
|
|
7
|
+
backendApiKey: string;
|
|
8
|
+
model: string;
|
|
9
|
+
publicEndpoint: string;
|
|
10
|
+
directoryUrl: string;
|
|
11
|
+
region: string;
|
|
12
|
+
intent: string;
|
|
13
|
+
maxConcurrent: number;
|
|
14
|
+
nodeId: string;
|
|
15
|
+
port: number;
|
|
16
|
+
host: string;
|
|
17
|
+
skipRegistration: boolean;
|
|
18
|
+
force: boolean;
|
|
19
|
+
autoDetectNat: boolean;
|
|
20
|
+
externalIpProbeUrl: string;
|
|
21
|
+
relayWorkerEndpoint: string;
|
|
22
|
+
node: string;
|
|
23
|
+
logDir?: string;
|
|
24
|
+
}
|
|
25
|
+
export declare function applySavedNode(opts: ServeOpts, saved: NodeIdentity): ServeOpts;
|
|
2
26
|
export declare function main(argv?: string[]): Promise<number>;
|
|
3
27
|
//# sourceMappingURL=cli.d.ts.map
|
package/dist/cli.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAiCA,OAAO,EASL,KAAK,YAAY,EAClB,MAAM,eAAe,CAAC;AAEvB,MAAM,WAAW,SAAS;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,qGAAqG;IACrG,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,gBAAgB,EAAE,OAAO,CAAC;IAC1B,KAAK,EAAE,OAAO,CAAC;IACf,aAAa,EAAE,OAAO,CAAC;IACvB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AA8UD,wBAAgB,cAAc,CAAC,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,YAAY,GAAG,SAAS,CAqB9E;AAwaD,wBAAsB,IAAI,CAAC,IAAI,GAAE,MAAM,EAA0B,GAAG,OAAO,CAAC,MAAM,CAAC,CA8FlF"}
|