@magpie-community/opencode-kiro-auth 0.1.7 → 0.1.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/README.md +3 -1
- package/index.mjs +41 -9
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -73,7 +73,9 @@ request:
|
|
|
73
73
|
- The system prompt goes at the head of the first message.
|
|
74
74
|
- Tool calls and results are paired: an unanswered call gets an error
|
|
75
75
|
result, and a result longer than 250,000 characters is cut.
|
|
76
|
-
- Tool ids Kiro wouldn't take are rewritten.
|
|
76
|
+
- Tool ids Kiro wouldn't take are rewritten. A tool name over 64
|
|
77
|
+
characters (an MCP plugin's, in Claude Code) is sent shortened with a
|
|
78
|
+
hash and its calls come back under the full name.
|
|
77
79
|
- Only the latest images are sent.
|
|
78
80
|
- Tools the history used but the request doesn't offer are declared.
|
|
79
81
|
- It turns the AWS event stream Kiro answers with back into Messages'
|
package/index.mjs
CHANGED
|
@@ -576,6 +576,36 @@ const TOOL_ID = /^[a-zA-Z0-9_.:-]{1,64}$/
|
|
|
576
576
|
// one of Kiro's own, the same each time.
|
|
577
577
|
const toolID = (id) => (TOOL_ID.test(id ?? "") ? id : "t_" + createHash("sha256").update(String(id ?? "")).digest("base64url").slice(0, 32))
|
|
578
578
|
|
|
579
|
+
// Kiro answers a tool named past 64 characters, or outside these, "Invalid
|
|
580
|
+
// tool use format." and won't raise the limit (kirodotdev/Kiro#7684), while
|
|
581
|
+
// MCP tools in Claude Code are named mcp__plugin_<plugin>_<server>__<tool>
|
|
582
|
+
// (yetone/magpie#1393).
|
|
583
|
+
const TOOL_NAME = /^[a-zA-Z0-9_-]{1,64}$/
|
|
584
|
+
|
|
585
|
+
// toolName is a tool's name as Kiro takes one: another is its head with a
|
|
586
|
+
// hash of the whole name, the same each time, so the conversation's later
|
|
587
|
+
// turns name it the same way. toolNames maps each such name back.
|
|
588
|
+
const toolName = (name) => {
|
|
589
|
+
const n = String(name ?? "")
|
|
590
|
+
if (TOOL_NAME.test(n)) return n
|
|
591
|
+
const hash = createHash("sha256").update(n).digest("hex").slice(0, 12)
|
|
592
|
+
return n.replace(/[^a-zA-Z0-9_-]/g, "_").slice(0, 64 - 1 - hash.length) + "_" + hash
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
// toolNames is the name the caller knows for each tool a request names
|
|
596
|
+
// that Kiro is sent under another name.
|
|
597
|
+
function toolNames(req) {
|
|
598
|
+
const names = new Map()
|
|
599
|
+
const add = (n) => {
|
|
600
|
+
if (typeof n !== "string" || !n) return
|
|
601
|
+
const k = toolName(n)
|
|
602
|
+
if (k !== n) names.set(k, n)
|
|
603
|
+
}
|
|
604
|
+
for (const t of req.tools ?? []) add(t?.name)
|
|
605
|
+
for (const m of req.messages ?? []) if (Array.isArray(m.content)) for (const p of m.content) if (p?.type === "tool_use") add(p.name)
|
|
606
|
+
return names
|
|
607
|
+
}
|
|
608
|
+
|
|
579
609
|
function imageFormat(mediaType) {
|
|
580
610
|
const t = String(mediaType ?? "").toLowerCase()
|
|
581
611
|
const f = t.replace(/^image\//, "")
|
|
@@ -620,7 +650,7 @@ function buildKiro(req, model, profile, budget) {
|
|
|
620
650
|
if (p?.type === "text" && p.text) texts.push(p.text)
|
|
621
651
|
else if (p?.type === "tool_use") {
|
|
622
652
|
const input = p.input && typeof p.input === "object" && !Array.isArray(p.input) ? p.input : {}
|
|
623
|
-
a.toolUses.push({ name: p.name, toolUseId: toolID(p.id), input })
|
|
653
|
+
a.toolUses.push({ name: toolName(p.name), toolUseId: toolID(p.id), input })
|
|
624
654
|
}
|
|
625
655
|
}
|
|
626
656
|
a.content = texts.join("\n\n")
|
|
@@ -719,8 +749,9 @@ function buildKiro(req, model, profile, budget) {
|
|
|
719
749
|
const EMPTY = { type: "object", properties: {} }
|
|
720
750
|
for (const t of req.tools ?? []) {
|
|
721
751
|
if (!t?.name || (t.type && t.type !== "custom" && !t.input_schema)) continue // server tools Kiro hasn't
|
|
722
|
-
|
|
723
|
-
|
|
752
|
+
const name = toolName(t.name)
|
|
753
|
+
offered.add(name)
|
|
754
|
+
tools.push({ toolSpecification: { name, description: t.description || t.name, inputSchema: { json: t.input_schema ?? EMPTY } } })
|
|
724
755
|
}
|
|
725
756
|
for (const e of entries)
|
|
726
757
|
for (const c of e.assistantResponseMessage?.toolUses ?? [])
|
|
@@ -1047,8 +1078,9 @@ const QUOTA_WORDS = /quota|insufficient|balance|credit|billing|exceeded|rate.?li
|
|
|
1047
1078
|
const failedBefore = (text) => errorResponse(QUOTA_WORDS.test(text) ? 429 : 502, text)
|
|
1048
1079
|
|
|
1049
1080
|
// reply answers the Messages request from Kiro's events: a stream of
|
|
1050
|
-
// Messages' events, or one message.
|
|
1051
|
-
|
|
1081
|
+
// Messages' events, or one message. names gives back the caller's name of
|
|
1082
|
+
// a tool Kiro was sent under another (toolNames).
|
|
1083
|
+
async function reply(it, model, stream, names = new Map()) {
|
|
1052
1084
|
const id = "msg_" + randomBytes(12).toString("hex")
|
|
1053
1085
|
if (!stream) {
|
|
1054
1086
|
const content = []
|
|
@@ -1066,7 +1098,7 @@ async function reply(it, model, stream) {
|
|
|
1066
1098
|
else add({ type: "thinking", thinking: e.text, signature: "" })
|
|
1067
1099
|
} else if (e.kind === "sig") {
|
|
1068
1100
|
if (last?.type === "thinking") last.signature += e.text
|
|
1069
|
-
} else if (e.kind === "toolStart") add({ type: "tool_use", id: e.id, name: e.name, input: "" })
|
|
1101
|
+
} else if (e.kind === "toolStart") add({ type: "tool_use", id: e.id, name: names.get(e.name) ?? e.name, input: "" })
|
|
1070
1102
|
else if (e.kind === "toolArgs") {
|
|
1071
1103
|
if (last?.type === "tool_use") last.input += e.text
|
|
1072
1104
|
} else if (e.kind === "error") {
|
|
@@ -1127,7 +1159,7 @@ async function reply(it, model, stream) {
|
|
|
1127
1159
|
if (open === "thinking") ctl.enqueue(sse("content_block_delta", { index, delta: { type: "signature_delta", signature: e.text } }))
|
|
1128
1160
|
break
|
|
1129
1161
|
case "toolStart":
|
|
1130
|
-
begin("tool", { type: "tool_use", id: e.id, name: e.name, input: {} })
|
|
1162
|
+
begin("tool", { type: "tool_use", id: e.id, name: names.get(e.name) ?? e.name, input: {} })
|
|
1131
1163
|
break
|
|
1132
1164
|
case "toolArgs":
|
|
1133
1165
|
if (open === "tool") ctl.enqueue(sse("content_block_delta", { index, delta: { type: "input_json_delta", partial_json: e.text } }))
|
|
@@ -1189,7 +1221,7 @@ async function generate(creds, auth, req, signal) {
|
|
|
1189
1221
|
const f = failure(res.status, (await res.text()).slice(0, 1 << 20))
|
|
1190
1222
|
return errorResponse(f.status, f.message)
|
|
1191
1223
|
}
|
|
1192
|
-
return kept(await reply(events(res.body, model, budget), model, req.stream === true))
|
|
1224
|
+
return kept(await reply(events(res.body, model, budget), model, req.stream === true, toolNames(req)))
|
|
1193
1225
|
}
|
|
1194
1226
|
|
|
1195
1227
|
// ---- signing in ----------------------------------------------------------------------
|
|
@@ -1453,4 +1485,4 @@ export async function KiroAuthPlugin({ client } = {}) {
|
|
|
1453
1485
|
}
|
|
1454
1486
|
|
|
1455
1487
|
// for tests
|
|
1456
|
-
export const _internal = { generate, refresh, usageOf, buildKiro, events, reply, failure, toolID, thinking, readCLI, readIDE, regionOf, planName, frames }
|
|
1488
|
+
export const _internal = { generate, refresh, usageOf, buildKiro, events, reply, failure, toolID, toolName, toolNames, thinking, readCLI, readIDE, regionOf, planName, frames }
|