@teith/openclaw-runware-provider 0.2.10 → 0.3.1
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 +9 -26
- package/dist/catalog.d.ts +15 -1
- package/dist/catalog.d.ts.map +1 -1
- package/dist/catalog.js +29 -19
- package/dist/catalog.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -19
- package/dist/index.js.map +1 -1
- package/dist/models.d.ts +8 -5
- package/dist/models.d.ts.map +1 -1
- package/dist/models.js +26 -22
- package/dist/models.js.map +1 -1
- package/dist/openclaw-api.d.ts +0 -18
- package/dist/openclaw-api.d.ts.map +1 -1
- package/dist/provider-discovery.d.ts.map +1 -1
- package/dist/provider-discovery.js +2 -15
- package/dist/provider-discovery.js.map +1 -1
- package/package.json +1 -1
- package/dist/logger.d.ts +0 -33
- package/dist/logger.d.ts.map +0 -1
- package/dist/logger.js +0 -68
- package/dist/logger.js.map +0 -1
- package/dist/stream-wrap.d.ts +0 -24
- package/dist/stream-wrap.d.ts.map +0 -1
- package/dist/stream-wrap.js +0 -51
- package/dist/stream-wrap.js.map +0 -1
package/README.md
CHANGED
|
@@ -39,35 +39,18 @@ from internal credential caches.
|
|
|
39
39
|
- Fetches `/v1/models` on every catalog resolution. TTL-cached for 5
|
|
40
40
|
minutes; concurrent requests are deduplicated; the last-known-good
|
|
41
41
|
catalog is served on transient upstream failures.
|
|
42
|
+
- Forwards per-model `context_length` and `max_output_tokens` from
|
|
43
|
+
Runware's extended `/v1/models` response into each model's
|
|
44
|
+
`contextWindow`/`maxTokens` in the OpenClaw catalog — so e.g. Opus 4.7
|
|
45
|
+
reports its real 1M window, GPT 5.4 its 1.05M window, etc. Models where
|
|
46
|
+
Runware leaves those fields null (currently the older Runware-owned
|
|
47
|
+
rows like `qwen-instruct`, `xai-grok-4-3`) fall back to conservative
|
|
48
|
+
defaults (200K context, 32K output).
|
|
49
|
+
- Uses each model's curated `name` from `/v1/models` when present (e.g.
|
|
50
|
+
`"Opus 4.7"` instead of the id-humanized `"Anthropic Claude Opus 4 7"`).
|
|
42
51
|
- Injects `extra_body: { reasoning_effort: "high" }` into every chat
|
|
43
52
|
completions request so reasoning-capable models stream thinking content.
|
|
44
53
|
|
|
45
|
-
## Logging
|
|
46
|
-
|
|
47
|
-
The plugin emits structured log lines prefixed with
|
|
48
|
-
`[runware-openclaw-provider]` on these conditions:
|
|
49
|
-
|
|
50
|
-
| Level | When |
|
|
51
|
-
|-------|----------------------------------------------------------------------|
|
|
52
|
-
| warn | `RUNWARE_API_KEY` missing — empty catalog returned |
|
|
53
|
-
| warn | `/v1/models` upstream failed but a cached catalog is being served |
|
|
54
|
-
| error | `/v1/models` upstream failed and no cached catalog exists |
|
|
55
|
-
| error | Any other failure inside `catalog.run` — falls back to empty catalog |
|
|
56
|
-
|
|
57
|
-
Transport is `console.{error,warn,info,debug}` by default. The openclaw
|
|
58
|
-
gateway CLI captures process console output into the shared gateway log,
|
|
59
|
-
so these lines show up in `openclaw logs --follow`, the Control UI Logs
|
|
60
|
-
tab, and the gateway stderr without any additional wiring. If a future
|
|
61
|
-
openclaw version starts invoking `register(api)` for external plugins,
|
|
62
|
-
the logger is automatically swapped to `api.logger` so lines are tagged
|
|
63
|
-
by the openclaw scoped logger instead.
|
|
64
|
-
|
|
65
|
-
To follow plugin output in a running managed deployment:
|
|
66
|
-
|
|
67
|
-
```bash
|
|
68
|
-
openclaw logs --follow | grep runware-openclaw-provider
|
|
69
|
-
```
|
|
70
|
-
|
|
71
54
|
## Architecture
|
|
72
55
|
|
|
73
56
|
```
|
package/dist/catalog.d.ts
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Subset of Runware's `/v1/models` row that the catalog consumer needs.
|
|
3
|
+
* Runware extends the OpenAI models shape with curated `name`,
|
|
4
|
+
* `context_length`, and `max_output_tokens`. Numeric fields are optional
|
|
5
|
+
* because Runware leaves them `null` for models whose limits haven't
|
|
6
|
+
* been filled in yet (currently `qwen-instruct`, `qwen3-vl-thinking-30b`,
|
|
7
|
+
* `minimax-m2-5`, `xai-grok-4-3`).
|
|
8
|
+
*/
|
|
9
|
+
export interface RunwareModel {
|
|
10
|
+
id: string;
|
|
11
|
+
name?: string;
|
|
12
|
+
contextLength?: number;
|
|
13
|
+
maxOutputTokens?: number;
|
|
14
|
+
}
|
|
15
|
+
export declare function fetchModels(baseUrl: string, apiKey: string): Promise<RunwareModel[]>;
|
|
2
16
|
export declare function resetCache(): void;
|
|
3
17
|
//# sourceMappingURL=catalog.d.ts.map
|
package/dist/catalog.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"catalog.d.ts","sourceRoot":"","sources":["../src/catalog.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"catalog.d.ts","sourceRoot":"","sources":["../src/catalog.ts"],"names":[],"mappings":"AAGA;;;;;;;GAOG;AACH,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAcD,wBAAsB,WAAW,CAC/B,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,YAAY,EAAE,CAAC,CAsBzB;AA8CD,wBAAgB,UAAU,IAAI,IAAI,CAGjC"}
|
package/dist/catalog.js
CHANGED
|
@@ -1,32 +1,23 @@
|
|
|
1
|
-
import { logger } from "./logger.js";
|
|
2
1
|
const CACHE_TTL_MS = 5 * 60 * 1000;
|
|
3
2
|
const FETCH_TIMEOUT_MS = 5000;
|
|
4
3
|
let cache = null;
|
|
5
4
|
let inflight = null;
|
|
6
|
-
export async function
|
|
5
|
+
export async function fetchModels(baseUrl, apiKey) {
|
|
7
6
|
const now = Date.now();
|
|
8
7
|
if (cache && now - cache.fetchedAt < CACHE_TTL_MS) {
|
|
9
|
-
return cache.
|
|
8
|
+
return cache.models;
|
|
10
9
|
}
|
|
11
10
|
if (inflight)
|
|
12
11
|
return inflight;
|
|
13
12
|
inflight = (async () => {
|
|
14
13
|
try {
|
|
15
|
-
const
|
|
16
|
-
cache = {
|
|
17
|
-
return
|
|
14
|
+
const models = await fetchFromUpstream(baseUrl, apiKey);
|
|
15
|
+
cache = { models, fetchedAt: Date.now() };
|
|
16
|
+
return models;
|
|
18
17
|
}
|
|
19
18
|
catch (err) {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
logger.warn("upstream /v1/models fetch failed; serving stale catalog", {
|
|
23
|
-
baseUrl,
|
|
24
|
-
cachedModels: cache.modelIds.length,
|
|
25
|
-
error: message,
|
|
26
|
-
});
|
|
27
|
-
return cache.modelIds;
|
|
28
|
-
}
|
|
29
|
-
logger.error("upstream /v1/models fetch failed and no cached catalog is available", { baseUrl, error: message });
|
|
19
|
+
if (cache)
|
|
20
|
+
return cache.models;
|
|
30
21
|
throw err;
|
|
31
22
|
}
|
|
32
23
|
finally {
|
|
@@ -48,14 +39,33 @@ async function fetchFromUpstream(baseUrl, apiKey) {
|
|
|
48
39
|
throw new Error(`Runware /models returned ${res.status} ${res.statusText}`);
|
|
49
40
|
}
|
|
50
41
|
const body = (await res.json());
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
.
|
|
42
|
+
const data = Array.isArray(body.data) ? body.data : [];
|
|
43
|
+
return data
|
|
44
|
+
.map(parseRunwareModel)
|
|
45
|
+
.filter((m) => m !== null);
|
|
54
46
|
}
|
|
55
47
|
finally {
|
|
56
48
|
clearTimeout(timeout);
|
|
57
49
|
}
|
|
58
50
|
}
|
|
51
|
+
function parseRunwareModel(raw) {
|
|
52
|
+
if (!raw || typeof raw !== "object")
|
|
53
|
+
return null;
|
|
54
|
+
const m = raw;
|
|
55
|
+
if (typeof m.id !== "string" || m.id.length === 0)
|
|
56
|
+
return null;
|
|
57
|
+
const parsed = { id: m.id };
|
|
58
|
+
if (typeof m.name === "string" && m.name.length > 0) {
|
|
59
|
+
parsed.name = m.name;
|
|
60
|
+
}
|
|
61
|
+
if (typeof m.context_length === "number" && m.context_length > 0) {
|
|
62
|
+
parsed.contextLength = m.context_length;
|
|
63
|
+
}
|
|
64
|
+
if (typeof m.max_output_tokens === "number" && m.max_output_tokens > 0) {
|
|
65
|
+
parsed.maxOutputTokens = m.max_output_tokens;
|
|
66
|
+
}
|
|
67
|
+
return parsed;
|
|
68
|
+
}
|
|
59
69
|
export function resetCache() {
|
|
60
70
|
cache = null;
|
|
61
71
|
inflight = null;
|
package/dist/catalog.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"catalog.js","sourceRoot":"","sources":["../src/catalog.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"catalog.js","sourceRoot":"","sources":["../src/catalog.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAkB,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAIrE;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,QAAA,MAAM,KAAK,EAAE,WAkCZ,CAAC;AAEF,eAAe,KAAK,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,9 +1,4 @@
|
|
|
1
|
-
import { setHostLogger } from "./logger.js";
|
|
2
1
|
import { API_KEY_ENV_VAR, BASE_URL_ENV_VAR, PROVIDER_ID, PROVIDER_LABEL, buildCatalogRows, buildProvider, resolveApiKey, resolveBaseUrl, } from "./models.js";
|
|
3
|
-
// Imported but intentionally not passed to registerProvider in 0.2.10 —
|
|
4
|
-
// see note inside register() below.
|
|
5
|
-
import { buildRunwareStreamWrapper as _buildRunwareStreamWrapper } from "./stream-wrap.js";
|
|
6
|
-
void _buildRunwareStreamWrapper;
|
|
7
2
|
const PLUGIN_ID = "runware-openclaw-provider";
|
|
8
3
|
/**
|
|
9
4
|
* Plugin entry that openclaw's plugin loader invokes after `npm install`-ing
|
|
@@ -31,8 +26,6 @@ const entry = {
|
|
|
31
26
|
name: PROVIDER_LABEL,
|
|
32
27
|
description: "Runware — unified OpenAI-compatible access to Claude, GPT, Gemini, Qwen, GLM, MiniMax, Kimi, and Gemma.",
|
|
33
28
|
register(api) {
|
|
34
|
-
if (api.logger)
|
|
35
|
-
setHostLogger(api.logger);
|
|
36
29
|
api.registerProvider({
|
|
37
30
|
id: PROVIDER_ID,
|
|
38
31
|
label: PROVIDER_LABEL,
|
|
@@ -49,18 +42,6 @@ const entry = {
|
|
|
49
42
|
return { provider };
|
|
50
43
|
},
|
|
51
44
|
},
|
|
52
|
-
// NOTE: `wrapStreamFn: buildRunwareStreamWrapper` was removed in
|
|
53
|
-
// 0.2.10 — its presence on a catalog-style registerProvider call
|
|
54
|
-
// triggers a TypeError in openclaw 2026.5.18's prompt-assembly
|
|
55
|
-
// path ("Cannot read properties of undefined (reading
|
|
56
|
-
// 'systemPrompt')") before any HTTP request is made. The hook is
|
|
57
|
-
// documented in the provider SDK but is apparently not wired up for
|
|
58
|
-
// providers that expose models via `catalog.run` returning a custom
|
|
59
|
-
// openai-completions provider config. Until we find the correct
|
|
60
|
-
// surface (likely `prepareExtraParams`) or openclaw fixes the
|
|
61
|
-
// lookup, the temperature-strip workaround is parked. Imports of
|
|
62
|
-
// buildRunwareStreamWrapper remain in the build so the helper ships
|
|
63
|
-
// unchanged; just not registered with the host.
|
|
64
45
|
});
|
|
65
46
|
api.registerModelCatalogProvider({
|
|
66
47
|
provider: PROVIDER_ID,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,gBAAgB,EAChB,WAAW,EACX,cAAc,EACd,gBAAgB,EAChB,aAAa,EACb,aAAa,EACb,cAAc,GACf,MAAM,aAAa,CAAC;AAGrB,MAAM,SAAS,GAAG,2BAA2B,CAAC;AAE9C;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,KAAK,GAAgB;IACzB,EAAE,EAAE,SAAS;IACb,IAAI,EAAE,cAAc;IACpB,WAAW,EACT,yGAAyG;IAE3G,QAAQ,CAAC,GAAG;QACV,GAAG,CAAC,gBAAgB,CAAC;YACnB,EAAE,EAAE,WAAW;YACf,KAAK,EAAE,cAAc;YACrB,QAAQ,EAAE,yBAAyB;YACnC,OAAO,EAAE,CAAC,eAAe,EAAE,gBAAgB,CAAC;YAC5C,IAAI,EAAE,EAAE;YACR,OAAO,EAAE;gBACP,KAAK,EAAE,QAAQ;gBACf,GAAG,EAAE,KAAK,EAAE,GAAmB,EAAE,EAAE;oBACjC,MAAM,MAAM,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC;oBAClC,IAAI,CAAC,MAAM;wBAAE,OAAO,IAAI,CAAC;oBACzB,MAAM,QAAQ,GAAG,MAAM,aAAa,CAAC,MAAM,EAAE,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;oBACtE,OAAO,EAAE,QAAQ,EAAE,CAAC;gBACtB,CAAC;aACF;SACF,CAAC,CAAC;QAEH,GAAG,CAAC,4BAA4B,CAAC;YAC/B,QAAQ,EAAE,WAAW;YACrB,KAAK,EAAE,CAAC,MAAM,CAAC;YACf,WAAW,EAAE,KAAK,EAAE,GAAmB,EAAE,EAAE;gBACzC,MAAM,MAAM,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC;gBAClC,IAAI,CAAC,MAAM;oBAAE,OAAO,IAAI,CAAC;gBACzB,OAAO,gBAAgB,CAAC,MAAM,EAAE,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;YAC3D,CAAC;SACF,CAAC,CAAC;IACL,CAAC;CACF,CAAC;AAEF,eAAe,KAAK,CAAC"}
|
package/dist/models.d.ts
CHANGED
|
@@ -4,16 +4,18 @@
|
|
|
4
4
|
* (src/provider-discovery.ts).
|
|
5
5
|
*
|
|
6
6
|
* The Runware gateway is OpenAI-compatible — every model accepts the same
|
|
7
|
-
* chat-completions request shape.
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
7
|
+
* chat-completions request shape. Per-model context window and max output
|
|
8
|
+
* tokens come from Runware's extended `/v1/models` response; models where
|
|
9
|
+
* Runware hasn't published those limits fall back to conservative
|
|
10
|
+
* provider defaults so OpenClaw never sees a missing value.
|
|
11
11
|
*/
|
|
12
12
|
export declare const PROVIDER_ID = "runware";
|
|
13
13
|
export declare const PROVIDER_LABEL = "Runware";
|
|
14
14
|
export declare const DEFAULT_BASE_URL = "https://api.runware.ai/v1";
|
|
15
15
|
export declare const API_KEY_ENV_VAR = "RUNWARE_API_KEY";
|
|
16
16
|
export declare const BASE_URL_ENV_VAR = "RUNWARE_BASE_URL";
|
|
17
|
+
export declare const DEFAULT_CONTEXT_WINDOW = 200000;
|
|
18
|
+
export declare const DEFAULT_MAX_TOKENS = 32768;
|
|
17
19
|
declare const MODEL_PARAMS: {
|
|
18
20
|
readonly extra_body: {
|
|
19
21
|
readonly reasoning_effort: "high";
|
|
@@ -56,7 +58,8 @@ export interface ModelCatalogRow {
|
|
|
56
58
|
}
|
|
57
59
|
/**
|
|
58
60
|
* Convert a Runware model id ("anthropic-claude-opus-4-7",
|
|
59
|
-
* "qwen35_27b_fp8") into a human-readable label
|
|
61
|
+
* "qwen35_27b_fp8") into a human-readable label. Used only when the
|
|
62
|
+
* upstream `/v1/models` entry does not provide a curated `name`.
|
|
60
63
|
* Pure function, exported for tests.
|
|
61
64
|
*/
|
|
62
65
|
export declare function humanizeModelId(id: string): string;
|
package/dist/models.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"models.d.ts","sourceRoot":"","sources":["../src/models.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;
|
|
1
|
+
{"version":3,"file":"models.d.ts","sourceRoot":"","sources":["../src/models.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAKH,eAAO,MAAM,WAAW,YAAY,CAAC;AACrC,eAAO,MAAM,cAAc,YAAY,CAAC;AACxC,eAAO,MAAM,gBAAgB,8BAA8B,CAAC;AAC5D,eAAO,MAAM,eAAe,oBAAoB,CAAC;AACjD,eAAO,MAAM,gBAAgB,qBAAqB,CAAC;AAGnD,eAAO,MAAM,sBAAsB,SAAU,CAAC;AAC9C,eAAO,MAAM,kBAAkB,QAAS,CAAC;AACzC,QAAA,MAAM,YAAY;;;;CAAwD,CAAC;AAC3E,QAAA,MAAM,SAAS;;;;;CAAgE,CAAC;AAEhF,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,IAAI,CAAC;IAChB,KAAK,EAAE,CAAC,MAAM,CAAC,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,OAAO,SAAS,CAAC;IACvB,MAAM,EAAE,OAAO,YAAY,CAAC;CAC7B;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,oBAAoB,CAAC;IAC1B,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,UAAU,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,IAAI,CAAC;IAChB,KAAK,EAAE,CAAC,MAAM,CAAC,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,OAAO,SAAS,CAAC;CACxB;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAQlD;AAMD;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,GAAG,MAAM,CAI/E;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE;IACjC,qBAAqB,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK;QAAE,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACpE,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;CAC1C,GAAG,MAAM,GAAG,SAAS,CAKrB;AA8BD;;;;;GAKG;AACH,wBAAsB,aAAa,CACjC,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,aAAa,CAAC,CASxB;AAED;;;;;GAKG;AACH,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,eAAe,EAAE,CAAC,CAG5B"}
|
package/dist/models.js
CHANGED
|
@@ -4,25 +4,26 @@
|
|
|
4
4
|
* (src/provider-discovery.ts).
|
|
5
5
|
*
|
|
6
6
|
* The Runware gateway is OpenAI-compatible — every model accepts the same
|
|
7
|
-
* chat-completions request shape.
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
7
|
+
* chat-completions request shape. Per-model context window and max output
|
|
8
|
+
* tokens come from Runware's extended `/v1/models` response; models where
|
|
9
|
+
* Runware hasn't published those limits fall back to conservative
|
|
10
|
+
* provider defaults so OpenClaw never sees a missing value.
|
|
11
11
|
*/
|
|
12
|
-
import {
|
|
12
|
+
import { fetchModels } from "./catalog.js";
|
|
13
13
|
export const PROVIDER_ID = "runware";
|
|
14
14
|
export const PROVIDER_LABEL = "Runware";
|
|
15
15
|
export const DEFAULT_BASE_URL = "https://api.runware.ai/v1";
|
|
16
16
|
export const API_KEY_ENV_VAR = "RUNWARE_API_KEY";
|
|
17
17
|
export const BASE_URL_ENV_VAR = "RUNWARE_BASE_URL";
|
|
18
18
|
const REQUEST_TIMEOUT_SECONDS = 600;
|
|
19
|
-
const
|
|
20
|
-
const
|
|
19
|
+
export const DEFAULT_CONTEXT_WINDOW = 200_000;
|
|
20
|
+
export const DEFAULT_MAX_TOKENS = 32_768;
|
|
21
21
|
const MODEL_PARAMS = { extra_body: { reasoning_effort: "high" } };
|
|
22
22
|
const ZERO_COST = { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 };
|
|
23
23
|
/**
|
|
24
24
|
* Convert a Runware model id ("anthropic-claude-opus-4-7",
|
|
25
|
-
* "qwen35_27b_fp8") into a human-readable label
|
|
25
|
+
* "qwen35_27b_fp8") into a human-readable label. Used only when the
|
|
26
|
+
* upstream `/v1/models` entry does not provide a curated `name`.
|
|
26
27
|
* Pure function, exported for tests.
|
|
27
28
|
*/
|
|
28
29
|
export function humanizeModelId(id) {
|
|
@@ -34,6 +35,9 @@ export function humanizeModelId(id) {
|
|
|
34
35
|
.map((word) => (word.length > 0 ? word[0].toUpperCase() + word.slice(1) : word))
|
|
35
36
|
.join(" ");
|
|
36
37
|
}
|
|
38
|
+
function displayName(model) {
|
|
39
|
+
return model.name ?? humanizeModelId(model.id);
|
|
40
|
+
}
|
|
37
41
|
/**
|
|
38
42
|
* Resolve the Runware base URL — `RUNWARE_BASE_URL` env override wins,
|
|
39
43
|
* falling back to the production endpoint. `env` is the explicit context
|
|
@@ -68,29 +72,29 @@ export function resolveApiKey(ctx) {
|
|
|
68
72
|
const fromAuth = ctx.resolveProviderApiKey?.(PROVIDER_ID).apiKey;
|
|
69
73
|
return typeof fromAuth === "string" && fromAuth.length > 0 ? fromAuth : undefined;
|
|
70
74
|
}
|
|
71
|
-
function buildModelEntry(
|
|
75
|
+
function buildModelEntry(model) {
|
|
72
76
|
return {
|
|
73
|
-
id,
|
|
74
|
-
name:
|
|
77
|
+
id: model.id,
|
|
78
|
+
name: displayName(model),
|
|
75
79
|
reasoning: true,
|
|
76
80
|
input: ["text"],
|
|
77
|
-
contextWindow:
|
|
78
|
-
maxTokens:
|
|
81
|
+
contextWindow: model.contextLength ?? DEFAULT_CONTEXT_WINDOW,
|
|
82
|
+
maxTokens: model.maxOutputTokens ?? DEFAULT_MAX_TOKENS,
|
|
79
83
|
cost: ZERO_COST,
|
|
80
84
|
params: MODEL_PARAMS,
|
|
81
85
|
};
|
|
82
86
|
}
|
|
83
|
-
function buildCatalogRow(
|
|
87
|
+
function buildCatalogRow(model) {
|
|
84
88
|
return {
|
|
85
89
|
kind: "text",
|
|
86
90
|
provider: PROVIDER_ID,
|
|
87
|
-
model: id,
|
|
88
|
-
label:
|
|
91
|
+
model: model.id,
|
|
92
|
+
label: displayName(model),
|
|
89
93
|
source: "live",
|
|
90
94
|
reasoning: true,
|
|
91
95
|
input: ["text"],
|
|
92
|
-
contextWindow:
|
|
93
|
-
maxTokens:
|
|
96
|
+
contextWindow: model.contextLength ?? DEFAULT_CONTEXT_WINDOW,
|
|
97
|
+
maxTokens: model.maxOutputTokens ?? DEFAULT_MAX_TOKENS,
|
|
94
98
|
cost: ZERO_COST,
|
|
95
99
|
};
|
|
96
100
|
}
|
|
@@ -101,13 +105,13 @@ function buildCatalogRow(id) {
|
|
|
101
105
|
* `/v1/models` from Runware via the TTL cache in `catalog.ts`.
|
|
102
106
|
*/
|
|
103
107
|
export async function buildProvider(apiKey, baseUrl) {
|
|
104
|
-
const
|
|
108
|
+
const models = await fetchModels(baseUrl, apiKey);
|
|
105
109
|
return {
|
|
106
110
|
baseUrl,
|
|
107
111
|
apiKey,
|
|
108
112
|
api: "openai-completions",
|
|
109
113
|
timeoutSeconds: REQUEST_TIMEOUT_SECONDS,
|
|
110
|
-
models:
|
|
114
|
+
models: models.map(buildModelEntry),
|
|
111
115
|
};
|
|
112
116
|
}
|
|
113
117
|
/**
|
|
@@ -117,7 +121,7 @@ export async function buildProvider(apiKey, baseUrl) {
|
|
|
117
121
|
* response.
|
|
118
122
|
*/
|
|
119
123
|
export async function buildCatalogRows(apiKey, baseUrl) {
|
|
120
|
-
const
|
|
121
|
-
return
|
|
124
|
+
const models = await fetchModels(baseUrl, apiKey);
|
|
125
|
+
return models.map(buildCatalogRow);
|
|
122
126
|
}
|
|
123
127
|
//# sourceMappingURL=models.js.map
|
package/dist/models.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"models.js","sourceRoot":"","sources":["../src/models.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"models.js","sourceRoot":"","sources":["../src/models.ts"],"names":[],"mappings":"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"}
|
package/dist/openclaw-api.d.ts
CHANGED
|
@@ -5,7 +5,6 @@
|
|
|
5
5
|
* a downstream consumer of openclaw's TypeScript types. Keeping the surface
|
|
6
6
|
* minimal here also lets us track exactly which hooks we touch.
|
|
7
7
|
*/
|
|
8
|
-
import type { HostLogger } from "./logger.js";
|
|
9
8
|
import type { ModelCatalogRow } from "./models.js";
|
|
10
9
|
/**
|
|
11
10
|
* Context passed to plugin hooks (`registerProvider.catalog.run`,
|
|
@@ -24,24 +23,7 @@ export interface CatalogContext {
|
|
|
24
23
|
* actually call. Other methods (registerMemoryEmbeddingProvider, etc) are
|
|
25
24
|
* available on the underlying object — we just don't type them here.
|
|
26
25
|
*/
|
|
27
|
-
/**
|
|
28
|
-
* Params object passed to a wrapped openai-completions StreamFn. Shape is
|
|
29
|
-
* the openclaw internal one — we type only the fields we touch. Other keys
|
|
30
|
-
* (messages, model, tools, headers, etc) pass through unchanged.
|
|
31
|
-
*/
|
|
32
|
-
export interface StreamFnParams {
|
|
33
|
-
temperature?: number;
|
|
34
|
-
[key: string]: unknown;
|
|
35
|
-
}
|
|
36
|
-
export type StreamFn = (params: StreamFnParams) => Promise<unknown>;
|
|
37
|
-
export interface WrapStreamFnCtx {
|
|
38
|
-
streamFn?: StreamFn;
|
|
39
|
-
model?: {
|
|
40
|
-
id?: string;
|
|
41
|
-
};
|
|
42
|
-
}
|
|
43
26
|
export interface PluginApi {
|
|
44
|
-
logger?: HostLogger;
|
|
45
27
|
registerProvider: (spec: unknown) => void;
|
|
46
28
|
registerModelCatalogProvider: (spec: {
|
|
47
29
|
provider: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"openclaw-api.d.ts","sourceRoot":"","sources":["../src/openclaw-api.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"openclaw-api.d.ts","sourceRoot":"","sources":["../src/openclaw-api.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEnD;;;;;GAKG;AACH,MAAM,WAAW,cAAc;IAC7B,qBAAqB,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK;QAAE,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACpE,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;CAC1C;AAED;;;;GAIG;AACH,MAAM,WAAW,SAAS;IACxB,gBAAgB,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IAC1C,4BAA4B,EAAE,CAAC,IAAI,EAAE;QACnC,QAAQ,EAAE,MAAM,CAAC;QACjB,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;QACrB,WAAW,EAAE,CAAC,GAAG,EAAE,cAAc,KAAK,OAAO,CAAC,eAAe,EAAE,GAAG,IAAI,CAAC,CAAC;KACzE,KAAK,IAAI,CAAC;CACZ;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,CAAC,GAAG,EAAE,SAAS,KAAK,IAAI,CAAC;CACpC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"provider-discovery.d.ts","sourceRoot":"","sources":["../src/provider-discovery.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"provider-discovery.d.ts","sourceRoot":"","sources":["../src/provider-discovery.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,gBAAgB,EAMjB,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEjD;;;;;;;;;;;;;;GAcG;AAEH,UAAU,YAAY;IACpB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;IACzC,qBAAqB,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK;QAAE,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CACrE;AAYD,iBAAe,iBAAiB,CAAC,GAAG,EAAE,YAAY,GAAG,OAAO,CAAC;IAAE,QAAQ,EAAE,aAAa,CAAA;CAAE,CAAC,CAUxF;AAED,QAAA,MAAM,wBAAwB;;;;;;;;;;CAU7B,CAAC;AAEF,eAAe,wBAAwB,CAAC;AACxC,OAAO,EAAE,gBAAgB,EAAE,CAAC"}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { logger } from "./logger.js";
|
|
2
1
|
import { API_KEY_ENV_VAR, BASE_URL_ENV_VAR, DEFAULT_BASE_URL, PROVIDER_ID, PROVIDER_LABEL, buildProvider, resolveApiKey, resolveBaseUrl, } from "./models.js";
|
|
3
2
|
function emptyProvider(baseUrl) {
|
|
4
3
|
return {
|
|
@@ -17,21 +16,9 @@ async function runwareCatalogRun(ctx) {
|
|
|
17
16
|
// an empty provider shape so openclaw treats the catalog as "known but
|
|
18
17
|
// currently unpopulated" rather than crashing. The next invocation will
|
|
19
18
|
// re-resolve and fill in models once the key is present.
|
|
20
|
-
if (!apiKey)
|
|
21
|
-
logger.warn(`${API_KEY_ENV_VAR} is not set — returning an empty Runware catalog`, { baseUrl });
|
|
19
|
+
if (!apiKey)
|
|
22
20
|
return { provider: emptyProvider(baseUrl) };
|
|
23
|
-
}
|
|
24
|
-
try {
|
|
25
|
-
return { provider: await buildProvider(apiKey, baseUrl) };
|
|
26
|
-
}
|
|
27
|
-
catch (err) {
|
|
28
|
-
// openclaw silently swallows rejections from catalog.run, which is why
|
|
29
|
-
// upstream failures were previously invisible. Log explicitly via the
|
|
30
|
-
// gateway CLI's console capture and degrade to an empty catalog so the
|
|
31
|
-
// gateway keeps booting — the next invocation will retry.
|
|
32
|
-
logger.error("failed to build Runware provider catalog — returning empty fallback", { baseUrl, error: err instanceof Error ? err.message : String(err) });
|
|
33
|
-
return { provider: emptyProvider(baseUrl) };
|
|
34
|
-
}
|
|
21
|
+
return { provider: await buildProvider(apiKey, baseUrl) };
|
|
35
22
|
}
|
|
36
23
|
const runwareProviderDiscovery = {
|
|
37
24
|
id: PROVIDER_ID,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"provider-discovery.js","sourceRoot":"","sources":["../src/provider-discovery.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"provider-discovery.js","sourceRoot":"","sources":["../src/provider-discovery.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,gBAAgB,EAChB,gBAAgB,EAChB,WAAW,EACX,cAAc,EACd,aAAa,EACb,aAAa,EACb,cAAc,GACf,MAAM,aAAa,CAAC;AAwBrB,SAAS,aAAa,CAAC,OAAe;IACpC,OAAO;QACL,OAAO;QACP,MAAM,EAAE,EAAE;QACV,GAAG,EAAE,oBAAoB;QACzB,cAAc,EAAE,GAAG;QACnB,MAAM,EAAE,EAAE;KACX,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,iBAAiB,CAAC,GAAiB;IAChD,MAAM,OAAO,GAAG,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACxC,MAAM,MAAM,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC;IAClC,uEAAuE;IACvE,0EAA0E;IAC1E,uEAAuE;IACvE,wEAAwE;IACxE,yDAAyD;IACzD,IAAI,CAAC,MAAM;QAAE,OAAO,EAAE,QAAQ,EAAE,aAAa,CAAC,OAAO,CAAC,EAAE,CAAC;IACzD,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;AAC5D,CAAC;AAED,MAAM,wBAAwB,GAAG;IAC/B,EAAE,EAAE,WAAW;IACf,KAAK,EAAE,cAAc;IACrB,QAAQ,EAAE,yBAAyB;IACnC,OAAO,EAAE,CAAC,eAAe,EAAE,gBAAgB,CAAC;IAC5C,IAAI,EAAE,EAAE;IACR,OAAO,EAAE;QACP,KAAK,EAAE,MAAe;QACtB,GAAG,EAAE,iBAAiB;KACvB;CACF,CAAC;AAEF,eAAe,wBAAwB,CAAC;AACxC,OAAO,EAAE,gBAAgB,EAAE,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@teith/openclaw-runware-provider",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"description": "OpenClaw provider plugin for Runware — unified OpenAI-compatible access to Claude, GPT, Gemini, Qwen, GLM, MiniMax, Kimi, and Gemma.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
package/dist/logger.d.ts
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Plugin-scoped logger with two transports:
|
|
3
|
-
*
|
|
4
|
-
* - default: console.error/warn/info/debug. OpenClaw's gateway CLI
|
|
5
|
-
* captures process console output and writes it to the shared gateway
|
|
6
|
-
* log file alongside its own logger output, so anything we emit here
|
|
7
|
-
* surfaces in `openclaw logs --follow` and the Control UI Logs tab
|
|
8
|
-
* without any wiring. This is the only path available from the
|
|
9
|
-
* `providerCatalogEntry` hook, where we never get a `register(api)` call
|
|
10
|
-
* and therefore never see `api.logger`.
|
|
11
|
-
*
|
|
12
|
-
* - host: `setHostLogger(api.logger)` swaps console for openclaw's plugin
|
|
13
|
-
* logger. Used from the `register(api)` flow when openclaw actually
|
|
14
|
-
* invokes it (currently 2026.5.x does not for external plugins, but
|
|
15
|
-
* future versions are expected to per the SDK docs).
|
|
16
|
-
*
|
|
17
|
-
* Both modes prepend the plugin id so the line is greppable in the shared
|
|
18
|
-
* gateway log next to log lines from bundled plugins.
|
|
19
|
-
*/
|
|
20
|
-
export interface HostLogger {
|
|
21
|
-
error: (message: string) => void;
|
|
22
|
-
warn: (message: string) => void;
|
|
23
|
-
info: (message: string) => void;
|
|
24
|
-
debug?: (message: string) => void;
|
|
25
|
-
}
|
|
26
|
-
export declare function setHostLogger(next: HostLogger | null): void;
|
|
27
|
-
export declare const logger: {
|
|
28
|
-
readonly error: (message: string, meta?: Record<string, unknown>) => void;
|
|
29
|
-
readonly warn: (message: string, meta?: Record<string, unknown>) => void;
|
|
30
|
-
readonly info: (message: string, meta?: Record<string, unknown>) => void;
|
|
31
|
-
readonly debug: (message: string, meta?: Record<string, unknown>) => void;
|
|
32
|
-
};
|
|
33
|
-
//# sourceMappingURL=logger.d.ts.map
|
package/dist/logger.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAIH,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACjC,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACnC;AAID,wBAAgB,aAAa,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI,GAAG,IAAI,CAE3D;AAeD,eAAO,MAAM,MAAM;8BACF,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAG,IAAI;6BAK9C,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAG,IAAI;6BAK7C,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAG,IAAI;8BAK5C,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAG,IAAI;CAKpD,CAAC"}
|
package/dist/logger.js
DELETED
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Plugin-scoped logger with two transports:
|
|
3
|
-
*
|
|
4
|
-
* - default: console.error/warn/info/debug. OpenClaw's gateway CLI
|
|
5
|
-
* captures process console output and writes it to the shared gateway
|
|
6
|
-
* log file alongside its own logger output, so anything we emit here
|
|
7
|
-
* surfaces in `openclaw logs --follow` and the Control UI Logs tab
|
|
8
|
-
* without any wiring. This is the only path available from the
|
|
9
|
-
* `providerCatalogEntry` hook, where we never get a `register(api)` call
|
|
10
|
-
* and therefore never see `api.logger`.
|
|
11
|
-
*
|
|
12
|
-
* - host: `setHostLogger(api.logger)` swaps console for openclaw's plugin
|
|
13
|
-
* logger. Used from the `register(api)` flow when openclaw actually
|
|
14
|
-
* invokes it (currently 2026.5.x does not for external plugins, but
|
|
15
|
-
* future versions are expected to per the SDK docs).
|
|
16
|
-
*
|
|
17
|
-
* Both modes prepend the plugin id so the line is greppable in the shared
|
|
18
|
-
* gateway log next to log lines from bundled plugins.
|
|
19
|
-
*/
|
|
20
|
-
const PREFIX = "[runware-openclaw-provider]";
|
|
21
|
-
let host = null;
|
|
22
|
-
export function setHostLogger(next) {
|
|
23
|
-
host = next;
|
|
24
|
-
}
|
|
25
|
-
function safeStringify(meta) {
|
|
26
|
-
try {
|
|
27
|
-
return JSON.stringify(meta);
|
|
28
|
-
}
|
|
29
|
-
catch {
|
|
30
|
-
return "[unserializable meta]";
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
function format(message, meta) {
|
|
34
|
-
if (!meta || Object.keys(meta).length === 0)
|
|
35
|
-
return `${PREFIX} ${message}`;
|
|
36
|
-
return `${PREFIX} ${message} ${safeStringify(meta)}`;
|
|
37
|
-
}
|
|
38
|
-
export const logger = {
|
|
39
|
-
error(message, meta) {
|
|
40
|
-
const line = format(message, meta);
|
|
41
|
-
if (host)
|
|
42
|
-
host.error(line);
|
|
43
|
-
else
|
|
44
|
-
console.error(line);
|
|
45
|
-
},
|
|
46
|
-
warn(message, meta) {
|
|
47
|
-
const line = format(message, meta);
|
|
48
|
-
if (host)
|
|
49
|
-
host.warn(line);
|
|
50
|
-
else
|
|
51
|
-
console.warn(line);
|
|
52
|
-
},
|
|
53
|
-
info(message, meta) {
|
|
54
|
-
const line = format(message, meta);
|
|
55
|
-
if (host)
|
|
56
|
-
host.info(line);
|
|
57
|
-
else
|
|
58
|
-
console.info(line);
|
|
59
|
-
},
|
|
60
|
-
debug(message, meta) {
|
|
61
|
-
const line = format(message, meta);
|
|
62
|
-
if (host?.debug)
|
|
63
|
-
host.debug(line);
|
|
64
|
-
else if (!host)
|
|
65
|
-
(console.debug ?? console.log).call(console, line);
|
|
66
|
-
},
|
|
67
|
-
};
|
|
68
|
-
//# sourceMappingURL=logger.js.map
|
package/dist/logger.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,MAAM,MAAM,GAAG,6BAA6B,CAAC;AAS7C,IAAI,IAAI,GAAsB,IAAI,CAAC;AAEnC,MAAM,UAAU,aAAa,CAAC,IAAuB;IACnD,IAAI,GAAG,IAAI,CAAC;AACd,CAAC;AAED,SAAS,aAAa,CAAC,IAA6B;IAClD,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IAC9B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,uBAAuB,CAAC;IACjC,CAAC;AACH,CAAC;AAED,SAAS,MAAM,CAAC,OAAe,EAAE,IAA8B;IAC7D,IAAI,CAAC,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,GAAG,MAAM,IAAI,OAAO,EAAE,CAAC;IAC3E,OAAO,GAAG,MAAM,IAAI,OAAO,IAAI,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC;AACvD,CAAC;AAED,MAAM,CAAC,MAAM,MAAM,GAAG;IACpB,KAAK,CAAC,OAAe,EAAE,IAA8B;QACnD,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QACnC,IAAI,IAAI;YAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;;YACtB,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC3B,CAAC;IACD,IAAI,CAAC,OAAe,EAAE,IAA8B;QAClD,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QACnC,IAAI,IAAI;YAAE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;;YACrB,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC;IACD,IAAI,CAAC,OAAe,EAAE,IAA8B;QAClD,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QACnC,IAAI,IAAI;YAAE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;;YACrB,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC;IACD,KAAK,CAAC,OAAe,EAAE,IAA8B;QACnD,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QACnC,IAAI,IAAI,EAAE,KAAK;YAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;aAC7B,IAAI,CAAC,IAAI;YAAE,CAAC,OAAO,CAAC,KAAK,IAAI,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IACrE,CAAC;CACO,CAAC"}
|
package/dist/stream-wrap.d.ts
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import type { StreamFn, WrapStreamFnCtx } from "./openclaw-api.js";
|
|
2
|
-
/**
|
|
3
|
-
* StreamFn wrapper for Runware. Two responsibilities:
|
|
4
|
-
*
|
|
5
|
-
* 1. Strip outgoing params Runware's text-inference endpoint rejects.
|
|
6
|
-
* Runware /v1/chat/completions returns HTTP 400 with
|
|
7
|
-
* "Unsupported use of 'settings.temperature' parameter. This
|
|
8
|
-
* parameter is not supported for text inference" if the request body
|
|
9
|
-
* contains a top-level `temperature`. Openclaw's bundled pi-ai
|
|
10
|
-
* openai-completions builder hardcodes sending temperature whenever a
|
|
11
|
-
* numeric value is configured (see openclaw#32496 — only `temperature`
|
|
12
|
-
* and `maxTokens` are forwarded out of extraParams, and there is no
|
|
13
|
-
* documented `compat` flag to skip it). Deleting the key on the way
|
|
14
|
-
* out is the only surface available to a plugin.
|
|
15
|
-
*
|
|
16
|
-
* 2. Translate cryptic upstream errors into a Runware-prefixed message
|
|
17
|
-
* that openclaw's `surface_error` path will show to the end user in
|
|
18
|
-
* webchat / TUI verbatim. Without this, every Runware 4xx collapses
|
|
19
|
-
* into openclaw's generic "provider rejected the request schema or
|
|
20
|
-
* tool payload" classifier and the actual cause is buried in
|
|
21
|
-
* diagnostics-only logs.
|
|
22
|
-
*/
|
|
23
|
-
export declare function buildRunwareStreamWrapper(ctx: WrapStreamFnCtx): StreamFn | undefined;
|
|
24
|
-
//# sourceMappingURL=stream-wrap.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"stream-wrap.d.ts","sourceRoot":"","sources":["../src/stream-wrap.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEnE;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,yBAAyB,CACvC,GAAG,EAAE,eAAe,GACnB,QAAQ,GAAG,SAAS,CA2BtB"}
|
package/dist/stream-wrap.js
DELETED
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import { logger } from "./logger.js";
|
|
2
|
-
/**
|
|
3
|
-
* StreamFn wrapper for Runware. Two responsibilities:
|
|
4
|
-
*
|
|
5
|
-
* 1. Strip outgoing params Runware's text-inference endpoint rejects.
|
|
6
|
-
* Runware /v1/chat/completions returns HTTP 400 with
|
|
7
|
-
* "Unsupported use of 'settings.temperature' parameter. This
|
|
8
|
-
* parameter is not supported for text inference" if the request body
|
|
9
|
-
* contains a top-level `temperature`. Openclaw's bundled pi-ai
|
|
10
|
-
* openai-completions builder hardcodes sending temperature whenever a
|
|
11
|
-
* numeric value is configured (see openclaw#32496 — only `temperature`
|
|
12
|
-
* and `maxTokens` are forwarded out of extraParams, and there is no
|
|
13
|
-
* documented `compat` flag to skip it). Deleting the key on the way
|
|
14
|
-
* out is the only surface available to a plugin.
|
|
15
|
-
*
|
|
16
|
-
* 2. Translate cryptic upstream errors into a Runware-prefixed message
|
|
17
|
-
* that openclaw's `surface_error` path will show to the end user in
|
|
18
|
-
* webchat / TUI verbatim. Without this, every Runware 4xx collapses
|
|
19
|
-
* into openclaw's generic "provider rejected the request schema or
|
|
20
|
-
* tool payload" classifier and the actual cause is buried in
|
|
21
|
-
* diagnostics-only logs.
|
|
22
|
-
*/
|
|
23
|
-
export function buildRunwareStreamWrapper(ctx) {
|
|
24
|
-
if (!ctx.streamFn)
|
|
25
|
-
return undefined;
|
|
26
|
-
const inner = ctx.streamFn;
|
|
27
|
-
const modelId = ctx.model?.id;
|
|
28
|
-
return async (params) => {
|
|
29
|
-
if ("temperature" in params) {
|
|
30
|
-
logger.debug("stripping unsupported `temperature` param for Runware request", {
|
|
31
|
-
model: modelId,
|
|
32
|
-
});
|
|
33
|
-
delete params.temperature;
|
|
34
|
-
}
|
|
35
|
-
try {
|
|
36
|
-
return await inner(params);
|
|
37
|
-
}
|
|
38
|
-
catch (err) {
|
|
39
|
-
const raw = err instanceof Error ? err.message : String(err);
|
|
40
|
-
logger.error("Runware inference call failed", {
|
|
41
|
-
model: modelId,
|
|
42
|
-
error: raw,
|
|
43
|
-
});
|
|
44
|
-
// Re-throw with a "Runware:" prefix so the gateway's surface_error
|
|
45
|
-
// path shows the real upstream message to the user instead of the
|
|
46
|
-
// generic classifier text.
|
|
47
|
-
throw new Error(`Runware: ${raw}`);
|
|
48
|
-
}
|
|
49
|
-
};
|
|
50
|
-
}
|
|
51
|
-
//# sourceMappingURL=stream-wrap.js.map
|
package/dist/stream-wrap.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"stream-wrap.js","sourceRoot":"","sources":["../src/stream-wrap.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAGrC;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,UAAU,yBAAyB,CACvC,GAAoB;IAEpB,IAAI,CAAC,GAAG,CAAC,QAAQ;QAAE,OAAO,SAAS,CAAC;IACpC,MAAM,KAAK,GAAG,GAAG,CAAC,QAAQ,CAAC;IAC3B,MAAM,OAAO,GAAG,GAAG,CAAC,KAAK,EAAE,EAAE,CAAC;IAE9B,OAAO,KAAK,EAAE,MAAM,EAAE,EAAE;QACtB,IAAI,aAAa,IAAI,MAAM,EAAE,CAAC;YAC5B,MAAM,CAAC,KAAK,CAAC,+DAA+D,EAAE;gBAC5E,KAAK,EAAE,OAAO;aACf,CAAC,CAAC;YACH,OAAO,MAAM,CAAC,WAAW,CAAC;QAC5B,CAAC;QAED,IAAI,CAAC;YACH,OAAO,MAAM,KAAK,CAAC,MAAM,CAAC,CAAC;QAC7B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAC7D,MAAM,CAAC,KAAK,CAAC,+BAA+B,EAAE;gBAC5C,KAAK,EAAE,OAAO;gBACd,KAAK,EAAE,GAAG;aACX,CAAC,CAAC;YACH,mEAAmE;YACnE,kEAAkE;YAClE,2BAA2B;YAC3B,MAAM,IAAI,KAAK,CAAC,YAAY,GAAG,EAAE,CAAC,CAAC;QACrC,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
|