@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.
Files changed (49) hide show
  1. package/README.md +120 -19
  2. package/dist/backends/anthropic.d.ts +40 -0
  3. package/dist/backends/anthropic.d.ts.map +1 -0
  4. package/dist/backends/anthropic.js +205 -0
  5. package/dist/backends/anthropic.js.map +1 -0
  6. package/dist/backends/index.d.ts +1 -1
  7. package/dist/backends/index.d.ts.map +1 -1
  8. package/dist/backends/index.js +3 -1
  9. package/dist/backends/index.js.map +1 -1
  10. package/dist/cip_policy.d.ts +9 -0
  11. package/dist/cip_policy.d.ts.map +1 -1
  12. package/dist/cip_policy.js +13 -0
  13. package/dist/cip_policy.js.map +1 -1
  14. package/dist/cli.d.ts +24 -0
  15. package/dist/cli.d.ts.map +1 -1
  16. package/dist/cli.js +205 -35
  17. package/dist/cli.js.map +1 -1
  18. package/dist/client.d.ts.map +1 -1
  19. package/dist/client.js +122 -36
  20. package/dist/client.js.map +1 -1
  21. package/dist/confidentiality.d.ts +14 -0
  22. package/dist/confidentiality.d.ts.map +1 -0
  23. package/dist/confidentiality.js +104 -0
  24. package/dist/confidentiality.js.map +1 -0
  25. package/dist/delegation.d.ts +40 -0
  26. package/dist/delegation.d.ts.map +1 -0
  27. package/dist/delegation.js +76 -0
  28. package/dist/delegation.js.map +1 -0
  29. package/dist/index.d.ts +2 -0
  30. package/dist/index.d.ts.map +1 -1
  31. package/dist/index.js +3 -1
  32. package/dist/index.js.map +1 -1
  33. package/dist/instance_lock.d.ts +11 -0
  34. package/dist/instance_lock.d.ts.map +1 -0
  35. package/dist/instance_lock.js +86 -0
  36. package/dist/instance_lock.js.map +1 -0
  37. package/dist/node.d.ts +48 -0
  38. package/dist/node.d.ts.map +1 -1
  39. package/dist/node.js +0 -0
  40. package/dist/node.js.map +1 -1
  41. package/dist/node_log.d.ts +5 -0
  42. package/dist/node_log.d.ts.map +1 -0
  43. package/dist/node_log.js +69 -0
  44. package/dist/node_log.js.map +1 -0
  45. package/dist/qualify.js +2 -2
  46. package/dist/qualify.js.map +1 -1
  47. package/dist/types.d.ts +10 -1
  48. package/dist/types.d.ts.map +1 -1
  49. package/package.json +1 -1
package/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
  [![CI](https://github.com/RobLe3/iicp-client-typescript/actions/workflows/ci.yml/badge.svg)](https://github.com/RobLe3/iicp-client-typescript/actions/workflows/ci.yml)
4
4
  [![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](LICENSE)
5
5
  [![Protocol](https://img.shields.io/badge/IICP-v1.7-indigo.svg)](https://iicp.network/spec)
6
- [![npm](https://img.shields.io/badge/npm-iicp--client-red?logo=npm)](https://www.npmjs.com/package/iicp-client)
6
+ [![npm](https://img.shields.io/badge/npm-%40iicp%2Fclient-red?logo=npm)](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-client
22
- # yarn add iicp-client
23
- # pnpm add iicp-client
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-client";
50
+ import { IicpClient } from "@iicp/client";
38
51
 
39
- const client = new IicpClient({ directory_url: "https://iicp.network" });
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-client";
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, // max 120 000 (SDK-04)
70
- region : "eu-central", // prefer nodes in region
71
- api_token : "your-token", // optional auth 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
- model : "phi3:mini",
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-client";
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-client";
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 # 184 unit tests
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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"}
@@ -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;AAKrE,eAAO,MAAM,aAAa,gDAAiD,CAAC;AAC5E,MAAM,MAAM,WAAW,GAAG,CAAC,OAAO,aAAa,CAAC,CAAC,MAAM,CAAC,CAAC;AAQzD,mEAAmE;AACnE,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,GAAE,cAAmB,GAAG,cAAc,CAQhG"}
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"}
@@ -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
- exports.BACKEND_TYPES = ["openai_compat", "vllm", "llamacpp"];
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;;;AAiBH,8CAQC;AAtBD,yDAAyD;AACzD,uCAAwC;AACxC,+CAAgD;AAEnC,QAAA,aAAa,GAAG,CAAC,eAAe,EAAE,MAAM,EAAE,UAAU,CAAU,CAAC;AAG5E,MAAM,SAAS,GAAkE;IAC/E,aAAa,EAAE,sCAAmB;IAClC,IAAI,EAAE,qBAAW;IACjB,QAAQ,EAAE,6BAAe;CAC1B,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"}
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"}
@@ -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. */
@@ -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;IASxD,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;CAMjD;AAMD,uFAAuF;AACvF,wBAAgB,YAAY,IAAI,0BAA0B,CAEzD;AAED,gFAAgF;AAChF,wBAAgB,kBAAkB,CAChC,IAAI,GAAE,iCAAsC,GAC3C,0BAA0B,CAG5B"}
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"}
@@ -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
  }
@@ -1 +1 @@
1
- {"version":3,"file":"cip_policy.js","sourceRoot":"","sources":["../src/cip_policy.ts"],"names":[],"mappings":";AAAA,sCAAsC;AACtC;;;;;;;;;GASG;;;AA4EH,oCAEC;AAGD,gDAKC;AA1ED,4EAA4E;AAC5E,MAAa,0BAA0B;IAC5B,OAAO,CAAU;IACjB,gBAAgB,CAAU;IAC1B,WAAW,CAAU;IACrB,WAAW,CAAS;IACpB,kBAAkB,CAAS;IAC3B,mBAAmB,CAAS;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;IACxE,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;SACzC,CAAC;IACJ,CAAC;CACF;AAxDD,gEAwDC;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"}
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":";AA+pBA,wBAAsB,IAAI,CAAC,IAAI,GAAE,MAAM,EAA0B,GAAG,OAAO,CAAC,MAAM,CAAC,CAkFlF"}
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"}