@magpie-community/opencode-kiro-auth 0.1.3 → 0.1.4

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.
Files changed (2) hide show
  1. package/index.mjs +37 -12
  2. package/package.json +1 -1
package/index.mjs CHANGED
@@ -952,6 +952,19 @@ async function* events(body, model, budget) {
952
952
  yield { kind: "stop", reason, usage }
953
953
  }
954
954
 
955
+ // finished is the message's blocks with each call's arguments read.
956
+ function finished(content) {
957
+ for (const b of content)
958
+ if (b.type === "tool_use") {
959
+ try {
960
+ b.input = b.input ? JSON.parse(b.input) : {}
961
+ } catch {
962
+ b.input = {}
963
+ }
964
+ }
965
+ return content
966
+ }
967
+
955
968
  const anthropicUsage = (u) => ({
956
969
  input_tokens: u.input,
957
970
  output_tokens: u.output,
@@ -959,6 +972,16 @@ const anthropicUsage = (u) => ({
959
972
  cache_creation_input_tokens: u.cacheWrite,
960
973
  })
961
974
 
975
+ // quotaWords are magpie's (internal/gateway/fallback.go): how a vendor says
976
+ // "out of quota" or "slow down".
977
+ const QUOTA_WORDS = /quota|insufficient|balance|credit|billing|exceeded|rate.?limit|usage.?limit|limit.?reached|hit your .*limit|limit.{0,24}resets|too many requests|overloaded|余额|额度|欠费|限流|频率|套餐|用量|上限/i
978
+
979
+ // failedBefore is the reply to an error before any of the answer, as
980
+ // magpie's built-in relay gives it: a status, not a stream, so another
981
+ // account can take over — a 429 when it reads as a quota or rate limit,
982
+ // else a 502.
983
+ const failedBefore = (text) => errorResponse(QUOTA_WORDS.test(text) ? 429 : 502, text)
984
+
962
985
  // reply answers the Messages request from Kiro's events: a stream of
963
986
  // Messages' events, or one message.
964
987
  async function reply(it, model, stream) {
@@ -982,23 +1005,24 @@ async function reply(it, model, stream) {
982
1005
  } else if (e.kind === "toolStart") add({ type: "tool_use", id: e.id, name: e.name, input: "" })
983
1006
  else if (e.kind === "toolArgs") {
984
1007
  if (last?.type === "tool_use") last.input += e.text
985
- } else if (e.kind === "error") return errorResponse(502, e.text)
986
- else if (e.kind === "stop") {
987
- for (const b of content)
988
- if (b.type === "tool_use") {
989
- try {
990
- b.input = b.input ? JSON.parse(b.input) : {}
991
- } catch {
992
- b.input = {}
993
- }
994
- }
995
- return Response.json({ id, type: "message", role: "assistant", model, content, stop_reason: e.reason, stop_sequence: null,
1008
+ } else if (e.kind === "error") {
1009
+ // with none of the answer said, a status; else what was said
1010
+ if (!content.length) return failedBefore(e.text)
1011
+ return Response.json({ id, type: "message", role: "assistant", model, content: finished(content), stop_reason: "end_turn",
1012
+ stop_sequence: null, usage: anthropicUsage({ input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }) })
1013
+ } else if (e.kind === "stop") {
1014
+ return Response.json({ id, type: "message", role: "assistant", model, content: finished(content), stop_reason: e.reason, stop_sequence: null,
996
1015
  usage: anthropicUsage(e.usage) })
997
1016
  }
998
1017
  }
999
1018
  return errorResponse(502, "the reply ended before it was complete")
1000
1019
  }
1001
1020
 
1021
+ // an error before any of the answer is a status, as the built-in's
1022
+ const head = await it.next()
1023
+ if (head.value?.kind === "error") return failedBefore(head.value.text)
1024
+ let pending = head
1025
+
1002
1026
  const enc = new TextEncoder()
1003
1027
  const sse = (type, data) => enc.encode(`event: ${type}\ndata: ${JSON.stringify({ type, ...data })}\n\n`)
1004
1028
  let index = -1
@@ -1022,7 +1046,8 @@ async function reply(it, model, stream) {
1022
1046
  open = kind
1023
1047
  ctl.enqueue(sse("content_block_start", { index, content_block: block }))
1024
1048
  }
1025
- const r = await it.next()
1049
+ const r = pending ?? (await it.next())
1050
+ pending = null
1026
1051
  if (r.done) return ctl.close()
1027
1052
  const e = r.value
1028
1053
  switch (e.kind) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@magpie-community/opencode-kiro-auth",
3
- "version": "0.1.3",
3
+ "version": "0.1.4",
4
4
  "description": "Kiro subscriptions (Free, Pro, Pro+, Power) in OpenCode and magpie",
5
5
  "type": "module",
6
6
  "main": "./index.mjs",