@dsh-edge/dsh-edge-agent 0.0.0-stage → 0.1.1
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.
- package/CHANGELOG.md +142 -0
- package/LICENSE +21 -0
- package/README.md +372 -2
- package/config/edge.example.json +179 -0
- package/config/privacy-policy.json +202 -0
- package/cordis.desktop-safe.patch.yml +129 -0
- package/cordis.patch.yml +382 -0
- package/cordis.yml +374 -0
- package/lib/attestation.d.ts +2 -0
- package/lib/attestation.d.ts.map +1 -0
- package/lib/attestation.js +2 -0
- package/lib/audit-log.d.ts +2 -0
- package/lib/audit-log.d.ts.map +1 -0
- package/lib/audit-log.js +2 -0
- package/lib/client.js +87 -0
- package/lib/cloud-llm-adapter.d.ts +2 -0
- package/lib/cloud-llm-adapter.d.ts.map +1 -0
- package/lib/cloud-llm-adapter.js +2 -0
- package/lib/dsh-adapter/attestation.d.ts +42 -0
- package/lib/dsh-adapter/attestation.d.ts.map +1 -0
- package/lib/dsh-adapter/attestation.js +40 -0
- package/lib/dsh-adapter/audit-log.d.ts +139 -0
- package/lib/dsh-adapter/audit-log.d.ts.map +1 -0
- package/lib/dsh-adapter/audit-log.js +376 -0
- package/lib/dsh-adapter/cloud-egress.d.ts +181 -0
- package/lib/dsh-adapter/cloud-egress.d.ts.map +1 -0
- package/lib/dsh-adapter/cloud-egress.js +257 -0
- package/lib/dsh-adapter/cloud-llm-adapter.d.ts +416 -0
- package/lib/dsh-adapter/cloud-llm-adapter.d.ts.map +1 -0
- package/lib/dsh-adapter/cloud-llm-adapter.js +1472 -0
- package/lib/dsh-adapter/contract.d.ts +80 -0
- package/lib/dsh-adapter/contract.d.ts.map +1 -0
- package/lib/dsh-adapter/contract.js +194 -0
- package/lib/dsh-adapter/desktop-cookie-janitor.d.ts +214 -0
- package/lib/dsh-adapter/desktop-cookie-janitor.d.ts.map +1 -0
- package/lib/dsh-adapter/desktop-cookie-janitor.js +409 -0
- package/lib/dsh-adapter/dsh-edge-agent.d.ts +48 -0
- package/lib/dsh-adapter/dsh-edge-agent.d.ts.map +1 -0
- package/lib/dsh-adapter/dsh-edge-agent.js +64 -0
- package/lib/dsh-adapter/edge-config.d.ts +484 -0
- package/lib/dsh-adapter/edge-config.d.ts.map +1 -0
- package/lib/dsh-adapter/edge-config.js +898 -0
- package/lib/dsh-adapter/edge-context-view.d.ts +184 -0
- package/lib/dsh-adapter/edge-context-view.d.ts.map +1 -0
- package/lib/dsh-adapter/edge-context-view.js +483 -0
- package/lib/dsh-adapter/effective-model.d.ts +85 -0
- package/lib/dsh-adapter/effective-model.d.ts.map +1 -0
- package/lib/dsh-adapter/effective-model.js +171 -0
- package/lib/dsh-adapter/etscli-shell-guard.d.ts +244 -0
- package/lib/dsh-adapter/etscli-shell-guard.d.ts.map +1 -0
- package/lib/dsh-adapter/etscli-shell-guard.js +420 -0
- package/lib/dsh-adapter/etscli-tools.d.ts +112 -0
- package/lib/dsh-adapter/etscli-tools.d.ts.map +1 -0
- package/lib/dsh-adapter/etscli-tools.js +393 -0
- package/lib/dsh-adapter/file-logger.d.ts +294 -0
- package/lib/dsh-adapter/file-logger.d.ts.map +1 -0
- package/lib/dsh-adapter/file-logger.js +564 -0
- package/lib/dsh-adapter/function-call-external.d.ts +357 -0
- package/lib/dsh-adapter/function-call-external.d.ts.map +1 -0
- package/lib/dsh-adapter/function-call-external.js +1005 -0
- package/lib/dsh-adapter/host-egress-guard.d.ts +161 -0
- package/lib/dsh-adapter/host-egress-guard.d.ts.map +1 -0
- package/lib/dsh-adapter/host-egress-guard.js +213 -0
- package/lib/dsh-adapter/host-llm-trace.d.ts +198 -0
- package/lib/dsh-adapter/host-llm-trace.d.ts.map +1 -0
- package/lib/dsh-adapter/host-llm-trace.js +344 -0
- package/lib/dsh-adapter/http-api-routes.d.ts +61 -0
- package/lib/dsh-adapter/http-api-routes.d.ts.map +1 -0
- package/lib/dsh-adapter/http-api-routes.js +79 -0
- package/lib/dsh-adapter/http-api-sessions.d.ts +105 -0
- package/lib/dsh-adapter/http-api-sessions.d.ts.map +1 -0
- package/lib/dsh-adapter/http-api-sessions.js +173 -0
- package/lib/dsh-adapter/http-api.d.ts +221 -0
- package/lib/dsh-adapter/http-api.d.ts.map +1 -0
- package/lib/dsh-adapter/http-api.js +1811 -0
- package/lib/dsh-adapter/index.d.ts +62 -0
- package/lib/dsh-adapter/index.d.ts.map +1 -0
- package/lib/dsh-adapter/index.js +97 -0
- package/lib/dsh-adapter/input-guard-messages.d.ts +56 -0
- package/lib/dsh-adapter/input-guard-messages.d.ts.map +1 -0
- package/lib/dsh-adapter/input-guard-messages.js +136 -0
- package/lib/dsh-adapter/input-guard.d.ts +508 -0
- package/lib/dsh-adapter/input-guard.d.ts.map +1 -0
- package/lib/dsh-adapter/input-guard.js +2174 -0
- package/lib/dsh-adapter/intent-prompts.d.ts +77 -0
- package/lib/dsh-adapter/intent-prompts.d.ts.map +1 -0
- package/lib/dsh-adapter/intent-prompts.js +97 -0
- package/lib/dsh-adapter/intent-router.d.ts +710 -0
- package/lib/dsh-adapter/intent-router.d.ts.map +1 -0
- package/lib/dsh-adapter/intent-router.js +2802 -0
- package/lib/dsh-adapter/intent-signals.d.ts +208 -0
- package/lib/dsh-adapter/intent-signals.d.ts.map +1 -0
- package/lib/dsh-adapter/intent-signals.js +391 -0
- package/lib/dsh-adapter/invariant-install.d.ts +16 -0
- package/lib/dsh-adapter/invariant-install.d.ts.map +1 -0
- package/lib/dsh-adapter/invariant-install.js +15 -0
- package/lib/dsh-adapter/invariant.d.ts +16 -0
- package/lib/dsh-adapter/invariant.d.ts.map +1 -0
- package/lib/dsh-adapter/invariant.js +22 -0
- package/lib/dsh-adapter/llm-adapters.d.ts +19 -0
- package/lib/dsh-adapter/llm-adapters.d.ts.map +1 -0
- package/lib/dsh-adapter/llm-adapters.js +16 -0
- package/lib/dsh-adapter/llm-internal-caller.d.ts +92 -0
- package/lib/dsh-adapter/llm-internal-caller.d.ts.map +1 -0
- package/lib/dsh-adapter/llm-internal-caller.js +100 -0
- package/lib/dsh-adapter/llm-max-turns.d.ts +55 -0
- package/lib/dsh-adapter/llm-max-turns.d.ts.map +1 -0
- package/lib/dsh-adapter/llm-max-turns.js +127 -0
- package/lib/dsh-adapter/llm-trace-store.d.ts +131 -0
- package/lib/dsh-adapter/llm-trace-store.d.ts.map +1 -0
- package/lib/dsh-adapter/llm-trace-store.js +205 -0
- package/lib/dsh-adapter/llm-trace.d.ts +450 -0
- package/lib/dsh-adapter/llm-trace.d.ts.map +1 -0
- package/lib/dsh-adapter/llm-trace.js +463 -0
- package/lib/dsh-adapter/local-llm-adapter.d.ts +141 -0
- package/lib/dsh-adapter/local-llm-adapter.d.ts.map +1 -0
- package/lib/dsh-adapter/local-llm-adapter.js +787 -0
- package/lib/dsh-adapter/local-storage.d.ts +96 -0
- package/lib/dsh-adapter/local-storage.d.ts.map +1 -0
- package/lib/dsh-adapter/local-storage.js +198 -0
- package/lib/dsh-adapter/model-router.d.ts +79 -0
- package/lib/dsh-adapter/model-router.d.ts.map +1 -0
- package/lib/dsh-adapter/model-router.js +107 -0
- package/lib/dsh-adapter/ohttp-gateway.d.ts +49 -0
- package/lib/dsh-adapter/ohttp-gateway.d.ts.map +1 -0
- package/lib/dsh-adapter/ohttp-gateway.js +32 -0
- package/lib/dsh-adapter/openai-sse.d.ts +85 -0
- package/lib/dsh-adapter/openai-sse.d.ts.map +1 -0
- package/lib/dsh-adapter/openai-sse.js +462 -0
- package/lib/dsh-adapter/pii-utils.d.ts +96 -0
- package/lib/dsh-adapter/pii-utils.d.ts.map +1 -0
- package/lib/dsh-adapter/pii-utils.js +324 -0
- package/lib/dsh-adapter/plugin-host.d.ts +38 -0
- package/lib/dsh-adapter/plugin-host.d.ts.map +1 -0
- package/lib/dsh-adapter/plugin-host.js +38 -0
- package/lib/dsh-adapter/plugin.d.ts +46 -0
- package/lib/dsh-adapter/plugin.d.ts.map +1 -0
- package/lib/dsh-adapter/plugin.js +100 -0
- package/lib/dsh-adapter/privacy-policy.d.ts +237 -0
- package/lib/dsh-adapter/privacy-policy.d.ts.map +1 -0
- package/lib/dsh-adapter/privacy-policy.js +391 -0
- package/lib/dsh-adapter/prompt-guard.d.ts +152 -0
- package/lib/dsh-adapter/prompt-guard.d.ts.map +1 -0
- package/lib/dsh-adapter/prompt-guard.js +872 -0
- package/lib/dsh-adapter/realm-skill-bridge.d.ts +365 -0
- package/lib/dsh-adapter/realm-skill-bridge.d.ts.map +1 -0
- package/lib/dsh-adapter/realm-skill-bridge.js +1180 -0
- package/lib/dsh-adapter/sanitizer-pipeline.d.ts +140 -0
- package/lib/dsh-adapter/sanitizer-pipeline.d.ts.map +1 -0
- package/lib/dsh-adapter/sanitizer-pipeline.js +431 -0
- package/lib/dsh-adapter/secure-bridge.d.ts +47 -0
- package/lib/dsh-adapter/secure-bridge.d.ts.map +1 -0
- package/lib/dsh-adapter/secure-bridge.js +35 -0
- package/lib/dsh-adapter/session-attribution.d.ts +70 -0
- package/lib/dsh-adapter/session-attribution.d.ts.map +1 -0
- package/lib/dsh-adapter/session-attribution.js +76 -0
- package/lib/dsh-adapter/sessions.d.ts +86 -0
- package/lib/dsh-adapter/sessions.d.ts.map +1 -0
- package/lib/dsh-adapter/sessions.js +179 -0
- package/lib/dsh-adapter/tcm.d.ts +55 -0
- package/lib/dsh-adapter/tcm.d.ts.map +1 -0
- package/lib/dsh-adapter/tcm.js +94 -0
- package/lib/dsh-adapter/td-bus.d.ts +87 -0
- package/lib/dsh-adapter/td-bus.d.ts.map +1 -0
- package/lib/dsh-adapter/td-bus.js +196 -0
- package/lib/dsh-adapter/tool-runner.d.ts +185 -0
- package/lib/dsh-adapter/tool-runner.d.ts.map +1 -0
- package/lib/dsh-adapter/tool-runner.js +271 -0
- package/lib/dsh-adapter/tools.d.ts +118 -0
- package/lib/dsh-adapter/tools.d.ts.map +1 -0
- package/lib/dsh-adapter/tools.js +292 -0
- package/lib/dsh-adapter/types.d.ts +23 -0
- package/lib/dsh-adapter/types.d.ts.map +1 -0
- package/lib/dsh-adapter/types.js +16 -0
- package/lib/dsh-adapter/voice-input.d.ts +30 -0
- package/lib/dsh-adapter/voice-input.d.ts.map +1 -0
- package/lib/dsh-adapter/voice-input.js +34 -0
- package/lib/dsh-adapter/web-search-tavily-bocha.d.ts +152 -0
- package/lib/dsh-adapter/web-search-tavily-bocha.d.ts.map +1 -0
- package/lib/dsh-adapter/web-search-tavily-bocha.js +289 -0
- package/lib/http-api.d.ts +2 -0
- package/lib/http-api.d.ts.map +1 -0
- package/lib/http-api.js +2 -0
- package/lib/index.d.ts +48 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +49 -0
- package/lib/intent-router.d.ts +2 -0
- package/lib/intent-router.d.ts.map +1 -0
- package/lib/intent-router.js +2 -0
- package/lib/llm-adapters.d.ts +2 -0
- package/lib/llm-adapters.d.ts.map +1 -0
- package/lib/llm-adapters.js +2 -0
- package/lib/local-llm-adapter.d.ts +2 -0
- package/lib/local-llm-adapter.d.ts.map +1 -0
- package/lib/local-llm-adapter.js +2 -0
- package/lib/local-storage.d.ts +2 -0
- package/lib/local-storage.d.ts.map +1 -0
- package/lib/local-storage.js +2 -0
- package/lib/model-router.d.ts +2 -0
- package/lib/model-router.d.ts.map +1 -0
- package/lib/model-router.js +2 -0
- package/lib/ohttp-gateway.d.ts +2 -0
- package/lib/ohttp-gateway.d.ts.map +1 -0
- package/lib/ohttp-gateway.js +2 -0
- package/lib/plugin-host.d.ts +2 -0
- package/lib/plugin-host.d.ts.map +1 -0
- package/lib/plugin-host.js +2 -0
- package/lib/privacy-policy.d.ts +2 -0
- package/lib/privacy-policy.d.ts.map +1 -0
- package/lib/privacy-policy.js +2 -0
- package/lib/prompt-guard.d.ts +2 -0
- package/lib/prompt-guard.d.ts.map +1 -0
- package/lib/prompt-guard.js +2 -0
- package/lib/sanitizer-pipeline.d.ts +2 -0
- package/lib/sanitizer-pipeline.d.ts.map +1 -0
- package/lib/sanitizer-pipeline.js +2 -0
- package/lib/secure-bridge.d.ts +2 -0
- package/lib/secure-bridge.d.ts.map +1 -0
- package/lib/secure-bridge.js +2 -0
- package/lib/sessions.d.ts +2 -0
- package/lib/sessions.d.ts.map +1 -0
- package/lib/sessions.js +2 -0
- package/lib/tcm.d.ts +2 -0
- package/lib/tcm.d.ts.map +1 -0
- package/lib/tcm.js +2 -0
- package/lib/td-bus.d.ts +2 -0
- package/lib/td-bus.d.ts.map +1 -0
- package/lib/td-bus.js +2 -0
- package/lib/tools.d.ts +2 -0
- package/lib/tools.d.ts.map +1 -0
- package/lib/tools.js +2 -0
- package/lib/voice-input.d.ts +2 -0
- package/lib/voice-input.d.ts.map +1 -0
- package/lib/voice-input.js +2 -0
- package/package.json +341 -3
- package/presets/agent-preset-edge.json +50 -0
- package/presets/edge.desktop-safe.patch.yml +503 -0
- 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
|
+
}
|