@bogyie/opencode-kiro-plugin 0.2.4 → 0.2.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/plugin.js +84 -45
  2. package/package.json +1 -1
package/dist/plugin.js CHANGED
@@ -9,12 +9,6 @@ import { ModelCache } from "./model-cache.js";
9
9
  import { refreshModelCacheFromCommand } from "./model-discovery.js";
10
10
  import { ModelResolver, normalizeModelName } from "./model-resolver.js";
11
11
  import { CodeWhispererKiroTransport } from "./kiro-transport.js";
12
- function mergeModels(extraModels, existing) {
13
- return {
14
- ...extraModels,
15
- ...(existing ?? {}),
16
- };
17
- }
18
12
  function discoveredProviderModels(cache) {
19
13
  return Object.fromEntries(cache.all().map((model) => [
20
14
  model.id,
@@ -31,6 +25,37 @@ function discoveredProviderModels(cache) {
31
25
  },
32
26
  ]));
33
27
  }
28
+ function modelRecord(value) {
29
+ if (!value || typeof value !== "object" || Array.isArray(value))
30
+ return {};
31
+ return Object.fromEntries(Object.entries(value).filter((entry) => Boolean(entry[0]) && Boolean(entry[1]) && typeof entry[1] === "object" && !Array.isArray(entry[1])));
32
+ }
33
+ function bearerToken(init) {
34
+ const header = new Headers(init?.headers).get("authorization");
35
+ const match = header?.match(/^Bearer\s+(.+)$/i);
36
+ return match?.[1] || undefined;
37
+ }
38
+ function localTransport(options, accessToken) {
39
+ if (options.backend === "acp")
40
+ return new KiroAcpTransport(acpTransportOptions(options));
41
+ if (options.backend === "cli-chat") {
42
+ return new KiroCliChatTransport({
43
+ trustAllTools: options.trustAllTools,
44
+ ...(options.requestTimeoutMs ? { requestTimeoutMs: options.requestTimeoutMs } : {}),
45
+ });
46
+ }
47
+ const apiKey = accessToken || process.env.KIRO_API_KEY;
48
+ if (apiKey && apiKey !== "kiro-plugin-local-transport") {
49
+ return new CodeWhispererKiroTransport(fetchTransportOptions(options, apiKey));
50
+ }
51
+ if (options.backend === "auto") {
52
+ return new KiroCliChatTransport({
53
+ trustAllTools: options.trustAllTools,
54
+ ...(options.requestTimeoutMs ? { requestTimeoutMs: options.requestTimeoutMs } : {}),
55
+ });
56
+ }
57
+ return undefined;
58
+ }
34
59
  export function acpTransportOptions(options) {
35
60
  return {
36
61
  trustAllTools: options.trustAllTools,
@@ -52,9 +77,10 @@ export function fetchTransportOptions(options, accessToken) {
52
77
  export function createKiroPlugin() {
53
78
  return async (_input, rawOptions) => {
54
79
  const options = loadOptions(rawOptions);
55
- const baseURL = options.endpoint ?? `https://q.${options.region}.amazonaws.com`;
56
80
  const modelCache = new ModelCache(options.modelCacheTtlSeconds);
57
81
  let localServer;
82
+ let configuredModels = { ...options.extraModels };
83
+ const disabledModels = new Set(options.disabledModels.map(normalizeModelName));
58
84
  if (Object.keys(options.extraModels).length > 0) {
59
85
  modelCache.update(Object.keys(options.extraModels).map((id) => ({ id: normalizeModelName(id) })));
60
86
  }
@@ -81,20 +107,39 @@ export function createKiroPlugin() {
81
107
  disabledModels: options.disabledModels,
82
108
  disablePassThrough: options.disableModelPassThrough,
83
109
  });
110
+ const ensureLocalServer = async () => {
111
+ if (localServer)
112
+ return localServer;
113
+ const localFetch = async (input, init) => {
114
+ const transport = localTransport(options, bearerToken(init));
115
+ return createKiroFetch({
116
+ resolver,
117
+ ...(transport ? { transport } : {}),
118
+ })(input, init);
119
+ };
120
+ localServer = await startLocalKiroServer(localFetch);
121
+ return localServer;
122
+ };
84
123
  return {
85
124
  dispose: async () => {
86
125
  await localServer?.close();
87
126
  localServer = undefined;
88
127
  },
89
128
  config: async (config) => {
129
+ await discoverIfStale();
90
130
  config.provider ??= {};
91
131
  config.provider[options.providerID] ??= {};
92
132
  const provider = config.provider[options.providerID];
133
+ const server = await ensureLocalServer();
134
+ configuredModels = {
135
+ ...options.extraModels,
136
+ ...modelRecord(provider.models),
137
+ };
93
138
  provider.name ??= "Kiro";
94
139
  provider.npm = "@ai-sdk/openai-compatible";
95
- provider.api ??= baseURL;
140
+ provider.api = server.baseURL;
96
141
  provider.options ??= {};
97
- provider.models = mergeModels(options.extraModels, provider.models);
142
+ provider.models = configuredModels;
98
143
  },
99
144
  auth: {
100
145
  provider: options.providerID,
@@ -121,29 +166,10 @@ export function createKiroPlugin() {
121
166
  loader: async (auth) => {
122
167
  await discoverIfStale();
123
168
  const apiKey = await resolveApiKey(auth);
124
- const transport = options.backend === "acp"
125
- ? new KiroAcpTransport(acpTransportOptions(options))
126
- : options.backend === "cli-chat"
127
- ? new KiroCliChatTransport({
128
- trustAllTools: options.trustAllTools,
129
- ...(options.requestTimeoutMs ? { requestTimeoutMs: options.requestTimeoutMs } : {}),
130
- })
131
- : apiKey
132
- ? new CodeWhispererKiroTransport(fetchTransportOptions(options, apiKey))
133
- : options.backend === "auto"
134
- ? new KiroCliChatTransport({
135
- trustAllTools: options.trustAllTools,
136
- ...(options.requestTimeoutMs ? { requestTimeoutMs: options.requestTimeoutMs } : {}),
137
- })
138
- : undefined;
139
- const localFetch = createKiroFetch({
140
- resolver,
141
- ...(transport ? { transport } : {}),
142
- });
143
- localServer ??= await startLocalKiroServer(localFetch);
169
+ const server = await ensureLocalServer();
144
170
  return {
145
171
  apiKey: apiKey || "kiro-plugin-local-transport",
146
- baseURL: localServer.baseURL,
172
+ baseURL: server.baseURL,
147
173
  };
148
174
  },
149
175
  },
@@ -180,22 +206,35 @@ export function createKiroPlugin() {
180
206
  id: options.providerID,
181
207
  models: async (provider) => {
182
208
  await discoverIfStale();
183
- const models = {
184
- ...discoveredProviderModels(modelCache),
185
- ...(provider.models ?? {}),
186
- };
187
- return Object.fromEntries(Object.entries(models).map(([id, model]) => [
188
- id,
189
- {
190
- ...model,
191
- api: {
192
- ...(model.api ?? {}),
193
- id,
194
- npm: "@ai-sdk/openai-compatible",
195
- url: baseURL,
209
+ const discovered = discoveredProviderModels(modelCache);
210
+ const existing = modelRecord(provider.models);
211
+ const allowedModelIDs = new Set([
212
+ ...Object.keys(discovered),
213
+ ...Object.keys(configuredModels),
214
+ ...Object.keys(options.hiddenModels),
215
+ ]);
216
+ const server = await ensureLocalServer();
217
+ return Object.fromEntries([...allowedModelIDs]
218
+ .filter((id) => !disabledModels.has(normalizeModelName(id)))
219
+ .map((id) => {
220
+ const model = {
221
+ ...(discovered[id] ?? {}),
222
+ ...(configuredModels[id] ?? {}),
223
+ ...(existing[id] ?? {}),
224
+ };
225
+ return [
226
+ id,
227
+ {
228
+ ...model,
229
+ api: {
230
+ ...(model.api ?? {}),
231
+ id,
232
+ npm: "@ai-sdk/openai-compatible",
233
+ url: server.baseURL,
234
+ },
196
235
  },
197
- },
198
- ]));
236
+ ];
237
+ }));
199
238
  },
200
239
  },
201
240
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bogyie/opencode-kiro-plugin",
3
- "version": "0.2.4",
3
+ "version": "0.2.5",
4
4
  "description": "OpenCode plugin for using Kiro as a provider adapter",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",