🎁 福利专区全网大模型免费应用 + 新用户福利 + 注册活动入口,低成本玩转 AI

Kiro 代理路由 liujiesmart/dsh-kiro-proxy

DeepSeek Harness
liujiesmart5 天前有提交已提供中文文档扫描:含敏感能力

把 Kiro 账号接入会话,并提供 OpenAI 兼容反向代理

30/100
综合分
0
GitHub 星标
—
npm 周下载
—/5
用户评分

数据截至 2026/10/27 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。

安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add liujiesmart/dsh-kiro-proxy
该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:仅索引
是什么
dsh 原生插件 · model
装得上吗
本站尚未做安装检查
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 5 天前
档位由哪些信号合成

本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。

验证判据与等级说明 →
社区实装还没有人打卡 · 装过的第一个就是你
安全扫描自动 · 静态分析源码
v2.7.0
🔵 扫描:含敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。

读写/删除本地文件写入剪贴板(不计风险)发起外部网络请求
查看扫描证据(共 15 处,展示前 15 条)
  • 读取本地文件
    index.js:69
    const value = JSON.parse(await readFile(this.path, 'utf8'))
  • 写入本地文件
    index.js:89
    await mkdir(this.directory, { recursive: true })
  • 写入本地文件
    index.js:90
    await writeFile(this.path, `${JSON.stringify(current, null, 2)}\n`, { encoding: 'utf8', mode: 0o600 })
  • 发起网络请求
    client.js:304
    const response = await fetch(API + path, init)
  • 写入剪贴板
    client.js:754
    await navigator.clipboard.writeText(String(value))
  • 读取本地文件
    lib/kiro-auth.js:196
    value = await fs.readFile(path, 'utf8')
  • 写入本地文件
    lib/kiro-auth.js:452
    await fs.mkdir(this.directory, { recursive: true })
  • 写入本地文件
    lib/kiro-auth.js:454
    await fs.writeFile(temporary, `${JSON.stringify({
  • 写入本地文件
    lib/kiro-auth.js:459
    await fs.rename(temporary, this.path)
  • 删除本地文件
    lib/kiro-auth.js:574
    await fs.unlink(this.path).catch(error => {
  • 读取本地文件
    lib/web.js:166
    const value = (await readFile(this.path, 'utf8')).trim()
  • 写入本地文件
    lib/web.js:183
    await mkdir(this.directory, { recursive: true })
  • 写入本地文件
    lib/web.js:184
    await writeFile(this.path, `${key}\n`, { encoding: 'utf8', mode: 0o600 })
  • 发起网络请求
    lib/kiro-transport.js:80
    const req = lib.request({
  • 发起网络请求
    lib/kiro-transport.js:145
    const req = https.request(requestOptions, response => {
扫描于 2026/11/1(0 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库

静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。

给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

DeepSeek Harness 的 Kiro(AWS CodeWhisperer/Amazon Q)服务商路由,外加 OpenAI/Anthropic 反向代理,复用现有的 Kiro IDE/命令行登录。

README

由 DeepSeek 最新模型翻译生成
dsh-kiro-proxy 把 Kiro(AWS CodeWhisperer / Amazon Q)接入 DeepSeek Harness,作为一条服务商路由;同时在同一账号前面加一层反向代理,兼容 OpenAI 和 Anthropic 协议。 不用 API key,也不用手工改 cordis.yml:装好插件包,kiro-proxy 路由就出现了。如果这台机器上的 Kiro IDE 或 Kiro CLI 已经登录,装完就能直接聊天。 这是独立集成,与 AWS 没有隶属关系,也未获其背书。Kiro 是 Amazon 的商标,详见 NOTICE.md。 安装 dsh plugin --profile <profile> add github:liujiesmart/dsh-kiro-proxy dsh --profile <profile> 也可以让 Harness 插件管理器指向本目录的本地检出(本地安装是链接,改完重载即生效)。 功能 1. 服务商路由 kiro-proxy —— 在会话里选一个 Kiro 模型,这一轮就直接从 Kiro 流式返回:文本、带外推理、工具调用、token 计量。
展开完整文档(README 剩余 1 节)
dsh-kiro-proxy

把 Kiro(AWS CodeWhisperer / Amazon Q)接入 DeepSeek Harness,作为一条服务商路由;同时在同一账号前面加一层反向代理,兼容 OpenAI 和 Anthropic 协议。

不用 API key,也不用手工改 cordis.yml:装好插件包,kiro-proxy 路由就出现了。如果这台机器上的 Kiro IDE 或 Kiro CLI 已经登录,装完就能直接聊天。

这是独立集成,与 AWS 没有隶属关系,也未获其背书。Kiro 是 Amazon 的商标,详见 NOTICE.md。

安装

dsh plugin --profile <profile> add github:liujiesmart/dsh-kiro-proxy
dsh --profile <profile>

也可以让 Harness 插件管理器指向本目录的本地检出(本地安装是链接,改完重载即生效)。

功能

1. 服务商路由 kiro-proxy —— 在会话里选一个 Kiro 模型,这一轮就直接从 Kiro 流式返回:文本、带外推理、工具调用、token 计量。
2. 反向代理 —— POST /v1/chat/completions(OpenAI)、POST /v1/messages(Anthropic)、GET /v1/models,任何说这几种协议的 CLI 都能连到同一个 Kiro 账号。
3. 设置 → Kiro Proxy —— 先是用量,然后是账号、模型白名单、代理 URL/key、连接设置。

凭据

没有内置任何凭据。优先级如下:

1. 本插件保存的账号($DSH_HOME/storages/kiro-proxy/accounts.json)
2. Kiro IDE / CLI 已经登录的凭据(~/.aws/sso/cache/kiro-auth-token.json)

Kiro 自己的文件只读不写;刷新后的 Kiro token 留在内存里。本插件写出的文件权限为 0600。

在 设置 → Kiro Proxy → 连接 里添加账号,共七种方式:

| 方式 | 会发生什么 |
| AWS Builder ID | AWS OIDC 设备码;打开链接,输入验证码,批准 |
| IAM Identity Center | 同一套设备码,走你自己的实例:需要门户 URL(https://<org>.awsapps.com/start)和它所在的区域 |
| Google / GitHub | Kiro 自己的社交登录设备码,在 app.kiro.dev 上批准 |
| Refresh token | 粘贴 token,本地校验;通过 Kiro 的认证服务刷新 |
| API key | 粘贴 ksk_ key;随 TokenType: API_KEY 发送 |
| External IdP | 粘贴 Microsoft Entra / 外部 IdP 的 JSON;在它自己的端点刷新 |

OIDC 注册里带的是 Kiro 自己的 Identity Center issuer。少了它,AWS 门户会对设备码回一句「We could not verify your sign-in credentials」——这是固定值,不是你的 start URL。

| authMethod | 刷新端点 | 聊天接口 |
| builder-id | oidc.<region>.amazonaws.com/token + 设备注册 | q.<region>.amazonaws.com |
| idc | 同上,走 Identity Center 实例所在区域 | codewhisperer.<region>.amazonaws.com,区域取自发现的 profile ARN |
| google / github / social | prod.us-east-1.auth.desktop.kiro.dev/refreshToken | q.<region>.amazonaws.com |
| imported | 同上 | q.<region>.amazonaws.com |
| api_key | 不刷新 | q.<region>.amazonaws.com + TokenType: API_KEY |
| external_idp | 用自己的 token 端点 | codewhisperer.<region>.amazonaws.com + TokenType: EXTERNAL_IDP |

在 Harness 之外使用

设置页会显示 base URL 和生成的代理密钥:

OpenAI-compatible
curl http://127.0.0.1:PORT/v1/chat/completions \
-H "authorization: Bearer kr-xxxx" -H 'content-type: application/json' \
-d '{"model":"claude-sonnet-4.5","stream":true,"messages":[{"role":"user","content":"hi"}]}'

Anthropic-compatible (Claude Code and friends)
ANTHROPIC_BASE_URL=http://127.0.0.1:PORT ANTHROPIC_API_KEY=kr-xxxx claude

默认不校验密钥(代理只监听回环地址)。要把 Harness 暴露到回环之外,先设置 requireProxyKey: true。

配置

Settings → Kiro Proxy 会写入 $DSH_HOME/storages/kiro-proxy/settings.json。配置档中的行优先于页面设置,所以部署时可以固定取值:

- id: kiro-proxy
config:
proxyUrl: http://127.0.0.1:1082
region: us-east-1
profileArn: arn:aws:codewhisperer:us-east-1:...:profile/...
maxContextWindow: 300000
enabledModels: [claude-sonnet-4.5, glm-5]
requireProxyKey: true
fallbackOnEmpty: true
fallbackModels: [claude-sonnet-4.5, glm-5]
maxConcurrency: 2
retryAttempts: 3
maxRequestChars: 320000

| 字段 | 默认值 | 含义 |
| proxyUrl | 直连 | 每个 Kiro 请求的 HTTP(S) CONNECT 出口。Kiro 按出口授权模型系列。 |
| region | token 所在区域 | 选择 q.<region> / codewhisperer.<region>。 |
| profileArn | 账号默认值 | CodeWhisperer 配置档;缺失时用 ListAvailableProfiles 发现。 |
| maxContextWindow | 200000 | 上报给 Harness 的容量。目录宣称 1M,但数据面会返回 Input is too long.,所以上报 1M 会让 Harness 永远不压缩。要调高请谨慎。 |
| enabledModels | 全部 | 过滤模型选择器和 /v1/models。请求已禁用的模型仍然放行。 |
| requireProxyKey | false | 在代理接口上强制校验 kr-… 密钥。 |
| fallbackOnEmpty | true | 模型返回空流时,尝试下一个模型。 |
| fallbackModels | 内置列表 | 该回退的候选顺序;只使用账号目录中存在的 id。 |
| maxConcurrency | 2 | 在途请求上限;其余排队。 |
| retryAttempts | 3 | 跨两个数据面的重试轮数。 |
| maxRequestChars | 320000 | 单个请求的字符预算;丢弃最旧的轮次,裁剪过大的工具结果。 |
| autoContinue | true | 流产生了推理内容但没有任何可见输出时,再发一轮 continue。 |
| maxContinuations | 2 | 这些自动续写的上限。 |

失败语义(实测,非假设)

限流。 Kiro 遇到 Encountered unexpectedly high load… 时,会以三种形式回应:HTTP 429、HTTP 200 里的 :exception-type 帧,或 5xx 响应体。每轮都会同时尝试两个数据面(q. 和 codewhisperer. 各自独立过载),记住哪个数据面可用,并且只在两者都失败时才退避——退避时遵守 x-amzn-kiro-ratelimit-retry-after。流一旦已经输出内容,就绝不重放。

空响应。 Kiro 不发送拒绝文本。对于模型不愿执行的输入,它返回 HTTP 200,只带一个 contextUsageEvent,内容帧为零。哪些模型会这样,取决于模型和提示词两者:

| 行为 | 观察到的模型 |
| 静默拒绝(空流) | claude-opus-5.5、claude-sonnet-5.5、claude-opus-5、gpt-5.6-sol、gpt-5.6-terra |
| 正常回答 | claude-sonnet-4.5、claude-opus-4.7、claude-sonnet-4.6、glm-5、deepseek-3.2、minimax-m2.5、claude-haiku-4.5、auto、gpt-5.6-luna、claude-opus-4.5、minimax-m2.1 |
| 用固定话术拒绝 | claude-sonnet-5、claude-opus-4.8、claude-opus-4.6、qwen3-coder-next |

因此,空回合会触发回退链,而不是让该回合失败;只有当所有候选都为空时,才报告 CONTENT_FILTERED(不可重试——重发同一提示词会得到同样的空流)。设置页会显示最近一次回退。

截断的回合。 有时流里只带推理内容,然后以 END_TURN/PAUSE_TURN 结束——没有可见内容,也没有工具调用。Kiro 自己的客户端会再发一个 continue 回合来应对,插件也照做(有次数上限,由 autoContinue + maxContinuations 控制),免得用户自己动手输入「继续」。续接以 assistant: understood + human: continue 发送,这样两个用户回合不会合并成一个。

超大请求。 Input is too long. 是 400,响应体只有这一句话,而 198 条历史记录的上限挡不住它:单个回合带上几十条巨大的工具结果,就能把载荷推到数 MB。因此序列化器还强制执行字符预算,优先丢弃最旧的回合对(保持交替结构,孤立的工具结果降级为文本),并把单条工具结果裁剪到 20k 字符(保留头尾,加标记)。

工具调用。 带参数的工具调用到达顺序是 start → 一个 input: "" 帧 → 参数片段 → stop。那个空片段携带工具名,若把它当成第二个 start,同一个 toolUseId 就会产生两个块——下一步重放它们会得到 400 Improperly formed request.。因此块以 toolUseId 为键,并且幂等。另外,纯工具回合里 Kiro 完全不发 metadataEvent——只有四个帧,别无他物。停止原因根据实际发生的情况推导,空参数会规范化为 {},因为 DSH 和 OpenAI 客户端都会对它们做 JSON.parse。

已验证

离线测试套件,用 npm test 全部跑一遍(tests/run-all.mjs);除 live- 探测外,其余都不需要凭证或 Host:

wire 110 checks translate 146 checks
adapter 49 checks auth 54 checks
wire events 6 checks retry/backoff 21 checks
model fallback 14 checks request budget 13 checks
auto-continue 12 checks
proxy over HTTP 40 checks host mount 32 checks
post-install 35 checks web UI 78 checks
import integrity 21 checks

对真实 Kiro 账号实测:发现 21 个模型,读取套餐与额度用量,流式文本,原生推理,两轮工具循环(tool-calls → stop),两个代理接口在流式与非流式模式下均可用,模型自动回退(所选模型拒绝的一轮约 5.7 秒),以及 8 MB 规模的历史记录约 7.9 秒内应答,而不是报 Input is too long.。

已知限制

- 图片只在用户轮次有位置;Kiro 的 AssistantResponseMessage 和 ToolResultContentBlock 都没有。工具产出的图片会被提升到携带其结果的用户轮次上。
- temperature / topP / stop 没有可接受的位置(additionalModelRequestFields 是 additionalProperties: false),因此不发送,而不是假装发送。
- tool_choice 在 Kiro 没有对应物,会被忽略。
- 工具名必须匹配 ^[A-Za-z][A-Za-z0-9_]{0,63}$;其他名字会被重命名,并记录映射。
- SOCKS 代理不支持;只支持 HTTP/HTTPS CONNECT。
- token 计数优先使用服务商上报的值;否则输入按 contextUsagePercentage × context window 计价,输出按发出的字符估算,用量标记为 estimated: true。

目录结构

index.js Host entry: config, adapter registration, web routes
lib/kiro-auth.js credential read / refresh / multi-account store
lib/kiro-transport.js HTTPS with CONNECT-proxy egress
lib/kiro-client.js models, usage, profile ARN, multi-surface streaming
lib/kiro-eventstream.js vnd.amazon.eventstream frame decoder
lib/kiro-serialize.js Harness messages -> wire request (+ size budget)
lib/kiro-openai.js OpenAI <-> Kiro
lib/kiro-anthropic.js Anthropic <-> Kiro
lib/adapter.js DSH LlmAdapter (structurally typed)
lib/web.js reverse proxy + state API
client.js settings page + composer quota chip
docs/CONTRACT.md module contract

许可证

MIT。见 LICENSE 和 NOTICE.md。

中文说明

把 Kiro(AWS CodeWhisperer / Amazon Q)接进 DeepSeek Harness,并在同一份登录态上开一个 OpenAI / Anthropic 双协议反向代理。

不内置 API key、不需要手改 cordis.yml:装完 bundle 就有 kiro-proxy 路由。本机 Kiro IDE 或 Kiro CLI 登录过,装完就能直接对话。

本项目是独立集成,与 AWS 无关;Kiro 是 Amazon 的商标,详见 NOTICE.md。

安装

dsh plugin --profile <profile> add github:liujiesmart/dsh-kiro-proxy
dsh --profile <profile>
或在 Harness 的 Plugin Manager 里安装本目录(本地目录安装是 link,改代码即时生效)。

它做三件事

1. provider 路由 kiro-proxy —— 会话里选 Kiro 的模型,直接流式拿到文本、独立 reasoning、工具调用与 token 计量。
2. 本地反向代理 —— POST /v1/chat/completions(OpenAI)、POST /v1/messages(Anthropic)、 GET /v1/models,任何只会说这两种协议的 CLI 都能用同一个账号。
3. Settings → Kiro Proxy —— 用量卡在最上,之后是账号管理、模型勾选、代理地址与 key、连接配置。

凭据

不内置任何凭据。优先级:

1. 插件自己存的账号($DSH_HOME/storages/kiro-proxy/accounts.json)
2. 本机 Kiro IDE / CLI 已登录的 ~/.aws/sso/cache/kiro-auth-token.json

Kiro 自己的文件只读不写;刷新出来的 token 只留在内存里。插件写出的文件是 0600。

Settings → Kiro Proxy → 连接 提供七种登录方式:

| 方式 | 过程 |
| AWS Builder ID | AWS OIDC 设备码:打开链接、输入验证码、批准 |
| IAM 身份中心 | 同样的设备码,但打到你的实例:需要门户 URL(https://<org>.awsapps.com/start)与实例区域 |
| Google / GitHub | Kiro 自己的社交设备码,在 app.kiro.dev 上确认 |
| Refresh token | 粘贴 token,本地校验;后续走 Kiro 的刷新服务 |
| API Key | 粘贴 ksk_ 开头的 key;请求带 TokenType: API_KEY |
| External IdP | 粘贴 Microsoft Entra / 外部 IdP 的 JSON;在它自己的端点刷新 |

OIDC 注册固定带 Kiro 自己的身份中心 issuer。少了它,AWS 门户会对设备码回「无法验证您的登录凭证」—— 那是固定值,不是你的起始 URL。

| authMethod | 刷新端点 | chat surface |
| builder-id | oidc.<region>.amazonaws.com/token + 设备注册 | q.<region>.amazonaws.com |
| idc | 同上,打到身份中心实例所在区域 | codewhisperer.<region>.amazonaws.com,区域取自查到的 profile ARN |
| google / github / social | prod.us-east-1.auth.desktop.kiro.dev/refreshToken | q.<region>.amazonaws.com |
| imported | 同上 | q.<region>.amazonaws.com |
| api_key | 不刷新 | q.<region>.amazonaws.com + TokenType: API_KEY |
| external_idp | 自己的 token endpoint | codewhisperer.<region>.amazonaws.com + TokenType: EXTERNAL_IDP |

在 Harness 之外使用

设置页会给出 base URL 与生成的 key:

OpenAI 兼容
curl http://127.0.0.1:PORT/v1/chat/completions \
-H "authorization: Bearer kr-xxxx" -H 'content-type: application/json' \
-d '{"model":"claude-sonnet-4.5","stream":true,"messages":[{"role":"user","content":"hi"}]}'

Anthropic 兼容(Claude Code 等)
ANTHROPIC_BASE_URL=http://127.0.0.1:PORT ANTHROPIC_API_KEY=kr-xxxx claude

默认不校验 key(只监听本机)。把 Harness 暴露到非 loopback 之前,先打开 requireProxyKey: true。

配置

Settings → Kiro Proxy 写入 $DSH_HOME/storages/kiro-proxy/settings.json;profile 的 row 优先级更高,所以部署可以钉住配置:

- id: kiro-proxy
config:
proxyUrl: http://127.0.0.1:1082
region: us-east-1
profileArn: arn:aws:codewhisperer:us-east-1:...:profile/...
maxContextWindow: 300000
enabledModels: [claude-sonnet-4.5, glm-5]
requireProxyKey: true
fallbackOnEmpty: true
fallbackModels: [claude-sonnet-4.5, glm-5]
maxConcurrency: 2
retryAttempts: 3
maxRequestChars: 320000

| 字段 | 默认 | 说明 |
| proxyUrl | 直连 | 每个 Kiro 请求的 HTTP(S) CONNECT 出口;Kiro 按出口授权模型族。 |
| region | token 里的 region | 选 q.<region> / codewhisperer.<region>。 |
| profileArn | 账号默认 | 缺省时用 ListAvailableProfiles 自己发现。 |
| maxContextWindow | 200000 | 上报给 Harness 的上下文容量。目录里报 1M,但数据面对长报文回 Input is too long.,报满 1M 等于让 Harness 永不压缩;要放开请显式配置。 |
| enabledModels | 全部 | 同时过滤模型选择器与 /v1/models;请求被禁用的模型仍然放行。 |
| requireProxyKey | false | 反代是否强制校验 kr-… key。 |
| fallbackOnEmpty | true | 模型回空流时是否换下一个模型。 |
| fallbackModels | 内置表 | 换模型的候选顺序;只在账号目录里存在的才用。 |
| maxConcurrency | 2 | 同时在飞的请求数,其余排队。 |
| retryAttempts | 3 | 跨两个数据面的重试轮数。 |
| maxRequestChars | 320000 | 单次请求的字符预算;超出时先丢最旧的整轮,再裁剪超长工具结果。 |
| autoContinue | true | 只有 reasoning、没有可见内容时,自动再发一轮 continue。 |
| maxContinuations | 2 | 自动续写的次数上限。 |

失败语义(全部来自实测)

节流。 Kiro 会用三种形态回 Encountered unexpectedly high load…:HTTP 429、HTTP 200 里的 :exception-type 帧、或 5xx body。每一轮都会把两个数据面都试一遍(q. 与 codewhisperer. 独立过载),记住能用的那个面;只有两个面都失败才按 x-amzn-kiro-ratelimit-retry-after 退避。
已经吐给调用方的流绝不重放。

空响应。 Kiro 不返回拒绝文本:对不愿执行的输入,它回 HTTP 200 + 单个 contextUsageEvent,零内容帧。哪些模型会这样,既看模型也看提示词:

| 行为 | 实测模型 |
| 静默拒答(空流) | claude-opus-5.5、claude-sonnet-5.5、claude-opus-5、gpt-5.6-sol、gpt-5.6-terra |
| 正常作答 | claude-sonnet-4.5、claude-opus-4.7、claude-sonnet-4.6、glm-5、deepseek-3.2、minimax-m2.5、claude-haiku-4.5、auto、gpt-5.6-luna、claude-opus-4.5、minimax-m2.1 |
| 作答但内容是固定拒绝句 | claude-sonnet-5、claude-opus-4.8、claude-opus-4.6、qwen3-coder-next |

所以空回合会触发换模型,而不是判死整轮;只有所有候选都空才报 CONTENT_FILTERED (不可重试——同一份提示词重发还是空流)。设置页会显示最近一次自动换模型。

回合被截断。 有时一条流只有 reasoning,然后以 END_TURN/PAUSE_TURN 收尾 —— 没有可见正文、也没有工具调用。Kiro 自己的客户端对这种情况会补一轮 continue,插件照做(有上限,autoContinue + maxContinuations),而不是让你手动输入"继续"。续写按 assistant: understood + human: continue 发,避免两条 user 轮被合并成一条。

超长请求。 Input is too long. 是一个只有这句话的 400,而 198 条历史上限管不住它:一个回合里几十条巨型工具结果就能把报文推到几 MB。所以序列化器还按字符兜底——先丢最旧的整轮(保持交替,悬空的工具结果降级为文本),再把单条工具结果裁到 2 万字符(保留头尾并加标记)。

工具调用。 带参数的工具调用在线上是 开始 → 一帧 input: "" → 参数增量 → stop。那一帧空片段带着工具名,若被当成"又一次开始"就会给同一个 toolUseId 产出两个块 —— 下一步回灌时服务端回 400 Improperly formed request.。所以工具块按 toolUseId 幂等。另外,只调工具、没有正文的回合完全不发 metadataEvent (整条流四帧)。所以结束原因是按"究竟发生了什么"推导的;空参数会补成 {},因为 DSH 与 OpenAI 客户端都会对它做 JSON.parse。

验证

离线套件(npm test 一次跑完;除 live- 探针外都不需要凭据,也不需要 Host):

wire 110 项 translate 146 项 adapter 49 项 auth 54 项 wire events 6 项 retry/backoff 21 项 model fallback 14 项 request budget 13 项 auto-continue 12 项 proxy over HTTP 40 项 host mount 32 项 post-install 35 项 web UI 78 项 import integrity 21 项

真实账号上验证过:21 个模型发现、计划与额度读取、流式文本、原生 reasoning、两轮工具循环(tool-calls → stop)、OpenAI 与 Anthropic 两个面的流式与非流式、自动换模型(被拒的那一轮约 5.7s 拿到回答)、以及 8MB 形状的历史在约 7.9s 内正常作答而不是 Input is too long.。

已知边界

- 图片只在 user 轮有座位;AssistantResponseMessage 与 ToolResultContentBlock 都没有。
工具产出的图片会被提升到承载结果的 user 轮。
- temperature / topP / stop 没有合法位置(additionalModelRequestFields 是 additionalProperties: false),所以不发,而不是假装发过。
- tool_choice 没有对应字段,忽略。
- 工具名必须匹配 ^[A-Za-z][A-Za-z0-9_]{0,63}$,否则改名并记录映射。
- SOCKS 代理不支持,只支持 HTTP/HTTPS CONNECT。
- token 计数优先用服务商上报值;缺失时输入侧按 contextUsagePercentage × 上下文窗口 定价、输出侧按字符数估算,并标 estimated: true。

目录

index.js Host 入口:配置、注册 adapter、挂 web 路由 lib/kiro-auth.js 凭据读取 / 刷新 / 多账号 lib/kiro-transport.js HTTPS + CONNECT 代理 lib/kiro-client.js 模型、用量、profile ARN、多数据面流 lib/kiro-eventstream.js vnd.amazon.eventstream 帧解码 lib/kiro-serialize.js Harness 消息 -> wire 请求(含体积预算)
lib/kiro-openai.js OpenAI <-> Kiro
lib/kiro-anthropic.js Anthropic <-> Kiro
lib/adapter.js DSH LlmAdapter(结构化类型) lib/web.js 反代 + 状态 API client.js 设置页 + 输入区额度徽标 docs/CONTRACT.md 模块契约

许可

MIT。详见 LICENSE 与 NOTICE.md。
预览分享卡片长什么样 ↓liujiesmart/dsh-kiro-proxy
分享 · DeepSeek Harness Hub
liujiesmart/dsh-kiro-proxy

把 Kiro 账号接入会话,并提供 OpenAI 兼容反向代理

回到顶部