@zhafron/opencode-kiro-auth 1.2.6 → 1.2.8
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/dist/plugin/request.js +118 -29
- package/dist/plugin/response.js +1 -1
- package/dist/plugin/streaming.js +1 -1
- package/package.json +1 -1
package/dist/plugin/request.js
CHANGED
|
@@ -2,10 +2,53 @@ import * as crypto from 'crypto';
|
|
|
2
2
|
import * as os from 'os';
|
|
3
3
|
import { KIRO_CONSTANTS } from '../constants.js';
|
|
4
4
|
import { resolveKiroModel } from './models.js';
|
|
5
|
-
|
|
5
|
+
function truncate(s, max) {
|
|
6
|
+
if (s.length <= max)
|
|
7
|
+
return s;
|
|
8
|
+
const half = Math.floor(max / 2);
|
|
9
|
+
return s.substring(0, half) + '\n... [TRUNCATED] ...\n' + s.substring(s.length - half);
|
|
10
|
+
}
|
|
11
|
+
function sanitizeHistory(history) {
|
|
12
|
+
const result = [];
|
|
13
|
+
for (let i = 0; i < history.length; i++) {
|
|
14
|
+
const m = history[i];
|
|
15
|
+
if (!m)
|
|
16
|
+
continue;
|
|
17
|
+
if (m.assistantResponseMessage?.toolUses) {
|
|
18
|
+
const next = history[i + 1];
|
|
19
|
+
if (next?.userInputMessage?.userInputMessageContext?.toolResults)
|
|
20
|
+
result.push(m);
|
|
21
|
+
}
|
|
22
|
+
else if (m.userInputMessage?.userInputMessageContext?.toolResults) {
|
|
23
|
+
const prev = result[result.length - 1];
|
|
24
|
+
if (prev?.assistantResponseMessage?.toolUses)
|
|
25
|
+
result.push(m);
|
|
26
|
+
}
|
|
27
|
+
else
|
|
28
|
+
result.push(m);
|
|
29
|
+
}
|
|
30
|
+
return result;
|
|
31
|
+
}
|
|
32
|
+
function findOriginalToolCall(msgs, toolUseId) {
|
|
33
|
+
for (const m of msgs) {
|
|
34
|
+
if (m.role === 'assistant') {
|
|
35
|
+
if (m.tool_calls) {
|
|
36
|
+
for (const tc of m.tool_calls)
|
|
37
|
+
if (tc.id === toolUseId)
|
|
38
|
+
return tc;
|
|
39
|
+
}
|
|
40
|
+
if (Array.isArray(m.content)) {
|
|
41
|
+
for (const p of m.content)
|
|
42
|
+
if (p.type === 'tool_use' && p.id === toolUseId)
|
|
43
|
+
return p;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
6
49
|
export function transformToCodeWhisperer(url, body, model, auth, think = false, budget = 20000) {
|
|
7
50
|
const req = typeof body === 'string' ? JSON.parse(body) : body;
|
|
8
|
-
const { messages, tools, system
|
|
51
|
+
const { messages, tools, system } = req;
|
|
9
52
|
const convId = crypto.randomUUID();
|
|
10
53
|
if (!messages || messages.length === 0)
|
|
11
54
|
throw new Error('No messages');
|
|
@@ -20,7 +63,7 @@ export function transformToCodeWhisperer(url, body, model, auth, think = false,
|
|
|
20
63
|
if (lastMsg && lastMsg.role === 'assistant' && getContentText(lastMsg) === '{')
|
|
21
64
|
msgs.pop();
|
|
22
65
|
const cwTools = tools ? convertToolsToCodeWhisperer(tools) : [];
|
|
23
|
-
|
|
66
|
+
let history = [];
|
|
24
67
|
let firstUserIndex = -1;
|
|
25
68
|
for (let i = 0; i < msgs.length; i++) {
|
|
26
69
|
if (msgs[i].role === 'user') {
|
|
@@ -38,9 +81,8 @@ export function transformToCodeWhisperer(url, body, model, auth, think = false,
|
|
|
38
81
|
...m.content.filter((p) => p.type !== 'text')
|
|
39
82
|
];
|
|
40
83
|
}
|
|
41
|
-
else
|
|
84
|
+
else
|
|
42
85
|
m.content = `${sys}\n\n${oldContent}`;
|
|
43
|
-
}
|
|
44
86
|
}
|
|
45
87
|
else {
|
|
46
88
|
history.push({
|
|
@@ -65,7 +107,7 @@ export function transformToCodeWhisperer(url, body, model, auth, think = false,
|
|
|
65
107
|
uim.content += p.text || '';
|
|
66
108
|
else if (p.type === 'tool_result')
|
|
67
109
|
trs.push({
|
|
68
|
-
content: [{ text: getContentText(p.content || p) }],
|
|
110
|
+
content: [{ text: truncate(getContentText(p.content || p), 250000) }],
|
|
69
111
|
status: 'success',
|
|
70
112
|
toolUseId: p.tool_use_id
|
|
71
113
|
});
|
|
@@ -83,9 +125,8 @@ export function transformToCodeWhisperer(url, body, model, auth, think = false,
|
|
|
83
125
|
if (trs.length)
|
|
84
126
|
uim.userInputMessageContext = { toolResults: deduplicateToolResults(trs) };
|
|
85
127
|
const prev = history[history.length - 1];
|
|
86
|
-
if (prev && prev.userInputMessage)
|
|
128
|
+
if (prev && prev.userInputMessage)
|
|
87
129
|
history.push({ assistantResponseMessage: { content: 'Continue' } });
|
|
88
|
-
}
|
|
89
130
|
history.push({ userInputMessage: uim });
|
|
90
131
|
}
|
|
91
132
|
else if (m.role === 'tool') {
|
|
@@ -93,22 +134,21 @@ export function transformToCodeWhisperer(url, body, model, auth, think = false,
|
|
|
93
134
|
if (m.tool_results) {
|
|
94
135
|
for (const tr of m.tool_results)
|
|
95
136
|
trs.push({
|
|
96
|
-
content: [{ text: getContentText(tr) }],
|
|
137
|
+
content: [{ text: truncate(getContentText(tr), 250000) }],
|
|
97
138
|
status: 'success',
|
|
98
139
|
toolUseId: tr.tool_call_id
|
|
99
140
|
});
|
|
100
141
|
}
|
|
101
142
|
else {
|
|
102
143
|
trs.push({
|
|
103
|
-
content: [{ text: getContentText(m) }],
|
|
144
|
+
content: [{ text: truncate(getContentText(m), 250000) }],
|
|
104
145
|
status: 'success',
|
|
105
146
|
toolUseId: m.tool_call_id
|
|
106
147
|
});
|
|
107
148
|
}
|
|
108
149
|
const prev = history[history.length - 1];
|
|
109
|
-
if (prev && prev.userInputMessage)
|
|
150
|
+
if (prev && prev.userInputMessage)
|
|
110
151
|
history.push({ assistantResponseMessage: { content: 'Continue' } });
|
|
111
|
-
}
|
|
112
152
|
history.push({
|
|
113
153
|
userInputMessage: {
|
|
114
154
|
content: 'Tool results provided.',
|
|
@@ -132,9 +172,8 @@ export function transformToCodeWhisperer(url, body, model, auth, think = false,
|
|
|
132
172
|
tus.push({ input: p.input, name: p.name, toolUseId: p.id });
|
|
133
173
|
}
|
|
134
174
|
}
|
|
135
|
-
else
|
|
175
|
+
else
|
|
136
176
|
arm.content = getContentText(m);
|
|
137
|
-
}
|
|
138
177
|
if (m.tool_calls && Array.isArray(m.tool_calls)) {
|
|
139
178
|
for (const tc of m.tool_calls) {
|
|
140
179
|
tus.push({
|
|
@@ -155,6 +194,19 @@ export function transformToCodeWhisperer(url, body, model, auth, think = false,
|
|
|
155
194
|
history.push({ assistantResponseMessage: arm });
|
|
156
195
|
}
|
|
157
196
|
}
|
|
197
|
+
history = sanitizeHistory(history);
|
|
198
|
+
let historySize = JSON.stringify(history).length;
|
|
199
|
+
while (historySize > 850000 && history.length > 2) {
|
|
200
|
+
history.shift();
|
|
201
|
+
while (history.length > 0) {
|
|
202
|
+
const first = history[0];
|
|
203
|
+
if (first && first.userInputMessage)
|
|
204
|
+
break;
|
|
205
|
+
history.shift();
|
|
206
|
+
}
|
|
207
|
+
history = sanitizeHistory(history);
|
|
208
|
+
historySize = JSON.stringify(history).length;
|
|
209
|
+
}
|
|
158
210
|
const curMsg = msgs[msgs.length - 1];
|
|
159
211
|
if (!curMsg)
|
|
160
212
|
throw new Error('Empty');
|
|
@@ -206,14 +258,14 @@ export function transformToCodeWhisperer(url, body, model, auth, think = false,
|
|
|
206
258
|
if (curMsg.tool_results) {
|
|
207
259
|
for (const tr of curMsg.tool_results)
|
|
208
260
|
curTrs.push({
|
|
209
|
-
content: [{ text: getContentText(tr) }],
|
|
261
|
+
content: [{ text: truncate(getContentText(tr), 250000) }],
|
|
210
262
|
status: 'success',
|
|
211
263
|
toolUseId: tr.tool_call_id
|
|
212
264
|
});
|
|
213
265
|
}
|
|
214
266
|
else {
|
|
215
267
|
curTrs.push({
|
|
216
|
-
content: [{ text: getContentText(curMsg) }],
|
|
268
|
+
content: [{ text: truncate(getContentText(curMsg), 250000) }],
|
|
217
269
|
status: 'success',
|
|
218
270
|
toolUseId: curMsg.tool_call_id
|
|
219
271
|
});
|
|
@@ -225,7 +277,7 @@ export function transformToCodeWhisperer(url, body, model, auth, think = false,
|
|
|
225
277
|
curContent += p.text || '';
|
|
226
278
|
else if (p.type === 'tool_result')
|
|
227
279
|
curTrs.push({
|
|
228
|
-
content: [{ text: getContentText(p.content || p) }],
|
|
280
|
+
content: [{ text: truncate(getContentText(p.content || p), 250000) }],
|
|
229
281
|
status: 'success',
|
|
230
282
|
toolUseId: p.tool_use_id
|
|
231
283
|
});
|
|
@@ -254,17 +306,60 @@ export function transformToCodeWhisperer(url, body, model, auth, think = false,
|
|
|
254
306
|
}
|
|
255
307
|
}
|
|
256
308
|
};
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
309
|
+
const toolUsesInHistory = history.flatMap((h) => h.assistantResponseMessage?.toolUses || []);
|
|
310
|
+
const allToolUseIdsInHistory = new Set(toolUsesInHistory.map((tu) => tu.toolUseId));
|
|
311
|
+
const finalCurTrs = [];
|
|
312
|
+
const orphanedTrs = [];
|
|
313
|
+
for (const tr of curTrs) {
|
|
314
|
+
if (allToolUseIdsInHistory.has(tr.toolUseId))
|
|
315
|
+
finalCurTrs.push(tr);
|
|
316
|
+
else {
|
|
317
|
+
const originalCall = findOriginalToolCall(messages, tr.toolUseId);
|
|
318
|
+
if (originalCall) {
|
|
319
|
+
orphanedTrs.push({
|
|
320
|
+
call: {
|
|
321
|
+
name: originalCall.name || originalCall.function?.name || 'tool',
|
|
322
|
+
toolUseId: tr.toolUseId,
|
|
323
|
+
input: originalCall.input ||
|
|
324
|
+
(originalCall.function?.arguments ? JSON.parse(originalCall.function.arguments) : {})
|
|
325
|
+
},
|
|
326
|
+
result: tr
|
|
327
|
+
});
|
|
328
|
+
}
|
|
329
|
+
else {
|
|
330
|
+
curContent += `\n\n[Output for tool call ${tr.toolUseId}]:\n${tr.content?.[0]?.text || ''}`;
|
|
331
|
+
}
|
|
332
|
+
}
|
|
260
333
|
}
|
|
334
|
+
if (orphanedTrs.length > 0) {
|
|
335
|
+
const prev = history[history.length - 1];
|
|
336
|
+
if (prev && !prev.userInputMessage) {
|
|
337
|
+
history.push({
|
|
338
|
+
userInputMessage: {
|
|
339
|
+
content: 'Running tools...',
|
|
340
|
+
modelId: resolved,
|
|
341
|
+
origin: KIRO_CONSTANTS.ORIGIN_AI_EDITOR
|
|
342
|
+
}
|
|
343
|
+
});
|
|
344
|
+
}
|
|
345
|
+
history.push({
|
|
346
|
+
assistantResponseMessage: {
|
|
347
|
+
content: 'I will execute the following tools.',
|
|
348
|
+
toolUses: orphanedTrs.map((o) => o.call)
|
|
349
|
+
}
|
|
350
|
+
});
|
|
351
|
+
finalCurTrs.push(...orphanedTrs.map((o) => o.result));
|
|
352
|
+
}
|
|
353
|
+
if (history.length > 0)
|
|
354
|
+
request.conversationState.history = history;
|
|
261
355
|
const uim = request.conversationState.currentMessage.userInputMessage;
|
|
262
356
|
if (uim) {
|
|
357
|
+
uim.content = curContent;
|
|
263
358
|
if (curImgs.length)
|
|
264
359
|
uim.images = curImgs;
|
|
265
360
|
const ctx = {};
|
|
266
|
-
if (
|
|
267
|
-
ctx.toolResults = deduplicateToolResults(
|
|
361
|
+
if (finalCurTrs.length)
|
|
362
|
+
ctx.toolResults = deduplicateToolResults(finalCurTrs);
|
|
268
363
|
if (cwTools.length)
|
|
269
364
|
ctx.tools = cwTools;
|
|
270
365
|
if (Object.keys(ctx).length)
|
|
@@ -277,17 +372,11 @@ export function transformToCodeWhisperer(url, body, model, auth, think = false,
|
|
|
277
372
|
const existingToolNames = new Set(existingTools.map((t) => t.toolSpecification?.name).filter(Boolean));
|
|
278
373
|
const missingToolNames = Array.from(toolNamesInHistory).filter((name) => !existingToolNames.has(name));
|
|
279
374
|
if (missingToolNames.length > 0) {
|
|
280
|
-
logger.log(`[Kiro] Adding ${missingToolNames.length} missing tool definitions: ${missingToolNames.join(', ')}`);
|
|
281
375
|
const placeholderTools = missingToolNames.map((name) => ({
|
|
282
376
|
toolSpecification: {
|
|
283
377
|
name,
|
|
284
378
|
description: 'Tool',
|
|
285
|
-
inputSchema: {
|
|
286
|
-
json: {
|
|
287
|
-
type: 'object',
|
|
288
|
-
properties: {}
|
|
289
|
-
}
|
|
290
|
-
}
|
|
379
|
+
inputSchema: { json: { type: 'object', properties: {} } }
|
|
291
380
|
}
|
|
292
381
|
}));
|
|
293
382
|
if (!uim.userInputMessageContext)
|
package/dist/plugin/response.js
CHANGED
|
@@ -76,7 +76,7 @@ function parseEventStreamChunk(rawText) {
|
|
|
76
76
|
};
|
|
77
77
|
});
|
|
78
78
|
if (contextUsagePercentage !== undefined) {
|
|
79
|
-
const totalTokens = Math.round((
|
|
79
|
+
const totalTokens = Math.round((200000 * contextUsagePercentage) / 100);
|
|
80
80
|
outputTokens = estimateTokens(content);
|
|
81
81
|
inputTokens = Math.max(0, totalTokens - outputTokens);
|
|
82
82
|
}
|
package/dist/plugin/streaming.js
CHANGED
|
@@ -224,7 +224,7 @@ export async function* transformKiroStream(response, model, conversationId) {
|
|
|
224
224
|
}
|
|
225
225
|
outputTokens = estimateTokens(totalContent);
|
|
226
226
|
if (contextUsagePercentage !== null && contextUsagePercentage > 0) {
|
|
227
|
-
const totalTokens = Math.round((
|
|
227
|
+
const totalTokens = Math.round((200000 * contextUsagePercentage) / 100);
|
|
228
228
|
inputTokens = Math.max(0, totalTokens - outputTokens);
|
|
229
229
|
}
|
|
230
230
|
yield convertToOpenAI({
|