ns-kiro-core 0.1.0
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/LICENSE +22 -0
- package/README.md +51 -0
- package/dist/blocks.d.ts +32 -0
- package/dist/blocks.js +83 -0
- package/dist/blocks.js.map +1 -0
- package/dist/bracket-tool-parser.d.ts +11 -0
- package/dist/bracket-tool-parser.js +78 -0
- package/dist/bracket-tool-parser.js.map +1 -0
- package/dist/cost.d.ts +3 -0
- package/dist/cost.js +10 -0
- package/dist/cost.js.map +1 -0
- package/dist/debug.d.ts +6 -0
- package/dist/debug.js +63 -0
- package/dist/debug.js.map +1 -0
- package/dist/effort.d.ts +36 -0
- package/dist/effort.js +138 -0
- package/dist/effort.js.map +1 -0
- package/dist/endpoints.d.ts +8 -0
- package/dist/endpoints.js +43 -0
- package/dist/endpoints.js.map +1 -0
- package/dist/event-parser.d.ts +49 -0
- package/dist/event-parser.js +56 -0
- package/dist/event-parser.js.map +1 -0
- package/dist/history-validator.d.ts +91 -0
- package/dist/history-validator.js +370 -0
- package/dist/history-validator.js.map +1 -0
- package/dist/history.d.ts +21 -0
- package/dist/history.js +130 -0
- package/dist/history.js.map +1 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.js +28 -0
- package/dist/index.js.map +1 -0
- package/dist/invoke-tool-parser.d.ts +16 -0
- package/dist/invoke-tool-parser.js +152 -0
- package/dist/invoke-tool-parser.js.map +1 -0
- package/dist/kiro-cli.d.ts +31 -0
- package/dist/kiro-cli.js +308 -0
- package/dist/kiro-cli.js.map +1 -0
- package/dist/kiro-ide.d.ts +12 -0
- package/dist/kiro-ide.js +74 -0
- package/dist/kiro-ide.js.map +1 -0
- package/dist/management.d.ts +34 -0
- package/dist/management.js +226 -0
- package/dist/management.js.map +1 -0
- package/dist/models.d.ts +58 -0
- package/dist/models.js +462 -0
- package/dist/models.js.map +1 -0
- package/dist/oauth.d.ts +50 -0
- package/dist/oauth.js +295 -0
- package/dist/oauth.js.map +1 -0
- package/dist/retry.d.ts +74 -0
- package/dist/retry.js +156 -0
- package/dist/retry.js.map +1 -0
- package/dist/stream.d.ts +36 -0
- package/dist/stream.js +898 -0
- package/dist/stream.js.map +1 -0
- package/dist/thinking-parser.d.ts +21 -0
- package/dist/thinking-parser.js +150 -0
- package/dist/thinking-parser.js.map +1 -0
- package/dist/token-type.d.ts +18 -0
- package/dist/token-type.js +45 -0
- package/dist/token-type.js.map +1 -0
- package/dist/tokenizer.d.ts +1 -0
- package/dist/tokenizer.js +19 -0
- package/dist/tokenizer.js.map +1 -0
- package/dist/transform.d.ts +111 -0
- package/dist/transform.js +268 -0
- package/dist/transform.js.map +1 -0
- package/dist/truncation.d.ts +3 -0
- package/dist/truncation.js +12 -0
- package/dist/truncation.js.map +1 -0
- package/dist/types.d.ts +159 -0
- package/dist/types.js +4 -0
- package/dist/types.js.map +1 -0
- package/dist/usage.d.ts +86 -0
- package/dist/usage.js +85 -0
- package/dist/usage.js.map +1 -0
- package/package.json +31 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 ngosangns
|
|
4
|
+
Copyright (c) 2025-2026 Mike O'Brien (pi-provider-kiro)
|
|
5
|
+
|
|
6
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
7
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
8
|
+
in the Software without restriction, including without limitation the rights
|
|
9
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
10
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
11
|
+
furnished to do so, subject to the following conditions:
|
|
12
|
+
|
|
13
|
+
The above copyright notice and this permission notice shall be included in all
|
|
14
|
+
copies or substantial portions of the Software.
|
|
15
|
+
|
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
17
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
18
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
19
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
20
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
21
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
22
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# ns-kiro-core
|
|
2
|
+
|
|
3
|
+
The Kiro (AWS CodeWhisperer/Q) protocol, with no host types in it.
|
|
4
|
+
|
|
5
|
+
This package is the shared half of
|
|
6
|
+
[ns-kiro-provider](https://github.com/ngosangns/ns-kiro-provider): everything a
|
|
7
|
+
Kiro client needs that is not specific to one coding agent.
|
|
8
|
+
|
|
9
|
+
- **Endpoints** — SSO region to management/runtime host resolution.
|
|
10
|
+
- **Model catalog** — the bootstrap list, the authenticated regional catalog,
|
|
11
|
+
and a validated on-disk cache at `~/.ns-kiro-provider-models-cache.json`.
|
|
12
|
+
- **Credentials** — reads the kiro-cli SQLite store and the Kiro IDE token file,
|
|
13
|
+
refreshes IDC / desktop / external-IdP / API-key sessions, and writes
|
|
14
|
+
refreshes back so kiro-cli stays on the same token.
|
|
15
|
+
- **Streaming** — AWS event-stream framing, thinking-tag parsing, native and
|
|
16
|
+
text-dialect tool-call recovery, history validation and repair, and the whole
|
|
17
|
+
retry ladder (transport timeouts, capacity pressure, request-rate windows, 403
|
|
18
|
+
credential rotation, degenerate 200s).
|
|
19
|
+
|
|
20
|
+
## The neutral seam
|
|
21
|
+
|
|
22
|
+
`streamKiro` takes a request built from this package's own vocabulary and yields
|
|
23
|
+
its own events:
|
|
24
|
+
|
|
25
|
+
```ts
|
|
26
|
+
import { streamKiro, resolveKiroCredentials, getCachedModels } from "ns-kiro-core";
|
|
27
|
+
|
|
28
|
+
const credentials = await resolveKiroCredentials();
|
|
29
|
+
const model = getCachedModels("us-east-1").find((m) => m.id === "claude-sonnet-4-6");
|
|
30
|
+
|
|
31
|
+
for await (const event of streamKiro({
|
|
32
|
+
model: { ...model, region: "us-east-1" },
|
|
33
|
+
messages: [{ role: "user", content: [{ type: "text", text: "hello" }] }],
|
|
34
|
+
accessToken: credentials.access,
|
|
35
|
+
effort: "medium",
|
|
36
|
+
})) {
|
|
37
|
+
if (event.type === "text_delta") process.stdout.write(event.delta);
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
An adapter owes two translations — host messages in, host stream events out —
|
|
42
|
+
and nothing else. Block indexes are monotonic across the whole response,
|
|
43
|
+
including across an internal retry, so a host that cannot un-deliver a block
|
|
44
|
+
still receives a coherent sequence; `canDiscardEmittedBlocks` tells the core
|
|
45
|
+
which kind of host it is talking to.
|
|
46
|
+
|
|
47
|
+
## Credit
|
|
48
|
+
|
|
49
|
+
Ported from [pi-provider-kiro](https://github.com/mikeyobrien/pi-provider-kiro)
|
|
50
|
+
by Mike O'Brien (MIT). The port replaces pi-ai's message and event types with
|
|
51
|
+
the neutral vocabulary above; the protocol behaviour is upstream's.
|
package/dist/blocks.d.ts
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { KiroStreamEvent } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Allocates block indexes and accumulates their content while emitting the
|
|
4
|
+
* neutral stream events for each transition.
|
|
5
|
+
*
|
|
6
|
+
* Indexes are monotonic across the whole response, including across an internal
|
|
7
|
+
* retry: {@link reset} announces the discard but never rewinds the counter, so a
|
|
8
|
+
* host that cannot drop delivered blocks still receives a coherent sequence.
|
|
9
|
+
*/
|
|
10
|
+
export declare class KiroBlockBuffer {
|
|
11
|
+
private readonly emit;
|
|
12
|
+
private blocks;
|
|
13
|
+
private nextIndex;
|
|
14
|
+
constructor(emit: (event: KiroStreamEvent) => void);
|
|
15
|
+
openText(): number;
|
|
16
|
+
appendText(index: number, delta: string): void;
|
|
17
|
+
endText(index: number): void;
|
|
18
|
+
openThinking(): number;
|
|
19
|
+
appendThinking(index: number, delta: string): void;
|
|
20
|
+
endThinking(index: number, signature?: string): void;
|
|
21
|
+
/** Reserve an index for a block this buffer does not accumulate (a tool call). */
|
|
22
|
+
reserve(): number;
|
|
23
|
+
getText(index: number): string;
|
|
24
|
+
/**
|
|
25
|
+
* Rewrite one accumulated block before it is closed. Used by the recovery
|
|
26
|
+
* passes that lift tool calls out of text and by echo-noise stripping, both
|
|
27
|
+
* of which decide only once the whole response has arrived.
|
|
28
|
+
*/
|
|
29
|
+
setText(index: number, text: string): void;
|
|
30
|
+
/** Announce that an internal retry discarded everything emitted so far. */
|
|
31
|
+
reset(): void;
|
|
32
|
+
}
|
package/dist/blocks.js
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
// ABOUTME: Content-block bookkeeping shared by the stream and the thinking parser.
|
|
2
|
+
// ABOUTME: Owns index allocation and accumulation so hosts only mirror emitted events.
|
|
3
|
+
/**
|
|
4
|
+
* Allocates block indexes and accumulates their content while emitting the
|
|
5
|
+
* neutral stream events for each transition.
|
|
6
|
+
*
|
|
7
|
+
* Indexes are monotonic across the whole response, including across an internal
|
|
8
|
+
* retry: {@link reset} announces the discard but never rewinds the counter, so a
|
|
9
|
+
* host that cannot drop delivered blocks still receives a coherent sequence.
|
|
10
|
+
*/
|
|
11
|
+
export class KiroBlockBuffer {
|
|
12
|
+
emit;
|
|
13
|
+
blocks = new Map();
|
|
14
|
+
nextIndex = 0;
|
|
15
|
+
constructor(emit) {
|
|
16
|
+
this.emit = emit;
|
|
17
|
+
}
|
|
18
|
+
openText() {
|
|
19
|
+
const index = this.nextIndex++;
|
|
20
|
+
this.blocks.set(index, { kind: "text", text: "", ended: false });
|
|
21
|
+
this.emit({ type: "text_start", index });
|
|
22
|
+
return index;
|
|
23
|
+
}
|
|
24
|
+
appendText(index, delta) {
|
|
25
|
+
const block = this.blocks.get(index);
|
|
26
|
+
if (!block || !delta)
|
|
27
|
+
return;
|
|
28
|
+
block.text += delta;
|
|
29
|
+
this.emit({ type: "text_delta", index, delta });
|
|
30
|
+
}
|
|
31
|
+
endText(index) {
|
|
32
|
+
const block = this.blocks.get(index);
|
|
33
|
+
if (!block || block.ended)
|
|
34
|
+
return;
|
|
35
|
+
block.ended = true;
|
|
36
|
+
this.emit({ type: "text_end", index, text: block.text });
|
|
37
|
+
}
|
|
38
|
+
openThinking() {
|
|
39
|
+
const index = this.nextIndex++;
|
|
40
|
+
this.blocks.set(index, { kind: "thinking", text: "", ended: false });
|
|
41
|
+
this.emit({ type: "thinking_start", index });
|
|
42
|
+
return index;
|
|
43
|
+
}
|
|
44
|
+
appendThinking(index, delta) {
|
|
45
|
+
const block = this.blocks.get(index);
|
|
46
|
+
if (!block || !delta)
|
|
47
|
+
return;
|
|
48
|
+
block.text += delta;
|
|
49
|
+
this.emit({ type: "thinking_delta", index, delta });
|
|
50
|
+
}
|
|
51
|
+
endThinking(index, signature) {
|
|
52
|
+
const block = this.blocks.get(index);
|
|
53
|
+
if (!block || block.ended)
|
|
54
|
+
return;
|
|
55
|
+
block.ended = true;
|
|
56
|
+
this.emit({ type: "thinking_end", index, thinking: block.text, ...(signature ? { signature } : {}) });
|
|
57
|
+
}
|
|
58
|
+
/** Reserve an index for a block this buffer does not accumulate (a tool call). */
|
|
59
|
+
reserve() {
|
|
60
|
+
const index = this.nextIndex++;
|
|
61
|
+
this.blocks.set(index, { kind: "toolCall", text: "", ended: true });
|
|
62
|
+
return index;
|
|
63
|
+
}
|
|
64
|
+
getText(index) {
|
|
65
|
+
return this.blocks.get(index)?.text ?? "";
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Rewrite one accumulated block before it is closed. Used by the recovery
|
|
69
|
+
* passes that lift tool calls out of text and by echo-noise stripping, both
|
|
70
|
+
* of which decide only once the whole response has arrived.
|
|
71
|
+
*/
|
|
72
|
+
setText(index, text) {
|
|
73
|
+
const block = this.blocks.get(index);
|
|
74
|
+
if (block)
|
|
75
|
+
block.text = text;
|
|
76
|
+
}
|
|
77
|
+
/** Announce that an internal retry discarded everything emitted so far. */
|
|
78
|
+
reset() {
|
|
79
|
+
this.blocks.clear();
|
|
80
|
+
this.emit({ type: "reset" });
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=blocks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"blocks.js","sourceRoot":"","sources":["../src/blocks.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export declare function findJsonEnd(text: string, start: number): number;
|
|
2
|
+
export interface BracketToolCall {
|
|
3
|
+
toolUseId: string;
|
|
4
|
+
name: string;
|
|
5
|
+
arguments: Record<string, unknown>;
|
|
6
|
+
}
|
|
7
|
+
export interface BracketParseResult {
|
|
8
|
+
toolCalls: BracketToolCall[];
|
|
9
|
+
cleanedText: string;
|
|
10
|
+
}
|
|
11
|
+
export declare function parseBracketToolCalls(text: string): BracketParseResult;
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
// ABOUTME: Extracts bracket-style tool calls from content text as a fallback.
|
|
2
|
+
// ABOUTME: Parses [Called func_name with args: {...}] patterns from model output.
|
|
3
|
+
export function findJsonEnd(text, start) {
|
|
4
|
+
let braceCount = 0;
|
|
5
|
+
let inString = false;
|
|
6
|
+
let escapeNext = false;
|
|
7
|
+
for (let i = start; i < text.length; i++) {
|
|
8
|
+
const char = text[i];
|
|
9
|
+
if (escapeNext) {
|
|
10
|
+
escapeNext = false;
|
|
11
|
+
continue;
|
|
12
|
+
}
|
|
13
|
+
if (char === "\\") {
|
|
14
|
+
escapeNext = true;
|
|
15
|
+
continue;
|
|
16
|
+
}
|
|
17
|
+
if (char === '"') {
|
|
18
|
+
inString = !inString;
|
|
19
|
+
continue;
|
|
20
|
+
}
|
|
21
|
+
if (!inString) {
|
|
22
|
+
if (char === "{")
|
|
23
|
+
braceCount++;
|
|
24
|
+
else if (char === "}") {
|
|
25
|
+
braceCount--;
|
|
26
|
+
if (braceCount === 0)
|
|
27
|
+
return i;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return -1;
|
|
32
|
+
}
|
|
33
|
+
const BRACKET_PATTERN = /\[Called\s+([\w-]+)\s+with\s+args:\s*/g;
|
|
34
|
+
export function parseBracketToolCalls(text) {
|
|
35
|
+
const toolCalls = [];
|
|
36
|
+
const removals = [];
|
|
37
|
+
// Reset the regex lastIndex to ensure consistent behavior
|
|
38
|
+
BRACKET_PATTERN.lastIndex = 0;
|
|
39
|
+
let match = BRACKET_PATTERN.exec(text);
|
|
40
|
+
while (match !== null) {
|
|
41
|
+
const name = match[1];
|
|
42
|
+
const jsonStart = match.index + match[0].length;
|
|
43
|
+
const braceIdx = text.indexOf("{", jsonStart);
|
|
44
|
+
if (braceIdx >= 0 && braceIdx === jsonStart) {
|
|
45
|
+
const jsonEndIdx = findJsonEnd(text, braceIdx);
|
|
46
|
+
if (jsonEndIdx >= 0) {
|
|
47
|
+
const afterJson = text.indexOf("]", jsonEndIdx + 1);
|
|
48
|
+
if (afterJson >= 0) {
|
|
49
|
+
const between = text.substring(jsonEndIdx + 1, afterJson).trim();
|
|
50
|
+
if (between.length === 0) {
|
|
51
|
+
const jsonStr = text.substring(braceIdx, jsonEndIdx + 1);
|
|
52
|
+
try {
|
|
53
|
+
const args = JSON.parse(jsonStr);
|
|
54
|
+
toolCalls.push({
|
|
55
|
+
toolUseId: crypto.randomUUID(),
|
|
56
|
+
name,
|
|
57
|
+
arguments: args,
|
|
58
|
+
});
|
|
59
|
+
removals.push({ start: match.index, end: afterJson + 1 });
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
// Malformed JSON — skip this match
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
match = BRACKET_PATTERN.exec(text);
|
|
69
|
+
}
|
|
70
|
+
// Build cleaned text by removing matched bracket patterns (reverse order to preserve indices)
|
|
71
|
+
let cleanedText = text;
|
|
72
|
+
for (let i = removals.length - 1; i >= 0; i--) {
|
|
73
|
+
const { start, end } = removals[i];
|
|
74
|
+
cleanedText = cleanedText.substring(0, start) + cleanedText.substring(end);
|
|
75
|
+
}
|
|
76
|
+
return { toolCalls, cleanedText };
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=bracket-tool-parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bracket-tool-parser.js","sourceRoot":"","sources":["../src/bracket-tool-parser.ts"],"names":[],"mappings":"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"}
|
package/dist/cost.d.ts
ADDED
package/dist/cost.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// ABOUTME: Cost attribution over the neutral model descriptor.
|
|
2
|
+
// ABOUTME: Each host ships its own calculator; the core repeats it so the seam stays one-way.
|
|
3
|
+
const PER_MILLION = 1_000_000;
|
|
4
|
+
/** Fill in {@link KiroUsage.cost} from the model's per-million rates. */
|
|
5
|
+
export function calculateKiroCost(cost, usage) {
|
|
6
|
+
const input = (usage.input * cost.input) / PER_MILLION;
|
|
7
|
+
const output = (usage.output * cost.output) / PER_MILLION;
|
|
8
|
+
return { input, output, cacheRead: 0, cacheWrite: 0, total: input + output };
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=cost.js.map
|
package/dist/cost.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cost.js","sourceRoot":"","sources":["../src/cost.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,8FAA8F;AAI9F,MAAM,WAAW,GAAG,SAAS,CAAC;AAE9B,yEAAyE;AACzE,MAAM,UAAU,iBAAiB,CAAC,IAAc,EAAE,KAAgB;IAChE,MAAM,KAAK,GAAG,CAAC,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,WAAW,CAAC;IACvD,MAAM,MAAM,GAAG,CAAC,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,WAAW,CAAC;IAC1D,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,KAAK,EAAE,KAAK,GAAG,MAAM,EAAE,CAAC;AAC/E,CAAC"}
|
package/dist/debug.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export declare function debugEnabled(): boolean;
|
|
2
|
+
export declare function debugLog(section: string, data?: unknown): void;
|
|
3
|
+
/** Remove credentials and profile identities from text before exposing it in logs or errors. */
|
|
4
|
+
export declare function redactSensitiveText(value: string): string;
|
|
5
|
+
/** Return a safe message for an unknown caught value. */
|
|
6
|
+
export declare function formatSafeError(error: unknown): string;
|
package/dist/debug.js
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
// ABOUTME: Debug logging — dumps requests, responses, stream events, and errors
|
|
2
|
+
// ABOUTME: to a log file when KIRO_DEBUG=1. Custom path via KIRO_DEBUG_LOG.
|
|
3
|
+
import { appendFileSync, mkdirSync } from "node:fs";
|
|
4
|
+
import { homedir } from "node:os";
|
|
5
|
+
import { dirname, join } from "node:path";
|
|
6
|
+
const ENABLED = !!process.env.KIRO_DEBUG && process.env.KIRO_DEBUG !== "0";
|
|
7
|
+
const LOG_FILE = process.env.KIRO_DEBUG_LOG || join(homedir(), ".ns-kiro-provider", "logs", "kiro-debug.log");
|
|
8
|
+
let dirReady = false;
|
|
9
|
+
export function debugEnabled() {
|
|
10
|
+
return ENABLED;
|
|
11
|
+
}
|
|
12
|
+
export function debugLog(section, data) {
|
|
13
|
+
if (!ENABLED)
|
|
14
|
+
return;
|
|
15
|
+
try {
|
|
16
|
+
if (!dirReady) {
|
|
17
|
+
mkdirSync(dirname(LOG_FILE), { recursive: true });
|
|
18
|
+
dirReady = true;
|
|
19
|
+
}
|
|
20
|
+
const ts = new Date().toISOString();
|
|
21
|
+
const body = data === undefined
|
|
22
|
+
? ""
|
|
23
|
+
: typeof data === "string"
|
|
24
|
+
? ` ${redactSensitiveText(data)}`
|
|
25
|
+
: ` ${JSON.stringify(data, redact, 2)}`;
|
|
26
|
+
appendFileSync(LOG_FILE, `${ts} [${section}]${body}\n`);
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
// best-effort; never break the provider
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
const PROFILE_ARN_PATTERN = /arn:[a-z0-9-]+:codewhisperer:[^:\s"']*:[^:\s"']*:profile\/[^\s"',}\]]+/gi;
|
|
33
|
+
const BEARER_TOKEN_PATTERN = /(\bBearer\s+)[^\s"',}\]]+/gi;
|
|
34
|
+
const QUOTED_SECRET_PATTERN = /(["'](?:access|refresh|authorization|access[_-]?token|refresh[_-]?token|client[_-]?secret)["']\s*:\s*["'])[^"']*(["'])/gi;
|
|
35
|
+
const ASSIGNED_SECRET_PATTERN = /(\b(?:access[_-]?token|refresh[_-]?token|client[_-]?secret)\s*=\s*)[^\s,;&]+/gi;
|
|
36
|
+
/** Remove credentials and profile identities from text before exposing it in logs or errors. */
|
|
37
|
+
export function redactSensitiveText(value) {
|
|
38
|
+
return value
|
|
39
|
+
.replace(QUOTED_SECRET_PATTERN, "$1<redacted>$2")
|
|
40
|
+
.replace(ASSIGNED_SECRET_PATTERN, "$1<redacted>")
|
|
41
|
+
.replace(BEARER_TOKEN_PATTERN, "$1<redacted>")
|
|
42
|
+
.replace(PROFILE_ARN_PATTERN, "<redacted-profile-arn>");
|
|
43
|
+
}
|
|
44
|
+
/** Return a safe message for an unknown caught value. */
|
|
45
|
+
export function formatSafeError(error) {
|
|
46
|
+
return redactSensitiveText(error instanceof Error ? error.message : String(error));
|
|
47
|
+
}
|
|
48
|
+
/** Redact auth tokens and profile identities in structured debug output. */
|
|
49
|
+
function redact(key, value) {
|
|
50
|
+
if (typeof value !== "string")
|
|
51
|
+
return value;
|
|
52
|
+
const normalizedKey = key.toLowerCase().replaceAll("_", "").replaceAll("-", "");
|
|
53
|
+
if (normalizedKey === "authorization" ||
|
|
54
|
+
normalizedKey === "access" ||
|
|
55
|
+
normalizedKey === "refresh" ||
|
|
56
|
+
normalizedKey === "profilearn" ||
|
|
57
|
+
normalizedKey.includes("token") ||
|
|
58
|
+
normalizedKey.includes("secret")) {
|
|
59
|
+
return normalizedKey === "profilearn" ? "<redacted-profile-arn>" : "<redacted>";
|
|
60
|
+
}
|
|
61
|
+
return redactSensitiveText(value);
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=debug.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"debug.js","sourceRoot":"","sources":["../src/debug.ts"],"names":[],"mappings":"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"}
|
package/dist/effort.d.ts
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { type KiroEffort, type KiroModelSpec } from "./types.js";
|
|
2
|
+
export type KiroEffortField = "reasoning" | "output_config";
|
|
3
|
+
export interface KiroEffortConfig {
|
|
4
|
+
field: KiroEffortField;
|
|
5
|
+
values: readonly string[];
|
|
6
|
+
summarizedThinking: boolean;
|
|
7
|
+
}
|
|
8
|
+
export type KiroAdditionalModelRequestFields = {
|
|
9
|
+
reasoning: {
|
|
10
|
+
effort: string;
|
|
11
|
+
};
|
|
12
|
+
} | {
|
|
13
|
+
output_config: {
|
|
14
|
+
effort: string;
|
|
15
|
+
};
|
|
16
|
+
thinking: {
|
|
17
|
+
type: "adaptive";
|
|
18
|
+
display?: "summarized";
|
|
19
|
+
};
|
|
20
|
+
};
|
|
21
|
+
/** Derive Kiro's structured effort field and allowed enum from an authenticated catalog schema. */
|
|
22
|
+
export declare function deriveKiroEffort(schema: unknown): KiroEffortConfig | undefined;
|
|
23
|
+
/** Known-model compatibility used only before catalog schema metadata is available. */
|
|
24
|
+
export declare function fallbackKiroEffort(kiroModelId: string): KiroEffortConfig | undefined;
|
|
25
|
+
/** Prefer catalog schema; fall back only when it is absent. */
|
|
26
|
+
export declare function getKiroEffortConfig(schema: unknown, kiroModelId: string): KiroEffortConfig | undefined;
|
|
27
|
+
/**
|
|
28
|
+
* Clamp a requested effort to what the model declares. Hosts each ship their
|
|
29
|
+
* own clamp over their own model type; the core repeats it over
|
|
30
|
+
* {@link KiroModelSpec} so a projection is the only thing an adapter owes.
|
|
31
|
+
*/
|
|
32
|
+
export declare function clampKiroEffort(model: KiroModelSpec, requested: KiroEffort | undefined): KiroEffort | undefined;
|
|
33
|
+
/** Map a clamped effort onto a value present in the selected model's Kiro enum. */
|
|
34
|
+
export declare function mapEffortToKiroValue(model: KiroModelSpec, level: KiroEffort, config: KiroEffortConfig): string | undefined;
|
|
35
|
+
/** Build the top-level Kiro runtime field for one requested reasoning level. */
|
|
36
|
+
export declare function buildKiroAdditionalModelRequestFields(model: KiroModelSpec, kiroModelId: string, level: KiroEffort | undefined): KiroAdditionalModelRequestFields | undefined;
|
package/dist/effort.js
ADDED
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
// Structured reasoning-effort handling for Kiro runtime requests.
|
|
2
|
+
import { KIRO_EFFORT_ORDER } from "./types.js";
|
|
3
|
+
const GPT_EFFORT_VALUES = ["low", "medium", "high", "xhigh"];
|
|
4
|
+
const CLAUDE_EXTENDED_EFFORT_VALUES = ["low", "medium", "high", "xhigh", "max"];
|
|
5
|
+
const CLAUDE_MAX_EFFORT_VALUES = ["low", "medium", "high", "max"];
|
|
6
|
+
const CLAUDE_EXTENDED_EFFORT_MODELS = new Set([
|
|
7
|
+
"claude-opus-4.8",
|
|
8
|
+
"claude-opus-4.7",
|
|
9
|
+
"claude-sonnet-5",
|
|
10
|
+
"claude-fable-5",
|
|
11
|
+
]);
|
|
12
|
+
const CLAUDE_MAX_EFFORT_MODELS = new Set([
|
|
13
|
+
"claude-opus-4.6",
|
|
14
|
+
"claude-sonnet-4.6",
|
|
15
|
+
"claude-opus-4.6-1m",
|
|
16
|
+
"claude-sonnet-4.6-1m",
|
|
17
|
+
]);
|
|
18
|
+
function isRecord(value) {
|
|
19
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
20
|
+
}
|
|
21
|
+
/** Derive Kiro's structured effort field and allowed enum from an authenticated catalog schema. */
|
|
22
|
+
export function deriveKiroEffort(schema) {
|
|
23
|
+
if (!isRecord(schema) || !isRecord(schema.properties))
|
|
24
|
+
return undefined;
|
|
25
|
+
for (const field of ["reasoning", "output_config"]) {
|
|
26
|
+
const fieldSchema = schema.properties[field];
|
|
27
|
+
if (!isRecord(fieldSchema) || !isRecord(fieldSchema.properties))
|
|
28
|
+
continue;
|
|
29
|
+
const effortSchema = fieldSchema.properties.effort;
|
|
30
|
+
if (!isRecord(effortSchema) || !Array.isArray(effortSchema.enum) || effortSchema.enum.length === 0)
|
|
31
|
+
continue;
|
|
32
|
+
if (!effortSchema.enum.every((value) => typeof value === "string" && value.length > 0))
|
|
33
|
+
continue;
|
|
34
|
+
const thinkingSchema = schema.properties.thinking;
|
|
35
|
+
const displaySchema = isRecord(thinkingSchema) && isRecord(thinkingSchema.properties) ? thinkingSchema.properties.display : undefined;
|
|
36
|
+
const summarizedThinking = isRecord(displaySchema) && Array.isArray(displaySchema.enum) && displaySchema.enum.includes("summarized");
|
|
37
|
+
return { field, values: [...new Set(effortSchema.enum)], summarizedThinking };
|
|
38
|
+
}
|
|
39
|
+
return undefined;
|
|
40
|
+
}
|
|
41
|
+
/** Known-model compatibility used only before catalog schema metadata is available. */
|
|
42
|
+
export function fallbackKiroEffort(kiroModelId) {
|
|
43
|
+
const normalizedId = kiroModelId.toLowerCase().replace(/(\d)-(\d)/g, "$1.$2");
|
|
44
|
+
if (normalizedId.startsWith("openai-gpt")) {
|
|
45
|
+
return { field: "reasoning", values: GPT_EFFORT_VALUES, summarizedThinking: false };
|
|
46
|
+
}
|
|
47
|
+
if (CLAUDE_EXTENDED_EFFORT_MODELS.has(normalizedId)) {
|
|
48
|
+
return { field: "output_config", values: CLAUDE_EXTENDED_EFFORT_VALUES, summarizedThinking: true };
|
|
49
|
+
}
|
|
50
|
+
if (CLAUDE_MAX_EFFORT_MODELS.has(normalizedId)) {
|
|
51
|
+
return { field: "output_config", values: CLAUDE_MAX_EFFORT_VALUES, summarizedThinking: false };
|
|
52
|
+
}
|
|
53
|
+
return undefined;
|
|
54
|
+
}
|
|
55
|
+
/** Prefer catalog schema; fall back only when it is absent. */
|
|
56
|
+
export function getKiroEffortConfig(schema, kiroModelId) {
|
|
57
|
+
if (schema !== undefined)
|
|
58
|
+
return deriveKiroEffort(schema);
|
|
59
|
+
return fallbackKiroEffort(kiroModelId);
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Clamp a requested effort to what the model declares. Hosts each ship their
|
|
63
|
+
* own clamp over their own model type; the core repeats it over
|
|
64
|
+
* {@link KiroModelSpec} so a projection is the only thing an adapter owes.
|
|
65
|
+
*/
|
|
66
|
+
export function clampKiroEffort(model, requested) {
|
|
67
|
+
if (!requested || !model.reasoning)
|
|
68
|
+
return undefined;
|
|
69
|
+
const supported = model.efforts;
|
|
70
|
+
if (!supported || supported.length === 0)
|
|
71
|
+
return requested;
|
|
72
|
+
if (supported.includes(requested))
|
|
73
|
+
return requested;
|
|
74
|
+
// Nearest supported neighbour, preferring the more intensive side so a
|
|
75
|
+
// request for more thinking is never silently answered with less than the
|
|
76
|
+
// model's own minimum.
|
|
77
|
+
const requestedRank = KIRO_EFFORT_ORDER.indexOf(requested);
|
|
78
|
+
let best;
|
|
79
|
+
let bestDistance = Number.POSITIVE_INFINITY;
|
|
80
|
+
for (const candidate of supported) {
|
|
81
|
+
const distance = Math.abs(KIRO_EFFORT_ORDER.indexOf(candidate) - requestedRank);
|
|
82
|
+
if (distance < bestDistance) {
|
|
83
|
+
best = candidate;
|
|
84
|
+
bestDistance = distance;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return best;
|
|
88
|
+
}
|
|
89
|
+
/** Map a clamped effort onto a value present in the selected model's Kiro enum. */
|
|
90
|
+
export function mapEffortToKiroValue(model, level, config) {
|
|
91
|
+
if (config.values.length === 0)
|
|
92
|
+
return undefined;
|
|
93
|
+
const explicitlyMapped = model.effortMap?.[level];
|
|
94
|
+
if (typeof explicitlyMapped === "string" && config.values.includes(explicitlyMapped)) {
|
|
95
|
+
return explicitlyMapped;
|
|
96
|
+
}
|
|
97
|
+
const target = level === "minimal" ? "low" : level;
|
|
98
|
+
if (config.values.includes(target))
|
|
99
|
+
return target;
|
|
100
|
+
const targetIndex = KIRO_EFFORT_ORDER.indexOf(target);
|
|
101
|
+
if (targetIndex >= 0) {
|
|
102
|
+
for (let index = targetIndex; index < KIRO_EFFORT_ORDER.length; index++) {
|
|
103
|
+
const candidate = KIRO_EFFORT_ORDER[index];
|
|
104
|
+
if (candidate && config.values.includes(candidate))
|
|
105
|
+
return candidate;
|
|
106
|
+
}
|
|
107
|
+
for (let index = targetIndex - 1; index >= 0; index--) {
|
|
108
|
+
const candidate = KIRO_EFFORT_ORDER[index];
|
|
109
|
+
if (candidate && config.values.includes(candidate))
|
|
110
|
+
return candidate;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
return config.values[0];
|
|
114
|
+
}
|
|
115
|
+
/** Build the top-level Kiro runtime field for one requested reasoning level. */
|
|
116
|
+
export function buildKiroAdditionalModelRequestFields(model, kiroModelId, level) {
|
|
117
|
+
if (!level || !model.reasoning)
|
|
118
|
+
return undefined;
|
|
119
|
+
const config = getKiroEffortConfig(model.additionalModelRequestFieldsSchema, kiroModelId);
|
|
120
|
+
if (!config)
|
|
121
|
+
return undefined;
|
|
122
|
+
const clamped = clampKiroEffort(model, level);
|
|
123
|
+
if (!clamped)
|
|
124
|
+
return undefined;
|
|
125
|
+
const effort = mapEffortToKiroValue(model, clamped, config);
|
|
126
|
+
if (!effort)
|
|
127
|
+
return undefined;
|
|
128
|
+
return config.field === "output_config"
|
|
129
|
+
? {
|
|
130
|
+
output_config: { effort },
|
|
131
|
+
thinking: {
|
|
132
|
+
type: "adaptive",
|
|
133
|
+
...(config.summarizedThinking ? { display: "summarized" } : {}),
|
|
134
|
+
},
|
|
135
|
+
}
|
|
136
|
+
: { reasoning: { effort } };
|
|
137
|
+
}
|
|
138
|
+
//# sourceMappingURL=effort.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"effort.js","sourceRoot":"","sources":["../src/effort.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export interface KiroEndpoints {
|
|
2
|
+
region: string;
|
|
3
|
+
management: string;
|
|
4
|
+
runtime: string;
|
|
5
|
+
}
|
|
6
|
+
export declare function resolveApiRegion(ssoRegion: string | undefined): string;
|
|
7
|
+
export declare function getKiroEndpoints(region: string): KiroEndpoints;
|
|
8
|
+
export declare function getKiroRegionFromEndpoint(endpoint: string): string | undefined;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
// ABOUTME: Resolves Kiro API regions and constructs current-service endpoints.
|
|
2
|
+
// ABOUTME: Keeps management and runtime host selection independent from request URLs.
|
|
3
|
+
const API_REGION_MAP = {
|
|
4
|
+
"us-west-1": "us-east-1",
|
|
5
|
+
"us-west-2": "us-east-1",
|
|
6
|
+
"us-east-2": "us-east-1",
|
|
7
|
+
"ap-southeast-1": "us-east-1",
|
|
8
|
+
"ap-southeast-2": "us-east-1",
|
|
9
|
+
"ap-northeast-1": "us-east-1",
|
|
10
|
+
"ap-south-1": "us-east-1",
|
|
11
|
+
"eu-west-1": "eu-central-1",
|
|
12
|
+
"eu-west-2": "eu-central-1",
|
|
13
|
+
"eu-west-3": "eu-central-1",
|
|
14
|
+
"eu-north-1": "eu-central-1",
|
|
15
|
+
"eu-south-1": "eu-central-1",
|
|
16
|
+
"eu-south-2": "eu-central-1",
|
|
17
|
+
"eu-central-2": "eu-central-1",
|
|
18
|
+
};
|
|
19
|
+
export function resolveApiRegion(ssoRegion) {
|
|
20
|
+
if (!ssoRegion)
|
|
21
|
+
return "us-east-1";
|
|
22
|
+
return API_REGION_MAP[ssoRegion] ?? ssoRegion;
|
|
23
|
+
}
|
|
24
|
+
export function getKiroEndpoints(region) {
|
|
25
|
+
return {
|
|
26
|
+
region,
|
|
27
|
+
management: `https://management.${region}.kiro.dev/`,
|
|
28
|
+
runtime: `https://runtime.${region}.kiro.dev/`,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
export function getKiroRegionFromEndpoint(endpoint) {
|
|
32
|
+
try {
|
|
33
|
+
const [service, region, ...suffix] = new URL(endpoint).hostname.split(".");
|
|
34
|
+
const domain = suffix.join(".");
|
|
35
|
+
if ((service === "management" || service === "runtime") && domain === "kiro.dev")
|
|
36
|
+
return region;
|
|
37
|
+
return undefined;
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
return undefined;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=endpoints.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"endpoints.js","sourceRoot":"","sources":["../src/endpoints.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,sFAAsF;AAEtF,MAAM,cAAc,GAA2B;IAC7C,WAAW,EAAE,WAAW;IACxB,WAAW,EAAE,WAAW;IACxB,WAAW,EAAE,WAAW;IACxB,gBAAgB,EAAE,WAAW;IAC7B,gBAAgB,EAAE,WAAW;IAC7B,gBAAgB,EAAE,WAAW;IAC7B,YAAY,EAAE,WAAW;IACzB,WAAW,EAAE,cAAc;IAC3B,WAAW,EAAE,cAAc;IAC3B,WAAW,EAAE,cAAc;IAC3B,YAAY,EAAE,cAAc;IAC5B,YAAY,EAAE,cAAc;IAC5B,YAAY,EAAE,cAAc;IAC5B,cAAc,EAAE,cAAc;CAC/B,CAAC;AAQF,MAAM,UAAU,gBAAgB,CAAC,SAA6B;IAC5D,IAAI,CAAC,SAAS;QAAE,OAAO,WAAW,CAAC;IACnC,OAAO,cAAc,CAAC,SAAS,CAAC,IAAI,SAAS,CAAC;AAChD,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,MAAc;IAC7C,OAAO;QACL,MAAM;QACN,UAAU,EAAE,sBAAsB,MAAM,YAAY;QACpD,OAAO,EAAE,mBAAmB,MAAM,YAAY;KAC/C,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,yBAAyB,CAAC,QAAgB;IACxD,IAAI,CAAC;QACH,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC3E,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAChC,IAAI,CAAC,OAAO,KAAK,YAAY,IAAI,OAAO,KAAK,SAAS,CAAC,IAAI,MAAM,KAAK,UAAU;YAAE,OAAO,MAAM,CAAC;QAChG,OAAO,SAAS,CAAC;IACnB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC"}
|