@magpie-community/opencode-kiro-auth 0.1.23 → 0.1.24

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 (3) hide show
  1. package/README.md +4 -1
  2. package/index.mjs +30 -5
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -152,7 +152,10 @@ request:
152
152
  - Anthropic's hosted web search is answered with Kiro's own web search
153
153
  (see [Web search](#web-search)).
154
154
  - Kiro's failures keep their meaning:
155
- - input too long → 400
155
+ - input too long → 400 "input is too long for the model's context", whether
156
+ Kiro says it as an HTTP answer, as an exception in the stream, or by
157
+ stopping with `MODEL_CONTEXT_WINDOW_EXCEEDED` before a word (after some
158
+ of the reply, it ends with stop reason `model_context_window_exceeded`)
156
159
  - no capacity → 503
157
160
  - usage limit → 429
158
161
  - throttling → "rate limited"
package/index.mjs CHANGED
@@ -1155,6 +1155,16 @@ function sendKiro(a, body, signal) {
1155
1155
  })
1156
1156
  }
1157
1157
 
1158
+ // tooLongSaid is whether Kiro's words say the conversation is past the
1159
+ // model's window: its ValidationException "Input is too long." with reason
1160
+ // CONTENT_LENGTH_EXCEEDS_THRESHOLD, as an HTTP answer or as an exception
1161
+ // in the event stream, or a reply it stopped with MODEL_CONTEXT_WINDOW_EXCEEDED.
1162
+ const tooLongSaid = (msg) => /CONTENT_LENGTH_EXCEEDS_THRESHOLD|MODEL_CONTEXT_WINDOW_EXCEEDED|input is too long/i.test(msg)
1163
+ // TOO_LONG heads a too-long failure in the words magpie's gateway takes
1164
+ // for one (tooLong): another member with a larger window is asked, no
1165
+ // account rests, and with none left the agent is told to compact.
1166
+ const TOO_LONG = "input is too long for the model's context: "
1167
+
1158
1168
  // failure is the status and message for an error Kiro answered with:
1159
1169
  // {"message": "...", "reason": "..."}.
1160
1170
  function failure(status, body) {
@@ -1164,8 +1174,7 @@ function failure(status, body) {
1164
1174
  if (e?.message) msg = e.message + (e.reason ? ` (${e.reason})` : "")
1165
1175
  } catch {}
1166
1176
  msg ||= STATUS_TEXT[status] ?? ""
1167
- if (msg.includes("CONTENT_LENGTH_EXCEEDS_THRESHOLD") || msg.toLowerCase().includes("input is too long"))
1168
- return { status: 400, message: "input is too long for the model's context: " + msg }
1177
+ if (tooLongSaid(msg)) return { status: 400, message: TOO_LONG + msg }
1169
1178
  if (msg.includes("INSUFFICIENT_MODEL_CAPACITY")) return { status: 503, message: msg }
1170
1179
  if (msg.includes("MONTHLY_REQUEST_COUNT") || msg.includes("USAGE_LIMIT")) return { status: 429, message: "usage limit reached: " + msg }
1171
1180
  return { status, message: msg }
@@ -1413,8 +1422,15 @@ async function* events(body, model, budget) {
1413
1422
  // Kiro says how full the context is rather than how many tokens
1414
1423
  if (!usage.input && pct > 0 && window > 0) usage.input = Math.floor((pct / 100) * window)
1415
1424
  if (!usage.output) usage.output = Math.floor((said + 3) / 4)
1425
+ const full = /^model_context_window_exceeded$/i.test(stop)
1426
+ if (full && !said && !tools) {
1427
+ // stopped for the window before a word: the conversation doesn't fit
1428
+ yield { kind: "error", text: "the reply stopped as the model's context window was full (MODEL_CONTEXT_WINDOW_EXCEEDED)" }
1429
+ return
1430
+ }
1416
1431
  let reason = "end_turn"
1417
1432
  if (tools > 0) reason = "tool_use"
1433
+ else if (full) reason = "model_context_window_exceeded" // cut short, as Anthropic's API says it
1418
1434
  else if (/^max_tokens$/i.test(stop)) reason = "max_tokens"
1419
1435
  else if (/^content_filtered$/i.test(stop)) reason = "refusal"
1420
1436
  yield { kind: "stop", reason, usage }
@@ -1454,7 +1470,14 @@ const QUOTA_WORDS = /quota|insufficient|balance|credit|billing|exceeded|rate.?li
1454
1470
  // magpie's built-in relay gives it: a status, not a stream, so another
1455
1471
  // account can take over — a 429 when it reads as a quota or rate limit,
1456
1472
  // else a 502.
1457
- const failedBefore = (text) => errorResponse(QUOTA_WORDS.test(text) ? 429 : 502, text)
1473
+ //
1474
+ // A conversation past the model's window is a 400 that says so, whichever
1475
+ // way Kiro said it, before the quota words ("exceeded"): as a 502, magpie
1476
+ // rested the account, asked it again, and told a lone agent of a vendor
1477
+ // error, so it never compacted (ergou0954_54426 on Discord: Kiro in a
1478
+ // group routed by intent, "超出上下文", the turn failed).
1479
+ const failedBefore = (text) =>
1480
+ tooLongSaid(text) ? errorResponse(400, TOO_LONG + text) : errorResponse(QUOTA_WORDS.test(text) ? 429 : 502, text)
1458
1481
 
1459
1482
  // reply answers the Messages request from Kiro's events: a stream of
1460
1483
  // Messages' events, or one message. names gives back the caller's name of
@@ -1887,8 +1910,10 @@ async function* searching(creds, auth, req, model, budget, signal, hosted, first
1887
1910
  else said.push({ type: "text", text: e.text })
1888
1911
  }
1889
1912
  if (e.kind === "error") {
1890
- // in a turn after a search, a status, not a finished answer (reply)
1891
- yield turn > 1 ? { ...e, status: 502 } : e
1913
+ // in a turn after a search, a status, not a finished answer
1914
+ // (reply): one past the window says so, as failedBefore does
1915
+ if (turn > 1 && tooLongSaid(e.text)) yield { ...e, status: 400, text: TOO_LONG + e.text }
1916
+ else yield turn > 1 ? { ...e, status: 502 } : e
1892
1917
  return
1893
1918
  }
1894
1919
  yield e
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@magpie-community/opencode-kiro-auth",
3
- "version": "0.1.23",
3
+ "version": "0.1.24",
4
4
  "description": "Kiro subscriptions (Free, Pro, Pro+, Power) in OpenCode and magpie",
5
5
  "type": "module",
6
6
  "main": "./index.mjs",