Multi-user fixes, rework of #97 (kiro → kiro-auth with fallback), performance fixes, tool usage errors and Opus 4.8#100
Open
RvVeen wants to merge 21 commits into
Open
Multi-user fixes, rework of #97 (kiro → kiro-auth with fallback), performance fixes, tool usage errors and Opus 4.8#100RvVeen wants to merge 21 commits into
RvVeen wants to merge 21 commits into
Conversation
TextDecoder in streaming mode buffers incomplete multi-byte sequences. Added explicit flush after the read loop so nothing gets dropped.
Was using crypto.randomUUID() on every request, so each tool call counted as a new Kiro session. Now persisting the ID in kiro.db keyed on workspace + first user message, so threads survive restarts. Also trigger reauth when all accounts are permanently unhealthy instead of throwing immediately.
Every re-auth rotates the clientId, so the account hash changed and a new row was inserted. Fixed the hash to use profileArn+email only, and added cleanup of stale rows on each upsert.
HTTP errors (400/401/403/429/500) were only visible as UI toasts. Added logger.warn calls so they land in plugin.log as well.
- Reauth: cross-process lock via SQLite, timeout after 90s, poll when another instance holds the lock - Bearer token invalid: force token refresh instead of permanent failure - Token refresher: use error.code for markUnhealthy - Health: remove HTTP_403 and bearer token from isPermanentError - Accounts: null-guard on round-robin, cursor anchored to full list - IDC: deterministic account ID ignores rotating clientId - Tests: 178 tests across 13 files
…ming - Add agentContinuationId and agentTaskType to conversationState so Kiro groups agentic loop turns for credit optimization - Determine isNewThread after mergeAdjacentMessages (prevents false 400 on subagents/compaction) - Tool call streaming: accept chunks by toolUseId alone (name only on first chunk), fixing incomplete JSON on large tool inputs - SDK client: Connection: close header, explicit timeouts
All behind DEBUG or OPENCODE_LOG_LEVEL=debug: - [REQ] convId, history length, agentContinuationId per request - [REQ] done/error on completion - [CREDITS] usage from Kiro metering event - [TOOL_CALL] invalid JSON on tool input parse failure - [STREAM] errors in stream transformer
- Enforce 64-char max on tool names with SHA256 hash suffix for long names - Bidirectional name mapping: shorten on send, restore on response - Sanitize tool inputs: strip empty-string keys that Kiro rejects - Deduplicate tool calls in response (by name+arguments) - User-Agent with version and stable machineId hash - x-amzn-codewhisperer-optout header Reviewed best practices from github.com/justlovemaki/AIClient2API
- Trim history from front when payload exceeds Kiro's ~615KB limit - Recursively strip additionalProperties and empty required arrays from tool input schemas (Kiro rejects these) - Remove empty toolUses arrays from history entries (Kiro quirk) Reviewed best practices from github.com/jwadow/kiro-gateway
- Payload trim: incremental size accounting (O(N) instead of O(N²) on large histories), strip orphaned toolUses/toolResults to keep history valid for Kiro - shortenToolName: don't split surrogate pairs when truncating long names - sanitizeSchema: recurse into not/patternProperties/prefixItems/$defs /definitions/contains, guard against circular schemas - deduplicateToolCallsByContent: use \\x00 separator to avoid name/input boundary collisions Adds edge-case test suite covering all of the above.
- fetchUsageLimits: only chain to next param combo on FEATURE_NOT_SUPPORTED; bubble up 429/401/5xx/network errors instead of hitting the API 4x per call - UsageTracker: skip retries on rate-limit errors (don't amplify), don't mark accounts unhealthy on 429 (the request flow handles it) - ErrorHandler 429: track sleep time so the request timeout budget excludes rate-limit waits — a 60s wait shouldn't burn a 120s request timeout - RetryStrategy: subtract excludedMs from elapsed time on shouldContinue - Reauth lock: INSERT OR REPLACE handles the race where two instances both observe the same dead/expired lock and both try to claim it
noUncheckedIndexedAccess types indexed access as T | undefined, so several test files failed tsc (TS2532) and one ManagedAccount fixture was missing a required field (rateLimitResetTime, TS2322). release.yml gates publishing on typecheck, so master could not be released until this was green. - Add rateLimitResetTime to account fixtures. - Add non-null assertions on length-checked indexed access in tests.
…request - createSdkClient tears down the cached client when the token rotated, so its sockets/agent don't leak before the replacement is cached. - RequestHandler passes the parsed body object (not the raw JSON string) to transformToSdkRequest.
- getUsageLimits reads currentUsageWithPrecision/usageLimitWithPrecision, so the usage toast matches the Kiro dashboard credit figure instead of a rounded, stale request count. - AuthHandler refreshes usage from the API at startup (token-refresh aware, non-blocking, falls back to the stored value), so the first toast of a new billing period is not last month's number. - transformSdkStream prefers Kiro's real tokenUsage over the context-% estimate. - Extract summarizeUsage() and UsageTracker.syncNow() to remove duplication.
…ckernelz#97) Merge PR tickernelz#97 with maintainer adjustments:\n\n- Align default plugin provider id with the new kiro provider id.\n- Harden OpenCode auth bootstrap so malformed auth.json files are not overwritten and restrictive file permissions are preserved.\n- Add regression tests for auth bootstrap, provider id, Zod enum compatibility, and empty OpenAI-compatible stream chunks.\n- Bump @opencode-ai/plugin to 1.15.11 and align docs/model context examples.
OpenCode briefly shipped a built-in `kiro` provider that collided with this plugin's `kiro` id and crashed every request with `Y.languageModel is not a function` (anomalyco/opencode#26221). It was reverted, but is likely to return — so this is a pre-emptive fix. Move the primary provider id to `kiro-auth` so installs never clash with a future built-in `kiro`. Keep `kiro` registered as a back-compat alias so existing installs keep working; both ids share one custom fetch. Mechanics: OpenCode binds auth.loader to a single provider id, so the custom fetch is attached via provider.options in the config hook. resolveSDK reads options.fetch per provider, so both ids route through the plugin, and the fetch self-identifies Kiro requests by URL.
Per the Kiro model docs (kiro.dev/docs/models), Opus 4.8 (1M context, 2.2x, experimental) is the latest model and was missing. Add the mapping, default model entry, thinking variant, README example, and a resolution test, mirroring the Opus 4.7 entries.
…a cherry-pick) PR tickernelz#97's changes are already in this branch (cherry-picked into 5703be6 with conflict resolution). This -s ours merge records upstream/master as an ancestor so the fork is purely ahead of upstream — making the PR diff clean and auto-mergeable — without changing our tree.
The plugin registers the kiro-auth provider and its models automatically, so the manual provider/models block is no longer needed — reduce the install example to just the plugin entry. Also call out explicitly that the old `kiro` id still works as a fallback alias, with `kiro-auth` recommended going forward.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Sorry for the size of this one — the plan was to split it into separate PRs,
but I kept fixing small things as more people started using it and the feedback
rolled in. Then #97 broke a few things, so I reworked that part a different way,
keeping backwards compatibility.
The rename (kiro → kiro-auth)
OpenCode was adding native
kirosupport, which clashed with this plugin andbroke requests (anomalyco/opencode#26221). They've since reverted it, but there's
still an open PR for official Kiro support — so the rename is there to stay out
of its way. The provider id is now
kiro-auth, with a fallback so the oldkironame keeps working for existing installs (both ids share the same custom fetch).
Everything else in here
creating a new one each time
startup slower and slower over time (with an automatic cleanup for existing rows)
counting its own backoff sleep
reset reflects the current period instead of last month's stored value
estimating from the context window
Testing
bun test— 254 tests pass across 18 filesbun run typecheck— cleanbun run build— green