@twinsearth/dsh-master 3.2.10 → 3.3.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 (93) hide show
  1. package/README.md +3 -0
  2. package/client.js +50 -0
  3. package/dist-host/cost/attribution.js +183 -0
  4. package/dist-host/cost/audit.js +163 -0
  5. package/dist-host/cost/budget.js +211 -0
  6. package/dist-host/cost/bus.js +95 -0
  7. package/dist-host/cost/cert-chain.js +100 -0
  8. package/dist-host/cost/experiment.js +132 -0
  9. package/dist-host/cost/gate.js +189 -0
  10. package/dist-host/cost/host-surface.js +80 -0
  11. package/dist-host/cost/index.js +312 -0
  12. package/dist-host/cost/ledger-report.js +193 -0
  13. package/dist-host/cost/ledger.js +401 -0
  14. package/dist-host/cost/metrics.js +198 -0
  15. package/dist-host/cost/milestones.js +171 -0
  16. package/dist-host/cost/modules/index.js +5 -0
  17. package/dist-host/cost/modules/manifests.js +130 -0
  18. package/dist-host/cost/policy.js +276 -0
  19. package/dist-host/cost/report.js +156 -0
  20. package/dist-host/cost/reuse-report.js +128 -0
  21. package/dist-host/cost/rsi.js +367 -0
  22. package/dist-host/cost/toolface.js +147 -0
  23. package/dist-host/cost/types.js +31 -0
  24. package/dist-host/kernel.js +28 -2
  25. package/dist-host/plugins/cost-optimizer.js +277 -27
  26. package/dist-host/plugins/superagent-router.js +88 -1
  27. package/dist-host/superagent/types.js +8 -0
  28. package/dist-worker/agent-loop.js +449 -7
  29. package/dist-worker/baseline-fit.js +66 -0
  30. package/dist-worker/budget-guard.js +93 -0
  31. package/dist-worker/ccs.js +99 -0
  32. package/dist-worker/cost-hooks.js +115 -0
  33. package/dist-worker/cost-modules.js +330 -0
  34. package/dist-worker/cost-spi.js +3 -0
  35. package/dist-worker/edg.js +372 -0
  36. package/dist-worker/gdr.js +159 -0
  37. package/dist-worker/index.js +80 -2
  38. package/dist-worker/llm-http.js +20 -0
  39. package/dist-worker/sink-http.js +1 -0
  40. package/dist-worker/spill.js +115 -0
  41. package/dist-worker/tool-batch.js +66 -0
  42. package/dist-worker/tool-compact.js +275 -0
  43. package/dist-worker/tool-disclosure.js +90 -0
  44. package/dist-worker/tools.js +16 -0
  45. package/docs/ARCHITECTURE.md +21 -0
  46. package/docs/CHANGELOG.md +50 -0
  47. package/docs/DESIGN-v3.3.0-cost-optimization.md +1053 -0
  48. package/docs/EXPERIMENT-M5-real-ab.md +82 -0
  49. package/docs/THIRD-PARTY.md +87 -0
  50. package/package.json +1 -1
  51. package/src/cost/attribution.ts +186 -0
  52. package/src/cost/audit.ts +170 -0
  53. package/src/cost/budget.ts +226 -0
  54. package/src/cost/bus.ts +97 -0
  55. package/src/cost/cert-chain.ts +102 -0
  56. package/src/cost/experiment.ts +136 -0
  57. package/src/cost/gate.ts +191 -0
  58. package/src/cost/host-surface.ts +97 -0
  59. package/src/cost/index.ts +316 -0
  60. package/src/cost/ledger-report.ts +186 -0
  61. package/src/cost/ledger.ts +385 -0
  62. package/src/cost/metrics.ts +193 -0
  63. package/src/cost/milestones.ts +170 -0
  64. package/src/cost/modules/index.ts +13 -0
  65. package/src/cost/modules/manifests.ts +129 -0
  66. package/src/cost/policy.ts +276 -0
  67. package/src/cost/report.ts +158 -0
  68. package/src/cost/reuse-report.ts +131 -0
  69. package/src/cost/rsi.ts +364 -0
  70. package/src/cost/toolface.ts +151 -0
  71. package/src/cost/types.ts +298 -0
  72. package/src/kernel.ts +27 -2
  73. package/src/plugins/cost-optimizer.ts +271 -26
  74. package/src/plugins/superagent-router.ts +82 -1
  75. package/src/superagent/types.ts +70 -0
  76. package/worker/agent-loop.ts +444 -7
  77. package/worker/baseline-fit.ts +80 -0
  78. package/worker/budget-guard.ts +156 -0
  79. package/worker/ccs.ts +202 -0
  80. package/worker/cost-hooks.ts +133 -0
  81. package/worker/cost-modules.ts +356 -0
  82. package/worker/cost-spi.ts +283 -0
  83. package/worker/edg.ts +424 -0
  84. package/worker/gdr.ts +233 -0
  85. package/worker/index.ts +84 -3
  86. package/worker/llm-http.ts +18 -0
  87. package/worker/sink-http.ts +5 -2
  88. package/worker/spill.ts +133 -0
  89. package/worker/tool-batch.ts +124 -0
  90. package/worker/tool-compact.ts +317 -0
  91. package/worker/tool-disclosure.ts +131 -0
  92. package/worker/tools.ts +553 -531
  93. package/worker/types.ts +191 -0
package/worker/types.ts CHANGED
@@ -88,6 +88,8 @@ export interface LLMUsage {
88
88
  promptTokens?: number
89
89
  completionTokens?: number
90
90
  totalTokens?: number
91
+ /** §11:provider 若返回缓存命中(prompt cache),透传给账本;未返回则省略。 */
92
+ cachedTokens?: number
91
93
  }
92
94
 
93
95
  export interface LLMResponse {
@@ -133,6 +135,8 @@ export interface WorkerTool {
133
135
  name: string
134
136
  description: string
135
137
  parameters: Record<string, unknown>
138
+ /** §11:破坏性动作(写文件/执行命令/建 PR)默认不得进入 EDG 复用池(不变量 I3)。 */
139
+ destructive?: boolean
136
140
  execute(args: Record<string, unknown>, context: ToolExecutionContext): Promise<string>
137
141
  }
138
142
 
@@ -176,6 +180,91 @@ export interface WorkerSink {
176
180
  phase?(phase: WorkerPhase): void
177
181
  /** 流式片段(无真实 streaming 时按块模拟;宿主可转发到 UI)。 */
178
182
  stream?(delta: { content?: string; toolName?: string }): void
183
+ /** 3.3.0 成本观测事件(只读;宿主/路由用于记账,不参与控制流)。 */
184
+ cost?(event: CostHookEvent): void
185
+ }
186
+
187
+ /* ------------------------------------------------------------------ *
188
+ * 3.3.0 成本切点(M1,observe-only)
189
+ *
190
+ * 这是 Worker 内**唯一**的成本观测面:四个函数只在对应时机发出结构化事件,
191
+ * 不改变状态机、预算判定或工具执行;实现方(createCostHooks)负责吞掉所有异常,
192
+ * 保证「省钱可以失败,执行不能受影响」。
193
+ * ------------------------------------------------------------------ */
194
+
195
+ export type CostHookPoint =
196
+ | 'beforeModelCall'
197
+ | 'afterModelResponse'
198
+ | 'beforeToolDispatch'
199
+ | 'afterToolReceipt'
200
+ | 'degraded'
201
+
202
+ export interface WorkerCostUsage {
203
+ input: number
204
+ output: number
205
+ total: number
206
+ }
207
+
208
+ export interface CostHookEvent {
209
+ point: CostHookPoint
210
+ at: number
211
+ ticketId: string
212
+ stepIndex: number
213
+ model?: string
214
+ usage?: WorkerCostUsage
215
+ latencyMs?: number
216
+ historyChars?: number
217
+ toolName?: string
218
+ argsChars?: number
219
+ resultChars?: number
220
+ truncated?: boolean
221
+ /** 3.3.0 M2 · A1 紧凑化的实测归因(shadow 时 applied=false)。 */
222
+ compaction?: {
223
+ module: 'a1-compact'
224
+ mode: string
225
+ applicable: boolean
226
+ applied: boolean
227
+ originalChars: number
228
+ compactChars: number
229
+ savedChars: number
230
+ estimatedTokens: number
231
+ }
232
+ /** 3.3.0 目标 2.1-5:模块异常导致的降级(必须留痕,不得伪装成节省)。 */
233
+ degraded?: {
234
+ module: string
235
+ phase: 'beforeDispatch' | 'afterReceipt' | 'author' | 'guard' | 'substitute' | 'beforeModelCall' | 'afterModelResponse'
236
+ message: string
237
+ count: number
238
+ }
239
+ /** 3.3.0 §6:工具面常驻成本(模块自报 + 实际 schema),供 prompt 成本报表。 */
240
+ toolPrompt?: {
241
+ /** 各 A 模块自报的常驻工具面成本。 */
242
+ moduleTokens: number
243
+ moduleSchemas: number
244
+ /** 本次 Worker 实际注入的工具 schema 成本(chars/4)。 */
245
+ schemaTokens: number
246
+ schemaCount: number
247
+ }
248
+ /** 3.3.0 §6 A2:渐进式纰漏的加载成本(记 governance,不算节省)。 */
249
+ disclosure?: {
250
+ enabled: boolean
251
+ residentCount: number
252
+ loaded: string[]
253
+ loadEvents: number
254
+ schemaTokens: number
255
+ schemaCount: number
256
+ }
257
+ /** 3.3.0 §5.1:本次 usage 是兜底估算(provider 未返回),报表须与实测分列。 */
258
+ estimated?: boolean
259
+ }
260
+
261
+ export interface CostHooks {
262
+ beforeModelCall(input: { ticketId: string; stepIndex: number; model?: string; historyChars: number }): void
263
+ afterModelResponse(input: { ticketId: string; stepIndex: number; usage?: WorkerCostUsage; latencyMs: number; estimated?: boolean }): void
264
+ beforeToolDispatch(input: { ticketId: string; stepIndex: number; toolName: string; argsChars: number }): void
265
+ afterToolReceipt(input: { ticketId: string; stepIndex: number; toolName: string; resultChars: number; truncated: boolean; compaction?: CostHookEvent['compaction'] }): void
266
+ /** 模块异常降级:留痕但不中断执行(目标 2.1-5)。 */
267
+ degraded(input: { ticketId: string; stepIndex: number; module: string; phase: 'beforeDispatch' | 'afterReceipt' | 'author' | 'guard' | 'substitute' | 'beforeModelCall' | 'afterModelResponse'; message: string; count: number }): void
179
268
  }
180
269
 
181
270
  export interface WorkerDeps {
@@ -196,6 +285,34 @@ export interface WorkerDeps {
196
285
  model?: string
197
286
  /** 需要从日志/步骤中抹掉的具体 secret 值(如 LLM key);正则脱敏之外的兜底。 */
198
287
  redactValues?: string[]
288
+ /** 取消信号:中止任务(含替换路径)。 */
289
+ signal?: AbortSignal
290
+ /** 3.3.0:可注入的成本钩子覆盖(测试/宿主自定义);默认由 sink.cost 输出。 */
291
+ costHooks?: Partial<CostHooks>
292
+ /** 3.3.0 M2:工具输出紧凑化模式(off/shadow/enforce);默认读 DSH_MASTER_COMPACT_MODE,缺省 shadow。 */
293
+ compactMode?: string
294
+ /** 3.3.0 模块层:额外注册的 A/B 类模块(按 SPI;内置 A1 已自动注册)。 */
295
+ costModules?: import('./cost-spi.ts').CostModule[]
296
+ /** 3.3.0 §5.2:① 预算闸配置(默认关闭;也可由 DSH_MASTER_BUDGET_* 环境变量启用)。 */
297
+ budget?: import('./budget-guard.ts').WorkerBudgetOptions
298
+ /** 3.3.0 §6 A2:渐进式纰漏配置(默认关闭 ⇒ 全量工具面;也可由 DSH_MASTER_DISCLOSURE=on 启用)。 */
299
+ disclosure?: import('./tool-disclosure.ts').DisclosureOptions
300
+ /** 3.3.0 §6 A3:批量调用引导(默认启用;PTC 模式未实现 ⇒ 显式 skipped)。 */
301
+ batch?: import('./tool-batch.ts').BatchOptions
302
+ /**
303
+ * 3.3.0 §7 B3:认证回调替换(CCS)。默认不配置 ⇒ 完全不替换,行为与 3.2.x 一致。
304
+ * 只有同时给出决策图与 `mode:'enforce'`(且白名单放行)才会真的跳过模型回调。
305
+ */
306
+ ccs?: {
307
+ graph: import('./edg.ts').EdgGraph
308
+ mode?: 'off' | 'shadow' | 'enforce'
309
+ allowlist?: string[]
310
+ forkId?: string
311
+ /** 跳过一次模型回调的预估 token(归因用)。 */
312
+ reserveTokens?: number
313
+ /** I3:显式允许破坏性工具进复用池(默认 false)。 */
314
+ allowDestructive?: boolean
315
+ }
199
316
  }
200
317
 
201
318
  export interface WorkerFailure {
@@ -222,6 +339,80 @@ export interface WorkerResult {
222
339
  draft?: boolean
223
340
  files?: Array<{ path: string; content: string }>
224
341
  }
342
+ /** 3.3.0 M2:本次任务的成本归因汇总(A1 紧凑化;shadow 时只记「本可节省」)。 */
343
+ cost?: {
344
+ compaction: {
345
+ mode: string
346
+ evaluated: number
347
+ applied: number
348
+ originalChars: number
349
+ compactChars: number
350
+ savedChars: number
351
+ estimatedTokens: number
352
+ }
353
+ /** 3.3.0 目标 2.1-5:本次任务发生过的降级(不伪装成节省)。 */
354
+ degraded?: {
355
+ count: number
356
+ events: Array<{ module: string; phase: string; message: string; count: number }>
357
+ }
358
+ /** 3.3.0 §5.1:实测与估算分开上报(provider 未返回 usage 时标记 estimated)。 */
359
+ tokens?: {
360
+ measured: number
361
+ estimated: number
362
+ }
363
+ /** 3.3.0 §6:工具面常驻成本(模块自报 + 实际注入 schema)。 */
364
+ toolPrompt?: {
365
+ moduleTokens: number
366
+ moduleSchemas: number
367
+ schemaTokens: number
368
+ schemaCount: number
369
+ }
370
+ /** 3.3.0 §6 A2:渐进式纰漏的加载成本(记 governance,不算节省)。 */
371
+ disclosure?: {
372
+ enabled: boolean
373
+ residentCount: number
374
+ loaded: string[]
375
+ loadEvents: number
376
+ schemaTokens: number
377
+ schemaCount: number
378
+ }
379
+ /** 3.3.0 §6 A3:批量引导状态(skipped 时显式给出原因)。 */
380
+ batch?: {
381
+ state: 'active' | 'skipped'
382
+ reason: string | null
383
+ mode: string
384
+ taught: boolean
385
+ corrections: number
386
+ }
387
+ /** 3.3.0 §7 B3/M3:替换结果、守卫尝试与「本可节省」证据。 */
388
+ ccs?: {
389
+ mode: string
390
+ skippedModelCalls: number
391
+ /** M3:每次复用尝试(命中率分母)。 */
392
+ attempts: Array<{ toolName: string; hit: boolean; reason: string | null; stage: string | null; edgeId: string | null; wouldSaveTokens: number; stepIndex: number }>
393
+ /** M3:shadow 下算出的「本可替换」证书(未派发)。 */
394
+ shadowCertificates: Array<Record<string, unknown>>
395
+ substitutions: Array<{
396
+ edgeId: string
397
+ toolName: string
398
+ schemaHash: string
399
+ guardExpr: string
400
+ receiptDigest: string
401
+ replacedCallbackId: string
402
+ viaNativeDispatcher: true
403
+ taskId: string
404
+ step: number
405
+ dispatched: boolean
406
+ error?: string
407
+ resultDigest?: string
408
+ resultChars?: number
409
+ savedTokens?: number
410
+ moduleId?: string
411
+ at: number
412
+ }>
413
+ guard: { matches: number; hits: number; hitRate: number; byReason: Record<string, number> }
414
+ }
415
+ }
225
416
  }
226
417
 
227
418
  export interface WorkerSnapshot {