@dsh-edge/dsh-edge-agent 0.0.0-stage → 0.1.2

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 (238) hide show
  1. package/CHANGELOG.md +158 -0
  2. package/LICENSE +21 -0
  3. package/README.md +181 -2
  4. package/config/edge.example.json +179 -0
  5. package/config/privacy-policy.json +202 -0
  6. package/cordis.desktop-safe.patch.yml +129 -0
  7. package/cordis.patch.yml +382 -0
  8. package/cordis.yml +374 -0
  9. package/lib/attestation.d.ts +2 -0
  10. package/lib/attestation.d.ts.map +1 -0
  11. package/lib/attestation.js +2 -0
  12. package/lib/audit-log.d.ts +2 -0
  13. package/lib/audit-log.d.ts.map +1 -0
  14. package/lib/audit-log.js +2 -0
  15. package/lib/client.js +87 -0
  16. package/lib/cloud-llm-adapter.d.ts +2 -0
  17. package/lib/cloud-llm-adapter.d.ts.map +1 -0
  18. package/lib/cloud-llm-adapter.js +2 -0
  19. package/lib/dsh-adapter/attestation.d.ts +42 -0
  20. package/lib/dsh-adapter/attestation.d.ts.map +1 -0
  21. package/lib/dsh-adapter/attestation.js +40 -0
  22. package/lib/dsh-adapter/audit-log.d.ts +139 -0
  23. package/lib/dsh-adapter/audit-log.d.ts.map +1 -0
  24. package/lib/dsh-adapter/audit-log.js +376 -0
  25. package/lib/dsh-adapter/cloud-egress.d.ts +181 -0
  26. package/lib/dsh-adapter/cloud-egress.d.ts.map +1 -0
  27. package/lib/dsh-adapter/cloud-egress.js +257 -0
  28. package/lib/dsh-adapter/cloud-llm-adapter.d.ts +416 -0
  29. package/lib/dsh-adapter/cloud-llm-adapter.d.ts.map +1 -0
  30. package/lib/dsh-adapter/cloud-llm-adapter.js +1472 -0
  31. package/lib/dsh-adapter/contract.d.ts +80 -0
  32. package/lib/dsh-adapter/contract.d.ts.map +1 -0
  33. package/lib/dsh-adapter/contract.js +194 -0
  34. package/lib/dsh-adapter/desktop-cookie-janitor.d.ts +214 -0
  35. package/lib/dsh-adapter/desktop-cookie-janitor.d.ts.map +1 -0
  36. package/lib/dsh-adapter/desktop-cookie-janitor.js +409 -0
  37. package/lib/dsh-adapter/dsh-edge-agent.d.ts +48 -0
  38. package/lib/dsh-adapter/dsh-edge-agent.d.ts.map +1 -0
  39. package/lib/dsh-adapter/dsh-edge-agent.js +64 -0
  40. package/lib/dsh-adapter/edge-config.d.ts +484 -0
  41. package/lib/dsh-adapter/edge-config.d.ts.map +1 -0
  42. package/lib/dsh-adapter/edge-config.js +898 -0
  43. package/lib/dsh-adapter/edge-context-view.d.ts +184 -0
  44. package/lib/dsh-adapter/edge-context-view.d.ts.map +1 -0
  45. package/lib/dsh-adapter/edge-context-view.js +483 -0
  46. package/lib/dsh-adapter/effective-model.d.ts +85 -0
  47. package/lib/dsh-adapter/effective-model.d.ts.map +1 -0
  48. package/lib/dsh-adapter/effective-model.js +171 -0
  49. package/lib/dsh-adapter/etscli-shell-guard.d.ts +244 -0
  50. package/lib/dsh-adapter/etscli-shell-guard.d.ts.map +1 -0
  51. package/lib/dsh-adapter/etscli-shell-guard.js +420 -0
  52. package/lib/dsh-adapter/etscli-tools.d.ts +112 -0
  53. package/lib/dsh-adapter/etscli-tools.d.ts.map +1 -0
  54. package/lib/dsh-adapter/etscli-tools.js +393 -0
  55. package/lib/dsh-adapter/file-logger.d.ts +294 -0
  56. package/lib/dsh-adapter/file-logger.d.ts.map +1 -0
  57. package/lib/dsh-adapter/file-logger.js +564 -0
  58. package/lib/dsh-adapter/function-call-external.d.ts +357 -0
  59. package/lib/dsh-adapter/function-call-external.d.ts.map +1 -0
  60. package/lib/dsh-adapter/function-call-external.js +1005 -0
  61. package/lib/dsh-adapter/host-egress-guard.d.ts +161 -0
  62. package/lib/dsh-adapter/host-egress-guard.d.ts.map +1 -0
  63. package/lib/dsh-adapter/host-egress-guard.js +213 -0
  64. package/lib/dsh-adapter/host-llm-trace.d.ts +198 -0
  65. package/lib/dsh-adapter/host-llm-trace.d.ts.map +1 -0
  66. package/lib/dsh-adapter/host-llm-trace.js +344 -0
  67. package/lib/dsh-adapter/http-api-routes.d.ts +61 -0
  68. package/lib/dsh-adapter/http-api-routes.d.ts.map +1 -0
  69. package/lib/dsh-adapter/http-api-routes.js +79 -0
  70. package/lib/dsh-adapter/http-api-sessions.d.ts +105 -0
  71. package/lib/dsh-adapter/http-api-sessions.d.ts.map +1 -0
  72. package/lib/dsh-adapter/http-api-sessions.js +173 -0
  73. package/lib/dsh-adapter/http-api.d.ts +221 -0
  74. package/lib/dsh-adapter/http-api.d.ts.map +1 -0
  75. package/lib/dsh-adapter/http-api.js +1811 -0
  76. package/lib/dsh-adapter/index.d.ts +62 -0
  77. package/lib/dsh-adapter/index.d.ts.map +1 -0
  78. package/lib/dsh-adapter/index.js +97 -0
  79. package/lib/dsh-adapter/input-guard-messages.d.ts +56 -0
  80. package/lib/dsh-adapter/input-guard-messages.d.ts.map +1 -0
  81. package/lib/dsh-adapter/input-guard-messages.js +136 -0
  82. package/lib/dsh-adapter/input-guard.d.ts +508 -0
  83. package/lib/dsh-adapter/input-guard.d.ts.map +1 -0
  84. package/lib/dsh-adapter/input-guard.js +2174 -0
  85. package/lib/dsh-adapter/intent-prompts.d.ts +77 -0
  86. package/lib/dsh-adapter/intent-prompts.d.ts.map +1 -0
  87. package/lib/dsh-adapter/intent-prompts.js +97 -0
  88. package/lib/dsh-adapter/intent-router.d.ts +710 -0
  89. package/lib/dsh-adapter/intent-router.d.ts.map +1 -0
  90. package/lib/dsh-adapter/intent-router.js +2802 -0
  91. package/lib/dsh-adapter/intent-signals.d.ts +208 -0
  92. package/lib/dsh-adapter/intent-signals.d.ts.map +1 -0
  93. package/lib/dsh-adapter/intent-signals.js +391 -0
  94. package/lib/dsh-adapter/invariant-install.d.ts +16 -0
  95. package/lib/dsh-adapter/invariant-install.d.ts.map +1 -0
  96. package/lib/dsh-adapter/invariant-install.js +15 -0
  97. package/lib/dsh-adapter/invariant.d.ts +16 -0
  98. package/lib/dsh-adapter/invariant.d.ts.map +1 -0
  99. package/lib/dsh-adapter/invariant.js +22 -0
  100. package/lib/dsh-adapter/llm-adapters.d.ts +19 -0
  101. package/lib/dsh-adapter/llm-adapters.d.ts.map +1 -0
  102. package/lib/dsh-adapter/llm-adapters.js +16 -0
  103. package/lib/dsh-adapter/llm-internal-caller.d.ts +92 -0
  104. package/lib/dsh-adapter/llm-internal-caller.d.ts.map +1 -0
  105. package/lib/dsh-adapter/llm-internal-caller.js +100 -0
  106. package/lib/dsh-adapter/llm-max-turns.d.ts +55 -0
  107. package/lib/dsh-adapter/llm-max-turns.d.ts.map +1 -0
  108. package/lib/dsh-adapter/llm-max-turns.js +127 -0
  109. package/lib/dsh-adapter/llm-trace-store.d.ts +131 -0
  110. package/lib/dsh-adapter/llm-trace-store.d.ts.map +1 -0
  111. package/lib/dsh-adapter/llm-trace-store.js +205 -0
  112. package/lib/dsh-adapter/llm-trace.d.ts +450 -0
  113. package/lib/dsh-adapter/llm-trace.d.ts.map +1 -0
  114. package/lib/dsh-adapter/llm-trace.js +463 -0
  115. package/lib/dsh-adapter/local-llm-adapter.d.ts +141 -0
  116. package/lib/dsh-adapter/local-llm-adapter.d.ts.map +1 -0
  117. package/lib/dsh-adapter/local-llm-adapter.js +787 -0
  118. package/lib/dsh-adapter/local-storage.d.ts +96 -0
  119. package/lib/dsh-adapter/local-storage.d.ts.map +1 -0
  120. package/lib/dsh-adapter/local-storage.js +198 -0
  121. package/lib/dsh-adapter/model-router.d.ts +79 -0
  122. package/lib/dsh-adapter/model-router.d.ts.map +1 -0
  123. package/lib/dsh-adapter/model-router.js +107 -0
  124. package/lib/dsh-adapter/ohttp-gateway.d.ts +49 -0
  125. package/lib/dsh-adapter/ohttp-gateway.d.ts.map +1 -0
  126. package/lib/dsh-adapter/ohttp-gateway.js +32 -0
  127. package/lib/dsh-adapter/openai-sse.d.ts +85 -0
  128. package/lib/dsh-adapter/openai-sse.d.ts.map +1 -0
  129. package/lib/dsh-adapter/openai-sse.js +462 -0
  130. package/lib/dsh-adapter/pii-utils.d.ts +96 -0
  131. package/lib/dsh-adapter/pii-utils.d.ts.map +1 -0
  132. package/lib/dsh-adapter/pii-utils.js +324 -0
  133. package/lib/dsh-adapter/plugin-host.d.ts +38 -0
  134. package/lib/dsh-adapter/plugin-host.d.ts.map +1 -0
  135. package/lib/dsh-adapter/plugin-host.js +38 -0
  136. package/lib/dsh-adapter/plugin.d.ts +46 -0
  137. package/lib/dsh-adapter/plugin.d.ts.map +1 -0
  138. package/lib/dsh-adapter/plugin.js +100 -0
  139. package/lib/dsh-adapter/privacy-policy.d.ts +237 -0
  140. package/lib/dsh-adapter/privacy-policy.d.ts.map +1 -0
  141. package/lib/dsh-adapter/privacy-policy.js +391 -0
  142. package/lib/dsh-adapter/prompt-guard.d.ts +152 -0
  143. package/lib/dsh-adapter/prompt-guard.d.ts.map +1 -0
  144. package/lib/dsh-adapter/prompt-guard.js +872 -0
  145. package/lib/dsh-adapter/realm-skill-bridge.d.ts +365 -0
  146. package/lib/dsh-adapter/realm-skill-bridge.d.ts.map +1 -0
  147. package/lib/dsh-adapter/realm-skill-bridge.js +1180 -0
  148. package/lib/dsh-adapter/sanitizer-pipeline.d.ts +140 -0
  149. package/lib/dsh-adapter/sanitizer-pipeline.d.ts.map +1 -0
  150. package/lib/dsh-adapter/sanitizer-pipeline.js +431 -0
  151. package/lib/dsh-adapter/secure-bridge.d.ts +47 -0
  152. package/lib/dsh-adapter/secure-bridge.d.ts.map +1 -0
  153. package/lib/dsh-adapter/secure-bridge.js +35 -0
  154. package/lib/dsh-adapter/session-attribution.d.ts +70 -0
  155. package/lib/dsh-adapter/session-attribution.d.ts.map +1 -0
  156. package/lib/dsh-adapter/session-attribution.js +76 -0
  157. package/lib/dsh-adapter/sessions.d.ts +86 -0
  158. package/lib/dsh-adapter/sessions.d.ts.map +1 -0
  159. package/lib/dsh-adapter/sessions.js +179 -0
  160. package/lib/dsh-adapter/tcm.d.ts +55 -0
  161. package/lib/dsh-adapter/tcm.d.ts.map +1 -0
  162. package/lib/dsh-adapter/tcm.js +94 -0
  163. package/lib/dsh-adapter/td-bus.d.ts +87 -0
  164. package/lib/dsh-adapter/td-bus.d.ts.map +1 -0
  165. package/lib/dsh-adapter/td-bus.js +196 -0
  166. package/lib/dsh-adapter/tool-runner.d.ts +185 -0
  167. package/lib/dsh-adapter/tool-runner.d.ts.map +1 -0
  168. package/lib/dsh-adapter/tool-runner.js +271 -0
  169. package/lib/dsh-adapter/tools.d.ts +118 -0
  170. package/lib/dsh-adapter/tools.d.ts.map +1 -0
  171. package/lib/dsh-adapter/tools.js +292 -0
  172. package/lib/dsh-adapter/types.d.ts +23 -0
  173. package/lib/dsh-adapter/types.d.ts.map +1 -0
  174. package/lib/dsh-adapter/types.js +16 -0
  175. package/lib/dsh-adapter/voice-input.d.ts +30 -0
  176. package/lib/dsh-adapter/voice-input.d.ts.map +1 -0
  177. package/lib/dsh-adapter/voice-input.js +34 -0
  178. package/lib/dsh-adapter/web-search-tavily-bocha.d.ts +152 -0
  179. package/lib/dsh-adapter/web-search-tavily-bocha.d.ts.map +1 -0
  180. package/lib/dsh-adapter/web-search-tavily-bocha.js +289 -0
  181. package/lib/http-api.d.ts +2 -0
  182. package/lib/http-api.d.ts.map +1 -0
  183. package/lib/http-api.js +2 -0
  184. package/lib/index.d.ts +48 -0
  185. package/lib/index.d.ts.map +1 -0
  186. package/lib/index.js +49 -0
  187. package/lib/intent-router.d.ts +2 -0
  188. package/lib/intent-router.d.ts.map +1 -0
  189. package/lib/intent-router.js +2 -0
  190. package/lib/llm-adapters.d.ts +2 -0
  191. package/lib/llm-adapters.d.ts.map +1 -0
  192. package/lib/llm-adapters.js +2 -0
  193. package/lib/local-llm-adapter.d.ts +2 -0
  194. package/lib/local-llm-adapter.d.ts.map +1 -0
  195. package/lib/local-llm-adapter.js +2 -0
  196. package/lib/local-storage.d.ts +2 -0
  197. package/lib/local-storage.d.ts.map +1 -0
  198. package/lib/local-storage.js +2 -0
  199. package/lib/model-router.d.ts +2 -0
  200. package/lib/model-router.d.ts.map +1 -0
  201. package/lib/model-router.js +2 -0
  202. package/lib/ohttp-gateway.d.ts +2 -0
  203. package/lib/ohttp-gateway.d.ts.map +1 -0
  204. package/lib/ohttp-gateway.js +2 -0
  205. package/lib/plugin-host.d.ts +2 -0
  206. package/lib/plugin-host.d.ts.map +1 -0
  207. package/lib/plugin-host.js +2 -0
  208. package/lib/privacy-policy.d.ts +2 -0
  209. package/lib/privacy-policy.d.ts.map +1 -0
  210. package/lib/privacy-policy.js +2 -0
  211. package/lib/prompt-guard.d.ts +2 -0
  212. package/lib/prompt-guard.d.ts.map +1 -0
  213. package/lib/prompt-guard.js +2 -0
  214. package/lib/sanitizer-pipeline.d.ts +2 -0
  215. package/lib/sanitizer-pipeline.d.ts.map +1 -0
  216. package/lib/sanitizer-pipeline.js +2 -0
  217. package/lib/secure-bridge.d.ts +2 -0
  218. package/lib/secure-bridge.d.ts.map +1 -0
  219. package/lib/secure-bridge.js +2 -0
  220. package/lib/sessions.d.ts +2 -0
  221. package/lib/sessions.d.ts.map +1 -0
  222. package/lib/sessions.js +2 -0
  223. package/lib/tcm.d.ts +2 -0
  224. package/lib/tcm.d.ts.map +1 -0
  225. package/lib/tcm.js +2 -0
  226. package/lib/td-bus.d.ts +2 -0
  227. package/lib/td-bus.d.ts.map +1 -0
  228. package/lib/td-bus.js +2 -0
  229. package/lib/tools.d.ts +2 -0
  230. package/lib/tools.d.ts.map +1 -0
  231. package/lib/tools.js +2 -0
  232. package/lib/voice-input.d.ts +2 -0
  233. package/lib/voice-input.d.ts.map +1 -0
  234. package/lib/voice-input.js +2 -0
  235. package/package.json +253 -3
  236. package/presets/agent-preset-edge.json +50 -0
  237. package/presets/edge.desktop-safe.patch.yml +503 -0
  238. package/presets/edge.patch.yml +557 -0
@@ -0,0 +1,118 @@
1
+ /**
2
+ * tools — Realm-aware tool registry *configuration* for dsh-edge-agent.
3
+ *
4
+ * M2 stage: this plugin does NOT maintain a parallel registry. The actual
5
+ * tool storage is `ctx.tools` from `@deepseek-ai/dsh-tools` (DSH upstream).
6
+ * dsh-edge-agent only configures the runtime (default rate limit, scope
7
+ * presentation) and exposes a thin service that downstream plugins call
8
+ * to filter or list the visible tool set by realm.
9
+ *
10
+ * Realm filtering is opt-in — agents that do not care about realm scope
11
+ * see the full upstream tool set. G8 (2026-08-23) wires `enableToolIsolation`
12
+ * to `filterTools(intent)` / `isToolAllowed(name, intent)`, so consumers
13
+ * (http-api, agent-loop) can drive tool visibility from the intent-router
14
+ * verdict. The flag is opt-out so legacy callers see the full set.
15
+ *
16
+ * @module dsh-edge-agent/tools
17
+ */
18
+ import type { Context } from '@deepseek-ai/cordis';
19
+ import { Service } from '@deepseek-ai/cordis';
20
+ import Schema from '@deepseek-ai/schemastery';
21
+ export declare const name = "tools";
22
+ export declare const inject: readonly ["auditLog", "tools"];
23
+ export type ToolRealm = 'LOCAL' | 'CLOUD' | 'SANITIZED';
24
+ export interface Config {
25
+ /** Default rate limit for registered tools that do not specify their own. */
26
+ defaultRateLimitPerMinute: number;
27
+ /** Whether realm isolation (scope restrictions) is active. M2 keeps it on. */
28
+ enableToolIsolation: boolean;
29
+ /** Reflection of the upstream `tools` runtime config this plugin maps on. */
30
+ presentationMode: 'native' | 'code-mode';
31
+ }
32
+ export declare const Config: Schema<Config>;
33
+ export interface ToolSummary {
34
+ name: string;
35
+ description: string;
36
+ realm: ToolRealm;
37
+ }
38
+ export interface ToolsService {
39
+ /** Lightweight snapshot of the current global tool set, optionally filtered by realm. */
40
+ list(realm?: ToolRealm): ToolSummary[];
41
+ /** Returns true when a name is registered globally. */
42
+ has(name: string): boolean;
43
+ /** The realm a tool was tagged with at registration; undefined if unknown. */
44
+ realmOf(name: string): ToolRealm | undefined;
45
+ /** M2 convenience: classify a tool name by its `local-` / `cloud-` / `sanitized-` prefix. */
46
+ classify(name: string): ToolRealm;
47
+ /** G8: tools visible to a given intent-router verdict. REJECT → []. When
48
+ * `enableToolIsolation: false`, returns all tools regardless of intent
49
+ * (legacy / opt-out callers). When `true`, returns the tools whose realm
50
+ * matches `intent.category`. */
51
+ filterTools(intent: IntentLike): ToolSummary[];
52
+ /** G8: single-tool check for the same matrix. False for REJECT, false for
53
+ * realm mismatches under isolation. */
54
+ isToolAllowed(toolName: string, intent: IntentLike): boolean;
55
+ }
56
+ /** Structural shape of an intent-router verdict that `filterTools` /
57
+ * `isToolAllowed` consume. Local to this module to avoid a circular
58
+ * dependency on intent-router.ts — we accept any object that has
59
+ * `category` in the right shape. intent-router's `Intent` already
60
+ * satisfies it. */
61
+ export type IntentLike = {
62
+ readonly category: 'LOCAL' | 'CLOUD' | 'SANITIZED' | 'REJECT';
63
+ };
64
+ declare module '@deepseek-ai/cordis' {
65
+ interface Context {
66
+ edgeTools: ToolsServiceImpl;
67
+ }
68
+ }
69
+ /**
70
+ * Live snapshot of the dsh-edge-agent tool surface. Reads from `ctx.tools`
71
+ * (upstream registry) and the in-memory realm map. The class is
72
+ * intentionally a thin view, not a writer — to add a tool, register
73
+ * through `ctx.tools.register()`.
74
+ *
75
+ * Note: DSH native tools (bash, read, write, edit, web_search, web_fetch)
76
+ * are now used directly. Phase 5 (2026-08-26) hard-codes the realm tags
77
+ * for DSH native tools via `DSH_NATIVE_REALM_MAP` so `filterTools(intent)`
78
+ * correctly hides `web_search` under a LOCAL verdict without relying on
79
+ * prefix heuristics. The map is applied lazily — every `list()` /
80
+ * `filterTools()` call re-projects from the upstream registry, so tools
81
+ * registered after boot (via the `tools/change` event) get the right tag.
82
+ */
83
+ export declare class ToolsServiceImpl extends Service {
84
+ /** Tool name → set of realms it belongs to. A tool can be in multiple realms. */
85
+ private readonly realm;
86
+ private readonly enableToolIsolation;
87
+ /** Default per-tool rate limit (informational; M3 persistence picks it up). */
88
+ private readonly defaultRateLimitPerMinute;
89
+ /** Tool presentation mode (informational; not consulted by this service yet). */
90
+ private readonly presentationMode;
91
+ constructor(ctx: Context, config?: Partial<Config>);
92
+ /** Set realm tag for a tool. Additive — a tool can belong to multiple realms
93
+ * (e.g. bash is both LOCAL and CLOUD). Call after tool registration. */
94
+ setRealm(toolName: string, realm: ToolRealm): void;
95
+ /** Resolve the realms of a tool name. Checks:
96
+ * 1. Explicit setRealm/addRealm calls (multi-realm Set)
97
+ * 2. DSH_NATIVE_MULTI_REALM (bash → [LOCAL, CLOUD])
98
+ * 3. DSH_NATIVE_REALM_MAP (single-realm fallback)
99
+ * 4. classifyByPrefix (default)
100
+ */
101
+ resolveRealms(toolName: string): Set<ToolRealm>;
102
+ /** Backward-compatible single-value resolver. Returns the first realm
103
+ * from the resolved set. For multi-realm tools (like bash), prefer
104
+ * resolveRealms() + Set.has() checks instead. */
105
+ resolveRealm(toolName: string): ToolRealm;
106
+ list(realm?: ToolRealm): ToolSummary[];
107
+ has(name: string): boolean;
108
+ realmOf(name: string): ToolRealm | undefined;
109
+ classify(name: string): ToolRealm;
110
+ /** G8: tools visible under a given intent-router verdict. */
111
+ filterTools(intent: IntentLike): ToolSummary[];
112
+ /** G8: single-tool check (cheaper than `filterTools(intent).some`). */
113
+ isToolAllowed(toolName: string, intent: IntentLike): boolean;
114
+ }
115
+ /** Pure classifier for tests and for the default realm tag. */
116
+ export declare function classifyByPrefix(toolName: string): ToolRealm;
117
+ export declare function apply(ctx: Context, config: Config): Promise<() => Promise<void>>;
118
+ //# sourceMappingURL=tools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../src/dsh-adapter/tools.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,292 @@
1
+ /**
2
+ * tools — Realm-aware tool registry *configuration* for dsh-edge-agent.
3
+ *
4
+ * M2 stage: this plugin does NOT maintain a parallel registry. The actual
5
+ * tool storage is `ctx.tools` from `@deepseek-ai/dsh-tools` (DSH upstream).
6
+ * dsh-edge-agent only configures the runtime (default rate limit, scope
7
+ * presentation) and exposes a thin service that downstream plugins call
8
+ * to filter or list the visible tool set by realm.
9
+ *
10
+ * Realm filtering is opt-in — agents that do not care about realm scope
11
+ * see the full upstream tool set. G8 (2026-08-23) wires `enableToolIsolation`
12
+ * to `filterTools(intent)` / `isToolAllowed(name, intent)`, so consumers
13
+ * (http-api, agent-loop) can drive tool visibility from the intent-router
14
+ * verdict. The flag is opt-out so legacy callers see the full set.
15
+ *
16
+ * @module dsh-edge-agent/tools
17
+ */
18
+ import { Service } from '@deepseek-ai/cordis';
19
+ import Schema from '@deepseek-ai/schemastery';
20
+ export const name = 'tools';
21
+ export const inject = ['auditLog', 'tools'];
22
+ export const Config = Schema.object({
23
+ defaultRateLimitPerMinute: Schema.natural().default(60),
24
+ enableToolIsolation: Schema.boolean().default(true),
25
+ presentationMode: Schema.union(['native', 'code-mode']).default('native'),
26
+ });
27
+ /**
28
+ * Hardcoded realm tags for upstream DSH tools whose default `classifyByPrefix`
29
+ * fallback would be wrong. Phase 5 (2026-08-26) wires web_search / web_fetch
30
+ * (from `@deepseek-ai/dsh-tool-web`) to CLOUD: they trigger outbound calls
31
+ * to DeepSeek's Anthropic-compatible endpoint and must NEVER run under a
32
+ * LOCAL or REJECT intent — see `intent-router` realm routing (G8).
33
+ *
34
+ * Anything not in this map still falls through to `classifyByPrefix`, which
35
+ * returns CLOUD by default (the safe path: explicit refusal rather than
36
+ * silently routing into LOCAL).
37
+ */
38
+ const DSH_NATIVE_REALM_MAP = {
39
+ web_search: 'CLOUD',
40
+ web_fetch: 'CLOUD',
41
+ write: 'LOCAL',
42
+ edit: 'LOCAL',
43
+ glob: 'LOCAL',
44
+ grep: 'LOCAL',
45
+ };
46
+ /**
47
+ * Tools that belong to multiple realms. These override DSH_NATIVE_REALM_MAP
48
+ * when present. `bash` and `read` are tagged both LOCAL and CLOUD so that
49
+ * CLOUD agents can invoke lark-cli (and other safe CLI tools) via bash,
50
+ * and read local files (e.g. skill reference docs like lark-shared/SKILL.md).
51
+ * Since `bash` already grants equivalent file access, `read` in CLOUD is
52
+ * consistent rather than a new risk.
53
+ *
54
+ * `skill` is the universal skill loader — it loads SKILL.md content regardless
55
+ * of realm. The actual realm separation happens at the skill level (ets-* →
56
+ * LOCAL, lark-* → CLOUD) via realm-skill-bridge catalog filtering. Making the
57
+ * tool itself multi-realm lets LOCAL agents load ets-* skills and CLOUD agents
58
+ * load lark-* skills, each seeing only their own catalog.
59
+ */
60
+ const DSH_NATIVE_MULTI_REALM = {
61
+ bash: ['LOCAL', 'CLOUD'],
62
+ read: ['LOCAL', 'CLOUD'],
63
+ skill: ['LOCAL', 'CLOUD'],
64
+ };
65
+ /**
66
+ * Live snapshot of the dsh-edge-agent tool surface. Reads from `ctx.tools`
67
+ * (upstream registry) and the in-memory realm map. The class is
68
+ * intentionally a thin view, not a writer — to add a tool, register
69
+ * through `ctx.tools.register()`.
70
+ *
71
+ * Note: DSH native tools (bash, read, write, edit, web_search, web_fetch)
72
+ * are now used directly. Phase 5 (2026-08-26) hard-codes the realm tags
73
+ * for DSH native tools via `DSH_NATIVE_REALM_MAP` so `filterTools(intent)`
74
+ * correctly hides `web_search` under a LOCAL verdict without relying on
75
+ * prefix heuristics. The map is applied lazily — every `list()` /
76
+ * `filterTools()` call re-projects from the upstream registry, so tools
77
+ * registered after boot (via the `tools/change` event) get the right tag.
78
+ */
79
+ export class ToolsServiceImpl extends Service {
80
+ /** Tool name → set of realms it belongs to. A tool can be in multiple realms. */
81
+ realm = new Map();
82
+ enableToolIsolation;
83
+ /** Default per-tool rate limit (informational; M3 persistence picks it up). */
84
+ defaultRateLimitPerMinute;
85
+ /** Tool presentation mode (informational; not consulted by this service yet). */
86
+ presentationMode;
87
+ constructor(ctx, config) {
88
+ super(ctx, 'edgeTools');
89
+ // G8: Config is now plumbed. Pre-G8 callers (existing tests / single-arg
90
+ // constructor) get isolation OFF by default, which matches the prior
91
+ // behavior (the flag was defined but never applied).
92
+ this.enableToolIsolation = config?.enableToolIsolation ?? false;
93
+ this.defaultRateLimitPerMinute = config?.defaultRateLimitPerMinute ?? 60;
94
+ this.presentationMode = config?.presentationMode ?? 'native';
95
+ }
96
+ /** Set realm tag for a tool. Additive — a tool can belong to multiple realms
97
+ * (e.g. bash is both LOCAL and CLOUD). Call after tool registration. */
98
+ setRealm(toolName, realm) {
99
+ const existing = this.realm.get(toolName) ?? new Set();
100
+ existing.add(realm);
101
+ this.realm.set(toolName, existing);
102
+ }
103
+ /** Resolve the realms of a tool name. Checks:
104
+ * 1. Explicit setRealm/addRealm calls (multi-realm Set)
105
+ * 2. DSH_NATIVE_MULTI_REALM (bash → [LOCAL, CLOUD])
106
+ * 3. DSH_NATIVE_REALM_MAP (single-realm fallback)
107
+ * 4. classifyByPrefix (default)
108
+ */
109
+ resolveRealms(toolName) {
110
+ // 1. Explicit multi-realm tags
111
+ const explicit = this.realm.get(toolName);
112
+ if (explicit !== undefined && explicit.size > 0)
113
+ return explicit;
114
+ // 2. Multi-realm native map
115
+ const multi = DSH_NATIVE_MULTI_REALM[toolName];
116
+ if (multi !== undefined)
117
+ return new Set(multi);
118
+ // 3. Single-realm native map
119
+ const single = DSH_NATIVE_REALM_MAP[toolName];
120
+ if (single !== undefined)
121
+ return new Set([single]);
122
+ // 4. Prefix fallback
123
+ return new Set([classifyByPrefix(toolName)]);
124
+ }
125
+ /** Backward-compatible single-value resolver. Returns the first realm
126
+ * from the resolved set. For multi-realm tools (like bash), prefer
127
+ * resolveRealms() + Set.has() checks instead. */
128
+ resolveRealm(toolName) {
129
+ const realms = this.resolveRealms(toolName);
130
+ return realms.values().next().value;
131
+ }
132
+ list(realm) {
133
+ const upstream = upstreamTools(this.ctx);
134
+ const out = [];
135
+ for (const tool of upstream) {
136
+ const realms = this.resolveRealms(tool.name);
137
+ // When filtering by realm, include tools that belong to that realm
138
+ if (realm !== undefined && !realms.has(realm))
139
+ continue;
140
+ // For the summary, use the first realm (or 'LOCAL' for multi-realm like bash)
141
+ const primaryRealm = realms.values().next().value;
142
+ out.push({ name: tool.name, description: tool.description, realm: primaryRealm });
143
+ }
144
+ return out;
145
+ }
146
+ has(name) {
147
+ return upstreamTools(this.ctx).some((tool) => tool.name === name);
148
+ }
149
+ realmOf(name) {
150
+ const explicit = this.realm.get(name);
151
+ if (explicit !== undefined && explicit.size > 0)
152
+ return explicit.values().next().value;
153
+ const multi = DSH_NATIVE_MULTI_REALM[name];
154
+ if (multi !== undefined)
155
+ return multi[0];
156
+ return DSH_NATIVE_REALM_MAP[name];
157
+ }
158
+ classify(name) {
159
+ return this.resolveRealm(name);
160
+ }
161
+ /** G8: tools visible under a given intent-router verdict. */
162
+ filterTools(intent) {
163
+ if (intent.category === 'REJECT')
164
+ return [];
165
+ if (!this.enableToolIsolation)
166
+ return this.list();
167
+ // Under isolation, include tools whose realm set contains the intent's
168
+ // category. Multi-realm tools (e.g. bash → LOCAL+CLOUD) appear in both.
169
+ const upstream = upstreamTools(this.ctx);
170
+ const out = [];
171
+ for (const tool of upstream) {
172
+ const realms = this.resolveRealms(tool.name);
173
+ if (!realms.has(intent.category))
174
+ continue;
175
+ const primaryRealm = realms.values().next().value;
176
+ out.push({ name: tool.name, description: tool.description, realm: primaryRealm });
177
+ }
178
+ return out;
179
+ }
180
+ /** G8: single-tool check (cheaper than `filterTools(intent).some`). */
181
+ isToolAllowed(toolName, intent) {
182
+ if (intent.category === 'REJECT')
183
+ return false;
184
+ if (!this.enableToolIsolation)
185
+ return this.has(toolName);
186
+ if (!this.has(toolName))
187
+ return false;
188
+ const realms = this.resolveRealms(toolName);
189
+ return realms.has(intent.category);
190
+ }
191
+ }
192
+ /** Pure classifier for tests and for the default realm tag. */
193
+ export function classifyByPrefix(toolName) {
194
+ if (toolName.startsWith('local_'))
195
+ return 'LOCAL';
196
+ if (toolName.startsWith('cloud_'))
197
+ return 'CLOUD';
198
+ if (toolName.startsWith('sanitized_'))
199
+ return 'SANITIZED';
200
+ // Unknown realm — leave it as CLOUD so the cloud path can refuse it
201
+ // explicitly rather than silently routing into LOCAL.
202
+ return 'CLOUD';
203
+ }
204
+ /** Read the global upstream tool list without depending on the dsh-tools types.
205
+ *
206
+ * Cordis exposes registered services through a `ReflectService` proxy on
207
+ * `ctx`: accessing `ctx.tools` triggers a Proxy `get` trap that throws
208
+ * `cannot get property "tools" without inject` when the service has not yet
209
+ * been bound to the active fiber. This happens at apply() time if `tools`
210
+ * has not finished mounting — the loader wires inject dependencies AFTER
211
+ * the apply() body starts. Defensive: catch the proxy throw and return []
212
+ * so `DSH_NATIVE_REALM_MAP` simply skips the boot-time scan. The
213
+ * `tools/change` listener installed below catches up once tools become
214
+ * available.
215
+ */
216
+ function upstreamTools(ctx) {
217
+ let candidate;
218
+ try {
219
+ candidate = ctx.tools;
220
+ }
221
+ catch {
222
+ return [];
223
+ }
224
+ if (candidate?.view === undefined)
225
+ return [];
226
+ const view = candidate.view();
227
+ const visible = view?.visible;
228
+ if (visible === undefined)
229
+ return [];
230
+ const out = [];
231
+ for (const [name, def] of visible.entries()) {
232
+ out.push({ name, description: def.description ?? '' });
233
+ }
234
+ return out;
235
+ }
236
+ export async function apply(ctx, config) {
237
+ // ToolsServiceImpl extends `Service`, so its constructor calls
238
+ // `ctx.reflect.provide('edgeTools', this)` for us. Do not call
239
+ // `ctx.provide` again — that would throw "service already registered".
240
+ // G8: Config now actually flows into the service — `enableToolIsolation`
241
+ // drives `filterTools` / `isToolAllowed`. Pre-G8 had `void config` here.
242
+ const service = new ToolsServiceImpl(ctx, config);
243
+ ctx.logger?.info?.('[edge-tools-registry] apply() called, ctx.edgeTools registered');
244
+ // Phase 5 (2026-08-26): wire `DSH_NATIVE_REALM_MAP` into the live registry.
245
+ // DSH tools are registered by other plugins (`@deepseek-ai/dsh-tool-web`,
246
+ // `dsh-tool-bash`, etc.) AFTER `edge-tools-registry` boots because they
247
+ // live in their own cordis rows. We apply the map immediately for tools
248
+ // already present, then subscribe to `tools/change` so any later
249
+ // registration auto-tags. The handler is a no-op for tools we don't care
250
+ // about (resolveRealm already falls back to classifyByPrefix).
251
+ const bootSnapshot = upstreamTools(ctx);
252
+ ctx.logger?.info?.(`[edge-tools-registry] boot scan: ${bootSnapshot.length} tools visible via ctx.tools`);
253
+ for (const tool of bootSnapshot) {
254
+ // Apply multi-realm native map first
255
+ const multiRealms = DSH_NATIVE_MULTI_REALM[tool.name];
256
+ if (multiRealms !== undefined) {
257
+ for (const r of multiRealms)
258
+ service.setRealm(tool.name, r);
259
+ continue;
260
+ }
261
+ // Then single-realm native map
262
+ const mapped = DSH_NATIVE_REALM_MAP[tool.name];
263
+ if (mapped !== undefined)
264
+ service.setRealm(tool.name, mapped);
265
+ }
266
+ if (bootSnapshot.length > 0) {
267
+ ctx.logger?.info?.(`[edge-tools-registry] boot snapshot: ${bootSnapshot.map((t) => t.name).join(', ')}`);
268
+ }
269
+ const onToolsChange = () => {
270
+ const after = upstreamTools(ctx);
271
+ if (after.length > bootSnapshot.length) {
272
+ ctx.logger?.info?.(`[edge-tools-registry] tools/change → ${after.length} tools now: ${after.map((t) => t.name).join(', ')}`);
273
+ }
274
+ for (const tool of after) {
275
+ const multiRealms = DSH_NATIVE_MULTI_REALM[tool.name];
276
+ if (multiRealms !== undefined) {
277
+ for (const r of multiRealms)
278
+ service.setRealm(tool.name, r);
279
+ continue;
280
+ }
281
+ const mapped = DSH_NATIVE_REALM_MAP[tool.name];
282
+ if (mapped !== undefined)
283
+ service.setRealm(tool.name, mapped);
284
+ }
285
+ };
286
+ // ctx.on returns a disposer; capture so the apply() return closure can
287
+ // tear it down on plugin dispose.
288
+ const disposeChange = ctx.on?.('tools/change', onToolsChange);
289
+ return async () => {
290
+ disposeChange?.();
291
+ };
292
+ }
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Type-only re-exports of every DSH / Cordis surface consumed by the
3
+ * edge-agent plugins. No runtime side effects — this file is `.d.ts`-
4
+ * friendly and is the canonical place the UI / business layer reaches
5
+ * to learn upstream types.
6
+ *
7
+ * Boundary rule: code outside `src/dsh-adapter/` must NOT import
8
+ * `@deepseek-ai/*` directly. It must come through this facade or the
9
+ * services exposed in `src/dsh-adapter/<plugin>.js`.
10
+ *
11
+ * Schemastery note: `@deepseek-ai/schemastery` only ships a default
12
+ * export (`Schema`). Consumers should import that directly when they
13
+ * need a schema constructor. There is no `Schema`/`SchemaOptions`/
14
+ * `TypeSchema` named export to re-export here.
15
+ */
16
+ export type { Context } from '@deepseek-ai/cordis';
17
+ export type { Agent, AgentHandle, AgentStatus, AgentOptions, CreateAgentOptions, PreStepDecision, RequestErrorAction, InboxTarget, } from '@deepseek-ai/dsh-agent';
18
+ export type { LlmAdapter, LlmCallConfig, LlmModelInfo, LlmRuntime, GenerateOptions, Message, StreamChunk, PreparedLlmCall, BlockAssembler, LlmError, LlmProviderInfo, LlmConfigurableProvider, AdapterRegistrationHandle, LlmFailure, } from '@deepseek-ai/dsh-llm';
19
+ export type { Session, SessionId, SessionEvent, SessionHeader, SessionEventMap, TurnEndReason, EpochHeader, } from '@deepseek-ai/dsh-session';
20
+ export type { ToolExecution, ToolExecutionResult, } from '@deepseek-ai/dsh-tools';
21
+ export type { PromptSection, PromptAssembly, } from '@deepseek-ai/dsh-system-prompt';
22
+ export type { Scope, ScopeKey, } from '@deepseek-ai/dsh-scope';
23
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/dsh-adapter/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,YAAY,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAElD,YAAY,EACV,KAAK,EACL,WAAW,EACX,WAAW,EACX,YAAY,EACZ,kBAAkB,EAClB,eAAe,EACf,kBAAkB,EAClB,WAAW,GACZ,MAAM,wBAAwB,CAAA;AAE/B,YAAY,EACV,UAAU,EACV,aAAa,EACb,YAAY,EACZ,UAAU,EACV,eAAe,EACf,OAAO,EACP,WAAW,EACX,eAAe,EACf,cAAc,EACd,QAAQ,EAER,eAAe,EACf,uBAAuB,EACvB,yBAAyB,EACzB,UAAU,GACX,MAAM,sBAAsB,CAAA;AAE7B,YAAY,EACV,OAAO,EACP,SAAS,EACT,YAAY,EACZ,aAAa,EACb,eAAe,EACf,aAAa,EACb,WAAW,GACZ,MAAM,0BAA0B,CAAA;AAEjC,YAAY,EACV,aAAa,EACb,mBAAmB,GACpB,MAAM,wBAAwB,CAAA;AAE/B,YAAY,EACV,aAAa,EACb,cAAc,GACf,MAAM,gCAAgC,CAAA;AAEvC,YAAY,EACV,KAAK,EACL,QAAQ,GACT,MAAM,wBAAwB,CAAA"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Type-only re-exports of every DSH / Cordis surface consumed by the
3
+ * edge-agent plugins. No runtime side effects — this file is `.d.ts`-
4
+ * friendly and is the canonical place the UI / business layer reaches
5
+ * to learn upstream types.
6
+ *
7
+ * Boundary rule: code outside `src/dsh-adapter/` must NOT import
8
+ * `@deepseek-ai/*` directly. It must come through this facade or the
9
+ * services exposed in `src/dsh-adapter/<plugin>.js`.
10
+ *
11
+ * Schemastery note: `@deepseek-ai/schemastery` only ships a default
12
+ * export (`Schema`). Consumers should import that directly when they
13
+ * need a schema constructor. There is no `Schema`/`SchemaOptions`/
14
+ * `TypeSchema` named export to re-export here.
15
+ */
16
+ export {};
@@ -0,0 +1,30 @@
1
+ /**
2
+ * voice-input — optional voice input channel. Wraps Whisper-tiny (or
3
+ * equivalent). Streams PCM in, emits text out, and feeds the result
4
+ * into the prompt-guard pipeline before landing in the agent inbox.
5
+ *
6
+ * @module dsh-edge-agent/voice-input
7
+ */
8
+ import { Service } from '@deepseek-ai/cordis';
9
+ import Schema from '@deepseek-ai/schemastery';
10
+ export declare const name = "voice-input";
11
+ export declare const inject: readonly ["sessions", "auditLog"];
12
+ export interface Config {
13
+ modelPath: string;
14
+ /** VAD silence threshold in seconds. */
15
+ vadSilenceThreshold: number;
16
+ /** Sample rate. */
17
+ sampleRate: number;
18
+ }
19
+ export declare const Config: Schema<Config>;
20
+ export interface VoiceInputService {
21
+ transcribe(audio: Uint8Array): Promise<string>;
22
+ transcribeStream(stream: AsyncIterable<Uint8Array>): Promise<string>;
23
+ }
24
+ export declare class VoiceInputServiceImpl extends Service {
25
+ constructor(ctx: any);
26
+ transcribe(audio: Uint8Array): Promise<string>;
27
+ transcribeStream(stream: AsyncIterable<Uint8Array>): Promise<string>;
28
+ }
29
+ export declare function apply(ctx: any, config: Config): Promise<() => Promise<void>>;
30
+ //# sourceMappingURL=voice-input.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"voice-input.d.ts","sourceRoot":"","sources":["../../src/dsh-adapter/voice-input.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAC7C,OAAO,MAAM,MAAM,0BAA0B,CAAA;AAE7C,eAAO,MAAM,IAAI,gBAAgB,CAAA;AAEjC,eAAO,MAAM,MAAM,mCAAoC,CAAA;AAEvD,MAAM,WAAW,MAAM;IACrB,SAAS,EAAE,MAAM,CAAA;IACjB,wCAAwC;IACxC,mBAAmB,EAAE,MAAM,CAAA;IAC3B,mBAAmB;IACnB,UAAU,EAAE,MAAM,CAAA;CACnB;AAED,eAAO,MAAM,MAAM,EAAE,MAAM,CAAC,MAAM,CAIhC,CAAA;AAEF,MAAM,WAAW,iBAAiB;IAChC,UAAU,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;IAC9C,gBAAgB,CAAC,MAAM,EAAE,aAAa,CAAC,UAAU,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;CACrE;AAED,qBAAa,qBAAsB,SAAQ,OAAO;gBACpC,GAAG,EAAE,GAAG;IAGd,UAAU,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC;IAI9C,gBAAgB,CAAC,MAAM,EAAE,aAAa,CAAC,UAAU,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC;CAI3E;AAED,wBAAsB,KAAK,CAAC,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,CAIlF"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * voice-input — optional voice input channel. Wraps Whisper-tiny (or
3
+ * equivalent). Streams PCM in, emits text out, and feeds the result
4
+ * into the prompt-guard pipeline before landing in the agent inbox.
5
+ *
6
+ * @module dsh-edge-agent/voice-input
7
+ */
8
+ import { Service } from '@deepseek-ai/cordis';
9
+ import Schema from '@deepseek-ai/schemastery';
10
+ export const name = 'voice-input';
11
+ export const inject = ['sessions', 'auditLog'];
12
+ export const Config = Schema.object({
13
+ modelPath: Schema.string().required(),
14
+ vadSilenceThreshold: Schema.number().default(0.6),
15
+ sampleRate: Schema.natural().default(16000),
16
+ });
17
+ export class VoiceInputServiceImpl extends Service {
18
+ constructor(ctx) {
19
+ super(ctx, 'voiceInput');
20
+ }
21
+ async transcribe(audio) {
22
+ void audio;
23
+ return '';
24
+ }
25
+ async transcribeStream(stream) {
26
+ void stream;
27
+ return '';
28
+ }
29
+ }
30
+ export async function apply(ctx, config) {
31
+ ctx.plugin(VoiceInputServiceImpl);
32
+ void config;
33
+ return async () => { };
34
+ }