@teith/openclaw-runware-provider 0.3.0 → 0.3.2
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 -0
- package/dist/catalog.d.ts +11 -1
- package/dist/catalog.d.ts.map +1 -1
- package/dist/catalog.js +40 -9
- package/dist/catalog.js.map +1 -1
- package/dist/models.d.ts +16 -13
- package/dist/models.d.ts.map +1 -1
- package/dist/models.js +37 -25
- package/dist/models.js.map +1 -1
- package/package.json +9 -2
package/README.md
CHANGED
|
@@ -39,6 +39,15 @@ 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
|
|
package/dist/catalog.d.ts
CHANGED
|
@@ -1,3 +1,13 @@
|
|
|
1
|
-
export
|
|
1
|
+
export interface RunwareModel {
|
|
2
|
+
id: string;
|
|
3
|
+
name?: string;
|
|
4
|
+
contextLength?: number;
|
|
5
|
+
maxOutputTokens?: number;
|
|
6
|
+
inputCost?: number;
|
|
7
|
+
outputCost?: number;
|
|
8
|
+
cacheReadCost?: number;
|
|
9
|
+
cacheWriteCost?: number;
|
|
10
|
+
}
|
|
11
|
+
export declare function fetchModels(baseUrl: string, apiKey: string): Promise<RunwareModel[]>;
|
|
2
12
|
export declare function resetCache(): void;
|
|
3
13
|
//# 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,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;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAcD,wBAAsB,WAAW,CAC/B,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,YAAY,EAAE,CAAC,CAsBzB;AA0DD,wBAAgB,UAAU,IAAI,IAAI,CAGjC"}
|
package/dist/catalog.js
CHANGED
|
@@ -2,22 +2,22 @@ const CACHE_TTL_MS = 5 * 60 * 1000;
|
|
|
2
2
|
const FETCH_TIMEOUT_MS = 5000;
|
|
3
3
|
let cache = null;
|
|
4
4
|
let inflight = null;
|
|
5
|
-
export async function
|
|
5
|
+
export async function fetchModels(baseUrl, apiKey) {
|
|
6
6
|
const now = Date.now();
|
|
7
7
|
if (cache && now - cache.fetchedAt < CACHE_TTL_MS) {
|
|
8
|
-
return cache.
|
|
8
|
+
return cache.models;
|
|
9
9
|
}
|
|
10
10
|
if (inflight)
|
|
11
11
|
return inflight;
|
|
12
12
|
inflight = (async () => {
|
|
13
13
|
try {
|
|
14
|
-
const
|
|
15
|
-
cache = {
|
|
16
|
-
return
|
|
14
|
+
const models = await fetchFromUpstream(baseUrl, apiKey);
|
|
15
|
+
cache = { models, fetchedAt: Date.now() };
|
|
16
|
+
return models;
|
|
17
17
|
}
|
|
18
18
|
catch (err) {
|
|
19
19
|
if (cache)
|
|
20
|
-
return cache.
|
|
20
|
+
return cache.models;
|
|
21
21
|
throw err;
|
|
22
22
|
}
|
|
23
23
|
finally {
|
|
@@ -39,14 +39,45 @@ async function fetchFromUpstream(baseUrl, apiKey) {
|
|
|
39
39
|
throw new Error(`Runware /models returned ${res.status} ${res.statusText}`);
|
|
40
40
|
}
|
|
41
41
|
const body = (await res.json());
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
.
|
|
42
|
+
const data = Array.isArray(body.data) ? body.data : [];
|
|
43
|
+
return data
|
|
44
|
+
.map(parseRunwareModel)
|
|
45
|
+
.filter((m) => m !== null);
|
|
45
46
|
}
|
|
46
47
|
finally {
|
|
47
48
|
clearTimeout(timeout);
|
|
48
49
|
}
|
|
49
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
|
+
if (typeof m.input_cost === "number" && m.input_cost >= 0) {
|
|
68
|
+
parsed.inputCost = m.input_cost;
|
|
69
|
+
}
|
|
70
|
+
if (typeof m.output_cost === "number" && m.output_cost >= 0) {
|
|
71
|
+
parsed.outputCost = m.output_cost;
|
|
72
|
+
}
|
|
73
|
+
if (typeof m.cache_read_cost === "number" && m.cache_read_cost >= 0) {
|
|
74
|
+
parsed.cacheReadCost = m.cache_read_cost;
|
|
75
|
+
}
|
|
76
|
+
if (typeof m.cache_write_cost === "number" && m.cache_write_cost >= 0) {
|
|
77
|
+
parsed.cacheWriteCost = m.cache_write_cost;
|
|
78
|
+
}
|
|
79
|
+
return parsed;
|
|
80
|
+
}
|
|
50
81
|
export function resetCache() {
|
|
51
82
|
cache = null;
|
|
52
83
|
inflight = null;
|
package/dist/catalog.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"catalog.js","sourceRoot":"","sources":["../src/catalog.ts"],"names":[],"mappings":"AAAA,MAAM,YAAY,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;AACnC,MAAM,gBAAgB,GAAG,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"catalog.js","sourceRoot":"","sources":["../src/catalog.ts"],"names":[],"mappings":"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"}
|
package/dist/models.d.ts
CHANGED
|
@@ -4,27 +4,29 @@
|
|
|
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";
|
|
20
22
|
};
|
|
21
23
|
};
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
}
|
|
24
|
+
export interface ModelCost {
|
|
25
|
+
input: number;
|
|
26
|
+
output: number;
|
|
27
|
+
cacheRead: number;
|
|
28
|
+
cacheWrite: number;
|
|
29
|
+
}
|
|
28
30
|
export interface ModelEntry {
|
|
29
31
|
id: string;
|
|
30
32
|
name: string;
|
|
@@ -32,7 +34,7 @@ export interface ModelEntry {
|
|
|
32
34
|
input: ["text"];
|
|
33
35
|
contextWindow: number;
|
|
34
36
|
maxTokens: number;
|
|
35
|
-
cost:
|
|
37
|
+
cost: ModelCost;
|
|
36
38
|
params: typeof MODEL_PARAMS;
|
|
37
39
|
}
|
|
38
40
|
export interface ProviderShape {
|
|
@@ -52,11 +54,12 @@ export interface ModelCatalogRow {
|
|
|
52
54
|
input: ["text"];
|
|
53
55
|
contextWindow: number;
|
|
54
56
|
maxTokens: number;
|
|
55
|
-
cost:
|
|
57
|
+
cost: ModelCost;
|
|
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;AAG3E,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,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,SAAS,CAAC;IAChB,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,SAAS,CAAC;CACjB;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;AAuCD;;;;;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
|
-
const
|
|
22
|
+
const DEFAULT_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,30 +72,38 @@ 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
|
|
75
|
+
function buildModelCost(model) {
|
|
76
|
+
return {
|
|
77
|
+
input: model.inputCost ?? DEFAULT_COST.input,
|
|
78
|
+
output: model.outputCost ?? DEFAULT_COST.output,
|
|
79
|
+
cacheRead: model.cacheReadCost ?? DEFAULT_COST.cacheRead,
|
|
80
|
+
cacheWrite: model.cacheWriteCost ?? DEFAULT_COST.cacheWrite,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
function buildModelEntry(model) {
|
|
72
84
|
return {
|
|
73
|
-
id,
|
|
74
|
-
name:
|
|
85
|
+
id: model.id,
|
|
86
|
+
name: displayName(model),
|
|
75
87
|
reasoning: true,
|
|
76
88
|
input: ["text"],
|
|
77
|
-
contextWindow:
|
|
78
|
-
maxTokens:
|
|
79
|
-
cost:
|
|
89
|
+
contextWindow: model.contextLength ?? DEFAULT_CONTEXT_WINDOW,
|
|
90
|
+
maxTokens: model.maxOutputTokens ?? DEFAULT_MAX_TOKENS,
|
|
91
|
+
cost: buildModelCost(model),
|
|
80
92
|
params: MODEL_PARAMS,
|
|
81
93
|
};
|
|
82
94
|
}
|
|
83
|
-
function buildCatalogRow(
|
|
95
|
+
function buildCatalogRow(model) {
|
|
84
96
|
return {
|
|
85
97
|
kind: "text",
|
|
86
98
|
provider: PROVIDER_ID,
|
|
87
|
-
model: id,
|
|
88
|
-
label:
|
|
99
|
+
model: model.id,
|
|
100
|
+
label: displayName(model),
|
|
89
101
|
source: "live",
|
|
90
102
|
reasoning: true,
|
|
91
103
|
input: ["text"],
|
|
92
|
-
contextWindow:
|
|
93
|
-
maxTokens:
|
|
94
|
-
cost:
|
|
104
|
+
contextWindow: model.contextLength ?? DEFAULT_CONTEXT_WINDOW,
|
|
105
|
+
maxTokens: model.maxOutputTokens ?? DEFAULT_MAX_TOKENS,
|
|
106
|
+
cost: buildModelCost(model),
|
|
95
107
|
};
|
|
96
108
|
}
|
|
97
109
|
/**
|
|
@@ -101,13 +113,13 @@ function buildCatalogRow(id) {
|
|
|
101
113
|
* `/v1/models` from Runware via the TTL cache in `catalog.ts`.
|
|
102
114
|
*/
|
|
103
115
|
export async function buildProvider(apiKey, baseUrl) {
|
|
104
|
-
const
|
|
116
|
+
const models = await fetchModels(baseUrl, apiKey);
|
|
105
117
|
return {
|
|
106
118
|
baseUrl,
|
|
107
119
|
apiKey,
|
|
108
120
|
api: "openai-completions",
|
|
109
121
|
timeoutSeconds: REQUEST_TIMEOUT_SECONDS,
|
|
110
|
-
models:
|
|
122
|
+
models: models.map(buildModelEntry),
|
|
111
123
|
};
|
|
112
124
|
}
|
|
113
125
|
/**
|
|
@@ -117,7 +129,7 @@ export async function buildProvider(apiKey, baseUrl) {
|
|
|
117
129
|
* response.
|
|
118
130
|
*/
|
|
119
131
|
export async function buildCatalogRows(apiKey, baseUrl) {
|
|
120
|
-
const
|
|
121
|
-
return
|
|
132
|
+
const models = await fetchModels(baseUrl, apiKey);
|
|
133
|
+
return models.map(buildCatalogRow);
|
|
122
134
|
}
|
|
123
135
|
//# 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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@teith/openclaw-runware-provider",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.2",
|
|
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",
|
|
@@ -35,7 +35,14 @@
|
|
|
35
35
|
],
|
|
36
36
|
"providers": [
|
|
37
37
|
"runware"
|
|
38
|
-
]
|
|
38
|
+
],
|
|
39
|
+
"compat": {
|
|
40
|
+
"pluginApi": ">=2026.3.24-beta.2",
|
|
41
|
+
"minGatewayVersion": "2026.5.18"
|
|
42
|
+
},
|
|
43
|
+
"build": {
|
|
44
|
+
"openclawVersion": "2026.5.18"
|
|
45
|
+
}
|
|
39
46
|
},
|
|
40
47
|
"keywords": [
|
|
41
48
|
"openclaw",
|