@openclaw/kilocode-provider 0.0.0 → 2026.6.9-beta.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 +11 -2
- package/dist/api.js +3 -0
- package/dist/index.js +42 -0
- package/dist/onboard.js +25 -0
- package/dist/provider-catalog.js +26 -0
- package/dist/provider-models.js +137 -0
- package/dist/stream.js +83 -0
- package/npm-shrinkwrap.json +12 -0
- package/openclaw.plugin.json +76 -0
- package/package.json +44 -8
package/README.md
CHANGED
|
@@ -1,3 +1,12 @@
|
|
|
1
|
-
#
|
|
1
|
+
# OpenClaw Kilo Gateway Provider
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Official OpenClaw provider plugin for Kilo Gateway.
|
|
4
|
+
|
|
5
|
+
Install from OpenClaw:
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
openclaw plugins install @openclaw/kilocode-provider
|
|
9
|
+
openclaw gateway restart
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
See <https://docs.openclaw.ai/providers/kilocode> for setup and configuration.
|
package/dist/api.js
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { KILOCODE_BASE_URL, KILOCODE_DEFAULT_CONTEXT_WINDOW, KILOCODE_DEFAULT_COST, KILOCODE_DEFAULT_MAX_TOKENS, KILOCODE_DEFAULT_MODEL_ID, KILOCODE_DEFAULT_MODEL_NAME, KILOCODE_DEFAULT_MODEL_REF, KILOCODE_MODELS_URL, KILOCODE_MODEL_CATALOG, buildKilocodeModelDefinition, discoverKilocodeModels } from "./provider-models.js";
|
|
2
|
+
import { buildKilocodeProvider, buildKilocodeProviderWithDiscovery } from "./provider-catalog.js";
|
|
3
|
+
export { KILOCODE_BASE_URL, KILOCODE_DEFAULT_CONTEXT_WINDOW, KILOCODE_DEFAULT_COST, KILOCODE_DEFAULT_MAX_TOKENS, KILOCODE_DEFAULT_MODEL_ID, KILOCODE_DEFAULT_MODEL_NAME, KILOCODE_DEFAULT_MODEL_REF, KILOCODE_MODELS_URL, KILOCODE_MODEL_CATALOG, buildKilocodeModelDefinition, buildKilocodeProvider, buildKilocodeProviderWithDiscovery, discoverKilocodeModels };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { KILOCODE_DEFAULT_MODEL_REF } from "./provider-models.js";
|
|
2
|
+
import { buildKilocodeProvider, buildKilocodeProviderWithDiscovery } from "./provider-catalog.js";
|
|
3
|
+
import { applyKilocodeConfig } from "./onboard.js";
|
|
4
|
+
import { wrapKilocodeProviderStream } from "./stream.js";
|
|
5
|
+
import { readConfiguredProviderCatalogEntries } from "openclaw/plugin-sdk/provider-catalog-shared";
|
|
6
|
+
import { defineSingleProviderPluginEntry } from "openclaw/plugin-sdk/provider-entry";
|
|
7
|
+
import { PASSTHROUGH_GEMINI_REPLAY_HOOKS } from "openclaw/plugin-sdk/provider-model-shared";
|
|
8
|
+
//#region extensions/kilocode/index.ts
|
|
9
|
+
const PROVIDER_ID = "kilocode";
|
|
10
|
+
var kilocode_default = defineSingleProviderPluginEntry({
|
|
11
|
+
id: PROVIDER_ID,
|
|
12
|
+
name: "Kilo Gateway Provider",
|
|
13
|
+
description: "Bundled Kilo Gateway provider plugin",
|
|
14
|
+
provider: {
|
|
15
|
+
label: "Kilo Gateway",
|
|
16
|
+
docsPath: "/providers/kilocode",
|
|
17
|
+
auth: [{
|
|
18
|
+
methodId: "api-key",
|
|
19
|
+
label: "Kilo Gateway API key",
|
|
20
|
+
hint: "API key (OpenRouter-compatible)",
|
|
21
|
+
optionKey: "kilocodeApiKey",
|
|
22
|
+
flagName: "--kilocode-api-key",
|
|
23
|
+
envVar: "KILOCODE_API_KEY",
|
|
24
|
+
promptMessage: "Enter Kilo Gateway API key",
|
|
25
|
+
defaultModel: KILOCODE_DEFAULT_MODEL_REF,
|
|
26
|
+
applyConfig: (cfg) => applyKilocodeConfig(cfg)
|
|
27
|
+
}],
|
|
28
|
+
catalog: {
|
|
29
|
+
buildProvider: buildKilocodeProviderWithDiscovery,
|
|
30
|
+
buildStaticProvider: buildKilocodeProvider
|
|
31
|
+
},
|
|
32
|
+
augmentModelCatalog: ({ config }) => readConfiguredProviderCatalogEntries({
|
|
33
|
+
config,
|
|
34
|
+
providerId: PROVIDER_ID
|
|
35
|
+
}),
|
|
36
|
+
...PASSTHROUGH_GEMINI_REPLAY_HOOKS,
|
|
37
|
+
wrapStreamFn: wrapKilocodeProviderStream,
|
|
38
|
+
isCacheTtlEligible: (ctx) => ctx.modelId.startsWith("anthropic/")
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
//#endregion
|
|
42
|
+
export { kilocode_default as default };
|
package/dist/onboard.js
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { KILOCODE_BASE_URL, KILOCODE_DEFAULT_MODEL_REF } from "./provider-models.js";
|
|
2
|
+
import { buildKilocodeProvider } from "./provider-catalog.js";
|
|
3
|
+
import { createModelCatalogPresetAppliers } from "openclaw/plugin-sdk/provider-onboard";
|
|
4
|
+
//#region extensions/kilocode/onboard.ts
|
|
5
|
+
const kilocodePresetAppliers = createModelCatalogPresetAppliers({
|
|
6
|
+
primaryModelRef: KILOCODE_DEFAULT_MODEL_REF,
|
|
7
|
+
resolveParams: (_cfg) => ({
|
|
8
|
+
providerId: "kilocode",
|
|
9
|
+
api: "openai-completions",
|
|
10
|
+
baseUrl: KILOCODE_BASE_URL,
|
|
11
|
+
catalogModels: buildKilocodeProvider().models ?? [],
|
|
12
|
+
aliases: [{
|
|
13
|
+
modelRef: KILOCODE_DEFAULT_MODEL_REF,
|
|
14
|
+
alias: "Kilo Gateway"
|
|
15
|
+
}]
|
|
16
|
+
})
|
|
17
|
+
});
|
|
18
|
+
function applyKilocodeProviderConfig(cfg) {
|
|
19
|
+
return kilocodePresetAppliers.applyProviderConfig(cfg);
|
|
20
|
+
}
|
|
21
|
+
function applyKilocodeConfig(cfg) {
|
|
22
|
+
return kilocodePresetAppliers.applyConfig(cfg);
|
|
23
|
+
}
|
|
24
|
+
//#endregion
|
|
25
|
+
export { KILOCODE_BASE_URL, KILOCODE_DEFAULT_MODEL_REF, applyKilocodeConfig, applyKilocodeProviderConfig };
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { KILOCODE_BASE_URL, KILOCODE_DEFAULT_COST, KILOCODE_MODEL_CATALOG, discoverKilocodeModels } from "./provider-models.js";
|
|
2
|
+
//#region extensions/kilocode/provider-catalog.ts
|
|
3
|
+
function buildKilocodeProvider() {
|
|
4
|
+
return {
|
|
5
|
+
baseUrl: KILOCODE_BASE_URL,
|
|
6
|
+
api: "openai-completions",
|
|
7
|
+
models: KILOCODE_MODEL_CATALOG.map((model) => ({
|
|
8
|
+
id: model.id,
|
|
9
|
+
name: model.name,
|
|
10
|
+
reasoning: model.reasoning,
|
|
11
|
+
input: model.input,
|
|
12
|
+
cost: KILOCODE_DEFAULT_COST,
|
|
13
|
+
contextWindow: model.contextWindow ?? 1e6,
|
|
14
|
+
maxTokens: model.maxTokens ?? 128e3
|
|
15
|
+
}))
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
async function buildKilocodeProviderWithDiscovery() {
|
|
19
|
+
return {
|
|
20
|
+
baseUrl: KILOCODE_BASE_URL,
|
|
21
|
+
api: "openai-completions",
|
|
22
|
+
models: await discoverKilocodeModels()
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
//#endregion
|
|
26
|
+
export { buildKilocodeProvider, buildKilocodeProviderWithDiscovery };
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { readProviderJsonArrayFieldResponse } from "openclaw/plugin-sdk/provider-http";
|
|
2
|
+
import { createSubsystemLogger } from "openclaw/plugin-sdk/runtime-env";
|
|
3
|
+
import { fetchWithSsrFGuard, ssrfPolicyFromHttpBaseUrlAllowedHostname } from "openclaw/plugin-sdk/ssrf-runtime";
|
|
4
|
+
import { asPositiveSafeInteger, normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
5
|
+
//#region extensions/kilocode/provider-models.ts
|
|
6
|
+
const log = createSubsystemLogger("kilocode-models");
|
|
7
|
+
const KILOCODE_BASE_URL = "https://api.kilo.ai/api/gateway/";
|
|
8
|
+
const KILOCODE_DEFAULT_MODEL_ID = "kilo/auto";
|
|
9
|
+
const KILOCODE_DEFAULT_MODEL_REF = `kilocode/${KILOCODE_DEFAULT_MODEL_ID}`;
|
|
10
|
+
const KILOCODE_DEFAULT_MODEL_NAME = "Kilo Auto";
|
|
11
|
+
const KILOCODE_MODEL_CATALOG = [{
|
|
12
|
+
id: KILOCODE_DEFAULT_MODEL_ID,
|
|
13
|
+
name: KILOCODE_DEFAULT_MODEL_NAME,
|
|
14
|
+
input: ["text", "image"],
|
|
15
|
+
reasoning: true
|
|
16
|
+
}];
|
|
17
|
+
const KILOCODE_DEFAULT_CONTEXT_WINDOW = 1e6;
|
|
18
|
+
const KILOCODE_DEFAULT_MAX_TOKENS = 128e3;
|
|
19
|
+
const KILOCODE_DEFAULT_COST = {
|
|
20
|
+
input: 0,
|
|
21
|
+
output: 0,
|
|
22
|
+
cacheRead: 0,
|
|
23
|
+
cacheWrite: 0
|
|
24
|
+
};
|
|
25
|
+
const KILOCODE_MODELS_URL = `${KILOCODE_BASE_URL}models`;
|
|
26
|
+
const DISCOVERY_TIMEOUT_MS = 5e3;
|
|
27
|
+
function toPricePerMillion(perToken) {
|
|
28
|
+
if (!perToken) return 0;
|
|
29
|
+
const num = Number(perToken);
|
|
30
|
+
if (!Number.isFinite(num) || num < 0) return 0;
|
|
31
|
+
return num * 1e6;
|
|
32
|
+
}
|
|
33
|
+
function parseModality(entry) {
|
|
34
|
+
const modalities = entry.architecture?.input_modalities;
|
|
35
|
+
if (!Array.isArray(modalities)) return ["text"];
|
|
36
|
+
return modalities.some((m) => typeof m === "string" && normalizeLowercaseStringOrEmpty(m) === "image") ? ["text", "image"] : ["text"];
|
|
37
|
+
}
|
|
38
|
+
function parseReasoning(entry) {
|
|
39
|
+
const params = entry.supported_parameters;
|
|
40
|
+
if (!Array.isArray(params)) return false;
|
|
41
|
+
return params.includes("reasoning") || params.includes("include_reasoning");
|
|
42
|
+
}
|
|
43
|
+
function toModelDefinition(entry) {
|
|
44
|
+
return {
|
|
45
|
+
id: entry.id,
|
|
46
|
+
name: entry.name || entry.id,
|
|
47
|
+
reasoning: parseReasoning(entry),
|
|
48
|
+
input: parseModality(entry),
|
|
49
|
+
cost: {
|
|
50
|
+
input: toPricePerMillion(entry.pricing.prompt),
|
|
51
|
+
output: toPricePerMillion(entry.pricing.completion),
|
|
52
|
+
cacheRead: toPricePerMillion(entry.pricing.input_cache_read),
|
|
53
|
+
cacheWrite: toPricePerMillion(entry.pricing.input_cache_write)
|
|
54
|
+
},
|
|
55
|
+
contextWindow: asPositiveSafeInteger(entry.context_length) ?? 1e6,
|
|
56
|
+
maxTokens: asPositiveSafeInteger(entry.top_provider?.max_completion_tokens) ?? 128e3
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
function buildStaticCatalog() {
|
|
60
|
+
return KILOCODE_MODEL_CATALOG.map((model) => ({
|
|
61
|
+
id: model.id,
|
|
62
|
+
name: model.name,
|
|
63
|
+
reasoning: model.reasoning,
|
|
64
|
+
input: model.input,
|
|
65
|
+
cost: KILOCODE_DEFAULT_COST,
|
|
66
|
+
contextWindow: model.contextWindow ?? 1e6,
|
|
67
|
+
maxTokens: model.maxTokens ?? 128e3
|
|
68
|
+
}));
|
|
69
|
+
}
|
|
70
|
+
function asGatewayModelEntry(value) {
|
|
71
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) throw new Error("Kilocode model list: malformed JSON response");
|
|
72
|
+
const entry = value;
|
|
73
|
+
if (typeof entry.id !== "string" || typeof entry.pricing !== "object" || entry.pricing === null || Array.isArray(entry.pricing)) throw new Error("Kilocode model list: malformed JSON response");
|
|
74
|
+
return value;
|
|
75
|
+
}
|
|
76
|
+
function readGatewayModelId(value) {
|
|
77
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) return "";
|
|
78
|
+
const id = value.id;
|
|
79
|
+
return typeof id === "string" ? id.trim() : "";
|
|
80
|
+
}
|
|
81
|
+
async function discoverKilocodeModels() {
|
|
82
|
+
if (process.env.VITEST) return buildStaticCatalog();
|
|
83
|
+
try {
|
|
84
|
+
const { response, release } = await fetchWithSsrFGuard({
|
|
85
|
+
url: KILOCODE_MODELS_URL,
|
|
86
|
+
init: { headers: { Accept: "application/json" } },
|
|
87
|
+
timeoutMs: DISCOVERY_TIMEOUT_MS,
|
|
88
|
+
policy: ssrfPolicyFromHttpBaseUrlAllowedHostname(KILOCODE_BASE_URL),
|
|
89
|
+
auditContext: "kilocode.model_discovery"
|
|
90
|
+
});
|
|
91
|
+
try {
|
|
92
|
+
if (!response.ok) {
|
|
93
|
+
log.warn(`Failed to discover models: HTTP ${response.status}, using static catalog`);
|
|
94
|
+
return buildStaticCatalog();
|
|
95
|
+
}
|
|
96
|
+
const data = await readProviderJsonArrayFieldResponse(response, "Kilocode model list", "data");
|
|
97
|
+
if (data.length === 0) {
|
|
98
|
+
log.warn("No models found from gateway API, using static catalog");
|
|
99
|
+
return buildStaticCatalog();
|
|
100
|
+
}
|
|
101
|
+
const models = [];
|
|
102
|
+
const discoveredIds = /* @__PURE__ */ new Set();
|
|
103
|
+
for (const rawEntry of data) {
|
|
104
|
+
const id = readGatewayModelId(rawEntry);
|
|
105
|
+
try {
|
|
106
|
+
const entry = asGatewayModelEntry(rawEntry);
|
|
107
|
+
if (!id || discoveredIds.has(id)) continue;
|
|
108
|
+
models.push(toModelDefinition(entry));
|
|
109
|
+
discoveredIds.add(id);
|
|
110
|
+
} catch (e) {
|
|
111
|
+
log.warn(`Skipping malformed model entry "${id}": ${String(e)}`);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
const staticModels = buildStaticCatalog();
|
|
115
|
+
for (const staticModel of staticModels) if (!discoveredIds.has(staticModel.id)) models.unshift(staticModel);
|
|
116
|
+
return models.length > 0 ? models : buildStaticCatalog();
|
|
117
|
+
} finally {
|
|
118
|
+
await release();
|
|
119
|
+
}
|
|
120
|
+
} catch (error) {
|
|
121
|
+
log.warn(`Discovery failed: ${String(error)}, using static catalog`);
|
|
122
|
+
return buildStaticCatalog();
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
function buildKilocodeModelDefinition() {
|
|
126
|
+
return {
|
|
127
|
+
id: KILOCODE_DEFAULT_MODEL_ID,
|
|
128
|
+
name: KILOCODE_DEFAULT_MODEL_NAME,
|
|
129
|
+
reasoning: true,
|
|
130
|
+
input: ["text", "image"],
|
|
131
|
+
cost: KILOCODE_DEFAULT_COST,
|
|
132
|
+
contextWindow: KILOCODE_DEFAULT_CONTEXT_WINDOW,
|
|
133
|
+
maxTokens: KILOCODE_DEFAULT_MAX_TOKENS
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
//#endregion
|
|
137
|
+
export { KILOCODE_BASE_URL, KILOCODE_DEFAULT_CONTEXT_WINDOW, KILOCODE_DEFAULT_COST, KILOCODE_DEFAULT_MAX_TOKENS, KILOCODE_DEFAULT_MODEL_ID, KILOCODE_DEFAULT_MODEL_NAME, KILOCODE_DEFAULT_MODEL_REF, KILOCODE_MODELS_URL, KILOCODE_MODEL_CATALOG, buildKilocodeModelDefinition, discoverKilocodeModels };
|
package/dist/stream.js
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { resolveProviderRequestHeaders } from "openclaw/plugin-sdk/provider-http";
|
|
2
|
+
import { normalizeOptionalLowercaseString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
3
|
+
//#region extensions/kilocode/stream.ts
|
|
4
|
+
const KILOCODE_FEATURE_HEADER = "X-KILOCODE-FEATURE";
|
|
5
|
+
const KILOCODE_FEATURE_DEFAULT = "openclaw";
|
|
6
|
+
const KILOCODE_FEATURE_ENV_VAR = "KILOCODE_FEATURE";
|
|
7
|
+
function resolveKilocodeAppHeaders() {
|
|
8
|
+
const feature = process.env[KILOCODE_FEATURE_ENV_VAR]?.trim() || KILOCODE_FEATURE_DEFAULT;
|
|
9
|
+
return { [KILOCODE_FEATURE_HEADER]: feature };
|
|
10
|
+
}
|
|
11
|
+
function mapThinkingLevelToReasoningEffort(thinkingLevel) {
|
|
12
|
+
if (thinkingLevel === "off") return "none";
|
|
13
|
+
if (thinkingLevel === "adaptive") return "medium";
|
|
14
|
+
if (thinkingLevel === "max") return "xhigh";
|
|
15
|
+
return thinkingLevel;
|
|
16
|
+
}
|
|
17
|
+
function normalizeKilocodeReasoningPayload(payloadObj, thinkingLevel) {
|
|
18
|
+
delete payloadObj.reasoning_effort;
|
|
19
|
+
if (!thinkingLevel || thinkingLevel === "off") return;
|
|
20
|
+
const existingReasoning = payloadObj.reasoning;
|
|
21
|
+
if (existingReasoning && typeof existingReasoning === "object" && !Array.isArray(existingReasoning)) {
|
|
22
|
+
const reasoningObj = existingReasoning;
|
|
23
|
+
if (!("max_tokens" in reasoningObj) && !("effort" in reasoningObj)) reasoningObj.effort = mapThinkingLevelToReasoningEffort(thinkingLevel);
|
|
24
|
+
} else if (!existingReasoning) payloadObj.reasoning = { effort: mapThinkingLevelToReasoningEffort(thinkingLevel) };
|
|
25
|
+
}
|
|
26
|
+
function normalizeKilocodeStopPayload(payloadObj) {
|
|
27
|
+
if (typeof payloadObj.stop === "string") payloadObj.stop = [payloadObj.stop];
|
|
28
|
+
}
|
|
29
|
+
function asRecord(value) {
|
|
30
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : void 0;
|
|
31
|
+
}
|
|
32
|
+
function normalizeKilocodeStopAfterCaller(value, fallbackPayload) {
|
|
33
|
+
const replacementPayload = asRecord(value);
|
|
34
|
+
if (replacementPayload) {
|
|
35
|
+
normalizeKilocodeStopPayload(replacementPayload);
|
|
36
|
+
return value;
|
|
37
|
+
}
|
|
38
|
+
if (fallbackPayload) normalizeKilocodeStopPayload(fallbackPayload);
|
|
39
|
+
return value;
|
|
40
|
+
}
|
|
41
|
+
function isProxyReasoningUnsupported(modelId) {
|
|
42
|
+
const trimmed = normalizeOptionalLowercaseString(modelId);
|
|
43
|
+
const slashIndex = trimmed?.indexOf("/") ?? -1;
|
|
44
|
+
return slashIndex > 0 && trimmed?.slice(0, slashIndex) === "x-ai";
|
|
45
|
+
}
|
|
46
|
+
function resolveKilocodeThinkingLevel(ctx) {
|
|
47
|
+
if (ctx.modelId === "kilo/auto" || isProxyReasoningUnsupported(ctx.modelId)) return;
|
|
48
|
+
return ctx.thinkingLevel;
|
|
49
|
+
}
|
|
50
|
+
function createKilocodeStreamWrapper(baseStreamFn, thinkingLevel) {
|
|
51
|
+
if (!baseStreamFn) return;
|
|
52
|
+
const underlying = baseStreamFn;
|
|
53
|
+
return (model, context, options) => {
|
|
54
|
+
const originalOnPayload = options?.onPayload;
|
|
55
|
+
const headers = resolveProviderRequestHeaders({
|
|
56
|
+
provider: typeof model.provider === "string" ? model.provider : "kilocode",
|
|
57
|
+
api: model.api,
|
|
58
|
+
baseUrl: typeof model.baseUrl === "string" ? model.baseUrl : void 0,
|
|
59
|
+
capability: "llm",
|
|
60
|
+
transport: "stream",
|
|
61
|
+
callerHeaders: options?.headers,
|
|
62
|
+
defaultHeaders: resolveKilocodeAppHeaders(),
|
|
63
|
+
precedence: "defaults-win"
|
|
64
|
+
});
|
|
65
|
+
return underlying(model, context, {
|
|
66
|
+
...options,
|
|
67
|
+
headers,
|
|
68
|
+
onPayload(payload, payloadModel) {
|
|
69
|
+
const payloadObj = asRecord(payload);
|
|
70
|
+
if (payloadObj) normalizeKilocodeReasoningPayload(payloadObj, thinkingLevel);
|
|
71
|
+
const result = originalOnPayload?.(payload, payloadModel);
|
|
72
|
+
if (result && typeof result.then === "function") return Promise.resolve(result).then((resolved) => normalizeKilocodeStopAfterCaller(resolved, payloadObj));
|
|
73
|
+
return normalizeKilocodeStopAfterCaller(result, payloadObj);
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
function wrapKilocodeProviderStream(ctx) {
|
|
79
|
+
if (normalizeOptionalLowercaseString(ctx.provider) !== "kilocode") return;
|
|
80
|
+
return createKilocodeStreamWrapper(ctx.streamFn, resolveKilocodeThinkingLevel(ctx));
|
|
81
|
+
}
|
|
82
|
+
//#endregion
|
|
83
|
+
export { createKilocodeStreamWrapper, wrapKilocodeProviderStream };
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "kilocode",
|
|
3
|
+
"activation": {
|
|
4
|
+
"onStartup": false
|
|
5
|
+
},
|
|
6
|
+
"enabledByDefault": true,
|
|
7
|
+
"providers": ["kilocode"],
|
|
8
|
+
"modelPricing": {
|
|
9
|
+
"providers": {
|
|
10
|
+
"kilocode": {
|
|
11
|
+
"openRouter": {
|
|
12
|
+
"passthroughProviderModel": true
|
|
13
|
+
},
|
|
14
|
+
"liteLLM": {
|
|
15
|
+
"passthroughProviderModel": true
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
"setup": {
|
|
21
|
+
"providers": [
|
|
22
|
+
{
|
|
23
|
+
"id": "kilocode",
|
|
24
|
+
"envVars": ["KILOCODE_API_KEY"]
|
|
25
|
+
}
|
|
26
|
+
]
|
|
27
|
+
},
|
|
28
|
+
"providerAuthChoices": [
|
|
29
|
+
{
|
|
30
|
+
"provider": "kilocode",
|
|
31
|
+
"method": "api-key",
|
|
32
|
+
"choiceId": "kilocode-api-key",
|
|
33
|
+
"choiceLabel": "Kilo Gateway API key",
|
|
34
|
+
"choiceHint": "API key (OpenRouter-compatible)",
|
|
35
|
+
"groupId": "kilocode",
|
|
36
|
+
"groupLabel": "Kilo Gateway",
|
|
37
|
+
"groupHint": "API key (OpenRouter-compatible)",
|
|
38
|
+
"optionKey": "kilocodeApiKey",
|
|
39
|
+
"cliFlag": "--kilocode-api-key",
|
|
40
|
+
"cliOption": "--kilocode-api-key <key>",
|
|
41
|
+
"cliDescription": "Kilo Gateway API key"
|
|
42
|
+
}
|
|
43
|
+
],
|
|
44
|
+
"configSchema": {
|
|
45
|
+
"type": "object",
|
|
46
|
+
"additionalProperties": false,
|
|
47
|
+
"properties": {}
|
|
48
|
+
},
|
|
49
|
+
"modelCatalog": {
|
|
50
|
+
"providers": {
|
|
51
|
+
"kilocode": {
|
|
52
|
+
"baseUrl": "https://api.kilo.ai/api/gateway/",
|
|
53
|
+
"api": "openai-completions",
|
|
54
|
+
"models": [
|
|
55
|
+
{
|
|
56
|
+
"id": "kilo/auto",
|
|
57
|
+
"name": "Kilo Auto",
|
|
58
|
+
"reasoning": true,
|
|
59
|
+
"input": ["text", "image"],
|
|
60
|
+
"cost": {
|
|
61
|
+
"input": 0,
|
|
62
|
+
"output": 0,
|
|
63
|
+
"cacheRead": 0,
|
|
64
|
+
"cacheWrite": 0
|
|
65
|
+
},
|
|
66
|
+
"contextWindow": 1000000,
|
|
67
|
+
"maxTokens": 128000
|
|
68
|
+
}
|
|
69
|
+
]
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
"discovery": {
|
|
73
|
+
"kilocode": "refreshable"
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
package/package.json
CHANGED
|
@@ -1,14 +1,50 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openclaw/kilocode-provider",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "
|
|
5
|
-
"license": "MIT",
|
|
3
|
+
"version": "2026.6.9-beta.1",
|
|
4
|
+
"description": "OpenClaw Kilo Gateway provider plugin.",
|
|
6
5
|
"repository": {
|
|
7
6
|
"type": "git",
|
|
8
|
-
"url": "
|
|
7
|
+
"url": "https://github.com/openclaw/openclaw"
|
|
9
8
|
},
|
|
10
|
-
"
|
|
11
|
-
|
|
12
|
-
"
|
|
13
|
-
|
|
9
|
+
"type": "module",
|
|
10
|
+
"openclaw": {
|
|
11
|
+
"extensions": [
|
|
12
|
+
"./index.ts"
|
|
13
|
+
],
|
|
14
|
+
"install": {
|
|
15
|
+
"clawhubSpec": "clawhub:@openclaw/kilocode-provider",
|
|
16
|
+
"npmSpec": "@openclaw/kilocode-provider",
|
|
17
|
+
"defaultChoice": "npm",
|
|
18
|
+
"minHostVersion": ">=2026.6.8"
|
|
19
|
+
},
|
|
20
|
+
"compat": {
|
|
21
|
+
"pluginApi": ">=2026.6.9-beta.1"
|
|
22
|
+
},
|
|
23
|
+
"build": {
|
|
24
|
+
"openclawVersion": "2026.6.9-beta.1",
|
|
25
|
+
"bundledDist": false
|
|
26
|
+
},
|
|
27
|
+
"release": {
|
|
28
|
+
"publishToClawHub": true,
|
|
29
|
+
"publishToNpm": true
|
|
30
|
+
},
|
|
31
|
+
"runtimeExtensions": [
|
|
32
|
+
"./dist/index.js"
|
|
33
|
+
]
|
|
34
|
+
},
|
|
35
|
+
"files": [
|
|
36
|
+
"dist/**",
|
|
37
|
+
"openclaw.plugin.json",
|
|
38
|
+
"npm-shrinkwrap.json",
|
|
39
|
+
"README.md"
|
|
40
|
+
],
|
|
41
|
+
"peerDependencies": {
|
|
42
|
+
"openclaw": ">=2026.6.9-beta.1"
|
|
43
|
+
},
|
|
44
|
+
"peerDependenciesMeta": {
|
|
45
|
+
"openclaw": {
|
|
46
|
+
"optional": true
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
"bundledDependencies": []
|
|
14
50
|
}
|