dsh-llm-fallbacks 0.6.13 → 0.8.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/README.md +34 -30
- package/README.zh-CN.md +32 -28
- package/dist/chain-walk.d.ts +197 -0
- package/dist/chains.d.ts +35 -82
- package/dist/client/FallbacksCard.d.ts +27 -80
- package/dist/client/fallbacks-store.d.ts +71 -225
- package/dist/client/index.d.ts +0 -1
- package/dist/client/index.js +1332 -2110
- package/dist/client/locales.d.ts +61 -117
- package/dist/commands.d.ts +70 -112
- package/dist/config.d.ts +152 -117
- package/dist/cooldown.d.ts +1 -15
- package/dist/events.d.ts +8 -8
- package/dist/gateway.d.ts +66 -110
- package/dist/index.d.ts +21 -64
- package/dist/index.js +900 -1313
- package/dist/role-resolution.d.ts +15 -83
- package/dist/schema.d.ts +6 -5
- package/dist/seeds.d.ts +5 -7
- package/dist/state.d.ts +15 -141
- package/dist/subagents-seam.d.ts +51 -14
- package/dist/time-slots.d.ts +21 -24
- package/dist/tui-settings.d.ts +5 -6
- package/dist/virtual-adapter.d.ts +70 -119
- package/docs/DETAIL.md +1 -0
- package/docs/DETAIL.zh.md +1 -0
- package/docs/preview.svg +47 -0
- package/docs/preview.zh.svg +47 -0
- package/locale/en.json +2 -1
- package/locale/zh.json +2 -1
- package/package.json +29 -25
- package/dist/authorized-route.d.ts +0 -68
- package/dist/automatch.d.ts +0 -98
- package/dist/client/GeneralFallbacksRow.d.ts +0 -19
- package/dist/override.d.ts +0 -39
- package/dist/roles.d.ts +0 -90
- package/dist/route-allowlist.d.ts +0 -43
- package/dist/subagent-policy.d.ts +0 -123
package/package.json
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"dsh",
|
|
6
6
|
"dsh-plugin"
|
|
7
7
|
],
|
|
8
|
-
"version": "0.
|
|
8
|
+
"version": "0.8.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.
|
|
69
|
-
"@deepseek-ai/dsh-api-gateway": "^0.2.
|
|
70
|
-
"@deepseek-ai/dsh-api-remotes": "^0.2.
|
|
71
|
-
"@deepseek-ai/dsh-api-session-controller": "^0.2.
|
|
72
|
-
"@deepseek-ai/dsh-client-connection": "^0.2.
|
|
73
|
-
"@deepseek-ai/dsh-client-locale": "^0.2.
|
|
74
|
-
"@deepseek-ai/dsh-client-store": "^0.2.
|
|
75
|
-
"@deepseek-ai/dsh-client-ui-chat": "^0.2.
|
|
76
|
-
"@deepseek-ai/dsh-client-ui-conversation": "^0.2.
|
|
77
|
-
"@deepseek-ai/dsh-client-ui-plugin-manager": "^0.2.
|
|
78
|
-
"@deepseek-ai/dsh-client-ui-renderer": "^0.2.
|
|
79
|
-
"@deepseek-ai/dsh-client-ui-settings": "^0.2.
|
|
80
|
-
"@deepseek-ai/dsh-client-ui-slots": "^0.2.
|
|
81
|
-
"@deepseek-ai/dsh-commands": "^0.2.
|
|
82
|
-
"@deepseek-ai/dsh-llm": "^0.2.
|
|
83
|
-
"@deepseek-ai/dsh-llm-retry": "^0.2.
|
|
84
|
-
"@deepseek-ai/dsh-session": "^0.2.
|
|
85
|
-
"@deepseek-ai/dsh-session-projection": "^0.2.
|
|
86
|
-
"@deepseek-ai/dsh-settings": "^0.2.
|
|
87
|
-
"@deepseek-ai/dsh-system-prompt": "^0.2.
|
|
88
|
-
"@deepseek-ai/dsh-tool-subagent": "^0.2.
|
|
89
|
-
"@deepseek-ai/dsh-typert-protocol": "^0.2.
|
|
90
|
-
"@deepseek-ai/dsh-typert-registry": "^0.2.
|
|
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;
|
package/dist/automatch.d.ts
DELETED
|
@@ -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,19 +0,0 @@
|
|
|
1
|
-
import type { ReactNode } from 'react';
|
|
2
|
-
import type { PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots';
|
|
3
|
-
import type { SnapshotSelectorHook } from '@deepseek-ai/dsh-client-ui-slots';
|
|
4
|
-
import type { FallbacksSettingsController, FallbacksSettingsState } from './fallbacks-store.ts';
|
|
5
|
-
/** Injected dependencies of {@link GeneralFallbacksRow} (slot `inject`). */
|
|
6
|
-
export interface GeneralFallbacksRowInjected {
|
|
7
|
-
/** The shared controller (loaded on first mount, refreshed on pushed invalidations). */
|
|
8
|
-
controller: FallbacksSettingsController;
|
|
9
|
-
/** uSES subscription hook bound to the store (inject face — advisor pattern). */
|
|
10
|
-
useSnapshot: SnapshotSelectorHook<FallbacksSettingsState>;
|
|
11
|
-
}
|
|
12
|
-
/** Props delivered by the slot outlet: runtime share + locale seat + inject face. */
|
|
13
|
-
export type GeneralFallbacksRowProps = PropsRuntime<'settings.general.item'> & PropsLocale<'fallbacks'> & GeneralFallbacksRowInjected;
|
|
14
|
-
/**
|
|
15
|
-
* Render the Fallbacks status row.
|
|
16
|
-
* @param props - composed slot props.
|
|
17
|
-
* @returns the row element tree.
|
|
18
|
-
*/
|
|
19
|
-
export declare function GeneralFallbacksRow({ controller, useSnapshot, t }: GeneralFallbacksRowProps): ReactNode;
|
package/dist/override.d.ts
DELETED
|
@@ -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;
|
package/dist/roles.d.ts
DELETED
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Role resolution for fallback chains (spec §7.1; plan fallbacks-role-runtime
|
|
3
|
-
* Task 1).
|
|
4
|
-
*
|
|
5
|
-
* This module is the RULES stage. Dispatch-time role resolution
|
|
6
|
-
* (plan fallbacks-role-automatch; plan dsh-148 added the dispatch stage) is
|
|
7
|
-
* the four-stage resolver in `role-resolution.ts` — explicit
|
|
8
|
-
* (`session.header.agentPreset`) → dispatch-declared role (the seam record
|
|
9
|
-
* resolved from `**Execute as**`) → this rules stage → an optional auto-match
|
|
10
|
-
* hook; `AgentLike` carries the additive `session.header.agentPreset?`
|
|
11
|
-
* carrier for that explicit stage.
|
|
12
|
-
*
|
|
13
|
-
* Precedence (first hit wins):
|
|
14
|
-
* 1. the first `rules` entry whose specified provider/model patterns match
|
|
15
|
-
* the agent — rules are SUBAGENT-ONLY (PR #62 feedback): a root-origin
|
|
16
|
-
* agent never matches rules and resolves straight to the built-in
|
|
17
|
-
* `'inherit'` (→ `rootChain`). The legacy per-rule `origin` field (a
|
|
18
|
-
* pre-feedback config may still carry `origin: root|subagent`) is
|
|
19
|
-
* IGNORED at match time — every rule applies to subagents regardless
|
|
20
|
-
* of the stored origin value;
|
|
21
|
-
* 2. the built-in `'inherit'` role (no-rule-match default, spec §7.1 / D4).
|
|
22
|
-
*
|
|
23
|
-
* A matched rule must target a declared role id (`roleIds`, derived from
|
|
24
|
-
* `config.roles.list`) or the built-in `'inherit'` — an undeclared target
|
|
25
|
-
* warns and falls back to `'inherit'` (defensive; startup validation already
|
|
26
|
-
* flagged the reference, spec §7.1 / AC-4).
|
|
27
|
-
*
|
|
28
|
-
* Role ids are canonicalized by trim (qc2 F-001, client-canonical trim
|
|
29
|
-
* alignment — `validateFallbacksConfig` trims ids and rule references, so
|
|
30
|
-
* the runtime must too): `roleIds` maps a TRIMMED id to the DECLARED RAW
|
|
31
|
-
* id, membership compares `rule.role.trim()`, and a matched rule returns
|
|
32
|
-
* the declared raw id — so roleDef lookups in `chains.ts` / `commands.ts`
|
|
33
|
-
* match the stored `roles.list[].id` exactly and a padded YAML id
|
|
34
|
-
* (`' coder '`) with a trimmed rule reference (`'coder'`) resolves to the
|
|
35
|
-
* same role instead of silently degrading to `'inherit'`.
|
|
36
|
-
*
|
|
37
|
-
* A missing agent origin is treated as `'root'` — and root agents never
|
|
38
|
-
* match rules (rules are subagent-only, PR #62 feedback). Origin is read
|
|
39
|
-
* from `session.header.origin` — a native `SessionHeader` field the store folds
|
|
40
|
-
* from `CreateSessionOptions.meta.origin` (`packages/core/session/src/
|
|
41
|
-
* index.ts:884`); subagent children set it via `childSessionMeta`
|
|
42
|
-
* (`packages/subagent/subagent/src/child-agent.ts:115`), root agents carry
|
|
43
|
-
* none. A subagent `persona` is NOT readable at the decision point:
|
|
44
|
-
* `AgentOptions` is provider/model/maxTokens only, and persona is installed
|
|
45
|
-
* as a scoped system-prompt section in the child's creation window — see
|
|
46
|
-
* `.mstar/iterations/iter-20260811-fallbacks-mount-only/guides/
|
|
47
|
-
* role-and-model-selection-exploration.md` (Role section).
|
|
48
|
-
*
|
|
49
|
-
* @module dsh-llm-fallbacks/roles
|
|
50
|
-
*/
|
|
51
|
-
import { type FallbacksRoleRule } from './config.ts';
|
|
52
|
-
export type { FallbacksRoleRule } from './config.ts';
|
|
53
|
-
/** Agent origins (spec §3) — an agent property, not a rule constraint:
|
|
54
|
-
* rules are subagent-only (PR #62 feedback). */
|
|
55
|
-
export type Origin = 'root' | 'subagent';
|
|
56
|
-
/** Loose agent shape sufficient for role resolution (spec §3 / brief). */
|
|
57
|
-
export interface AgentLike {
|
|
58
|
-
options?: {
|
|
59
|
-
provider?: string;
|
|
60
|
-
model?: string;
|
|
61
|
-
};
|
|
62
|
-
session?: {
|
|
63
|
-
header?: {
|
|
64
|
-
origin?: Origin;
|
|
65
|
-
/** Dispatch-time explicit role carrier (plan fallbacks-role-automatch Task 2). */
|
|
66
|
-
agentPreset?: string;
|
|
67
|
-
};
|
|
68
|
-
};
|
|
69
|
-
}
|
|
70
|
-
/**
|
|
71
|
-
* Resolve the fallback-chain role for an agent: first matching rule (in
|
|
72
|
-
* listed order) → the built-in `'inherit'` role. A rule targeting an id
|
|
73
|
-
* outside the declared-id set ∪ {'inherit'} warns once and resolves to
|
|
74
|
-
* `'inherit'` (the defensive path — `validateFallbacksConfig` already
|
|
75
|
-
* warned at startup, spec §7.1).
|
|
76
|
-
*
|
|
77
|
-
* `roleIds` is the canonical trimmed-id map built by the wiring
|
|
78
|
-
* (`trimmed id → declared raw id`, see `src/index.ts` apply()): a matched
|
|
79
|
-
* rule returns the declared RAW id so the roleDef lookups in
|
|
80
|
-
* `chains.ts` / `commands.ts` find the stored `roles.list[]` entry exactly
|
|
81
|
-
* (qc2 F-001 — no silent rule inertness on padded YAML ids).
|
|
82
|
-
*
|
|
83
|
-
* `warn` defaults to `console.warn` (direct-call compatibility); the
|
|
84
|
-
* decision path injects the cordis `logger.warn` so every plugin warning
|
|
85
|
-
* flows through the plugin log namespace (qc2 F-002 / qc3 S-3).
|
|
86
|
-
*/
|
|
87
|
-
export declare function resolveRole(agent: AgentLike, rules: FallbacksRoleRule[], roleIds: ReadonlyMap<string, string>, warn?: (message: string) => void, servedRoute?: {
|
|
88
|
-
provider: string;
|
|
89
|
-
model: string;
|
|
90
|
-
}): string;
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Route identity and allowlist intersection on resolved candidates (plan
|
|
3
|
-
* dsh-012-subagent-routing T2; spec D1 ∩ D2).
|
|
4
|
-
*
|
|
5
|
-
* Pure, host-free module: plain route data in, results out. Route identity is
|
|
6
|
-
* the EXACT provider string plus the EXACT model string — no aliasing, no
|
|
7
|
-
* case-folding, no catalog-id substitution (spec Terms). Intersections run on
|
|
8
|
-
* RESOLVED candidates (concrete provider+model after the chain candidate
|
|
9
|
-
* pipeline); this module never resolves chains or expands wildcards — the
|
|
10
|
-
* caller passes already-resolved candidates in.
|
|
11
|
-
*
|
|
12
|
-
* Fail-closed direction: an empty allowlist contains nothing and an empty
|
|
13
|
-
* intersection yields `undefined` — the caller must skip the
|
|
14
|
-
* plugin-originated route rather than fall back to an unproven one (spec D1).
|
|
15
|
-
* Never throws.
|
|
16
|
-
*
|
|
17
|
-
* @module dsh-llm-fallbacks/route-allowlist
|
|
18
|
-
*/
|
|
19
|
-
import type { PolicyRoute } from './subagent-policy.ts';
|
|
20
|
-
/** One resolved chain candidate: a selector anchored to a concrete model id. */
|
|
21
|
-
export type ResolvedCandidate = {
|
|
22
|
-
readonly provider: string;
|
|
23
|
-
readonly model?: string;
|
|
24
|
-
};
|
|
25
|
-
/**
|
|
26
|
-
* Normalize resolved chain candidates into detached plain routes. Candidates
|
|
27
|
-
* without a concrete model id are dropped (they are not routes); every
|
|
28
|
-
* surviving entry is a fresh object, so the result never aliases the
|
|
29
|
-
* caller's candidate list.
|
|
30
|
-
*/
|
|
31
|
-
export declare function resolvedRoutes(candidates: readonly ResolvedCandidate[]): PolicyRoute[];
|
|
32
|
-
/**
|
|
33
|
-
* Whether the route is on the allowlist under exact route identity: both the
|
|
34
|
-
* provider and the model strings must equal an allowed route exactly.
|
|
35
|
-
*/
|
|
36
|
-
export declare function routeOnAllowlist(route: PolicyRoute, allowedModels: readonly PolicyRoute[]): boolean;
|
|
37
|
-
/**
|
|
38
|
-
* The first resolved candidate that is on the allowlist, preserving the
|
|
39
|
-
* candidate order (the chain's first in-allowlist entry wins), or `undefined`
|
|
40
|
-
* when the intersection is empty — the caller then skips the inject / switch
|
|
41
|
-
* and the host seed stands (spec D1 ∩ D2).
|
|
42
|
-
*/
|
|
43
|
-
export declare function firstAllowedCandidate(resolved: readonly PolicyRoute[], allowedModels: readonly PolicyRoute[]): PolicyRoute | undefined;
|
|
@@ -1,123 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Subagent routing policy reader (plan dsh-012-subagent-routing T1; spec D1).
|
|
3
|
-
*
|
|
4
|
-
* Pure, host-free module: plain data in, results out. It resolves the
|
|
5
|
-
* effective subagent model-selection policy from two snapshots the wiring
|
|
6
|
-
* layer extracts from the host:
|
|
7
|
-
*
|
|
8
|
-
* 1. the session's `subagent/model-selection-policy` event payload, read
|
|
9
|
-
* STRUCTURALLY — the upstream reader is not published from
|
|
10
|
-
* `@deepseek-ai/dsh-tool-subagent` and throws on malformed payloads,
|
|
11
|
-
* which is incompatible with the fail-closed no-throw requirement;
|
|
12
|
-
* 2. the host settings service snapshot (`SubagentModelSelectionConfig`
|
|
13
|
-
* `.current()`), typed via a type-only peer import that is erased at emit.
|
|
14
|
-
*
|
|
15
|
-
* The session event wins over settings (ADR read order). Anything present but
|
|
16
|
-
* unreadable yields `'unprovable'` (fail-closed): callers must not emit a
|
|
17
|
-
* plugin-originated route they cannot prove is allowed. This module never
|
|
18
|
-
* throws.
|
|
19
|
-
*
|
|
20
|
-
* @module dsh-llm-fallbacks/subagent-policy
|
|
21
|
-
*/
|
|
22
|
-
import type { SubagentModelSelectionSettings } from '@deepseek-ai/dsh-tool-subagent/model-selection-settings';
|
|
23
|
-
declare module '@deepseek-ai/dsh-session/types' {
|
|
24
|
-
interface SessionEventMap {
|
|
25
|
-
/**
|
|
26
|
-
* Host-recorded route policy for a model-selectable subagent session.
|
|
27
|
-
* The payload shape mirrors upstream exactly, so a future published
|
|
28
|
-
* upstream augmentation merges identically. Read structurally by this
|
|
29
|
-
* plugin; never written here.
|
|
30
|
-
*/
|
|
31
|
-
'subagent/model-selection-policy': {
|
|
32
|
-
/** Exact routes this session may select explicitly for a child. */
|
|
33
|
-
allowedModels: {
|
|
34
|
-
provider: string;
|
|
35
|
-
model: string;
|
|
36
|
-
}[];
|
|
37
|
-
};
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
/** One exact child LLM route (structural twin of upstream `AllowedModelRoute`). */
|
|
41
|
-
export type PolicyRoute = {
|
|
42
|
-
readonly provider: string;
|
|
43
|
-
readonly model: string;
|
|
44
|
-
};
|
|
45
|
-
/**
|
|
46
|
-
* Effective subagent routing policy for one session.
|
|
47
|
-
*
|
|
48
|
-
* - `disabled`: host policy off or absent — selection matches pre-policy
|
|
49
|
-
* behavior.
|
|
50
|
-
* - `enabled`: an allowlist is proven; plugin-originated routes must stay
|
|
51
|
-
* inside it.
|
|
52
|
-
* - `unprovable`: the policy is on but unreadable (malformed event payload,
|
|
53
|
-
* or enabled settings with a malformed route list) — fail-closed; no
|
|
54
|
-
* plugin-originated route may be emitted.
|
|
55
|
-
*/
|
|
56
|
-
export type EffectivePolicy = {
|
|
57
|
-
readonly state: 'disabled';
|
|
58
|
-
} | {
|
|
59
|
-
readonly state: 'enabled';
|
|
60
|
-
readonly allowedModels: readonly PolicyRoute[];
|
|
61
|
-
} | {
|
|
62
|
-
readonly state: 'unprovable';
|
|
63
|
-
};
|
|
64
|
-
/** Outcome of the structural session-event read. */
|
|
65
|
-
export type SessionPolicyEventRead = {
|
|
66
|
-
readonly ok: true;
|
|
67
|
-
readonly allowedModels: PolicyRoute[];
|
|
68
|
-
} | {
|
|
69
|
-
readonly ok: false;
|
|
70
|
-
readonly present: true;
|
|
71
|
-
} | {
|
|
72
|
-
readonly ok: false;
|
|
73
|
-
readonly present: false;
|
|
74
|
-
};
|
|
75
|
-
/** Settings snapshot consumed by the reader — plain structural data, no host objects. */
|
|
76
|
-
export type PolicySettings = {
|
|
77
|
-
readonly enabled: boolean;
|
|
78
|
-
readonly allowedModels: readonly PolicyRoute[];
|
|
79
|
-
};
|
|
80
|
-
/** Assignability guard: fails typecheck if the peer's settings shape drifts from the reader's snapshot contract. */
|
|
81
|
-
type AssertSettingsShape<T extends PolicySettings> = T;
|
|
82
|
-
/**
|
|
83
|
-
* The host settings service snapshot type, re-exported from the published
|
|
84
|
-
* peer subpath (type-only). Wiring reads the service's `current()` and passes
|
|
85
|
-
* the result in as plain data; if upstream drifts, this alias fails typecheck
|
|
86
|
-
* instead of drifting silently at runtime (plan ADR).
|
|
87
|
-
*/
|
|
88
|
-
export type PeerSettingsSnapshot = AssertSettingsShape<SubagentModelSelectionSettings>;
|
|
89
|
-
/**
|
|
90
|
-
* Structurally read the session's `subagent/model-selection-policy` event.
|
|
91
|
-
* Never throws: a present-but-malformed payload is reported, not raised.
|
|
92
|
-
*
|
|
93
|
-
* Recency (qc fix wave S-asym — deliberate asymmetry, both sides mirror
|
|
94
|
-
* upstream): this read takes the FIRST occurrence, exactly like the upstream
|
|
95
|
-
* reader's `.find` — the host writes the policy event at most once per
|
|
96
|
-
* session (its ensure-guard checks the reader before appending), so a second
|
|
97
|
-
* occurrence would already be off-contract. The re-emittable
|
|
98
|
-
* `model/selection` log is the opposite: `authorized-route.ts`
|
|
99
|
-
* `lastModelSelection` scans backwards because upstream's selection
|
|
100
|
-
* projection folds to the newest entry.
|
|
101
|
-
*
|
|
102
|
-
* @param events - plain event descriptors (`type` + optional `data`) captured
|
|
103
|
-
* from the session by the wiring layer.
|
|
104
|
-
* @returns the detached route list when the event is present and valid;
|
|
105
|
-
* otherwise a presence flag distinguishing "no policy event" (pure
|
|
106
|
-
* inheritance path) from "policy event unreadable" (fail-closed).
|
|
107
|
-
*/
|
|
108
|
-
export declare function readSessionPolicyEvent(events: readonly {
|
|
109
|
-
type: string;
|
|
110
|
-
data?: unknown;
|
|
111
|
-
}[]): SessionPolicyEventRead;
|
|
112
|
-
/**
|
|
113
|
-
* Resolve the effective policy from the session-event read and the settings
|
|
114
|
-
* snapshot. The session event wins over settings (ADR read order).
|
|
115
|
-
* Fail-closed: a present-but-malformed event, or enabled settings with a
|
|
116
|
-
* malformed route list, yields `'unprovable'`. Never throws.
|
|
117
|
-
*
|
|
118
|
-
* @param event - result of {@link readSessionPolicyEvent}.
|
|
119
|
-
* @param settings - settings service snapshot, or undefined when the host
|
|
120
|
-
* does not compose the service.
|
|
121
|
-
*/
|
|
122
|
-
export declare function effectivePolicy(event: SessionPolicyEventRead, settings: PolicySettings | undefined): EffectivePolicy;
|
|
123
|
-
export {};
|