@bogyie/opencode-kiro-plugin 0.2.4 → 0.2.6

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 +92 -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,50 @@ 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 visibleProviderModels(cache, configuredModels, hiddenModels, disabledModels) {
34
+ const discovered = discoveredProviderModels(cache);
35
+ const modelIDs = new Set([...Object.keys(discovered), ...Object.keys(configuredModels), ...Object.keys(hiddenModels)]);
36
+ return Object.fromEntries([...modelIDs]
37
+ .filter((id) => !disabledModels.has(normalizeModelName(id)))
38
+ .map((id) => [
39
+ id,
40
+ {
41
+ ...(discovered[id] ?? {}),
42
+ ...(configuredModels[id] ?? {}),
43
+ },
44
+ ]));
45
+ }
46
+ function bearerToken(init) {
47
+ const header = new Headers(init?.headers).get("authorization");
48
+ const match = header?.match(/^Bearer\s+(.+)$/i);
49
+ return match?.[1] || undefined;
50
+ }
51
+ function localTransport(options, accessToken) {
52
+ if (options.backend === "acp")
53
+ return new KiroAcpTransport(acpTransportOptions(options));
54
+ if (options.backend === "cli-chat") {
55
+ return new KiroCliChatTransport({
56
+ trustAllTools: options.trustAllTools,
57
+ ...(options.requestTimeoutMs ? { requestTimeoutMs: options.requestTimeoutMs } : {}),
58
+ });
59
+ }
60
+ const apiKey = accessToken || process.env.KIRO_API_KEY;
61
+ if (apiKey && apiKey !== "kiro-plugin-local-transport") {
62
+ return new CodeWhispererKiroTransport(fetchTransportOptions(options, apiKey));
63
+ }
64
+ if (options.backend === "auto") {
65
+ return new KiroCliChatTransport({
66
+ trustAllTools: options.trustAllTools,
67
+ ...(options.requestTimeoutMs ? { requestTimeoutMs: options.requestTimeoutMs } : {}),
68
+ });
69
+ }
70
+ return undefined;
71
+ }
34
72
  export function acpTransportOptions(options) {
35
73
  return {
36
74
  trustAllTools: options.trustAllTools,
@@ -52,9 +90,11 @@ export function fetchTransportOptions(options, accessToken) {
52
90
  export function createKiroPlugin() {
53
91
  return async (_input, rawOptions) => {
54
92
  const options = loadOptions(rawOptions);
55
- const baseURL = options.endpoint ?? `https://q.${options.region}.amazonaws.com`;
56
93
  const modelCache = new ModelCache(options.modelCacheTtlSeconds);
57
94
  let localServer;
95
+ let configuredModels = { ...options.extraModels };
96
+ let userModelOverrides;
97
+ const disabledModels = new Set(options.disabledModels.map(normalizeModelName));
58
98
  if (Object.keys(options.extraModels).length > 0) {
59
99
  modelCache.update(Object.keys(options.extraModels).map((id) => ({ id: normalizeModelName(id) })));
60
100
  }
@@ -81,20 +121,40 @@ export function createKiroPlugin() {
81
121
  disabledModels: options.disabledModels,
82
122
  disablePassThrough: options.disableModelPassThrough,
83
123
  });
124
+ const ensureLocalServer = async () => {
125
+ if (localServer)
126
+ return localServer;
127
+ const localFetch = async (input, init) => {
128
+ const transport = localTransport(options, bearerToken(init));
129
+ return createKiroFetch({
130
+ resolver,
131
+ ...(transport ? { transport } : {}),
132
+ })(input, init);
133
+ };
134
+ localServer = await startLocalKiroServer(localFetch);
135
+ return localServer;
136
+ };
84
137
  return {
85
138
  dispose: async () => {
86
139
  await localServer?.close();
87
140
  localServer = undefined;
88
141
  },
89
142
  config: async (config) => {
143
+ await discoverIfStale();
90
144
  config.provider ??= {};
91
145
  config.provider[options.providerID] ??= {};
92
146
  const provider = config.provider[options.providerID];
147
+ const server = await ensureLocalServer();
148
+ userModelOverrides ??= modelRecord(provider.models);
149
+ configuredModels = {
150
+ ...options.extraModels,
151
+ ...userModelOverrides,
152
+ };
93
153
  provider.name ??= "Kiro";
94
154
  provider.npm = "@ai-sdk/openai-compatible";
95
- provider.api ??= baseURL;
155
+ provider.api = server.baseURL;
96
156
  provider.options ??= {};
97
- provider.models = mergeModels(options.extraModels, provider.models);
157
+ provider.models = visibleProviderModels(modelCache, configuredModels, options.hiddenModels, disabledModels);
98
158
  },
99
159
  auth: {
100
160
  provider: options.providerID,
@@ -121,29 +181,10 @@ export function createKiroPlugin() {
121
181
  loader: async (auth) => {
122
182
  await discoverIfStale();
123
183
  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);
184
+ const server = await ensureLocalServer();
144
185
  return {
145
186
  apiKey: apiKey || "kiro-plugin-local-transport",
146
- baseURL: localServer.baseURL,
187
+ baseURL: server.baseURL,
147
188
  };
148
189
  },
149
190
  },
@@ -180,22 +221,28 @@ export function createKiroPlugin() {
180
221
  id: options.providerID,
181
222
  models: async (provider) => {
182
223
  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,
224
+ const existing = modelRecord(provider.models);
225
+ const visibleModels = visibleProviderModels(modelCache, configuredModels, options.hiddenModels, disabledModels);
226
+ const server = await ensureLocalServer();
227
+ return Object.fromEntries(Object.keys(visibleModels)
228
+ .map((id) => {
229
+ const model = {
230
+ ...(visibleModels[id] ?? {}),
231
+ ...(existing[id] ?? {}),
232
+ };
233
+ return [
234
+ id,
235
+ {
236
+ ...model,
237
+ api: {
238
+ ...(model.api ?? {}),
239
+ id,
240
+ npm: "@ai-sdk/openai-compatible",
241
+ url: server.baseURL,
242
+ },
196
243
  },
197
- },
198
- ]));
244
+ ];
245
+ }));
199
246
  },
200
247
  },
201
248
  };
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.6",
4
4
  "description": "OpenCode plugin for using Kiro as a provider adapter",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",