dsh-tap 0.20.0

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 (121) hide show
  1. package/AGENTS.md +99 -0
  2. package/CHANGELOG.md +751 -0
  3. package/LICENSE +21 -0
  4. package/README.en.md +59 -0
  5. package/README.md +256 -0
  6. package/cordis.patch.yml +385 -0
  7. package/core/bridge.js +698 -0
  8. package/core/json-store.js +91 -0
  9. package/core/rotation.js +108 -0
  10. package/core/usage-meter.js +176 -0
  11. package/docs/diagnosis-cache-quota.md +181 -0
  12. package/docs/diagnosis-qoder-flash.md +67 -0
  13. package/docs/diagnosis-trae-3003.md +302 -0
  14. package/docs/goals/bridge-port-host-split.md +91 -0
  15. package/docs/goals/desktop-adaptation.md +106 -0
  16. package/docs/goals/qoder-cn-provider-design.md +308 -0
  17. package/docs/goals/settings-card-ux-redesign-plan.md +1680 -0
  18. package/docs/goals/settings-card-ux-redesign.md +162 -0
  19. package/docs/goals/trae-agent-v3.md +41 -0
  20. package/docs/goals/trae-work-cn-repair.md +44 -0
  21. package/docs/goals/v0.8-/351/242/235/345/272/246/345/217/257/350/247/201-/346/250/241/345/236/213/345/212/250/346/200/201/345/214/226-/345/244/232/346/234/215/345/212/241/345/225/206.md +85 -0
  22. package/docs/pitfalls.md +105 -0
  23. package/docs/reverse/trae-cloud-api.md +218 -0
  24. package/docs/reverse/trae-model-catalog.md +129 -0
  25. package/docs/reverse/traework-cn.md +520 -0
  26. package/docs/rules/STATE.md +198 -0
  27. package/docs/rules/content-moderation.md +54 -0
  28. package/docs/rules/dev-role-boundary.md +94 -0
  29. package/docs/rules/extra-providers.md +42 -0
  30. package/docs/rules/gateway-facts.md +91 -0
  31. package/docs/rules/oauth-handshake.md +76 -0
  32. package/docs/rules/prompt-cache.md +93 -0
  33. package/docs/rules/quota-signals.md +125 -0
  34. package/docs/rules/routing.md +84 -0
  35. package/docs/rules/templates/oauth-reverse-checklist.md +42 -0
  36. package/docs/rules/trae-surface.md +242 -0
  37. package/docs/rules/ua-validation.md +81 -0
  38. package/host-config.js +282 -0
  39. package/index.js +2306 -0
  40. package/lib/client.js +2893 -0
  41. package/local-scan.js +104 -0
  42. package/package.json +82 -0
  43. package/providers/ark/index.js +11 -0
  44. package/providers/bailian/index.js +10 -0
  45. package/providers/bigmodel/index.js +11 -0
  46. package/providers/codebuddy/agenttool.js +122 -0
  47. package/providers/codebuddy/catalog.js +227 -0
  48. package/providers/codebuddy/errors.js +44 -0
  49. package/providers/codebuddy/headers.js +36 -0
  50. package/providers/codebuddy/images.js +125 -0
  51. package/providers/codebuddy/index.js +123 -0
  52. package/providers/codebuddy/oauth.js +279 -0
  53. package/providers/deepseek/index.js +11 -0
  54. package/providers/moonshot/index.js +11 -0
  55. package/providers/openai-compat.js +177 -0
  56. package/providers/openrouter/index.js +27 -0
  57. package/providers/qoder/catalog.js +145 -0
  58. package/providers/qoder/cosy.js +419 -0
  59. package/providers/qoder/gateway.js +563 -0
  60. package/providers/qoder/index.js +116 -0
  61. package/providers/qoder/oauth.js +364 -0
  62. package/providers/qoder/qoder_auth.wasm +0 -0
  63. package/providers/qoder/quota.js +56 -0
  64. package/providers/qwen/index.js +15 -0
  65. package/providers/tool-pairing.js +129 -0
  66. package/providers/trae/catalog.js +103 -0
  67. package/providers/trae/errors.js +85 -0
  68. package/providers/trae/gateway.js +853 -0
  69. package/providers/trae/index.js +126 -0
  70. package/providers/trae/oauth.js +443 -0
  71. package/providers/trae/quota.js +75 -0
  72. package/providers/trae/remote.js +365 -0
  73. package/scripts/capture-cache.mjs +65 -0
  74. package/scripts/capture-traffic.mjs +83 -0
  75. package/scripts/hermes-probe-dev-role.mjs +263 -0
  76. package/scripts/measure-latency.mjs +253 -0
  77. package/scripts/probe-ark-thinking.mjs +298 -0
  78. package/scripts/probe-cache-decline.mjs +292 -0
  79. package/scripts/probe-cache-ttl.mjs +221 -0
  80. package/scripts/probe-cache.mjs +156 -0
  81. package/scripts/probe-codebuddy-efforts.mjs +355 -0
  82. package/scripts/probe-codebuddy-tier-wiring.mjs +244 -0
  83. package/scripts/probe-effort-gaps.mjs +133 -0
  84. package/scripts/probe-media.mjs +115 -0
  85. package/scripts/probe-moderation.mjs +159 -0
  86. package/scripts/probe-oauth.mjs +617 -0
  87. package/scripts/probe-qoder-attribution-arm8.mjs +92 -0
  88. package/scripts/probe-qoder-attribution-arm9.mjs +102 -0
  89. package/scripts/probe-qoder-attribution.mjs +266 -0
  90. package/scripts/probe-qoder-flash-confirm.mjs +94 -0
  91. package/scripts/probe-qoder-live.mjs +344 -0
  92. package/scripts/probe-qoder-matrix.mjs +274 -0
  93. package/scripts/probe-qoder-null-content.mjs +153 -0
  94. package/scripts/probe-qoder-pairing.mjs +308 -0
  95. package/scripts/probe-qoder-quota.mjs +162 -0
  96. package/scripts/probe-qoder-thinking-config.mjs +52 -0
  97. package/scripts/probe-qoder-thinking-efforts.mjs +269 -0
  98. package/scripts/probe-quota.mjs +136 -0
  99. package/scripts/probe-quota2.mjs +144 -0
  100. package/scripts/probe-routing.mjs +226 -0
  101. package/scripts/probe-trae-3003-diagnosis.mjs +139 -0
  102. package/scripts/probe-trae-agent-v3.mjs +399 -0
  103. package/scripts/probe-trae-efforts.mjs +149 -0
  104. package/scripts/probe-trae-live.mjs +147 -0
  105. package/scripts/probe-trae-max-effort.mjs +179 -0
  106. package/scripts/probe-trae-model-routing.mjs +381 -0
  107. package/scripts/probe-trae-thinking-scene.mjs +238 -0
  108. package/scripts/probe-trae-transport-outage.mjs +176 -0
  109. package/scripts/probe-ua.mjs +508 -0
  110. package/scripts/trae-model-catalog.mjs +632 -0
  111. package/scripts/verify-agents-md.mjs +45 -0
  112. package/scripts/verify-bridge.mjs +1041 -0
  113. package/scripts/verify-core-generic.mjs +302 -0
  114. package/scripts/verify-desktop-acceptance.mjs +184 -0
  115. package/scripts/verify-host-config.mjs +265 -0
  116. package/scripts/verify-models.mjs +390 -0
  117. package/scripts/verify-providers.mjs +255 -0
  118. package/scripts/verify-qoder-provider.mjs +1020 -0
  119. package/scripts/verify-rotation.mjs +308 -0
  120. package/scripts/verify-trae-model-catalog.mjs +284 -0
  121. package/scripts/verify-trae-provider.mjs +1451 -0
@@ -0,0 +1,176 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * probe-trae-transport-outage.mjs — inline 3003 持续故障下的主聊天出路探测。
4
+ *
5
+ * 背景(docs/diagnosis-trae-3003.md 2026-10-04 补记 + 用户复报「还是不能用」):
6
+ * inline_chat 面全臂 3003(scene thinking=disabled × 模型默认档 high,服务端行为),
7
+ * dsh 主聊天带 agent 工具表 ⇒ 网关不自动降级;remote 面(chat_sessions)不支持
8
+ * OpenAI tools(remote-no-tools 400)。主聊天是否两头堵,取决于 chat_v3 面对带
9
+ * tools 请求的行为——本探针三臂各一发实测:
10
+ * [R] remote 面(chat_sessions)baseline:纯文本会话当前可用性
11
+ * [C2] chat_v3 无 tools:信封/鉴权健康性对照([C] 臂重试)
12
+ * [C3] chat_v3 + tools:**主聊天出路判定**——若正常出回答/工具调用,放开网关
13
+ * 3003 降级的 !hasTools 限制即可救主聊天(改派模型诚实披露)
14
+ *
15
+ * 用法:node scripts/probe-trae-transport-outage.mjs [--model glm-5.3]
16
+ * 纪律:raw 面臂间隔 ≥20s(4011 限流);证据 → docs/probes/trae-transport-outage-<ts>.json
17
+ */
18
+ import { writeFileSync, mkdirSync } from 'node:fs'
19
+ import { homedir } from 'node:os'
20
+ import { join, dirname } from 'node:path'
21
+
22
+ import { createTraeOAuth } from '../providers/trae/oauth.js'
23
+ import { buildChatRequest, traeOutboundHeaders } from '../providers/trae/gateway.js'
24
+ import {
25
+ createRemoteSession, openRemoteEvents, stopRemoteSession, createRemoteEventParser,
26
+ } from '../providers/trae/remote.js'
27
+ import { readJson } from '../core/json-store.js'
28
+
29
+ const args = process.argv.slice(2)
30
+ const argOf = (n, d) => { const i = args.indexOf(n); return i >= 0 && args[i + 1] !== undefined ? args[i + 1] : d }
31
+ const MODEL = argOf('--model', 'glm-5.3')
32
+ const PROMPT = '只回复两个字:成功'
33
+
34
+ const DSH_HOME = process.env.DSH_HOME ?? join(homedir(), '.dsh')
35
+ const AUTH_PATH = join(DSH_HOME, 'trae-plugin-auth.json')
36
+ const MCHOST = 'https://trae-api-cn.mchost.guru'
37
+ const SETTINGS = { traeAuthBaseURL: 'https://api.trae.cn', traeChatBaseURL: MCHOST, traeLoginHost: 'https://www.trae.cn' }
38
+
39
+ const oauth = createTraeOAuth({ readAuth: () => readJson(AUTH_PATH), writeAuth: (v) => { /* 探针不写回 */ } })
40
+ const cred = await oauth.resolveTraeCredential(SETTINGS)
41
+ if (!cred) { console.error('未登录 Trae(先跑 node scripts/probe-trae-live.mjs --login)'); process.exit(2) }
42
+ const token = String(cred.authorization).replace(/^Cloud-IDE-JWT\s+/, '')
43
+ const authStore = readJson(AUTH_PATH)
44
+ const device = authStore.device ?? {}
45
+ const uid = String(authStore.account?.uid ?? '')
46
+ const ideHeaders = (requestId) => ({
47
+ ...traeOutboundHeaders(device, uid ? Number(uid) : undefined, requestId),
48
+ Authorization: `Cloud-IDE-JWT ${token}`,
49
+ 'X-Cloudide-Token': token,
50
+ })
51
+
52
+ // ---------------------------------------------------------------------------
53
+ // [R] remote 面(chat_sessions)baseline
54
+
55
+ async function remoteArm() {
56
+ let sessionId = null
57
+ let messageId = null
58
+ const out = { arm: 'R', transport: 'remote(chat_sessions)' }
59
+ const t0 = Date.now()
60
+ try {
61
+ const created = await createRemoteSession(MCHOST, token, MODEL, [{ role: 'user', content: PROMPT }])
62
+ sessionId = created.sessionId
63
+ messageId = created.messageId
64
+ out.createHttp = 200
65
+ const evResp = await openRemoteEvents(MCHOST, token, sessionId, messageId)
66
+ const raw = await evResp.text()
67
+ out.eventsHttp = evResp.status
68
+ const parser = createRemoteEventParser()
69
+ let visible = ''
70
+ for (const line of raw.split('\n')) {
71
+ const s = line.trim()
72
+ if (!s) continue
73
+ if (s.startsWith('event:')) { parser.lastEventName = s.slice(6).trim(); continue }
74
+ if (s.startsWith('id:') || s.startsWith(':')) continue
75
+ if (!s.startsWith('data:')) continue
76
+ const dataStr = s.slice(5).trim()
77
+ if (!dataStr || dataStr === '[DONE]') continue
78
+ let chunk
79
+ try { chunk = JSON.parse(dataStr) } catch { continue }
80
+ const ev = parser.handle(parser.lastEventName, chunk)
81
+ if (ev.error) out.error = JSON.stringify(ev.error).slice(0, 300)
82
+ if (typeof ev.text === 'string') visible += ev.text
83
+ }
84
+ out.textChars = visible.length
85
+ out.textHead = visible.slice(0, 40)
86
+ out.actualModel = parser.actualModel()
87
+ out.bytes = raw.length
88
+ } catch (err) {
89
+ out.error = String(err?.message ?? err).slice(0, 300)
90
+ } finally {
91
+ if (sessionId) await stopRemoteSession(MCHOST, token, sessionId, messageId).catch(() => {})
92
+ }
93
+ out.ms = Date.now() - t0
94
+ return out
95
+ }
96
+
97
+ // ---------------------------------------------------------------------------
98
+ // raw 面(llm_utils_chat)chat_v3 臂
99
+
100
+ function parseRawSse(raw) {
101
+ const events = []
102
+ let lastEvt = null
103
+ for (const l of raw.split('\n')) {
104
+ if (!l.startsWith('data:')) { if (l.trim().startsWith('event:')) lastEvt = l.trim().slice(6).trim(); continue }
105
+ try {
106
+ const j = JSON.parse(l.slice(5).trim())
107
+ const evName = (typeof j.event === 'string' && j.event) ? j.event : lastEvt
108
+ events.push({ ev: evName ?? null, code: j.code, message: j.message, providerModel: j.provider_model_name, hasToolCalls: Array.isArray(j.tool_calls) && j.tool_calls.length > 0 })
109
+ } catch { /* 非 JSON data 忽略 */ }
110
+ }
111
+ return events
112
+ }
113
+
114
+ async function chatV3Arm(label, withTools) {
115
+ const payload = { model: MODEL, stream: true, messages: [{ role: 'user', content: PROMPT }] }
116
+ if (withTools) {
117
+ payload.tools = [{
118
+ type: 'function',
119
+ function: { name: 'get_current_time', description: '获取当前时间', parameters: { type: 'object', properties: {} } },
120
+ }]
121
+ payload.tool_choice = 'auto'
122
+ }
123
+ const { body, requestId } = buildChatRequest(payload, `outage-${label}`)
124
+ body.function = 'chat_v3'
125
+ const out = { arm: label, fn: 'chat_v3', tools: withTools ? 1 : 0 }
126
+ const t0 = Date.now()
127
+ try {
128
+ const resp = await fetch(`${MCHOST}/api/agent/v3/llm_utils_chat`, {
129
+ method: 'POST', headers: ideHeaders(requestId), body: JSON.stringify(body), signal: AbortSignal.timeout(90_000),
130
+ })
131
+ const raw = await resp.text()
132
+ out.status = resp.status
133
+ out.rawBytes = raw.length
134
+ const events = parseRawSse(raw)
135
+ out.errors = events.filter((e) => e.code != null && e.ev === 'error').slice(0, 2)
136
+ out.providerModels = [...new Set(events.map((e) => e.providerModel).filter(Boolean))]
137
+ out.hasText = events.some((e) => e.ev === 'output' || (e.message != null && !e.code))
138
+ out.hasToolCalls = events.some((e) => e.hasToolCalls)
139
+ } catch (err) {
140
+ out.error = String(err?.message ?? err).slice(0, 200)
141
+ }
142
+ out.ms = Date.now() - t0
143
+ return out
144
+ }
145
+
146
+ // ---------------------------------------------------------------------------
147
+
148
+ const sleep = (ms) => new Promise((r) => setTimeout(r, ms))
149
+ const evidence = {
150
+ at: new Date().toISOString(), model: MODEL, prompt: PROMPT,
151
+ note: 'inline 3003 持续故障下的传输出路探测;判读见 docs/diagnosis-trae-3003.md',
152
+ accountUidMasked: uid.slice(0, 3) + '***',
153
+ arms: [],
154
+ }
155
+
156
+ console.log('[R] remote 面 baseline')
157
+ const r = await remoteArm()
158
+ evidence.arms.push(r)
159
+ console.log(JSON.stringify(r))
160
+
161
+ await sleep(20_000)
162
+ console.log('[C2] chat_v3 无 tools(对照)')
163
+ const c2 = await chatV3Arm('C2', false)
164
+ evidence.arms.push(c2)
165
+ console.log(JSON.stringify(c2))
166
+
167
+ await sleep(20_000)
168
+ console.log('[C3] chat_v3 + tools(主聊天出路判定)')
169
+ const c3 = await chatV3Arm('C3', true)
170
+ evidence.arms.push(c3)
171
+ console.log(JSON.stringify(c3))
172
+
173
+ const outPath = join(process.cwd(), 'docs/probes', `trae-transport-outage-${Date.now()}.json`)
174
+ mkdirSync(dirname(outPath), { recursive: true })
175
+ writeFileSync(outPath, JSON.stringify(evidence, null, 2) + '\n')
176
+ console.log(`证据 → ${outPath}`)