ns-omp-provider-kiro 0.3.5 → 0.3.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/index.js +278 -25
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -2420,8 +2420,52 @@ function convertToolsToKiro(tools) {
|
|
|
2420
2420
|
}
|
|
2421
2421
|
}));
|
|
2422
2422
|
}
|
|
2423
|
+
var KIRO_IMAGE_FORMAT_ALIASES = {
|
|
2424
|
+
png: "png",
|
|
2425
|
+
"x-png": "png",
|
|
2426
|
+
jpeg: "jpeg",
|
|
2427
|
+
jpg: "jpeg",
|
|
2428
|
+
pjpeg: "jpeg",
|
|
2429
|
+
gif: "gif",
|
|
2430
|
+
webp: "webp"
|
|
2431
|
+
};
|
|
2432
|
+
function toKiroImageFormat(mimeType) {
|
|
2433
|
+
const subtype = mimeType.trim().toLowerCase().split("/").pop()?.split(";")[0]?.trim() ?? "";
|
|
2434
|
+
return KIRO_IMAGE_FORMAT_ALIASES[subtype];
|
|
2435
|
+
}
|
|
2436
|
+
function toKiroImageBytes(data) {
|
|
2437
|
+
const trimmed = data.trim();
|
|
2438
|
+
const marker = "base64,";
|
|
2439
|
+
if (!trimmed.startsWith("data:") || !trimmed.includes(marker))
|
|
2440
|
+
return trimmed;
|
|
2441
|
+
return trimmed.slice(trimmed.indexOf(marker) + marker.length);
|
|
2442
|
+
}
|
|
2423
2443
|
function convertImagesToKiro(images) {
|
|
2424
|
-
|
|
2444
|
+
const out = [];
|
|
2445
|
+
for (const img of images) {
|
|
2446
|
+
const format = toKiroImageFormat(img.mimeType);
|
|
2447
|
+
const bytes = toKiroImageBytes(img.data);
|
|
2448
|
+
if (!format || !bytes)
|
|
2449
|
+
continue;
|
|
2450
|
+
out.push({ format, source: { bytes } });
|
|
2451
|
+
}
|
|
2452
|
+
return out;
|
|
2453
|
+
}
|
|
2454
|
+
function toKiroToolInput(input) {
|
|
2455
|
+
if (isPlainObject(input))
|
|
2456
|
+
return input;
|
|
2457
|
+
if (typeof input === "string") {
|
|
2458
|
+
try {
|
|
2459
|
+
const parsed = JSON.parse(input);
|
|
2460
|
+
if (isPlainObject(parsed))
|
|
2461
|
+
return parsed;
|
|
2462
|
+
} catch {
|
|
2463
|
+
}
|
|
2464
|
+
}
|
|
2465
|
+
return {};
|
|
2466
|
+
}
|
|
2467
|
+
function isPlainObject(value) {
|
|
2468
|
+
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
2425
2469
|
}
|
|
2426
2470
|
function toolResultOf(msg) {
|
|
2427
2471
|
return {
|
|
@@ -2453,12 +2497,12 @@ function buildHistory(messages, modelId, systemPrompt) {
|
|
|
2453
2497
|
${content}`;
|
|
2454
2498
|
systemPrepended = true;
|
|
2455
2499
|
}
|
|
2456
|
-
const images = extractImages(msg);
|
|
2500
|
+
const images = convertImagesToKiro(extractImages(msg));
|
|
2457
2501
|
const uim = {
|
|
2458
2502
|
content: sanitizeSurrogates(content),
|
|
2459
2503
|
modelId,
|
|
2460
2504
|
origin: "KIRO_CLI",
|
|
2461
|
-
...images.length > 0 ? { images
|
|
2505
|
+
...images.length > 0 ? { images } : {}
|
|
2462
2506
|
};
|
|
2463
2507
|
const prevUim = history[history.length - 1]?.userInputMessage;
|
|
2464
2508
|
if (prevUim) {
|
|
@@ -2484,7 +2528,7 @@ ${uim.content}` : prevUim.content || uim.content;
|
|
|
2484
2528
|
armToolUses.push({
|
|
2485
2529
|
name: toKiroToolName(block.name),
|
|
2486
2530
|
toolUseId: toKiroToolUseId(block.id),
|
|
2487
|
-
input: block.arguments
|
|
2531
|
+
input: toKiroToolInput(block.arguments)
|
|
2488
2532
|
});
|
|
2489
2533
|
armHadBlocks = true;
|
|
2490
2534
|
}
|
|
@@ -2509,8 +2553,9 @@ ${uim.content}` : prevUim.content || uim.content;
|
|
|
2509
2553
|
i = j - 1;
|
|
2510
2554
|
const prevTr = history[history.length - 1]?.userInputMessage;
|
|
2511
2555
|
if (prevTr) {
|
|
2512
|
-
|
|
2513
|
-
|
|
2556
|
+
const images = convertImagesToKiro(trImages);
|
|
2557
|
+
if (images.length > 0)
|
|
2558
|
+
prevTr.images = [...prevTr.images || [], ...images];
|
|
2514
2559
|
if (!prevTr.userInputMessageContext)
|
|
2515
2560
|
prevTr.userInputMessageContext = {};
|
|
2516
2561
|
prevTr.userInputMessageContext.toolResults = [
|
|
@@ -2518,6 +2563,7 @@ ${uim.content}` : prevUim.content || uim.content;
|
|
|
2518
2563
|
...toolResults
|
|
2519
2564
|
];
|
|
2520
2565
|
} else {
|
|
2566
|
+
const images = convertImagesToKiro(trImages);
|
|
2521
2567
|
history.push({
|
|
2522
2568
|
userInputMessage: {
|
|
2523
2569
|
// Empty by design: `toolResults` is this turn's payload. See
|
|
@@ -2525,7 +2571,7 @@ ${uim.content}` : prevUim.content || uim.content;
|
|
|
2525
2571
|
content: "",
|
|
2526
2572
|
modelId,
|
|
2527
2573
|
origin: "KIRO_CLI",
|
|
2528
|
-
...
|
|
2574
|
+
...images.length > 0 ? { images } : {},
|
|
2529
2575
|
userInputMessageContext: { toolResults }
|
|
2530
2576
|
}
|
|
2531
2577
|
});
|
|
@@ -3078,7 +3124,7 @@ function buildKiroRequest(params) {
|
|
|
3078
3124
|
armToolUses.push({
|
|
3079
3125
|
name: toKiroToolName(block.name),
|
|
3080
3126
|
toolUseId: toKiroToolUseId(block.id),
|
|
3081
|
-
input: block.arguments
|
|
3127
|
+
input: toKiroToolInput(block.arguments)
|
|
3082
3128
|
});
|
|
3083
3129
|
}
|
|
3084
3130
|
}
|
|
@@ -3107,8 +3153,9 @@ ${armContent}` : prevArm.content || armContent;
|
|
|
3107
3153
|
currentToolResults.push(toolResultOf2(m));
|
|
3108
3154
|
toolResultImages.push(...extractImages(m));
|
|
3109
3155
|
}
|
|
3110
|
-
|
|
3111
|
-
|
|
3156
|
+
const convertedToolImages = convertImagesToKiro(toolResultImages);
|
|
3157
|
+
if (convertedToolImages.length > 0)
|
|
3158
|
+
currentImages = convertedToolImages;
|
|
3112
3159
|
currentContent = "";
|
|
3113
3160
|
} else if (firstMsg?.role === "toolResult") {
|
|
3114
3161
|
const toolResultImages = [];
|
|
@@ -3118,8 +3165,9 @@ ${armContent}` : prevArm.content || armContent;
|
|
|
3118
3165
|
currentToolResults.push(toolResultOf2(m));
|
|
3119
3166
|
toolResultImages.push(...extractImages(m));
|
|
3120
3167
|
}
|
|
3121
|
-
|
|
3122
|
-
|
|
3168
|
+
const convertedToolImages = convertImagesToKiro(toolResultImages);
|
|
3169
|
+
if (convertedToolImages.length > 0)
|
|
3170
|
+
currentImages = convertedToolImages;
|
|
3123
3171
|
currentContent = "";
|
|
3124
3172
|
} else if (firstMsg?.role === "user") {
|
|
3125
3173
|
currentContent = getContentText(firstMsg);
|
|
@@ -3145,9 +3193,9 @@ ${currentContent}`;
|
|
|
3145
3193
|
uimc.tools = finalTools;
|
|
3146
3194
|
}
|
|
3147
3195
|
if (firstMsg?.role === "user") {
|
|
3148
|
-
const imgs = extractImages(firstMsg);
|
|
3196
|
+
const imgs = convertImagesToKiro(extractImages(firstMsg));
|
|
3149
3197
|
if (imgs.length > 0)
|
|
3150
|
-
currentImages =
|
|
3198
|
+
currentImages = imgs;
|
|
3151
3199
|
}
|
|
3152
3200
|
if (currentContent === "" && currentToolResults.length === 0)
|
|
3153
3201
|
currentContent = EMPTY_CONTENT_PLACEHOLDER;
|
|
@@ -3518,12 +3566,177 @@ function countTokens(text) {
|
|
|
3518
3566
|
return getEncoder().encode(text).length;
|
|
3519
3567
|
}
|
|
3520
3568
|
|
|
3569
|
+
// ../kiro-core/dist/tool-name-aliases.js
|
|
3570
|
+
var TOOL_NAME_ALIASES = {
|
|
3571
|
+
// read
|
|
3572
|
+
read_file: "read",
|
|
3573
|
+
readfile: "read",
|
|
3574
|
+
fs_read: "read",
|
|
3575
|
+
view_file: "read",
|
|
3576
|
+
// write
|
|
3577
|
+
write_file: "write",
|
|
3578
|
+
writefile: "write",
|
|
3579
|
+
fs_write: "write",
|
|
3580
|
+
create_file: "write",
|
|
3581
|
+
// edit
|
|
3582
|
+
edit_file: "edit",
|
|
3583
|
+
editfile: "edit",
|
|
3584
|
+
str_replace: "edit",
|
|
3585
|
+
str_replace_editor: "edit",
|
|
3586
|
+
str_replace_based_edit_tool: "edit",
|
|
3587
|
+
apply_patch: "edit",
|
|
3588
|
+
// ls
|
|
3589
|
+
list_directory: "ls",
|
|
3590
|
+
list_dir: "ls",
|
|
3591
|
+
list_files: "ls",
|
|
3592
|
+
// find
|
|
3593
|
+
find_files: "find",
|
|
3594
|
+
file_search: "find"
|
|
3595
|
+
};
|
|
3596
|
+
function normalizeKiroToolName(name, declared) {
|
|
3597
|
+
if (!declared || declared.size === 0 || declared.has(name))
|
|
3598
|
+
return name;
|
|
3599
|
+
const alias = TOOL_NAME_ALIASES[name.toLowerCase()];
|
|
3600
|
+
return alias !== void 0 && declared.has(alias) ? alias : name;
|
|
3601
|
+
}
|
|
3602
|
+
|
|
3603
|
+
// ../kiro-core/dist/tool-use-parser.js
|
|
3604
|
+
var TAG_NAMES = ["tool_use", "tool_call", "function_call", "tool"];
|
|
3605
|
+
var FENCE2 = "```";
|
|
3606
|
+
function nextTagBlock(text, from) {
|
|
3607
|
+
let best = null;
|
|
3608
|
+
for (const name of TAG_NAMES) {
|
|
3609
|
+
const open = `<${name}>`;
|
|
3610
|
+
const close = `</${name}>`;
|
|
3611
|
+
const openStart = text.indexOf(open, from);
|
|
3612
|
+
if (openStart < 0)
|
|
3613
|
+
continue;
|
|
3614
|
+
if (best && openStart >= best.openStart)
|
|
3615
|
+
continue;
|
|
3616
|
+
const bodyStart = openStart + open.length;
|
|
3617
|
+
const closeIdx = text.indexOf(close, bodyStart);
|
|
3618
|
+
if (closeIdx < 0)
|
|
3619
|
+
continue;
|
|
3620
|
+
best = { openStart, bodyStart, closeIdx, closeEnd: closeIdx + close.length };
|
|
3621
|
+
}
|
|
3622
|
+
return best;
|
|
3623
|
+
}
|
|
3624
|
+
function fencedRanges2(text) {
|
|
3625
|
+
const ranges = [];
|
|
3626
|
+
let searchFrom = 0;
|
|
3627
|
+
while (true) {
|
|
3628
|
+
const open = text.indexOf(FENCE2, searchFrom);
|
|
3629
|
+
if (open < 0)
|
|
3630
|
+
break;
|
|
3631
|
+
const close = text.indexOf(FENCE2, open + FENCE2.length);
|
|
3632
|
+
if (close < 0) {
|
|
3633
|
+
ranges.push({ start: open, end: text.length });
|
|
3634
|
+
break;
|
|
3635
|
+
}
|
|
3636
|
+
ranges.push({ start: open, end: close + FENCE2.length });
|
|
3637
|
+
searchFrom = close + FENCE2.length;
|
|
3638
|
+
}
|
|
3639
|
+
return ranges;
|
|
3640
|
+
}
|
|
3641
|
+
function normalizeOne(value) {
|
|
3642
|
+
if (typeof value !== "object" || value === null || Array.isArray(value))
|
|
3643
|
+
return null;
|
|
3644
|
+
const record = value;
|
|
3645
|
+
const rawName = record.tool_name ?? record.name;
|
|
3646
|
+
if (typeof rawName !== "string" || rawName.length === 0)
|
|
3647
|
+
return null;
|
|
3648
|
+
const rawArgs = record.tool_input ?? record.input ?? record.arguments;
|
|
3649
|
+
if (rawArgs === void 0) {
|
|
3650
|
+
return { name: rawName, arguments: {} };
|
|
3651
|
+
}
|
|
3652
|
+
if (typeof rawArgs !== "object" || rawArgs === null || Array.isArray(rawArgs))
|
|
3653
|
+
return null;
|
|
3654
|
+
return { name: rawName, arguments: rawArgs };
|
|
3655
|
+
}
|
|
3656
|
+
function extractDescriptors(value) {
|
|
3657
|
+
if (typeof value === "object" && value !== null && !Array.isArray(value)) {
|
|
3658
|
+
const record = value;
|
|
3659
|
+
const wrapped = record.tool_calls ?? record.calls;
|
|
3660
|
+
if (Array.isArray(wrapped)) {
|
|
3661
|
+
const out = [];
|
|
3662
|
+
for (const entry of wrapped) {
|
|
3663
|
+
const one = normalizeOne(entry);
|
|
3664
|
+
if (one === null)
|
|
3665
|
+
return [];
|
|
3666
|
+
out.push(one);
|
|
3667
|
+
}
|
|
3668
|
+
return out;
|
|
3669
|
+
}
|
|
3670
|
+
}
|
|
3671
|
+
const single = normalizeOne(value);
|
|
3672
|
+
return single ? [single] : [];
|
|
3673
|
+
}
|
|
3674
|
+
function parseToolUseCalls(text) {
|
|
3675
|
+
const toolCalls = [];
|
|
3676
|
+
const removals = [];
|
|
3677
|
+
const fences = fencedRanges2(text);
|
|
3678
|
+
let cursor = 0;
|
|
3679
|
+
while (cursor < text.length) {
|
|
3680
|
+
const hit = nextTagBlock(text, cursor);
|
|
3681
|
+
if (hit === null)
|
|
3682
|
+
break;
|
|
3683
|
+
const { openStart, bodyStart, closeIdx, closeEnd } = hit;
|
|
3684
|
+
const containingFence = fences.find((range) => openStart >= range.start && openStart < range.end);
|
|
3685
|
+
if (containingFence) {
|
|
3686
|
+
cursor = containingFence.end;
|
|
3687
|
+
continue;
|
|
3688
|
+
}
|
|
3689
|
+
const braceStart = text.indexOf("{", bodyStart);
|
|
3690
|
+
if (braceStart < 0 || braceStart > closeIdx) {
|
|
3691
|
+
cursor = closeEnd;
|
|
3692
|
+
continue;
|
|
3693
|
+
}
|
|
3694
|
+
const braceEnd = findJsonEnd(text, braceStart);
|
|
3695
|
+
if (braceEnd < 0 || braceEnd > closeIdx) {
|
|
3696
|
+
cursor = closeEnd;
|
|
3697
|
+
continue;
|
|
3698
|
+
}
|
|
3699
|
+
const beforeJson = text.substring(bodyStart, braceStart).trim();
|
|
3700
|
+
const afterJson = text.substring(braceEnd + 1, closeIdx).trim();
|
|
3701
|
+
if (beforeJson.length > 0 || afterJson.length > 0) {
|
|
3702
|
+
cursor = closeEnd;
|
|
3703
|
+
continue;
|
|
3704
|
+
}
|
|
3705
|
+
let descriptors = [];
|
|
3706
|
+
try {
|
|
3707
|
+
descriptors = extractDescriptors(JSON.parse(text.substring(braceStart, braceEnd + 1)));
|
|
3708
|
+
} catch {
|
|
3709
|
+
descriptors = [];
|
|
3710
|
+
}
|
|
3711
|
+
if (descriptors.length === 0) {
|
|
3712
|
+
cursor = closeEnd;
|
|
3713
|
+
continue;
|
|
3714
|
+
}
|
|
3715
|
+
for (const descriptor of descriptors) {
|
|
3716
|
+
toolCalls.push({
|
|
3717
|
+
toolUseId: crypto.randomUUID(),
|
|
3718
|
+
name: descriptor.name,
|
|
3719
|
+
arguments: descriptor.arguments
|
|
3720
|
+
});
|
|
3721
|
+
}
|
|
3722
|
+
removals.push({ start: openStart, end: closeEnd });
|
|
3723
|
+
cursor = closeEnd;
|
|
3724
|
+
}
|
|
3725
|
+
let cleanedText = text;
|
|
3726
|
+
for (let i = removals.length - 1; i >= 0; i--) {
|
|
3727
|
+
const { start, end } = removals[i];
|
|
3728
|
+
cleanedText = cleanedText.substring(0, start) + cleanedText.substring(end);
|
|
3729
|
+
}
|
|
3730
|
+
return { toolCalls, cleanedText };
|
|
3731
|
+
}
|
|
3732
|
+
|
|
3521
3733
|
// ../kiro-core/dist/response-assembler.js
|
|
3522
3734
|
var ECHO_NOISE_PATTERN = /^\s*(continue|\.+)\s*$/i;
|
|
3523
3735
|
var KiroResponseAssembler = class {
|
|
3524
3736
|
model;
|
|
3525
3737
|
thinkingEnabled;
|
|
3526
3738
|
toolNameAliases;
|
|
3739
|
+
declaredToolNames;
|
|
3527
3740
|
pending = [];
|
|
3528
3741
|
blocks = new KiroBlockBuffer((event) => this.pending.push(event));
|
|
3529
3742
|
usage = {
|
|
@@ -3533,7 +3746,6 @@ var KiroResponseAssembler = class {
|
|
|
3533
3746
|
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 }
|
|
3534
3747
|
};
|
|
3535
3748
|
totalContent = "";
|
|
3536
|
-
lastContentData = "";
|
|
3537
3749
|
usageEvent = null;
|
|
3538
3750
|
meteringEvent = null;
|
|
3539
3751
|
receivedContextUsage = false;
|
|
@@ -3546,18 +3758,19 @@ var KiroResponseAssembler = class {
|
|
|
3546
3758
|
droppedToolCalls = [];
|
|
3547
3759
|
currentToolCall = null;
|
|
3548
3760
|
stopReason = "stop";
|
|
3549
|
-
constructor(model, thinkingEnabled, toolNameAliases) {
|
|
3761
|
+
constructor(model, thinkingEnabled, toolNameAliases, declaredToolNames) {
|
|
3550
3762
|
this.model = model;
|
|
3551
3763
|
this.thinkingEnabled = thinkingEnabled;
|
|
3552
3764
|
this.toolNameAliases = toolNameAliases;
|
|
3765
|
+
this.declaredToolNames = declaredToolNames;
|
|
3553
3766
|
}
|
|
3767
|
+
/** Wire name -> the name the host registered, then alias repair. */
|
|
3554
3768
|
originalToolName(name) {
|
|
3555
|
-
return this.toolNameAliases?.get(name) ?? name;
|
|
3769
|
+
return normalizeKiroToolName(this.toolNameAliases?.get(name) ?? name, this.declaredToolNames);
|
|
3556
3770
|
}
|
|
3557
3771
|
/** Clear per-attempt state. Only block indexes are kept. */
|
|
3558
3772
|
beginAttempt() {
|
|
3559
3773
|
this.totalContent = "";
|
|
3560
|
-
this.lastContentData = "";
|
|
3561
3774
|
this.usageEvent = null;
|
|
3562
3775
|
this.meteringEvent = null;
|
|
3563
3776
|
this.receivedContextUsage = false;
|
|
@@ -3613,10 +3826,9 @@ var KiroResponseAssembler = class {
|
|
|
3613
3826
|
break;
|
|
3614
3827
|
}
|
|
3615
3828
|
case "content": {
|
|
3616
|
-
|
|
3617
|
-
if (event.data === this.lastContentData)
|
|
3829
|
+
if (event.data === "")
|
|
3618
3830
|
break;
|
|
3619
|
-
this.
|
|
3831
|
+
this.endNativeThinking();
|
|
3620
3832
|
this.totalContent += event.data;
|
|
3621
3833
|
if (this.thinkingParser) {
|
|
3622
3834
|
this.thinkingParser.processChunk(event.data);
|
|
@@ -3655,6 +3867,14 @@ var KiroResponseAssembler = class {
|
|
|
3655
3867
|
}
|
|
3656
3868
|
case "usage": {
|
|
3657
3869
|
this.usageEvent = { ...this.usageEvent ?? {}, ...event.data };
|
|
3870
|
+
const pct = event.data.contextUsagePercentage;
|
|
3871
|
+
if (pct !== void 0) {
|
|
3872
|
+
if (this.usageEvent.inputTokens === void 0) {
|
|
3873
|
+
this.usage.input = Math.round(pct / 100 * this.model.contextWindow);
|
|
3874
|
+
}
|
|
3875
|
+
this.usage.contextPercent = pct;
|
|
3876
|
+
this.receivedContextUsage = true;
|
|
3877
|
+
}
|
|
3658
3878
|
if (debugEnabled())
|
|
3659
3879
|
debugLog("response.usageRaw", payload);
|
|
3660
3880
|
break;
|
|
@@ -3688,7 +3908,18 @@ var KiroResponseAssembler = class {
|
|
|
3688
3908
|
this.stripEchoNoise();
|
|
3689
3909
|
const responseText = this.textBlockIndex === null ? "" : this.blocks.getText(this.textBlockIndex);
|
|
3690
3910
|
const hasText2 = responseText.length > 0;
|
|
3691
|
-
|
|
3911
|
+
const wireStopReason = this.usageEvent?.rawStopReason;
|
|
3912
|
+
switch (wireStopReason) {
|
|
3913
|
+
case "MAX_TOKENS":
|
|
3914
|
+
this.stopReason = "length";
|
|
3915
|
+
break;
|
|
3916
|
+
case "END_TURN":
|
|
3917
|
+
case "TOOL_USE":
|
|
3918
|
+
this.stopReason = this.emittedToolCalls > 0 ? "toolUse" : "stop";
|
|
3919
|
+
break;
|
|
3920
|
+
default:
|
|
3921
|
+
this.stopReason = !this.receivedContextUsage && this.emittedToolCalls === 0 ? "length" : this.emittedToolCalls > 0 ? "toolUse" : "stop";
|
|
3922
|
+
}
|
|
3692
3923
|
return {
|
|
3693
3924
|
responseText,
|
|
3694
3925
|
hasText: hasText2,
|
|
@@ -3697,7 +3928,9 @@ var KiroResponseAssembler = class {
|
|
|
3697
3928
|
isEchoLoop: hasText2 && !this.sawAnyToolCalls && ECHO_NOISE_PATTERN.test(responseText),
|
|
3698
3929
|
isEmpty: !hasText2 && !this.sawAnyToolCalls,
|
|
3699
3930
|
stopReason: this.stopReason,
|
|
3700
|
-
droppedToolCalls: this.droppedToolCalls
|
|
3931
|
+
droppedToolCalls: this.droppedToolCalls,
|
|
3932
|
+
...wireStopReason !== void 0 ? { wireStopReason } : {},
|
|
3933
|
+
...this.usageEvent?.stopDetails !== void 0 ? { wireStopDetails: this.usageEvent.stopDetails } : {}
|
|
3701
3934
|
};
|
|
3702
3935
|
}
|
|
3703
3936
|
/** Drop an echo the caller decided not to retry, so it is not read as a continuation signal. */
|
|
@@ -3781,10 +4014,14 @@ var KiroResponseAssembler = class {
|
|
|
3781
4014
|
}
|
|
3782
4015
|
/**
|
|
3783
4016
|
* Extract text-dialect tool calls from content when no native tool calls
|
|
3784
|
-
* arrived.
|
|
4017
|
+
* arrived. Three dialects are recovered at this seam:
|
|
3785
4018
|
* 1. Kiro's own `[Called name with args: {...}]` bracket form.
|
|
3786
4019
|
* 2. Anthropic's `<invoke name="..."><parameter .../></invoke>` XML form,
|
|
3787
4020
|
* which opus-class models emit as plain text at high context.
|
|
4021
|
+
* 3. A JSON descriptor wrapped in `<tool_use>`, `<tool_call>`,
|
|
4022
|
+
* `<function_call>` or `<tool>` tags (upstream #163), spelled
|
|
4023
|
+
* `tool_name`/`tool_input`, `name`/`input` or `name`/`arguments`,
|
|
4024
|
+
* or wrapped in a `{"tool_calls": [...]}` array.
|
|
3788
4025
|
* Without this, the turn ends `stop` with zero tool calls — the agent loop
|
|
3789
4026
|
* sees a finished answer and an unattended session stalls with no error
|
|
3790
4027
|
* recorded anywhere.
|
|
@@ -3811,6 +4048,11 @@ var KiroResponseAssembler = class {
|
|
|
3811
4048
|
text = invokeResult.cleanedText;
|
|
3812
4049
|
recovered.push(...invokeResult.toolCalls);
|
|
3813
4050
|
}
|
|
4051
|
+
const toolUseResult = parseToolUseCalls(text);
|
|
4052
|
+
if (toolUseResult.toolCalls.length > 0) {
|
|
4053
|
+
text = toolUseResult.cleanedText;
|
|
4054
|
+
recovered.push(...toolUseResult.toolCalls);
|
|
4055
|
+
}
|
|
3814
4056
|
if (recovered.length === 0)
|
|
3815
4057
|
return;
|
|
3816
4058
|
this.blocks.setText(this.textBlockIndex, text);
|
|
@@ -4861,6 +5103,16 @@ function describeReturnedContent(kinds) {
|
|
|
4861
5103
|
}
|
|
4862
5104
|
var skipProfileResolutionForTests = false;
|
|
4863
5105
|
var TEST_PROFILE_ARN = "arn:aws:codewhisperer:us-east-1:000000000000:profile/test";
|
|
5106
|
+
function throwOnTerminalWireStop(wireStopReason, stopDetails) {
|
|
5107
|
+
switch (wireStopReason) {
|
|
5108
|
+
case "MODEL_CONTEXT_WINDOW_EXCEEDED":
|
|
5109
|
+
throw new Error("Kiro API error: context_length_exceeded (MODEL_CONTEXT_WINDOW_EXCEEDED)");
|
|
5110
|
+
case "CONTENT_FILTERED":
|
|
5111
|
+
throw new Error(`Kiro content filtered: ${clampForDiagnostic(redactSensitiveText(JSON.stringify(stopDetails ?? {})))}`);
|
|
5112
|
+
case "PAUSE_TURN":
|
|
5113
|
+
throw new Error("Kiro paused the turn (PAUSE_TURN); automatic continuation is not supported");
|
|
5114
|
+
}
|
|
5115
|
+
}
|
|
4864
5116
|
async function* streamKiro(request) {
|
|
4865
5117
|
const { model, signal } = request;
|
|
4866
5118
|
const initialAccessToken = request.accessToken;
|
|
@@ -4919,7 +5171,7 @@ async function* streamKiro(request) {
|
|
|
4919
5171
|
systemPrompt = `<thinking_mode>enabled</thinking_mode><max_thinking_length>${budget}</max_thinking_length>${systemPrompt ? `
|
|
4920
5172
|
${systemPrompt}` : ""}`;
|
|
4921
5173
|
}
|
|
4922
|
-
const assembler = new KiroResponseAssembler(model, thinkingEnabled, kiroToolNameAliases(request.tools));
|
|
5174
|
+
const assembler = new KiroResponseAssembler(model, thinkingEnabled, kiroToolNameAliases(request.tools), new Set((request.tools ?? []).map((tool) => String(tool.name))));
|
|
4923
5175
|
const usageTracking = request.usageTracking ?? KIRO_USAGE_TRACKING_DISABLED;
|
|
4924
5176
|
let retryCount = 0;
|
|
4925
5177
|
const maxRetries = 3;
|
|
@@ -5103,6 +5355,7 @@ ${systemPrompt}` : ""}`;
|
|
|
5103
5355
|
throw new Error(`Kiro API error: ${outcome.firstTokenTimedOut ? "first token" : "idle"} timeout after max retries`);
|
|
5104
5356
|
}
|
|
5105
5357
|
const summary = assembler.endTurn();
|
|
5358
|
+
throwOnTerminalWireStop(summary.wireStopReason, summary.wireStopDetails);
|
|
5106
5359
|
yield* assembler.takeEvents();
|
|
5107
5360
|
const degenerate = summary.isEmpty || summary.isEchoLoop;
|
|
5108
5361
|
if (summary.isEchoLoop)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ns-omp-provider-kiro",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.8",
|
|
4
4
|
"description": "OMP (oh-my-pi) provider plugin: adds Kiro (AWS CodeWhisperer/Q) models via your kiro-cli login",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"README.md"
|
|
38
38
|
],
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"ns-kiro-core": "0.3.
|
|
40
|
+
"ns-kiro-core": "0.3.8"
|
|
41
41
|
},
|
|
42
42
|
"peerDependencies": {
|
|
43
43
|
"@oh-my-pi/pi-ai": ">=18.2.0",
|