dsh-llm-fallbacks 0.6.13 → 0.7.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.
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "dsh",
6
6
  "dsh-plugin"
7
7
  ],
8
- "version": "0.6.13",
8
+ "version": "0.7.0",
9
9
  "type": "module",
10
10
  "main": "./dist/index.js",
11
11
  "types": "./dist/index.d.ts",
@@ -28,7 +28,11 @@
28
28
  "bundle",
29
29
  "locale",
30
30
  "icon.svg",
31
- "scripts"
31
+ "scripts",
32
+ "docs/DETAIL.md",
33
+ "docs/DETAIL.zh.md",
34
+ "docs/preview.svg",
35
+ "docs/preview.zh.svg"
32
36
  ],
33
37
  "dsh": {
34
38
  "bundle": {
@@ -65,29 +69,29 @@
65
69
  },
66
70
  "peerDependencies": {
67
71
  "@deepseek-ai/cordis": "^4.0.5",
68
- "@deepseek-ai/dsh-agent": "^0.2.1-rc.4",
69
- "@deepseek-ai/dsh-api-gateway": "^0.2.1-rc.4",
70
- "@deepseek-ai/dsh-api-remotes": "^0.2.1-rc.4",
71
- "@deepseek-ai/dsh-api-session-controller": "^0.2.1-rc.4",
72
- "@deepseek-ai/dsh-client-connection": "^0.2.1-rc.4",
73
- "@deepseek-ai/dsh-client-locale": "^0.2.1-rc.4",
74
- "@deepseek-ai/dsh-client-store": "^0.2.1-rc.4",
75
- "@deepseek-ai/dsh-client-ui-chat": "^0.2.1-rc.4",
76
- "@deepseek-ai/dsh-client-ui-conversation": "^0.2.1-rc.4",
77
- "@deepseek-ai/dsh-client-ui-plugin-manager": "^0.2.1-rc.4",
78
- "@deepseek-ai/dsh-client-ui-renderer": "^0.2.1-rc.4",
79
- "@deepseek-ai/dsh-client-ui-settings": "^0.2.1-rc.4",
80
- "@deepseek-ai/dsh-client-ui-slots": "^0.2.1-rc.4",
81
- "@deepseek-ai/dsh-commands": "^0.2.1-rc.4",
82
- "@deepseek-ai/dsh-llm": "^0.2.1-rc.4",
83
- "@deepseek-ai/dsh-llm-retry": "^0.2.1-rc.4",
84
- "@deepseek-ai/dsh-session": "^0.2.1-rc.4",
85
- "@deepseek-ai/dsh-session-projection": "^0.2.1-rc.4",
86
- "@deepseek-ai/dsh-settings": "^0.2.1-rc.4",
87
- "@deepseek-ai/dsh-system-prompt": "^0.2.1-rc.4",
88
- "@deepseek-ai/dsh-tool-subagent": "^0.2.1-rc.4",
89
- "@deepseek-ai/dsh-typert-protocol": "^0.2.1-rc.4",
90
- "@deepseek-ai/dsh-typert-registry": "^0.2.1-rc.4",
72
+ "@deepseek-ai/dsh-agent": "^0.2.2-rc.1",
73
+ "@deepseek-ai/dsh-api-gateway": "^0.2.2-rc.1",
74
+ "@deepseek-ai/dsh-api-remotes": "^0.2.2-rc.1",
75
+ "@deepseek-ai/dsh-api-session-controller": "^0.2.2-rc.1",
76
+ "@deepseek-ai/dsh-client-connection": "^0.2.2-rc.1",
77
+ "@deepseek-ai/dsh-client-locale": "^0.2.2-rc.1",
78
+ "@deepseek-ai/dsh-client-store": "^0.2.2-rc.1",
79
+ "@deepseek-ai/dsh-client-ui-chat": "^0.2.2-rc.1",
80
+ "@deepseek-ai/dsh-client-ui-conversation": "^0.2.2-rc.1",
81
+ "@deepseek-ai/dsh-client-ui-plugin-manager": "^0.2.2-rc.1",
82
+ "@deepseek-ai/dsh-client-ui-renderer": "^0.2.2-rc.1",
83
+ "@deepseek-ai/dsh-client-ui-settings": "^0.2.2-rc.1",
84
+ "@deepseek-ai/dsh-client-ui-slots": "^0.2.2-rc.1",
85
+ "@deepseek-ai/dsh-commands": "^0.2.2-rc.1",
86
+ "@deepseek-ai/dsh-llm": "^0.2.2-rc.1",
87
+ "@deepseek-ai/dsh-llm-retry": "^0.2.2-rc.1",
88
+ "@deepseek-ai/dsh-session": "^0.2.2-rc.1",
89
+ "@deepseek-ai/dsh-session-projection": "^0.2.2-rc.1",
90
+ "@deepseek-ai/dsh-settings": "^0.2.2-rc.1",
91
+ "@deepseek-ai/dsh-system-prompt": "^0.2.2-rc.1",
92
+ "@deepseek-ai/dsh-tool-subagent": "^0.2.2-rc.1",
93
+ "@deepseek-ai/dsh-typert-protocol": "^0.2.2-rc.1",
94
+ "@deepseek-ai/dsh-typert-registry": "^0.2.2-rc.1",
91
95
  "@deepseek-ai/schemastery": "^3.18.5",
92
96
  "react": "^18.2.0"
93
97
  },
@@ -1,68 +0,0 @@
1
- /**
2
- * Authorized-route detection from durable child state (plan
3
- * dsh-012-subagent-routing T2; spec D2).
4
- *
5
- * Pure, host-free module: a plain-data session view in, one route out. The
6
- * wiring captures the view at a subagent's first request from the detection
7
- * sources the plan names (shapes verified against upstream
8
- * `packages/subagent/subagent/src/child-agent.ts:68-85` and
9
- * `packages/api/session-controller/src/types.ts:284`):
10
- *
11
- * - the session's `model/selection` log entries (plain descriptors; payload
12
- * is the `ModelSelection` shape — provider, model, optional
13
- * reasoningEffort), an explicit host-recorded selection for this session;
14
- * - the durable `request/header` config fold (`requestHeader()?.config`);
15
- * - the resolved creation options (`agent.options`) as the pre-first-request
16
- * fallback — upstream precedence: the durable header wins, options
17
- * fallback (`parentAgentOptionsForDelegation`);
18
- * - the pure-inheritance baseline: the delegating parent's current route,
19
- * resolved by the wiring the same way (`requestHeader()?.config` else
20
- * creation options).
21
- *
22
- * A source yields a route only when BOTH provider and model are present
23
- * non-empty strings — an effort alone is not a route (spec Terms). A
24
- * `model/selection` entry is definitionally an explicit selection, so it is
25
- * authorized as-is. A route read from the header or the creation options is
26
- * explicit only when it is NOT the pure-inheritance continuation: when the
27
- * baseline is provable (complete) and equals the candidate exactly, the
28
- * candidate is the parent's inherited route, not a selection — pure
29
- * inheritance is NOT an authorized route (spec Terms; upstream
30
- * `resolveChildAgentOptions` materializes the parent route into child
31
- * options even without an explicit selection, so equality with the baseline
32
- * is the only child-side inheritance signal). With the baseline unprovable
33
- * the candidate stands: D2 keeps authorized chain heads unoverwritten, and
34
- * the allowlist-constrained inject below this decision holds D1 either way.
35
- *
36
- * Never throws; malformed source shapes yield `undefined`, not routes.
37
- *
38
- * @module dsh-llm-fallbacks/authorized-route
39
- */
40
- import type { PolicyRoute } from './subagent-policy.ts';
41
- /** One plain route-bearing source shape (header config, options, selection payload, baseline). */
42
- export type RouteSource = {
43
- readonly provider?: unknown;
44
- readonly model?: unknown;
45
- readonly reasoningEffort?: unknown;
46
- };
47
- /** Structural session view consumed by {@link detectAuthorizedRoute} — plain data only, no live host objects. */
48
- export interface AuthorizedRouteSession {
49
- /** Durable request-header config fold captured from the child session (absent before the first logged header). */
50
- readonly requestHeader?: RouteSource | undefined;
51
- /** Plain event descriptors (`type` + optional `data`) captured from the child session's log. */
52
- readonly events?: readonly {
53
- readonly type: string;
54
- readonly data?: unknown;
55
- }[] | undefined;
56
- /** Resolved creation options captured from the agent (pre-first-request fallback). */
57
- readonly options?: RouteSource | undefined;
58
- /** Pure-inheritance baseline: the delegating parent's current route (absent when unprovable). */
59
- readonly inherited?: RouteSource | undefined;
60
- }
61
- /**
62
- * Detect the subagent's explicit authorized route at its first request, or
63
- * `undefined` for pure inheritance (semantics in the module doc). The wiring
64
- * skips role-inject on a defined result — the authorized route is the chain
65
- * head (spec D2) — and runs the allowlist-constrained four-stage inject on
66
- * `undefined`.
67
- */
68
- export declare function detectAuthorizedRoute(session: AuthorizedRouteSession): PolicyRoute | undefined;
@@ -1,98 +0,0 @@
1
- /**
2
- * LLM auto-match role selection (plan fallbacks-role-automatch Task 3).
3
- *
4
- * This module is the bounded LLM caller behind the resolver's stage-3
5
- * auto-match hook (`resolveRoleAtDispatch`, `role-resolution.ts`). When the
6
- * explicit and rules stages resolve to `'inherit'` and `roleAutoMatch` is
7
- * enabled, `pickRoleByLlm` asks the model to pick the best-fit declared role
8
- * from the taxonomy and returns its declared RAW id, or `null` (= `'inherit'`).
9
- *
10
- * Contract (architect-locked, plan Global Constraints · Auto-match bounded):
11
- * - ONE bounded completion per decision: small `maxTokens`
12
- * ({@link AUTOMATCH_MAX_TOKENS}) and a timeout
13
- * ({@link AUTOMATCH_TIMEOUT_MS}, default 5s) that abandons the stream via
14
- * the streaming contract's cancellation (`options.signal`) — no dangling
15
- * iterator, no unhandled rejection.
16
- * - Never throws. Every failure mode — throw, timeout, `none`, no valid id,
17
- * garbage answer, malformed inputs — resolves to `null`, so the "never
18
- * throws out of `agent/request`" invariant holds end-to-end (the resolver
19
- * deliberately does NOT catch the hook).
20
- * - Fast paths that avoid an LLM call entirely: empty taxonomy, absent
21
- * `ctx.llm` service, and no concrete provider/model route for the judgment
22
- * call. The plugin does NOT listen on `llm/stream`, so this call cannot
23
- * recurse into the plugin.
24
- *
25
- * Judgment-call route choice (documented): the concrete provider/model for the
26
- * judgment call is taken from the roles' DECLARED context first — the first
27
- * exact (non-wildcard) `provider/model` selector across the declared chains,
28
- * in declaration order (the operator's own taxonomy is the most stable route
29
- * set). If no declared chain yields an exact selector, the agent's current
30
- * `options.provider`/`options.model` is used when both halves are present;
31
- * otherwise the call is skipped (`null`).
32
- *
33
- * Pure helpers exported for unit testing:
34
- * - {@link buildAutomatchPrompt} — the taxonomy prompt (declared ids +
35
- * personas + agent origin/agentPreset; instructs exactly-one-declared-id-or-
36
- * `none`).
37
- * - {@link parseAutomatchAnswer} — parses a declared id out of the model
38
- * answer with surrounding whitespace/punctuation/quote/backtick tolerance;
39
- * `none` (case-insensitive) and unknown ids → `null`. `roleIds` is the
40
- * trimmed-id → declared-raw-id map, the same canonicalization the resolver
41
- * uses.
42
- *
43
- * @module dsh-llm-fallbacks/automatch
44
- */
45
- import { type GenerateOptions, type StreamChunk } from '@deepseek-ai/dsh-llm';
46
- import type { FallbacksRole, FallbacksRoles } from './config.ts';
47
- import type { AgentLike } from './roles.ts';
48
- /** Default auto-match completion timeout in ms — abandons the stream. */
49
- export declare const AUTOMATCH_TIMEOUT_MS = 5000;
50
- /** Output bound (tokens) for the judgment call: one id or the literal `none`. */
51
- export declare const AUTOMATCH_MAX_TOKENS = 32;
52
- /**
53
- * Minimal `llm` service surface {@link pickRoleByLlm} reads. The real
54
- * `LlmRuntime.stream(options)` matches structurally; this face keeps the
55
- * module free of the full cordis Context merge.
56
- */
57
- export interface AutomatchLlm {
58
- stream(options: GenerateOptions): AsyncIterable<StreamChunk>;
59
- }
60
- /**
61
- * Minimal context surface: `ctx.get('llm')` (optional service — absent →
62
- * `null` fast-path). The broad `get(name: string)` face is satisfied by the
63
- * real cordis `Context` (`ReflectService.get` overloads return `any`/the
64
- * merged service), so the Task-4 wiring can pass `ctx` directly.
65
- */
66
- export interface AutomatchContext {
67
- get(name: string): AutomatchLlm | undefined;
68
- }
69
- /** Options for {@link pickRoleByLlm}. */
70
- export interface PickRoleByLlmOptions {
71
- /** Completion timeout in ms; defaults to {@link AUTOMATCH_TIMEOUT_MS}. */
72
- timeoutMs?: number;
73
- /** Warning sink — the decision path injects the plugin logger. */
74
- warn: (message: string) => void;
75
- }
76
- /**
77
- * Build the auto-match taxonomy prompt: every declared role's trimmed id and
78
- * persona, the agent's origin (and non-empty `agentPreset` when present), and
79
- * the exactly-one-declared-id-or-`none` instruction. Pure — no I/O.
80
- */
81
- export declare function buildAutomatchPrompt(roles: readonly FallbacksRole[], agent: AgentLike): string;
82
- /**
83
- * Parse the model's answer into a declared role id.
84
- *
85
- * The answer is expected to BE an id (possibly wrapped in whitespace, quotes,
86
- * backticks, or trailing punctuation); surrounding characters outside the id
87
- * grammar (`[a-zA-Z0-9-]`) are stripped, then the remaining string must match
88
- * a declared id exactly (case-insensitive) via `roleIds` (trimmed id →
89
- * declared RAW id, the resolver's canonicalization). `none` (case-insensitive)
90
- * and any unknown/malformed answer → `null`.
91
- */
92
- export declare function parseAutomatchAnswer(answer: string, roleIds: ReadonlyMap<string, string>): string | null;
93
- /**
94
- * Bounded LLM role-selection call (see module header). Resolves the declared
95
- * RAW id of the best-fit role, or `null` on any fast path or failure. NEVER
96
- * throws.
97
- */
98
- export declare function pickRoleByLlm(ctx: AutomatchContext, roles: FallbacksRoles, agent: AgentLike, opts: PickRoleByLlmOptions): Promise<string | null>;
@@ -1,39 +0,0 @@
1
- /**
2
- * RouteChanged effort rule for config overrides (plan dsh-012-subagent-routing
3
- * T4; spec D3).
4
- *
5
- * Pure, host-free module: plain seed config plus a target route in, the
6
- * overridden config out. The effort handling mirrors the upstream
7
- * `resolveChildAgentOptions` rule (deepseek-harness
8
- * `subagent/src/child-agent.ts:117`): a changed provider+model route drops the
9
- * seed's route-owned `reasoningEffort` so the selected model resolves its own
10
- * default, unless an effort is explicitly named for the override; an
11
- * unchanged route keeps the seed effort. Policy-independent by design — the
12
- * same rule applies on every override path whether the subagent routing
13
- * policy is on or off (spec D3). Never throws.
14
- *
15
- * @module dsh-llm-fallbacks/override
16
- */
17
- import type { LlmCallConfig } from '@deepseek-ai/dsh-llm';
18
- /** Reasoning-effort value carried by `LlmCallConfig.reasoningEffort`. */
19
- export type LlmReasoningEffort = NonNullable<LlmCallConfig['reasoningEffort']>;
20
- /**
21
- * Override a request config with a target route under the upstream
22
- * routeChanged effort rule (spec D3):
23
- *
24
- * - An explicitly named effort always survives — it wins over the seed effort
25
- * on either route (upstream semantics: the request overrides the parent).
26
- * - Same provider+model route → the seed `reasoningEffort` is preserved.
27
- * - Route changed without an explicit effort → the seed effort is dropped
28
- * (never carry a stale effort into a different provider/model route).
29
- *
30
- * @param seed - the caller's current request config.
31
- * @param to - the effective target route.
32
- * @param explicitEffort - an effort explicitly named for this override.
33
- * @returns a fresh config routed to `to` with the effort rule applied; never
34
- * mutates `seed`.
35
- */
36
- export declare function overrideConfigWithRouteRule(seed: LlmCallConfig, to: {
37
- provider: string;
38
- model: string;
39
- }, explicitEffort?: LlmReasoningEffort): LlmCallConfig;