dsh-llm-fallbacks 0.5.1 → 0.5.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.
package/README.md CHANGED
@@ -190,7 +190,7 @@ The durable fix belongs upstream at the migration edges (the frozen V0→V1 edge
190
190
  - **Dispatch-time role resolution**: on a subagent's first request its role is resolved in three stages — explicit (`agentPreset` matches a declared role id) → deterministic rules (matching either the recorded pair or the served head — see [FallbacksChain in the model picker](#fallbackschain-in-the-model-picker)) → LLM auto-match from the declared role taxonomy (`fallbacks.roleAutoMatch`, default `true`). The resolved role's chain-head model is injected into the first request and recorded via an explicit `role → model` log line (no durable `fallbacks/switch` event is written — issue #52 stop-write); set `roleAutoMatch: false` to disable the LLM auto-match stage (the explicit `agentPreset` stage still applies — with no explicit role this reproduces the previous rules-only behavior). The settings card always renders an **Enable role auto-match** switch (default `true`) to toggle it — the schema default applies even to legacy configs that never declared the key.
191
191
  - **Role persona on the child (chain-independent)**: when a subagent's dispatch declares a role this plugin knows (the `**Execute as**: <id>` field of its Assignment), that role's `persona` is installed on the child as its own persona — the role is the child's identity, not only a routing decision, and delivery does not depend on routing: a role with an empty `chain` gets its persona exactly like a chained one (the chain only picks the model). A persona the caller already set is never overwritten; a provider that cannot carry a persona skips it and the dispatch runs natively.
192
192
  - **Role announced inside the subagent's own session**: a child dispatched with a declared role gets exactly one plugin notice row in its own session, naming the role it was dispatched as — `[role: <id>]`, with ` (persona not applied)` when the role declares a persona that was skipped — written once at the child's first non-empty pre-step, never for a root session and never for `inherit`/unresolved dispatches. The row is a durable transcript row, so the role stays readable in the child's session after it settles.
193
- - **Subagent role badge**: when a subagent is **dispatched with a declared role** — the `**Execute as**: <id>` field of its Assignment, the same declaration that carries the persona, and the badge's ONLY source (policy on or off) — its session shows a compact role badge next to the session title in the web session header; hover shows `role → latest request route` (the route of the newest recorded request, not the dispatch-time route). Only the DECLARED header is read, so a child whose role came from another stage (`agentPreset` match, a role rule, or the LLM auto-match) but which declares no Assignment header is still routed as that role yet shows **no** badge — the badge never reports a role inferred after the fact. `inherit`/unresolved sessions render no badge. The badge is durable: it is read from the child's own session record, so it is still shown for a **settled** subagent session and **after a host restart**.
193
+ - **Subagent role badge**: when a subagent is **dispatched with a declared role** — the `**Execute as**: <id>` field of its Assignment, the same declaration that carries the persona, and the badge's ONLY source (policy on or off) — its session shows a compact role badge next to the session's agent-preset (mode) chip in the web session header; hover shows `role → latest request route` (the route of the newest recorded request, not the dispatch-time route). Only the DECLARED header is read, so a child whose role came from another stage (`agentPreset` match, a role rule, or the LLM auto-match) but which declares no Assignment header is still routed as that role yet shows **no** badge — the badge never reports a role inferred after the fact. `inherit`/unresolved sessions render no badge. The badge is durable: it is read from the child's own session record, so it is still shown for a **settled** subagent session and **after a host restart**.
194
194
  - **Context-window-aware fallback**: `triggerCodes` accepts any dsh failure code, including `CONTEXT_WINDOW_EXCEEDED` — a request too big for the current model fails over to a candidate with a **larger** context window (candidates that cannot fit either are skipped), and because the route itself is healthy the switch is request-scoped: no cooldown, no half-open probe burned (see [Fallback triggers](#fallback-triggers-triggercodes)).
195
195
  - **Cooldown and revert**: failed / switched-away models are not re-selected during cooldown; `revertPolicy: cooldown-expiry` returns to the primary model automatically.
196
196
  - **Host subagent model policy (dsh 0.1.2)**: when the host `subagent-model-selection` policy is enabled, its allowlist is a hard constraint on every plugin-originated subagent route — an explicit authorized spawn route stays the chain head (role-inject skipped), inheritance inject heads and failure-switch targets are intersected with the effective allowlist, and an empty intersection skips the inject/switch (warn log + read-only card warning; no out-of-allowlist request is ever sent). A present-but-unreadable policy fails closed. Policy off/absent → inject and failure-switch selection exactly as 0.3.5. Override `reasoningEffort` follows the upstream routeChanged rule on every path (same route → keep; route change → drop unless explicit). See [Host subagent model policy](#host-subagent-model-policy-dsh-012).
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Session-header subagent role badge (plan subagent-role-badge T3; durable
3
3
  * channel plan role-based-subagent-adoption Task 3b): a compact read-only pill
4
- * in `conversation.session.header.utilities` showing which Subagent role the
4
+ * in `conversation.session.header.actions` showing which Subagent role the
5
5
  * viewed session's dispatch resolved, hovering as `role → latest request route`.
6
6
  *
7
7
  * Contract notes (verified 2026-09-09 against the harness checkout):
@@ -33,12 +33,12 @@
33
33
  * - Render-only discipline (C4 pattern, same as `ConversationFallbackSwitch`):
34
34
  * the badge contributes a view; no message construction, no model-context
35
35
  * injection. Degrade-never-crash: a missing/foreign projection value or an
36
- * `inherit` role renders `null` — the utilities strip collapses cleanly.
36
+ * `inherit` role renders `null` — the actions row collapses cleanly.
37
37
  */
38
38
  import type { ReactNode } from 'react';
39
39
  import type { PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots';
40
- /** Props delivered by the utilities slot outlet: runtime share + locale seat. */
41
- export type SubagentRoleBadgeProps = PropsRuntime<'conversation.session.header.utilities'> & PropsLocale<'fallbacks'>;
40
+ /** Props delivered by the actions slot outlet: runtime share + locale seat. */
41
+ export type SubagentRoleBadgeProps = PropsRuntime<'conversation.session.header.actions'> & PropsLocale<'fallbacks'>;
42
42
  /**
43
43
  * Render the viewed session's dispatch-resolved role badge.
44
44
  * @param props - composed slot props (the session-kit `useProjection` seat is
@@ -4683,11 +4683,11 @@ window.__ModuleLoader__.load({
4683
4683
  locale: NS
4684
4684
  }, ConversationFallbackSwitch);
4685
4685
  });
4686
- ctx.slots.inject("conversation.session.header.utilities", function* () {
4686
+ ctx.slots.inject("conversation.session.header.actions", function* () {
4687
4687
  yield ctx.slots.register({
4688
- name: "conversation.session.header.utilities",
4688
+ name: "conversation.session.header.actions",
4689
4689
  id: "fallbacks-subagent-role",
4690
- order: -20,
4690
+ order: -5,
4691
4691
  locale: NS
4692
4692
  }, SubagentRoleBadge);
4693
4693
  });
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "dsh",
6
6
  "dsh-plugin"
7
7
  ],
8
- "version": "0.5.1",
8
+ "version": "0.5.2",
9
9
  "type": "module",
10
10
  "main": "./dist/index.js",
11
11
  "types": "./dist/index.d.ts",