@zhafron/opencode-kiro-auth 1.4.11 → 1.5.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 +2 -2
- package/dist/constants.d.ts +0 -1
- package/dist/constants.js +0 -9
- package/dist/core/account/account-selector.d.ts +25 -0
- package/dist/core/account/account-selector.js +84 -0
- package/dist/core/account/usage-tracker.d.ts +17 -0
- package/dist/core/account/usage-tracker.js +39 -0
- package/dist/core/auth/auth-handler.d.ts +15 -0
- package/dist/core/auth/auth-handler.js +33 -0
- package/dist/core/auth/idc-auth-method.d.ts +17 -0
- package/dist/core/auth/idc-auth-method.js +200 -0
- package/dist/core/auth/token-refresher.d.ts +22 -0
- package/dist/core/auth/token-refresher.js +53 -0
- package/dist/core/index.d.ts +9 -0
- package/dist/core/index.js +9 -0
- package/dist/core/request/error-handler.d.ts +30 -0
- package/dist/core/request/error-handler.js +113 -0
- package/dist/core/request/request-handler.d.ts +27 -0
- package/dist/core/request/request-handler.js +199 -0
- package/dist/core/request/response-handler.d.ts +5 -0
- package/dist/core/request/response-handler.js +61 -0
- package/dist/core/request/retry-strategy.d.ts +18 -0
- package/dist/core/request/retry-strategy.js +28 -0
- package/dist/infrastructure/database/account-cache.d.ts +14 -0
- package/dist/infrastructure/database/account-cache.js +44 -0
- package/dist/infrastructure/database/account-repository.d.ts +12 -0
- package/dist/infrastructure/database/account-repository.js +64 -0
- package/dist/infrastructure/index.d.ts +7 -0
- package/dist/infrastructure/index.js +7 -0
- package/dist/infrastructure/transformers/event-stream-parser.d.ts +7 -0
- package/dist/infrastructure/transformers/event-stream-parser.js +115 -0
- package/dist/infrastructure/transformers/history-builder.d.ts +5 -0
- package/dist/infrastructure/transformers/history-builder.js +171 -0
- package/dist/infrastructure/transformers/message-transformer.d.ts +6 -0
- package/dist/infrastructure/transformers/message-transformer.js +102 -0
- package/dist/infrastructure/transformers/tool-call-parser.d.ts +4 -0
- package/dist/infrastructure/transformers/tool-call-parser.js +45 -0
- package/dist/infrastructure/transformers/tool-transformer.d.ts +2 -0
- package/dist/infrastructure/transformers/tool-transformer.js +19 -0
- package/dist/kiro/auth.d.ts +0 -1
- package/dist/kiro/auth.js +0 -7
- package/dist/plugin/accounts.d.ts +0 -1
- package/dist/plugin/accounts.js +4 -4
- package/dist/plugin/cli.d.ts +2 -1
- package/dist/plugin/cli.js +67 -2
- package/dist/plugin/config/schema.js +4 -4
- package/dist/plugin/models.d.ts +0 -2
- package/dist/plugin/models.js +0 -6
- package/dist/plugin/request.d.ts +0 -2
- package/dist/plugin/request.js +5 -282
- package/dist/plugin/response.d.ts +2 -5
- package/dist/plugin/response.js +3 -161
- package/dist/plugin/storage/migrations.d.ts +2 -0
- package/dist/plugin/storage/migrations.js +109 -0
- package/dist/plugin/storage/sqlite.js +5 -56
- package/dist/plugin/streaming/index.d.ts +2 -0
- package/dist/plugin/streaming/index.js +2 -0
- package/dist/plugin/streaming/openai-converter.d.ts +2 -0
- package/dist/plugin/streaming/openai-converter.js +68 -0
- package/dist/plugin/streaming/stream-parser.d.ts +5 -0
- package/dist/plugin/streaming/stream-parser.js +136 -0
- package/dist/plugin/streaming/stream-state.d.ts +5 -0
- package/dist/plugin/streaming/stream-state.js +59 -0
- package/dist/plugin/streaming/stream-transformer.d.ts +1 -0
- package/dist/plugin/{streaming.js → streaming/stream-transformer.js} +6 -268
- package/dist/plugin/streaming/types.d.ts +25 -0
- package/dist/plugin/streaming/types.js +2 -0
- package/dist/plugin/sync/kiro-cli-parser.d.ts +8 -0
- package/dist/plugin/sync/kiro-cli-parser.js +72 -0
- package/dist/plugin/sync/kiro-cli.js +1 -73
- package/dist/plugin/types.d.ts +0 -13
- package/dist/plugin.d.ts +6 -6
- package/dist/plugin.js +16 -512
- package/package.json +11 -3
- package/dist/plugin/storage/migration.d.ts +0 -1
- package/dist/plugin/storage/migration.js +0 -54
- package/dist/plugin/streaming.d.ts +0 -3
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
export function convertToOpenAI(event, id, model) {
|
|
2
|
+
const base = {
|
|
3
|
+
id,
|
|
4
|
+
object: 'chat.completion.chunk',
|
|
5
|
+
created: Math.floor(Date.now() / 1000),
|
|
6
|
+
model,
|
|
7
|
+
choices: []
|
|
8
|
+
};
|
|
9
|
+
if (event.type === 'content_block_delta') {
|
|
10
|
+
if (event.delta.type === 'text_delta') {
|
|
11
|
+
base.choices.push({
|
|
12
|
+
index: 0,
|
|
13
|
+
delta: { content: event.delta.text },
|
|
14
|
+
finish_reason: null
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
else if (event.delta.type === 'thinking_delta') {
|
|
18
|
+
base.choices.push({
|
|
19
|
+
index: 0,
|
|
20
|
+
delta: { reasoning_content: event.delta.thinking },
|
|
21
|
+
finish_reason: null
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
else if (event.delta.type === 'input_json_delta') {
|
|
25
|
+
base.choices.push({
|
|
26
|
+
index: 0,
|
|
27
|
+
delta: {
|
|
28
|
+
tool_calls: [
|
|
29
|
+
{
|
|
30
|
+
index: event.index,
|
|
31
|
+
function: { arguments: event.delta.partial_json }
|
|
32
|
+
}
|
|
33
|
+
]
|
|
34
|
+
},
|
|
35
|
+
finish_reason: null
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
else if (event.type === 'content_block_start' && event.content_block?.type === 'tool_use') {
|
|
40
|
+
base.choices.push({
|
|
41
|
+
index: 0,
|
|
42
|
+
delta: {
|
|
43
|
+
tool_calls: [
|
|
44
|
+
{
|
|
45
|
+
index: event.index,
|
|
46
|
+
id: event.content_block.id,
|
|
47
|
+
type: 'function',
|
|
48
|
+
function: { name: event.content_block.name, arguments: '' }
|
|
49
|
+
}
|
|
50
|
+
]
|
|
51
|
+
},
|
|
52
|
+
finish_reason: null
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
else if (event.type === 'message_delta') {
|
|
56
|
+
base.choices.push({
|
|
57
|
+
index: 0,
|
|
58
|
+
delta: {},
|
|
59
|
+
finish_reason: event.delta.stop_reason === 'tool_use' ? 'tool_calls' : 'stop'
|
|
60
|
+
});
|
|
61
|
+
base.usage = {
|
|
62
|
+
prompt_tokens: event.usage?.input_tokens || 0,
|
|
63
|
+
completion_tokens: event.usage?.output_tokens || 0,
|
|
64
|
+
total_tokens: (event.usage?.input_tokens || 0) + (event.usage?.output_tokens || 0)
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
return base;
|
|
68
|
+
}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { parseEventLine } from '../../infrastructure/transformers/event-stream-parser.js';
|
|
2
|
+
export function parseStreamBuffer(buffer) {
|
|
3
|
+
const events = [];
|
|
4
|
+
let remaining = buffer;
|
|
5
|
+
let searchStart = 0;
|
|
6
|
+
while (true) {
|
|
7
|
+
const contentStart = remaining.indexOf('{"content":', searchStart);
|
|
8
|
+
const nameStart = remaining.indexOf('{"name":', searchStart);
|
|
9
|
+
const followupStart = remaining.indexOf('{"followupPrompt":', searchStart);
|
|
10
|
+
const inputStart = remaining.indexOf('{"input":', searchStart);
|
|
11
|
+
const stopStart = remaining.indexOf('{"stop":', searchStart);
|
|
12
|
+
const contextUsageStart = remaining.indexOf('{"contextUsagePercentage":', searchStart);
|
|
13
|
+
const candidates = [
|
|
14
|
+
contentStart,
|
|
15
|
+
nameStart,
|
|
16
|
+
followupStart,
|
|
17
|
+
inputStart,
|
|
18
|
+
stopStart,
|
|
19
|
+
contextUsageStart
|
|
20
|
+
].filter((pos) => pos >= 0);
|
|
21
|
+
if (candidates.length === 0)
|
|
22
|
+
break;
|
|
23
|
+
const jsonStart = Math.min(...candidates);
|
|
24
|
+
if (jsonStart < 0)
|
|
25
|
+
break;
|
|
26
|
+
let braceCount = 0;
|
|
27
|
+
let jsonEnd = -1;
|
|
28
|
+
let inString = false;
|
|
29
|
+
let escapeNext = false;
|
|
30
|
+
for (let i = jsonStart; i < remaining.length; i++) {
|
|
31
|
+
const char = remaining[i];
|
|
32
|
+
if (escapeNext) {
|
|
33
|
+
escapeNext = false;
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
if (char === '\\') {
|
|
37
|
+
escapeNext = true;
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
if (char === '"') {
|
|
41
|
+
inString = !inString;
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
if (!inString) {
|
|
45
|
+
if (char === '{') {
|
|
46
|
+
braceCount++;
|
|
47
|
+
}
|
|
48
|
+
else if (char === '}') {
|
|
49
|
+
braceCount--;
|
|
50
|
+
if (braceCount === 0) {
|
|
51
|
+
jsonEnd = i;
|
|
52
|
+
break;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
if (jsonEnd < 0) {
|
|
58
|
+
remaining = remaining.substring(jsonStart);
|
|
59
|
+
break;
|
|
60
|
+
}
|
|
61
|
+
const jsonStr = remaining.substring(jsonStart, jsonEnd + 1);
|
|
62
|
+
const parsed = parseEventLine(jsonStr);
|
|
63
|
+
if (parsed) {
|
|
64
|
+
if (parsed.content !== undefined && !parsed.followupPrompt) {
|
|
65
|
+
events.push({ type: 'content', data: parsed.content });
|
|
66
|
+
}
|
|
67
|
+
else if (parsed.name && parsed.toolUseId) {
|
|
68
|
+
events.push({
|
|
69
|
+
type: 'toolUse',
|
|
70
|
+
data: {
|
|
71
|
+
name: parsed.name,
|
|
72
|
+
toolUseId: parsed.toolUseId,
|
|
73
|
+
input: parsed.input || '',
|
|
74
|
+
stop: parsed.stop || false
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
else if (parsed.input !== undefined && !parsed.name) {
|
|
79
|
+
events.push({
|
|
80
|
+
type: 'toolUseInput',
|
|
81
|
+
data: {
|
|
82
|
+
input: parsed.input
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
else if (parsed.stop !== undefined && parsed.contextUsagePercentage === undefined) {
|
|
87
|
+
events.push({
|
|
88
|
+
type: 'toolUseStop',
|
|
89
|
+
data: {
|
|
90
|
+
stop: parsed.stop
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
else if (parsed.contextUsagePercentage !== undefined) {
|
|
95
|
+
events.push({
|
|
96
|
+
type: 'contextUsage',
|
|
97
|
+
data: {
|
|
98
|
+
contextUsagePercentage: parsed.contextUsagePercentage
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
searchStart = jsonEnd + 1;
|
|
104
|
+
if (searchStart >= remaining.length) {
|
|
105
|
+
remaining = '';
|
|
106
|
+
break;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
if (searchStart > 0 && remaining.length > 0) {
|
|
110
|
+
remaining = remaining.substring(searchStart);
|
|
111
|
+
}
|
|
112
|
+
return { events, remaining };
|
|
113
|
+
}
|
|
114
|
+
export function findRealTag(buffer, tag) {
|
|
115
|
+
const codeBlockPattern = /```[\s\S]*?```/g;
|
|
116
|
+
const codeBlocks = [];
|
|
117
|
+
let match;
|
|
118
|
+
while ((match = codeBlockPattern.exec(buffer)) !== null) {
|
|
119
|
+
codeBlocks.push([match.index, match.index + match[0].length]);
|
|
120
|
+
}
|
|
121
|
+
let pos = 0;
|
|
122
|
+
while ((pos = buffer.indexOf(tag, pos)) !== -1) {
|
|
123
|
+
let inCodeBlock = false;
|
|
124
|
+
for (const [start, end] of codeBlocks) {
|
|
125
|
+
if (pos >= start && pos < end) {
|
|
126
|
+
inCodeBlock = true;
|
|
127
|
+
break;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
if (!inCodeBlock) {
|
|
131
|
+
return pos;
|
|
132
|
+
}
|
|
133
|
+
pos += tag.length;
|
|
134
|
+
}
|
|
135
|
+
return -1;
|
|
136
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { StreamEvent, StreamState } from './types.js';
|
|
2
|
+
export declare function ensureBlockStart(blockType: 'thinking' | 'text', streamState: StreamState): StreamEvent[];
|
|
3
|
+
export declare function stopBlock(index: number | null, streamState: StreamState): StreamEvent[];
|
|
4
|
+
export declare function createTextDeltaEvents(text: string, streamState: StreamState): StreamEvent[];
|
|
5
|
+
export declare function createThinkingDeltaEvents(thinking: string, streamState: StreamState): StreamEvent[];
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
export function ensureBlockStart(blockType, streamState) {
|
|
2
|
+
if (blockType === 'thinking') {
|
|
3
|
+
if (streamState.thinkingBlockIndex != null)
|
|
4
|
+
return [];
|
|
5
|
+
const idx = streamState.nextBlockIndex++;
|
|
6
|
+
streamState.thinkingBlockIndex = idx;
|
|
7
|
+
return [
|
|
8
|
+
{
|
|
9
|
+
type: 'content_block_start',
|
|
10
|
+
index: idx,
|
|
11
|
+
content_block: { type: 'thinking', thinking: '' }
|
|
12
|
+
}
|
|
13
|
+
];
|
|
14
|
+
}
|
|
15
|
+
if (blockType === 'text') {
|
|
16
|
+
if (streamState.textBlockIndex != null)
|
|
17
|
+
return [];
|
|
18
|
+
const idx = streamState.nextBlockIndex++;
|
|
19
|
+
streamState.textBlockIndex = idx;
|
|
20
|
+
return [
|
|
21
|
+
{
|
|
22
|
+
type: 'content_block_start',
|
|
23
|
+
index: idx,
|
|
24
|
+
content_block: { type: 'text', text: '' }
|
|
25
|
+
}
|
|
26
|
+
];
|
|
27
|
+
}
|
|
28
|
+
return [];
|
|
29
|
+
}
|
|
30
|
+
export function stopBlock(index, streamState) {
|
|
31
|
+
if (index == null)
|
|
32
|
+
return [];
|
|
33
|
+
if (streamState.stoppedBlocks.has(index))
|
|
34
|
+
return [];
|
|
35
|
+
streamState.stoppedBlocks.add(index);
|
|
36
|
+
return [{ type: 'content_block_stop', index }];
|
|
37
|
+
}
|
|
38
|
+
export function createTextDeltaEvents(text, streamState) {
|
|
39
|
+
if (!text)
|
|
40
|
+
return [];
|
|
41
|
+
const events = [];
|
|
42
|
+
events.push(...ensureBlockStart('text', streamState));
|
|
43
|
+
events.push({
|
|
44
|
+
type: 'content_block_delta',
|
|
45
|
+
index: streamState.textBlockIndex,
|
|
46
|
+
delta: { type: 'text_delta', text }
|
|
47
|
+
});
|
|
48
|
+
return events;
|
|
49
|
+
}
|
|
50
|
+
export function createThinkingDeltaEvents(thinking, streamState) {
|
|
51
|
+
const events = [];
|
|
52
|
+
events.push(...ensureBlockStart('thinking', streamState));
|
|
53
|
+
events.push({
|
|
54
|
+
type: 'content_block_delta',
|
|
55
|
+
index: streamState.thinkingBlockIndex,
|
|
56
|
+
delta: { type: 'thinking_delta', thinking }
|
|
57
|
+
});
|
|
58
|
+
return events;
|
|
59
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function transformKiroStream(response: Response, model: string, conversationId: string): AsyncGenerator<any>;
|
|
@@ -1,6 +1,9 @@
|
|
|
1
|
-
import { parseBracketToolCalls
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import { parseBracketToolCalls } from '../../infrastructure/transformers/tool-call-parser.js';
|
|
2
|
+
import { estimateTokens } from '../response.js';
|
|
3
|
+
import { convertToOpenAI } from './openai-converter.js';
|
|
4
|
+
import { findRealTag, parseStreamBuffer } from './stream-parser.js';
|
|
5
|
+
import { createTextDeltaEvents, createThinkingDeltaEvents, stopBlock } from './stream-state.js';
|
|
6
|
+
import { THINKING_END_TAG, THINKING_START_TAG } from './types.js';
|
|
4
7
|
export async function* transformKiroStream(response, model, conversationId) {
|
|
5
8
|
const thinkingRequested = true;
|
|
6
9
|
const streamState = {
|
|
@@ -243,268 +246,3 @@ export async function* transformKiroStream(response, model, conversationId) {
|
|
|
243
246
|
reader.releaseLock();
|
|
244
247
|
}
|
|
245
248
|
}
|
|
246
|
-
function convertToOpenAI(event, id, model) {
|
|
247
|
-
const base = {
|
|
248
|
-
id,
|
|
249
|
-
object: 'chat.completion.chunk',
|
|
250
|
-
created: Math.floor(Date.now() / 1000),
|
|
251
|
-
model,
|
|
252
|
-
choices: []
|
|
253
|
-
};
|
|
254
|
-
if (event.type === 'content_block_delta') {
|
|
255
|
-
if (event.delta.type === 'text_delta') {
|
|
256
|
-
base.choices.push({
|
|
257
|
-
index: 0,
|
|
258
|
-
delta: { content: event.delta.text },
|
|
259
|
-
finish_reason: null
|
|
260
|
-
});
|
|
261
|
-
}
|
|
262
|
-
else if (event.delta.type === 'thinking_delta') {
|
|
263
|
-
base.choices.push({
|
|
264
|
-
index: 0,
|
|
265
|
-
delta: { reasoning_content: event.delta.thinking },
|
|
266
|
-
finish_reason: null
|
|
267
|
-
});
|
|
268
|
-
}
|
|
269
|
-
else if (event.delta.type === 'input_json_delta') {
|
|
270
|
-
base.choices.push({
|
|
271
|
-
index: 0,
|
|
272
|
-
delta: {
|
|
273
|
-
tool_calls: [
|
|
274
|
-
{
|
|
275
|
-
index: event.index,
|
|
276
|
-
function: { arguments: event.delta.partial_json }
|
|
277
|
-
}
|
|
278
|
-
]
|
|
279
|
-
},
|
|
280
|
-
finish_reason: null
|
|
281
|
-
});
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
else if (event.type === 'content_block_start' && event.content_block?.type === 'tool_use') {
|
|
285
|
-
base.choices.push({
|
|
286
|
-
index: 0,
|
|
287
|
-
delta: {
|
|
288
|
-
tool_calls: [
|
|
289
|
-
{
|
|
290
|
-
index: event.index,
|
|
291
|
-
id: event.content_block.id,
|
|
292
|
-
type: 'function',
|
|
293
|
-
function: { name: event.content_block.name, arguments: '' }
|
|
294
|
-
}
|
|
295
|
-
]
|
|
296
|
-
},
|
|
297
|
-
finish_reason: null
|
|
298
|
-
});
|
|
299
|
-
}
|
|
300
|
-
else if (event.type === 'message_delta') {
|
|
301
|
-
base.choices.push({
|
|
302
|
-
index: 0,
|
|
303
|
-
delta: {},
|
|
304
|
-
finish_reason: event.delta.stop_reason === 'tool_use' ? 'tool_calls' : 'stop'
|
|
305
|
-
});
|
|
306
|
-
base.usage = {
|
|
307
|
-
prompt_tokens: event.usage?.input_tokens || 0,
|
|
308
|
-
completion_tokens: event.usage?.output_tokens || 0,
|
|
309
|
-
total_tokens: (event.usage?.input_tokens || 0) + (event.usage?.output_tokens || 0)
|
|
310
|
-
};
|
|
311
|
-
}
|
|
312
|
-
return base;
|
|
313
|
-
}
|
|
314
|
-
function parseStreamBuffer(buffer) {
|
|
315
|
-
const events = [];
|
|
316
|
-
let remaining = buffer;
|
|
317
|
-
let searchStart = 0;
|
|
318
|
-
while (true) {
|
|
319
|
-
const contentStart = remaining.indexOf('{"content":', searchStart);
|
|
320
|
-
const nameStart = remaining.indexOf('{"name":', searchStart);
|
|
321
|
-
const followupStart = remaining.indexOf('{"followupPrompt":', searchStart);
|
|
322
|
-
const inputStart = remaining.indexOf('{"input":', searchStart);
|
|
323
|
-
const stopStart = remaining.indexOf('{"stop":', searchStart);
|
|
324
|
-
const contextUsageStart = remaining.indexOf('{"contextUsagePercentage":', searchStart);
|
|
325
|
-
const candidates = [
|
|
326
|
-
contentStart,
|
|
327
|
-
nameStart,
|
|
328
|
-
followupStart,
|
|
329
|
-
inputStart,
|
|
330
|
-
stopStart,
|
|
331
|
-
contextUsageStart
|
|
332
|
-
].filter((pos) => pos >= 0);
|
|
333
|
-
if (candidates.length === 0)
|
|
334
|
-
break;
|
|
335
|
-
const jsonStart = Math.min(...candidates);
|
|
336
|
-
if (jsonStart < 0)
|
|
337
|
-
break;
|
|
338
|
-
let braceCount = 0;
|
|
339
|
-
let jsonEnd = -1;
|
|
340
|
-
let inString = false;
|
|
341
|
-
let escapeNext = false;
|
|
342
|
-
for (let i = jsonStart; i < remaining.length; i++) {
|
|
343
|
-
const char = remaining[i];
|
|
344
|
-
if (escapeNext) {
|
|
345
|
-
escapeNext = false;
|
|
346
|
-
continue;
|
|
347
|
-
}
|
|
348
|
-
if (char === '\\') {
|
|
349
|
-
escapeNext = true;
|
|
350
|
-
continue;
|
|
351
|
-
}
|
|
352
|
-
if (char === '"') {
|
|
353
|
-
inString = !inString;
|
|
354
|
-
continue;
|
|
355
|
-
}
|
|
356
|
-
if (!inString) {
|
|
357
|
-
if (char === '{') {
|
|
358
|
-
braceCount++;
|
|
359
|
-
}
|
|
360
|
-
else if (char === '}') {
|
|
361
|
-
braceCount--;
|
|
362
|
-
if (braceCount === 0) {
|
|
363
|
-
jsonEnd = i;
|
|
364
|
-
break;
|
|
365
|
-
}
|
|
366
|
-
}
|
|
367
|
-
}
|
|
368
|
-
}
|
|
369
|
-
if (jsonEnd < 0) {
|
|
370
|
-
remaining = remaining.substring(jsonStart);
|
|
371
|
-
break;
|
|
372
|
-
}
|
|
373
|
-
const jsonStr = remaining.substring(jsonStart, jsonEnd + 1);
|
|
374
|
-
const parsed = parseEventLine(jsonStr);
|
|
375
|
-
if (parsed) {
|
|
376
|
-
if (parsed.content !== undefined && !parsed.followupPrompt) {
|
|
377
|
-
events.push({ type: 'content', data: parsed.content });
|
|
378
|
-
}
|
|
379
|
-
else if (parsed.name && parsed.toolUseId) {
|
|
380
|
-
events.push({
|
|
381
|
-
type: 'toolUse',
|
|
382
|
-
data: {
|
|
383
|
-
name: parsed.name,
|
|
384
|
-
toolUseId: parsed.toolUseId,
|
|
385
|
-
input: parsed.input || '',
|
|
386
|
-
stop: parsed.stop || false
|
|
387
|
-
}
|
|
388
|
-
});
|
|
389
|
-
}
|
|
390
|
-
else if (parsed.input !== undefined && !parsed.name) {
|
|
391
|
-
events.push({
|
|
392
|
-
type: 'toolUseInput',
|
|
393
|
-
data: {
|
|
394
|
-
input: parsed.input
|
|
395
|
-
}
|
|
396
|
-
});
|
|
397
|
-
}
|
|
398
|
-
else if (parsed.stop !== undefined && parsed.contextUsagePercentage === undefined) {
|
|
399
|
-
events.push({
|
|
400
|
-
type: 'toolUseStop',
|
|
401
|
-
data: {
|
|
402
|
-
stop: parsed.stop
|
|
403
|
-
}
|
|
404
|
-
});
|
|
405
|
-
}
|
|
406
|
-
else if (parsed.contextUsagePercentage !== undefined) {
|
|
407
|
-
events.push({
|
|
408
|
-
type: 'contextUsage',
|
|
409
|
-
data: {
|
|
410
|
-
contextUsagePercentage: parsed.contextUsagePercentage
|
|
411
|
-
}
|
|
412
|
-
});
|
|
413
|
-
}
|
|
414
|
-
}
|
|
415
|
-
searchStart = jsonEnd + 1;
|
|
416
|
-
if (searchStart >= remaining.length) {
|
|
417
|
-
remaining = '';
|
|
418
|
-
break;
|
|
419
|
-
}
|
|
420
|
-
}
|
|
421
|
-
if (searchStart > 0 && remaining.length > 0) {
|
|
422
|
-
remaining = remaining.substring(searchStart);
|
|
423
|
-
}
|
|
424
|
-
return { events, remaining };
|
|
425
|
-
}
|
|
426
|
-
function ensureBlockStart(blockType, streamState) {
|
|
427
|
-
if (blockType === 'thinking') {
|
|
428
|
-
if (streamState.thinkingBlockIndex != null)
|
|
429
|
-
return [];
|
|
430
|
-
const idx = streamState.nextBlockIndex++;
|
|
431
|
-
streamState.thinkingBlockIndex = idx;
|
|
432
|
-
return [
|
|
433
|
-
{
|
|
434
|
-
type: 'content_block_start',
|
|
435
|
-
index: idx,
|
|
436
|
-
content_block: { type: 'thinking', thinking: '' }
|
|
437
|
-
}
|
|
438
|
-
];
|
|
439
|
-
}
|
|
440
|
-
if (blockType === 'text') {
|
|
441
|
-
if (streamState.textBlockIndex != null)
|
|
442
|
-
return [];
|
|
443
|
-
const idx = streamState.nextBlockIndex++;
|
|
444
|
-
streamState.textBlockIndex = idx;
|
|
445
|
-
return [
|
|
446
|
-
{
|
|
447
|
-
type: 'content_block_start',
|
|
448
|
-
index: idx,
|
|
449
|
-
content_block: { type: 'text', text: '' }
|
|
450
|
-
}
|
|
451
|
-
];
|
|
452
|
-
}
|
|
453
|
-
return [];
|
|
454
|
-
}
|
|
455
|
-
function stopBlock(index, streamState) {
|
|
456
|
-
if (index == null)
|
|
457
|
-
return [];
|
|
458
|
-
if (streamState.stoppedBlocks.has(index))
|
|
459
|
-
return [];
|
|
460
|
-
streamState.stoppedBlocks.add(index);
|
|
461
|
-
return [{ type: 'content_block_stop', index }];
|
|
462
|
-
}
|
|
463
|
-
function createTextDeltaEvents(text, streamState) {
|
|
464
|
-
if (!text)
|
|
465
|
-
return [];
|
|
466
|
-
const events = [];
|
|
467
|
-
events.push(...ensureBlockStart('text', streamState));
|
|
468
|
-
events.push({
|
|
469
|
-
type: 'content_block_delta',
|
|
470
|
-
index: streamState.textBlockIndex,
|
|
471
|
-
delta: { type: 'text_delta', text }
|
|
472
|
-
});
|
|
473
|
-
return events;
|
|
474
|
-
}
|
|
475
|
-
function createThinkingDeltaEvents(thinking, streamState) {
|
|
476
|
-
const events = [];
|
|
477
|
-
events.push(...ensureBlockStart('thinking', streamState));
|
|
478
|
-
events.push({
|
|
479
|
-
type: 'content_block_delta',
|
|
480
|
-
index: streamState.thinkingBlockIndex,
|
|
481
|
-
delta: { type: 'thinking_delta', thinking }
|
|
482
|
-
});
|
|
483
|
-
return events;
|
|
484
|
-
}
|
|
485
|
-
export function findRealTag(buffer, tag) {
|
|
486
|
-
const codeBlockPattern = /```[\s\S]*?```/g;
|
|
487
|
-
const codeBlocks = [];
|
|
488
|
-
let match;
|
|
489
|
-
while ((match = codeBlockPattern.exec(buffer)) !== null) {
|
|
490
|
-
codeBlocks.push([match.index, match.index + match[0].length]);
|
|
491
|
-
}
|
|
492
|
-
let pos = 0;
|
|
493
|
-
while ((pos = buffer.indexOf(tag, pos)) !== -1) {
|
|
494
|
-
let inCodeBlock = false;
|
|
495
|
-
for (const [start, end] of codeBlocks) {
|
|
496
|
-
if (pos >= start && pos < end) {
|
|
497
|
-
inCodeBlock = true;
|
|
498
|
-
break;
|
|
499
|
-
}
|
|
500
|
-
}
|
|
501
|
-
if (!inCodeBlock) {
|
|
502
|
-
return pos;
|
|
503
|
-
}
|
|
504
|
-
pos += tag.length;
|
|
505
|
-
}
|
|
506
|
-
return -1;
|
|
507
|
-
}
|
|
508
|
-
export function estimateTokens(text) {
|
|
509
|
-
return Math.ceil(text.length / 4);
|
|
510
|
-
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export interface StreamEvent {
|
|
2
|
+
type: string;
|
|
3
|
+
message?: any;
|
|
4
|
+
content_block?: any;
|
|
5
|
+
delta?: any;
|
|
6
|
+
index?: number;
|
|
7
|
+
usage?: any;
|
|
8
|
+
}
|
|
9
|
+
export interface StreamState {
|
|
10
|
+
thinkingRequested: boolean;
|
|
11
|
+
buffer: string;
|
|
12
|
+
inThinking: boolean;
|
|
13
|
+
thinkingExtracted: boolean;
|
|
14
|
+
thinkingBlockIndex: number | null;
|
|
15
|
+
textBlockIndex: number | null;
|
|
16
|
+
nextBlockIndex: number;
|
|
17
|
+
stoppedBlocks: Set<number>;
|
|
18
|
+
}
|
|
19
|
+
export interface ToolCallState {
|
|
20
|
+
toolUseId: string;
|
|
21
|
+
name: string;
|
|
22
|
+
input: string;
|
|
23
|
+
}
|
|
24
|
+
export declare const THINKING_START_TAG = "<thinking>";
|
|
25
|
+
export declare const THINKING_END_TAG = "</thinking>";
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export declare function getCliDbPath(): string;
|
|
2
|
+
export declare function safeJsonParse(value: unknown): any | null;
|
|
3
|
+
export declare function normalizeExpiresAt(input: unknown): number;
|
|
4
|
+
export declare function findClientCredsRecursive(input: unknown): {
|
|
5
|
+
clientId?: string;
|
|
6
|
+
clientSecret?: string;
|
|
7
|
+
};
|
|
8
|
+
export declare function makePlaceholderEmail(authMethod: string, region: string, clientId?: string, profileArn?: string): string;
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import { homedir, platform } from 'node:os';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
export function getCliDbPath() {
|
|
5
|
+
const override = process.env.KIROCLI_DB_PATH;
|
|
6
|
+
if (override)
|
|
7
|
+
return override;
|
|
8
|
+
const p = platform();
|
|
9
|
+
if (p === 'win32')
|
|
10
|
+
return join(process.env.APPDATA || join(homedir(), 'AppData', 'Roaming'), 'kiro-cli', 'data.sqlite3');
|
|
11
|
+
if (p === 'darwin')
|
|
12
|
+
return join(homedir(), 'Library', 'Application Support', 'kiro-cli', 'data.sqlite3');
|
|
13
|
+
return join(homedir(), '.local', 'share', 'kiro-cli', 'data.sqlite3');
|
|
14
|
+
}
|
|
15
|
+
export function safeJsonParse(value) {
|
|
16
|
+
if (typeof value !== 'string')
|
|
17
|
+
return null;
|
|
18
|
+
try {
|
|
19
|
+
return JSON.parse(value);
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
export function normalizeExpiresAt(input) {
|
|
26
|
+
if (typeof input === 'number') {
|
|
27
|
+
return input < 10_000_000_000 ? input * 1000 : input;
|
|
28
|
+
}
|
|
29
|
+
if (typeof input === 'string' && input.trim()) {
|
|
30
|
+
const t = new Date(input).getTime();
|
|
31
|
+
if (!Number.isNaN(t) && t > 0)
|
|
32
|
+
return t;
|
|
33
|
+
const n = Number(input);
|
|
34
|
+
if (Number.isFinite(n) && n > 0)
|
|
35
|
+
return normalizeExpiresAt(n);
|
|
36
|
+
}
|
|
37
|
+
return 0;
|
|
38
|
+
}
|
|
39
|
+
export function findClientCredsRecursive(input) {
|
|
40
|
+
const root = input;
|
|
41
|
+
if (!root || typeof root !== 'object')
|
|
42
|
+
return {};
|
|
43
|
+
const stack = [root];
|
|
44
|
+
const visited = new Set();
|
|
45
|
+
while (stack.length) {
|
|
46
|
+
const cur = stack.pop();
|
|
47
|
+
if (!cur || typeof cur !== 'object')
|
|
48
|
+
continue;
|
|
49
|
+
if (visited.has(cur))
|
|
50
|
+
continue;
|
|
51
|
+
visited.add(cur);
|
|
52
|
+
const clientId = cur.client_id || cur.clientId;
|
|
53
|
+
const clientSecret = cur.client_secret || cur.clientSecret;
|
|
54
|
+
if (typeof clientId === 'string' && typeof clientSecret === 'string') {
|
|
55
|
+
if (clientId && clientSecret)
|
|
56
|
+
return { clientId, clientSecret };
|
|
57
|
+
}
|
|
58
|
+
if (Array.isArray(cur)) {
|
|
59
|
+
for (const v of cur)
|
|
60
|
+
stack.push(v);
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
for (const v of Object.values(cur))
|
|
64
|
+
stack.push(v);
|
|
65
|
+
}
|
|
66
|
+
return {};
|
|
67
|
+
}
|
|
68
|
+
export function makePlaceholderEmail(authMethod, region, clientId, profileArn) {
|
|
69
|
+
const seed = `${authMethod}:${region}:${clientId || ''}:${profileArn || ''}`;
|
|
70
|
+
const h = createHash('sha256').update(seed).digest('hex').slice(0, 16);
|
|
71
|
+
return `${authMethod}-placeholder+${h}@awsapps.local`;
|
|
72
|
+
}
|