@bogyie/opencode-kiro-plugin 0.2.1 → 0.2.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 +11 -27
- package/dist/config.d.ts +1 -0
- package/dist/config.js +3 -1
- package/dist/model-discovery.js +20 -3
- package/dist/models.js +35 -5
- package/dist/plugin.js +8 -0
- package/docs/e2e-validation.md +2 -2
- package/examples/opencode.jsonc +5 -14
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -10,16 +10,7 @@ After the package is published to npm, add it directly to your OpenCode config:
|
|
|
10
10
|
|
|
11
11
|
```jsonc
|
|
12
12
|
{
|
|
13
|
-
"plugin": ["@bogyie/opencode-kiro-plugin"]
|
|
14
|
-
"provider": {
|
|
15
|
-
"kiro": {
|
|
16
|
-
"models": {
|
|
17
|
-
"sonnet": {
|
|
18
|
-
"name": "Sonnet alias"
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
}
|
|
13
|
+
"plugin": ["@bogyie/opencode-kiro-plugin"]
|
|
23
14
|
}
|
|
24
15
|
```
|
|
25
16
|
|
|
@@ -34,16 +25,7 @@ Then add the plugin to your OpenCode config. See [examples/opencode.jsonc](examp
|
|
|
34
25
|
|
|
35
26
|
```jsonc
|
|
36
27
|
{
|
|
37
|
-
"plugin": ["file:/absolute/path/to/opencode-kiro-plugin"]
|
|
38
|
-
"provider": {
|
|
39
|
-
"kiro": {
|
|
40
|
-
"models": {
|
|
41
|
-
"sonnet": {
|
|
42
|
-
"name": "Sonnet alias"
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
}
|
|
28
|
+
"plugin": ["file:/absolute/path/to/opencode-kiro-plugin"]
|
|
47
29
|
}
|
|
48
30
|
```
|
|
49
31
|
|
|
@@ -92,7 +74,7 @@ Supported values:
|
|
|
92
74
|
|
|
93
75
|
## Model Churn Handling
|
|
94
76
|
|
|
95
|
-
The resolver intentionally avoids a hard whitelist.
|
|
77
|
+
The resolver intentionally avoids a hard whitelist. By default, the plugin reads the current Kiro CLI model list with `kiro-cli chat --list-models --format json`. Bundled presets are only used as UI metadata and as a fallback when discovery is unavailable.
|
|
96
78
|
|
|
97
79
|
Useful options:
|
|
98
80
|
|
|
@@ -104,13 +86,13 @@ Useful options:
|
|
|
104
86
|
{
|
|
105
87
|
"modelCacheTtlSeconds": 21600,
|
|
106
88
|
"modelDiscovery": "auto",
|
|
107
|
-
"modelDiscoveryCommand": ["kiro-cli", "models", "--json"],
|
|
89
|
+
"modelDiscoveryCommand": ["kiro-cli", "chat", "--list-models", "--format", "json"],
|
|
108
90
|
"modelAliases": {
|
|
109
|
-
"sonnet": "claude-sonnet-
|
|
110
|
-
"opus": "claude-opus-4.
|
|
91
|
+
"sonnet": "claude-sonnet-5",
|
|
92
|
+
"opus": "claude-opus-4.8"
|
|
111
93
|
},
|
|
112
94
|
"extraModels": {
|
|
113
|
-
"claude-opus-4
|
|
95
|
+
"claude-opus-4.9": {
|
|
114
96
|
"name": "Claude Opus 4.9",
|
|
115
97
|
"limit": { "context": 1000000, "output": 64000 },
|
|
116
98
|
"modalities": { "input": ["text", "image", "pdf"], "output": ["text"] },
|
|
@@ -138,9 +120,11 @@ Resolution order:
|
|
|
138
120
|
6. Hidden/manual model mapping
|
|
139
121
|
7. Optimistic pass-through unless disabled
|
|
140
122
|
|
|
141
|
-
This keeps new Kiro model ids
|
|
123
|
+
This keeps new Kiro model ids visible before the package is updated. Use `extraModels` only when a new model should appear in OpenCode's model picker but is not yet listed by your installed Kiro CLI. Set `disableModelPassThrough: true` only when you need strict model governance.
|
|
124
|
+
|
|
125
|
+
The plugin injects `provider.kiro` automatically. You only need to add `provider.kiro.models` yourself when overriding OpenCode model-picker metadata, such as a display name or context limit. Use plugin `modelAliases` for aliases that should resolve one requested model id to another.
|
|
142
126
|
|
|
143
|
-
`modelDiscoveryCommand`
|
|
127
|
+
`modelDiscoveryCommand` defaults to `["kiro-cli", "chat", "--list-models", "--format", "json"]`. Set `modelDiscovery` to `"off"` to skip runtime discovery. Discovery stdout can be a JSON array, `{ "models": [...] }`, `{ "data": [...] }`, Kiro CLI list-models JSON, Kiro CLI plain list output, or one model id per line.
|
|
144
128
|
|
|
145
129
|
## Troubleshooting
|
|
146
130
|
|
package/dist/config.d.ts
CHANGED
|
@@ -22,6 +22,7 @@ export interface KiroPluginOptions {
|
|
|
22
22
|
}
|
|
23
23
|
export declare const DEFAULT_PROVIDER_ID = "kiro";
|
|
24
24
|
export declare const DEFAULT_REGION = "us-east-1";
|
|
25
|
+
export declare const DEFAULT_MODEL_DISCOVERY_COMMAND: readonly ["kiro-cli", "chat", "--list-models", "--format", "json"];
|
|
25
26
|
export declare const DEFAULT_MODEL_CACHE_TTL_SECONDS: number;
|
|
26
27
|
export declare const DEFAULT_MAX_ATTEMPTS = 3;
|
|
27
28
|
export declare function loadOptions(raw?: unknown): KiroPluginOptions;
|
package/dist/config.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export const DEFAULT_PROVIDER_ID = "kiro";
|
|
2
2
|
export const DEFAULT_REGION = "us-east-1";
|
|
3
|
+
export const DEFAULT_MODEL_DISCOVERY_COMMAND = ["kiro-cli", "chat", "--list-models", "--format", "json"];
|
|
3
4
|
export const DEFAULT_MODEL_CACHE_TTL_SECONDS = 6 * 60 * 60;
|
|
4
5
|
export const DEFAULT_MAX_ATTEMPTS = 3;
|
|
5
6
|
const BACKENDS = new Set(["auto", "fetch", "cli-chat", "acp"]);
|
|
@@ -53,13 +54,14 @@ export function loadOptions(raw = {}) {
|
|
|
53
54
|
const profileArn = optionalString(input.profileArn);
|
|
54
55
|
const userAgent = optionalString(input.userAgent);
|
|
55
56
|
const agentMode = optionalString(input.agentMode);
|
|
57
|
+
const modelDiscoveryCommand = "modelDiscoveryCommand" in input ? stringArray(input.modelDiscoveryCommand) : [...DEFAULT_MODEL_DISCOVERY_COMMAND];
|
|
56
58
|
return {
|
|
57
59
|
providerID: typeof input.providerID === "string" && input.providerID ? input.providerID : DEFAULT_PROVIDER_ID,
|
|
58
60
|
region: typeof input.region === "string" && input.region ? input.region : DEFAULT_REGION,
|
|
59
61
|
...(endpoint ? { endpoint } : {}),
|
|
60
62
|
backend,
|
|
61
63
|
modelDiscovery,
|
|
62
|
-
modelDiscoveryCommand
|
|
64
|
+
modelDiscoveryCommand,
|
|
63
65
|
modelCacheTtlSeconds: positiveNumber(input.modelCacheTtlSeconds, DEFAULT_MODEL_CACHE_TTL_SECONDS),
|
|
64
66
|
...(requestTimeoutMs ? { requestTimeoutMs } : {}),
|
|
65
67
|
maxAttempts: positiveInteger(input.maxAttempts, DEFAULT_MAX_ATTEMPTS),
|
package/dist/model-discovery.js
CHANGED
|
@@ -6,6 +6,9 @@ function record(value) {
|
|
|
6
6
|
function stringValue(value) {
|
|
7
7
|
return typeof value === "string" && value.trim() ? value.trim() : undefined;
|
|
8
8
|
}
|
|
9
|
+
function positiveNumberValue(value) {
|
|
10
|
+
return typeof value === "number" && Number.isFinite(value) && value > 0 ? value : undefined;
|
|
11
|
+
}
|
|
9
12
|
function fromItem(item) {
|
|
10
13
|
if (typeof item === "string") {
|
|
11
14
|
const id = normalizeModelName(item);
|
|
@@ -14,16 +17,25 @@ function fromItem(item) {
|
|
|
14
17
|
const object = record(item);
|
|
15
18
|
if (!object)
|
|
16
19
|
return undefined;
|
|
17
|
-
const id = stringValue(object.id) ??
|
|
20
|
+
const id = stringValue(object.id) ??
|
|
21
|
+
stringValue(object.modelId) ??
|
|
22
|
+
stringValue(object.model_id) ??
|
|
23
|
+
stringValue(object.model) ??
|
|
24
|
+
stringValue(object.model_name) ??
|
|
25
|
+
stringValue(object.name);
|
|
18
26
|
if (!id)
|
|
19
27
|
return undefined;
|
|
20
28
|
const normalized = normalizeModelName(id);
|
|
21
29
|
if (!normalized)
|
|
22
30
|
return undefined;
|
|
23
31
|
const name = stringValue(object.name) ?? stringValue(object.displayName) ?? stringValue(object.label);
|
|
32
|
+
const contextLimit = positiveNumberValue(object.contextLimit) ?? positiveNumberValue(object.context_window_tokens);
|
|
33
|
+
const outputLimit = positiveNumberValue(object.outputLimit) ?? positiveNumberValue(object.output_limit_tokens);
|
|
24
34
|
return {
|
|
25
35
|
id: normalized,
|
|
26
36
|
...(name ? { name } : {}),
|
|
37
|
+
...(contextLimit ? { contextLimit } : {}),
|
|
38
|
+
...(outputLimit ? { outputLimit } : {}),
|
|
27
39
|
raw: item,
|
|
28
40
|
};
|
|
29
41
|
}
|
|
@@ -34,13 +46,18 @@ function fromJson(value) {
|
|
|
34
46
|
if (!object)
|
|
35
47
|
return [];
|
|
36
48
|
const items = object.models ?? object.data ?? object.items;
|
|
37
|
-
|
|
49
|
+
if (Array.isArray(items))
|
|
50
|
+
return fromJson(items);
|
|
51
|
+
const configuredModel = object["chat.defaultModel"] ?? object.defaultModel ?? object.model;
|
|
52
|
+
return configuredModel ? fromJson([configuredModel]) : [];
|
|
38
53
|
}
|
|
39
54
|
function fromLines(raw) {
|
|
40
55
|
return raw
|
|
41
56
|
.split(/\r?\n/)
|
|
42
57
|
.map((line) => line.trim())
|
|
43
|
-
.
|
|
58
|
+
.map((line) => line.replace(/^\*\s*/, ""))
|
|
59
|
+
.map((line) => /^\S+/.exec(line)?.[0] ?? "")
|
|
60
|
+
.filter((line) => line === "auto" || /[.-]/.test(line))
|
|
44
61
|
.map(fromItem)
|
|
45
62
|
.filter((item) => item !== undefined);
|
|
46
63
|
}
|
package/dist/models.js
CHANGED
|
@@ -7,31 +7,61 @@ export const FALLBACK_MODELS = {
|
|
|
7
7
|
modalities: TEXT_IMAGE_PDF,
|
|
8
8
|
tool_call: true,
|
|
9
9
|
},
|
|
10
|
+
"claude-fable-5": {
|
|
11
|
+
name: "Claude Fable 5",
|
|
12
|
+
limit: { context: 1_000_000, output: 64_000 },
|
|
13
|
+
modalities: TEXT_IMAGE_PDF,
|
|
14
|
+
tool_call: true,
|
|
15
|
+
},
|
|
16
|
+
"claude-sonnet-5": {
|
|
17
|
+
name: "Claude Sonnet 5",
|
|
18
|
+
limit: { context: 1_000_000, output: 64_000 },
|
|
19
|
+
modalities: TEXT_IMAGE_PDF,
|
|
20
|
+
tool_call: true,
|
|
21
|
+
},
|
|
10
22
|
"claude-sonnet-4": {
|
|
11
|
-
name: "Claude Sonnet 4",
|
|
23
|
+
name: "Claude Sonnet 4.0",
|
|
12
24
|
limit: { context: 200_000, output: 64_000 },
|
|
13
25
|
modalities: TEXT_IMAGE_PDF,
|
|
14
26
|
tool_call: true,
|
|
15
27
|
},
|
|
16
|
-
"claude-sonnet-4
|
|
28
|
+
"claude-sonnet-4.5": {
|
|
17
29
|
name: "Claude Sonnet 4.5",
|
|
18
30
|
limit: { context: 200_000, output: 64_000 },
|
|
19
31
|
modalities: TEXT_IMAGE_PDF,
|
|
20
32
|
tool_call: true,
|
|
21
33
|
},
|
|
22
|
-
"claude-sonnet-4
|
|
34
|
+
"claude-sonnet-4.6": {
|
|
23
35
|
name: "Claude Sonnet 4.6",
|
|
24
36
|
limit: { context: 1_000_000, output: 64_000 },
|
|
25
37
|
modalities: TEXT_IMAGE_PDF,
|
|
26
38
|
tool_call: true,
|
|
27
39
|
},
|
|
28
|
-
"claude-opus-4
|
|
40
|
+
"claude-opus-4.8": {
|
|
29
41
|
name: "Claude Opus 4.8",
|
|
42
|
+
limit: { context: 1_000_000, output: 128_000 },
|
|
43
|
+
modalities: TEXT_IMAGE_PDF,
|
|
44
|
+
tool_call: true,
|
|
45
|
+
},
|
|
46
|
+
"claude-opus-4.7": {
|
|
47
|
+
name: "Claude Opus 4.7",
|
|
48
|
+
limit: { context: 1_000_000, output: 64_000 },
|
|
49
|
+
modalities: TEXT_IMAGE_PDF,
|
|
50
|
+
tool_call: true,
|
|
51
|
+
},
|
|
52
|
+
"claude-opus-4.6": {
|
|
53
|
+
name: "Claude Opus 4.6",
|
|
30
54
|
limit: { context: 1_000_000, output: 64_000 },
|
|
31
55
|
modalities: TEXT_IMAGE_PDF,
|
|
32
56
|
tool_call: true,
|
|
33
57
|
},
|
|
34
|
-
"claude-
|
|
58
|
+
"claude-opus-4.5": {
|
|
59
|
+
name: "Claude Opus 4.5",
|
|
60
|
+
limit: { context: 200_000, output: 64_000 },
|
|
61
|
+
modalities: TEXT_IMAGE_PDF,
|
|
62
|
+
tool_call: true,
|
|
63
|
+
},
|
|
64
|
+
"claude-haiku-4.5": {
|
|
35
65
|
name: "Claude Haiku 4.5",
|
|
36
66
|
limit: { context: 200_000, output: 64_000 },
|
|
37
67
|
modalities: { input: ["text", "image"], output: ["text"] },
|
package/dist/plugin.js
CHANGED
|
@@ -21,6 +21,14 @@ function discoveredProviderModels(cache) {
|
|
|
21
21
|
model.id,
|
|
22
22
|
{
|
|
23
23
|
name: model.name ?? model.id,
|
|
24
|
+
...(model.contextLimit || model.outputLimit
|
|
25
|
+
? {
|
|
26
|
+
limit: {
|
|
27
|
+
context: model.contextLimit ?? 200_000,
|
|
28
|
+
output: model.outputLimit ?? 64_000,
|
|
29
|
+
},
|
|
30
|
+
}
|
|
31
|
+
: {}),
|
|
24
32
|
},
|
|
25
33
|
]));
|
|
26
34
|
}
|
package/docs/e2e-validation.md
CHANGED
|
@@ -152,7 +152,7 @@ Before publishing, verify that new model ids can be used without a code release:
|
|
|
152
152
|
"modelAliases": {
|
|
153
153
|
"new-model": "new-model-id"
|
|
154
154
|
},
|
|
155
|
-
"modelDiscoveryCommand": ["kiro-cli", "models", "--json"]
|
|
155
|
+
"modelDiscoveryCommand": ["kiro-cli", "chat", "--list-models", "--format", "json"]
|
|
156
156
|
}
|
|
157
157
|
]
|
|
158
158
|
]
|
|
@@ -161,7 +161,7 @@ Before publishing, verify that new model ids can be used without a code release:
|
|
|
161
161
|
|
|
162
162
|
Checks:
|
|
163
163
|
|
|
164
|
-
-
|
|
164
|
+
- Confirm `kiro-cli chat --list-models --format json` succeeds and discovered models appear in provider metadata.
|
|
165
165
|
- The model appears in OpenCode provider metadata.
|
|
166
166
|
- The alias resolves to the configured id.
|
|
167
167
|
- Unknown models still pass through when `disableModelPassThrough` is false.
|
package/examples/opencode.jsonc
CHANGED
|
@@ -13,15 +13,15 @@
|
|
|
13
13
|
// "agentMode": "vibe",
|
|
14
14
|
"modelCacheTtlSeconds": 21600,
|
|
15
15
|
"modelDiscovery": "auto",
|
|
16
|
-
"modelDiscoveryCommand": [],
|
|
16
|
+
"modelDiscoveryCommand": ["kiro-cli", "chat", "--list-models", "--format", "json"],
|
|
17
17
|
"maxAttempts": 3,
|
|
18
18
|
"requestTimeoutMs": 120000,
|
|
19
19
|
"modelAliases": {
|
|
20
|
-
"sonnet": "claude-sonnet-
|
|
21
|
-
"opus": "claude-opus-4.
|
|
20
|
+
"sonnet": "claude-sonnet-5",
|
|
21
|
+
"opus": "claude-opus-4.8"
|
|
22
22
|
},
|
|
23
23
|
"extraModels": {
|
|
24
|
-
"claude-opus-4
|
|
24
|
+
"claude-opus-4.9": {
|
|
25
25
|
"name": "Claude Opus 4.9",
|
|
26
26
|
"limit": { "context": 1000000, "output": 64000 },
|
|
27
27
|
"modalities": { "input": ["text", "image", "pdf"], "output": ["text"] },
|
|
@@ -34,14 +34,5 @@
|
|
|
34
34
|
"trustAllTools": false
|
|
35
35
|
}
|
|
36
36
|
]
|
|
37
|
-
]
|
|
38
|
-
"provider": {
|
|
39
|
-
"kiro": {
|
|
40
|
-
"models": {
|
|
41
|
-
"sonnet": {
|
|
42
|
-
"name": "Claude Sonnet via Kiro"
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
}
|
|
37
|
+
]
|
|
47
38
|
}
|