Skip to content

Releases: dat-lequoc/dsh-kiro

v0.1.19 — image input

Choose a tag to compare

@dat-lequoc dat-lequoc released this 25 Aug 20:13

Kiro routes can now take images. The adapter previously refused all image content
with UNSUPPORTED_CONTENT, which also kept the harness's own read_image tool
shut: that tool gates on inputModalities.includes('image'), and this reported
every model as text-only.

Capability is read, not guessed

ListAvailableModels states it per model as supportedInputTypes: ["TEXT","IMAGE"].
On the verified account 17 of 19 models accept images, including every Claude
route, while glm-5 and minimax-m2.5 report text only — an id-based rule would
have sent images to those two.

models[].inputModalities overrides the catalog, and a model that states nothing
stays text-only, matching the harness rule that an unstated capability is not a
capability.

How images travel

  • userInputMessage.imagesImageBlock { format, source: { bytes } }, format
    limited to png, jpeg, gif and webp
  • re-encoded to at most 8000×8000 pixels and 3.75 MB before base64 expansion
  • bytes come from the attachment service via readImageRequest, resolved per
    request and capability-checked, so a profile without it reports images
    unsupported rather than failing mid-request

Placement follows the wire

Only user messages have an image seat. AssistantResponseMessage has none, so an
image in replayed assistant history is refused rather than silently dropped. And
ToolResultContentBlock is a union of text and json alone, so an image returned by
a tool is hoisted onto the user turn carrying its result — the nearest seat that
keeps it.

Verified live, twice

  • Raw wire (tests/live-image.spec.ts): a generated PNG of green over red —
    colours the prompt never named — answered green red.
  • Full harness: a headless turn on a temporary profile used read_image on a
    blue-over-yellow PNG and answered blue / yellow, exercising the capability
    gate, the attachment service, this adapter, and the model together.

npm run check: 204 tests pass (10 live probes skipped), plus typecheck, build and
syntax checks.

Install

dsh plugin --profile <name> add github:dat-lequoc/dsh-kiro#v0.1.19

Artifact checksum

sha256  5b371b0bfc3ace981e6009e450cdfc61ca96e22a32e728e41258e57916b2bc96  dsh-kiro-0.1.19.tgz

v0.1.18 — credential import confirms, closes, and reloads

Choose a tag to compare

@dat-lequoc dat-lequoc released this 25 Aug 14:29

Fixes the credential-import experience reported from the settings page: pasting an
API key gave no sign it had been checked, left the dialog open, and left the usage
card showing the previous account.

Cause

One dependency. Both the dialog close and the usage re-read hung off
status.authenticated, which does not change when a Kiro IDE credential is already
present — precisely the situation a first import happens in. Signing in from a
signed-out page worked, so the bug only showed on the path most users take.

The effects now key on which credential is in force (source, method, expiry), and
the import closes and refreshes directly rather than waiting on a derived change,
because re-importing the same kind of credential can leave every observed field
equal.

The confirmation says what was verified

  • API key — already validated against the live model catalog before storage;
    that check's model count now reaches the page: Credential verified · 19 models available
  • Refresh token — reports verification, because its exchange minted a real
    access token
  • External IdP JSON — only reshaped locally, so it says Credentials saved and
    claims nothing more

The notice clears itself after eight seconds and cancels its timer on unmount.

Also

The pasted secret is dropped from the page once the server holds it — keeping a
copy in component state only widens where it can leak.

Verification

Against the live deployment: a bogus key returns Kiro API key validation failed,
and replaying the stored key returns verified: {"models": 19} with the usage card
repopulating (KIRO PRO MAX, credits 237.09/5000). Six of the eight new tests in
tests/client-import.spec.ts fail against the previous revision. npm run check:
193 tests pass, 9 live probes skipped.

Install

dsh plugin --profile <name> add github:dat-lequoc/dsh-kiro#v0.1.18

Artifact checksum

sha256  f59d02cb381c827d810a3cda7fc7c3c29b19dbac96f46b2fee6a7423bf5cfdd2  dsh-kiro-0.1.18.tgz

v0.1.17 — cache question settled, quota vocabulary corrected

Choose a tag to compare

@dat-lequoc dat-lequoc released this 25 Aug 13:58

The account's monthly allowance reset, so two questions that were previously
blocked could be answered by asking the service rather than reasoning about it.

Can cache usage be forwarded to DSH? No — Kiro never sends it

Seven request shapes were replayed; five returned 200 and two were throttled.
Across both surfaces, three agent modes, two chatTriggerType values and two model
families, every response was metadataEvent {"stopReason":"END_TURN"} with no
tokenUsage — therefore no cacheReadInputTokens or cacheWriteInputTokens.

Cache hit 0% in the session line is DSH displaying an absent signal, not a
measurement: cacheHitPercent divides cache reads by billed input, and derived
usage supplies a real input figure with no cache buckets. The only plugin-side
alternative would be to invent cache numbers.

Caching happens anyway, and cachePoint is a no-op

A 2×2 with a separate ~24 KB prefix per arm, so neither arm warms the other:

arm first call repeat
no cache points 0.07866418315091211 credits 0.041732541359867335
with cache points 0.07866418315091211 credits 0.041732541359867335

Identical to 17 significant digits in all four cells. So Kiro caches
automatically, server-side, keyed on the prefix — a repeat costs 47% less, and the
harness's turn loop already benefits from resending history. And cachePoint
(declared on UserInputMessage, AssistantResponseMessage, and as a Tool union
arm) is accepted but changes nothing, so it is deliberately not added to the
serializer.

The experiment is kept as tests/live-cache.spec.ts, including the control that
disproved a first, wrong reading of it.

Quota vocabulary corrected

0.1.15's reasons were partly guessed. The service model's own enums:

  • ThrottlingExceptionReason: CREDIT_CONSUMPTION_RATE_EXCEEDED,
    DAILY_REQUEST_COUNT, INSUFFICIENT_MODEL_CAPACITY, MONTHLY_REQUEST_COUNT,
    SERVICE_REQUEST_RATE_EXCEEDED, USER_REQUEST_RATE_EXCEEDED
  • ServiceQuotaExceededExceptionReason: CONVERSATION_LIMIT_EXCEEDED,
    MONTHLY_REQUEST_COUNT, OVERAGE_REQUEST_LIMIT_EXCEEDED

FREE_TIER_LIMIT_REACHED does not exist and was removed;
OVERAGE_REQUEST_LIMIT_EXCEEDED was added; CREDIT_CONSUMPTION_RATE_EXCEEDED
returns to RATE_LIMIT because it names a burn rate, not an empty balance;
CONVERSATION_LIMIT_EXCEEDED reports as CONTEXT_WINDOW_EXCEEDED whatever status
carries it, since a smaller conversation is the harness's only lever. Reason
matching now runs ahead of the status branches, because the service uses more than
one status for the same condition.

Verification

npm run check: 185 tests pass (9 live probes skipped), plus typecheck, build and
syntax checks.

Install

dsh plugin --profile <name> add github:dat-lequoc/dsh-kiro#v0.1.17

Artifact checksum

sha256  c475ed47e951712a651857846337350c6938958dc70157206677614690b89fa9  dsh-kiro-0.1.17.tgz

v0.1.16 — the adapter never compacts

Choose a tag to compare

@dat-lequoc dat-lequoc released this 25 Aug 13:41

Pins an architectural boundary that was intended but unenforced: this plugin
never compacts.

As an adapter it owns the provider seam and nothing else. What a conversation
should contain is dsh-compaction-basic's decision, driven by the token meter and
by the overflow code reported here. Nothing stopped a future change from trimming
history to make a request fit, which would discard turns the harness still
believes it has and hide the overflow that triggers recovery.

Audit

The only byte limits in the plugin are the event-stream frame guard, HTTP
content-length, and the web API's request-body cap. No message or history
trimming exists anywhere in it.

Now enforced by tests

  • every message reaches the wire for a mixed tool conversation
  • a conversation over 2 MB is sent in full rather than trimmed, so the provider's
    refusal is what starts recovery
  • an orphaned tool result is kept as text rather than discarded
  • the only omission is the legacy [system: conversation continues] padding this
    plugin itself once authored, because replaying it teaches the model to reproduce it
  • the overflow path contributes exactly one error code, with no retry and no edit
  • the plugin injects nothing but llm

Both READMEs now state the boundary and its single deliberate exception.

Verification

npm run check: 184 tests pass (8 live probes skipped), plus typecheck, build and
syntax checks.

Install

dsh plugin --profile <name> add github:dat-lequoc/dsh-kiro#v0.1.16

Artifact checksum

sha256  4a1ee31c3baf7d1f4f38a018477b8697af7b33e1d1c22d327de2e5618534ff70  dsh-kiro-0.1.16.tgz

v0.1.15 — token accounting and quota classification

Choose a tag to compare

@dat-lequoc dat-lequoc released this 25 Aug 13:26

Adds token accounting on Kiro, which the harness previously had none of: the
session line showed turns, steps and timings but no tokens.

Why it matters beyond display

DSH's token meter anchors its context accounting on provider usage
(baseline: {kind: 'usage'}). With no usage at all it prices the whole
conversation from a local heuristic, so compaction thresholds drift from what the
provider actually charged.

What the protocol offers

The wire schema settles it. MetadataEvent declares
{tokenUsage, stopReason, stopDetails}, and TokenUsage declares seven members:
uncachedInputTokens, outputTokens, totalTokens, cacheReadInputTokens,
cacheWriteInputTokens, contextUsagePercentage, normalizedTokenUsage.

Exact usage is therefore part of the contract — but no observed route on the test
account sends the metadata event, while every one sends contextUsageEvent.

What this release does

  • Exact when available. tokenUsage maps straight to DSH's buckets, and
    totalTokens now recovers the uncached input when a route reports only the
    total.
  • Otherwise priced from the provider's own measurement. No buckets means the
    call is priced from contextUsagePercentage times the model's advertised
    context window. Both reference implementations convert it the same way, for the
    same stated reason: clients rely on it to decide when to compact.
  • Honest about precision. The input side is the provider's measurement of how
    full the window is, at the precision it reported. The output side has no
    provider signal and is scaled from emitted characters. Cache buckets are never
    invented.

Spent plans are now classified

Probing the usage question hit HTTP 402 {"reason":"MONTHLY_REQUEST_COUNT"},
which surfaced as an opaque HTTP_402. An exhausted allowance is now QUOTA
including a 403 or a throttle whose reason names the monthly or daily allowance —
because retrying cannot help and it must not read as a rate limit or a permission
problem. A burst throttle stays RATE_LIMIT.

Verification

npm run check: 178 tests pass (8 live probes skipped), plus typecheck, build and
syntax checks. New coverage in tests/repro.spec.ts ("P1-4 usage telemetry",
"account allowance classification") and tests/adapter-request.spec.ts.

Install

dsh plugin --profile <name> add github:dat-lequoc/dsh-kiro#v0.1.15

Artifact checksum

sha256  23dee1eda99ef5915d4f8c9498dabea29c82d03af989703a269d4fdc484ddf03  dsh-kiro-0.1.15.tgz

v0.1.14 — Kiro IDE/CLI credential refresh

Choose a tag to compare

@dat-lequoc dat-lequoc released this 25 Aug 13:09

Fixes a first-run failure reported on a machine that already had Kiro IDE/CLI
signed in.

Kiro IDE/CLI credentials now refresh

A fresh install has no plugin-owned credential, so the adapter falls back to
Kiro's shared SSO cache. That file records Kiro's own vocabulary — its
refreshToken() switches on social, IdC, and external_idp — and social
was not a method this adapter knew. It fell through to builder-id, so refresh
demanded a client registration that a social credential neither has nor needs:
Kiro refreshes those with nothing but the refresh token. Every fresh install on
the fallback path was stranded as soon as that token expired, with:

Kiro credential cannot be refreshed without its client registration

Now social is a first-class method, Kiro's spellings are read
case-insensitively (IdCidc, so an Identity Center credential is not
misrouted to the Amazon Q surface), and social refreshes against Kiro's auth
service alongside imported, google, and github. The remaining registration
error names the method and says what to do, and the settings card reports the
method the adapter actually acts on.

Same credential file, identical input:

0.1.13 and earlier -> INVALID_CREDENTIAL  (no network call attempted)
0.1.14             -> reaches Kiro's refresh service

The fallback state now offers an action

Sign in appeared only when nothing was authenticated and Sign out only
for plugin-owned credentials, so a Kiro IDE/CLI credential showed neither —
signing out appeared to do nothing. Sign out stays scoped, because this plugin
must never delete Kiro's files, but sign-in is now offered whenever the
credential is not plugin-owned, and the card explains who owns the credential
and why Sign out cannot remove it. A plugin-owned sign-in takes precedence over
the Kiro cache.

Verification

npm run check: 168 tests pass (7 live probes skipped), plus typecheck, build,
and client/CLI syntax checks. New regression tests in tests/auth.spec.ts
("Kiro IDE/CLI credential vocabulary") and tests/client-nav-icon.spec.ts.

Install

dsh plugin --profile <name> add github:dat-lequoc/dsh-kiro#v0.1.14

Artifact checksum

sha256  41b4db23253f45721923a2a3768f92f02ce7918c9d88c5a79d013c9fab96e82a  dsh-kiro-0.1.14.tgz

v0.1.13 — provider-contract fixes

Choose a tag to compare

@dat-lequoc dat-lequoc released this 25 Aug 12:55

Provider-contract fixes found by an audit of the previous build. Every item was
reproduced first, then fixed, then verified against the live service.

Fixed

  • Context overflow now triggers DSH recovery. Kiro's
    CONTENT_LENGTH_EXCEEDS_THRESHOLD reason and its input/prompt is too long
    wording map to CONTEXT_WINDOW_EXCEEDED, the code compaction keys emergency
    recovery to. Every other HTTP 400 stays INVALID_REQUEST.
  • [system: conversation continues] no longer leaks. Structural padding is
    the official client's own neutral text (Continue / understood), persisted
    marker blocks are stripped when history is rebuilt, and a reply that is nothing
    but the marker is suppressed. Replaying local transcripts: 23 stored marker
    blocks reached the wire 83 times before, 0 now.
  • Native reasoning is surfaced. reasoningContentEvent frames become DSH
    reasoning blocks; signatures and redacted content are consumed silently.
  • Provider stop reasons are honored. END_TURN, TOOL_USE, MAX_TOKENS,
    MODEL_CONTEXT_WINDOW_EXCEEDED, CONTENT_FILTERED, and PAUSE_TURN map to
    the matching outcome; an unrecognized reason stays diagnosable.
  • Output caps go where the service accepts them.
    generateAssistantResponse has no inferenceConfig — the service ignores one.
    maxTokens now travels as additionalModelRequestFields.max_tokens, clamped
    to the bounds the model advertises, and only for models that advertise a
    schema. temperature and topP have no accepted placement and are ignored.
  • One stable conversation id per DSH session, derived from a keyed digest.
  • Usage parsing for bonus grants, add-on credits, active-only trials, and the
    no-limit sentinel.
  • Explicit credential origin on refresh-token import, so a Builder ID credential
    is no longer classified as Identity Center.
  • Settings-nav icon: scoped observer, no polling, disposed with the plugin.
  • Model-catalog pagination with duplicate, repeated-token, and no-progress guards.
  • Token-telemetry claims qualified to the case where Kiro actually sends terminal
    token metadata.

Verification

npm run check: 163 tests pass (7 live probes skipped), plus typecheck, build,
and client/CLI syntax checks. tests/live-*.spec.ts (KIRO_LIVE=1) re-verify
the wire contract against a real account; tests/session-replay.spec.ts
(DSH_SESSIONS=1) replays the local session store; verification/overflow-probe
proves a context-overflow failure makes DSH compact and retry a turn without
spending provider credits.

Install

dsh plugin --profile <name> add github:dat-lequoc/dsh-kiro#v0.1.13

Not published to npm. The attached tarball is the artifact this release was
verified with.

Artifact checksum

sha256  2f82c8db3136fd8cd3a8647e45247aade3506a01e27714823a0cdaf2c9eb0c99  dsh-kiro-0.1.13.tgz

v0.1.7

Choose a tag to compare

@dat-lequoc dat-lequoc released this 24 Aug 19:54

Correct Google and GitHub login to use Kiro's provider-specific social device authorization. These methods now return an app.kiro.dev/account/device URL with the selected login_provider and a one-time code, while Builder ID and IAM Identity Center remain on the separate AWS OIDC device flow.

v0.1.6

Choose a tag to compare

@dat-lequoc dat-lequoc released this 24 Aug 19:43

Fix Google and GitHub sign-in for remote DSH sessions by using Kiro's one-time device-code flow. The web UI now shows the authorization URL and XXXX-XXXX code with explicit Copy and Open browser controls; the obsolete manual kiro:// callback flow has been removed.

dsh-kiro v0.1.5

Choose a tag to compare

@dat-lequoc dat-lequoc released this 24 Aug 16:22

Browser-based Kiro login no longer opens a popup automatically. The authorization step now displays the full selectable URL with Copy and Open browser controls, including a responsive mobile layout.