dsh-llm-fallbacks 0.4.0-alpha.1 → 0.4.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 CHANGED
@@ -7,7 +7,7 @@
7
7
  ![node](https://img.shields.io/badge/node-%3E%3D22-339933.svg)
8
8
  ![pnpm](https://img.shields.io/badge/pnpm-%3E%3D10-f69220.svg)
9
9
  ![dsh tui](https://img.shields.io/badge/dsh%20tui-compatible-4B32C3.svg)
10
- ![dsh](https://img.shields.io/badge/DSH-0.1.2--alpha.2-4B32C3.svg)
10
+ ![dsh](https://img.shields.io/badge/DSH-0.1.2--rc.1-4B32C3.svg)
11
11
  [![dshfind](https://dshfind.com/api/badge/omdsh-dev/dsh-llm-fallbacks?lang=en)](https://dshfind.com/zh/plugins/omdsh-dev/dsh-llm-fallbacks?ref=badge)
12
12
 
13
13
  Automatic provider/model fallback chains for dsh (DeepSeek Harness): when an agent's LLM requests keep failing — retries exhausted, auth errors, quota exceeded, rate limiting (429) — the plugin switches provider/model along the fallback chain for the current role, and the current step/turn continues on the target model: tasks are not interrupted by model problems.
package/README.zh-CN.md CHANGED
@@ -7,7 +7,7 @@
7
7
  ![node](https://img.shields.io/badge/node-%3E%3D22-339933.svg)
8
8
  ![pnpm](https://img.shields.io/badge/pnpm-%3E%3D10-f69220.svg)
9
9
  ![dsh tui](https://img.shields.io/badge/dsh%20tui-compatible-4B32C3.svg)
10
- ![dsh](https://img.shields.io/badge/DSH-0.1.2--alpha.2-4B32C3.svg)
10
+ ![dsh](https://img.shields.io/badge/DSH-0.1.2--rc.1-4B32C3.svg)
11
11
  [![dshfind](https://dshfind.com/api/badge/omdsh-dev/dsh-llm-fallbacks?lang=zh)](https://dshfind.com/zh/plugins/omdsh-dev/dsh-llm-fallbacks?ref=badge)
12
12
 
13
13
  dsh(DeepSeek Harness)的自动模型降级插件:当 root agent 或 subagent 的模型请求持续失败(重试耗尽、权限、配额超限、限流 429)时,按角色/模型 fallback 链自动切换 provider/model,当前 step/turn 在目标模型上继续完成——任务不因模型问题中断。
@@ -48,7 +48,7 @@ export interface FallbacksCommandAgent {
48
48
  readonly header?: {
49
49
  readonly origin?: Origin;
50
50
  };
51
- readonly events: readonly unknown[];
51
+ readonly snapshotEvents: () => readonly unknown[];
52
52
  };
53
53
  }
54
54
  /** One active cooldown entry displayed by `/fallbacks`. */
package/dist/index.js CHANGED
@@ -2291,7 +2291,7 @@ async function makeModelExists(ctx, providers) {
2291
2291
  }
2292
2292
  function countRetryEvents(session, turn, step, provider) {
2293
2293
  let count = 0;
2294
- const events = session.events;
2294
+ const events = session.snapshotEvents();
2295
2295
  for (let index = events.length - 1; index >= 0; index -= 1) {
2296
2296
  const event = events[index];
2297
2297
  const data = event.data;
@@ -2348,7 +2348,7 @@ function authorizedRouteView(ctx, agent) {
2348
2348
  const parentOptions = parent?.options;
2349
2349
  return {
2350
2350
  requestHeader: agent.session?.requestHeader()?.config,
2351
- events: agent.session?.events,
2351
+ events: agent.session?.snapshotEvents(),
2352
2352
  options: agent.options,
2353
2353
  inherited: parentHeader ?? (typeof parentOptions?.provider === "string" && typeof parentOptions?.model === "string" ? {
2354
2354
  provider: parentOptions.provider,
@@ -2480,7 +2480,7 @@ function apply(ctx, config = defaultFallbacksConfig) {
2480
2480
  };
2481
2481
  if (agent.session?.header?.origin === "subagent" && target !== void 0) {
2482
2482
  const settingsRead = readGuardedPolicySettings(ctx, agent.id, lastKnownPolicySettings, logger.warn);
2483
- const policy = settingsRead.ok ? effectivePolicy(readSessionPolicyEvent(agent.session.events), settingsRead.settings) : { state: "unprovable" };
2483
+ const policy = settingsRead.ok ? effectivePolicy(readSessionPolicyEvent(agent.session.snapshotEvents()), settingsRead.settings) : { state: "unprovable" };
2484
2484
  if (policy.state === "unprovable") {
2485
2485
  logger.warn("llm-fallbacks: agent \"%s\" subagent model-selection policy is on but unreadable — skipping fallback switch", agent.id);
2486
2486
  return null;
@@ -2593,7 +2593,7 @@ function apply(ctx, config = defaultFallbacksConfig) {
2593
2593
  dispatchInjected.add(agent.id);
2594
2594
  try {
2595
2595
  const settingsRead = readGuardedPolicySettings(ctx, agent.id, lastKnownPolicySettings, logger.warn);
2596
- const policy = settingsRead.ok ? effectivePolicy(readSessionPolicyEvent(agent.session.events), settingsRead.settings) : { state: "unprovable" };
2596
+ const policy = settingsRead.ok ? effectivePolicy(readSessionPolicyEvent(agent.session.snapshotEvents()), settingsRead.settings) : { state: "unprovable" };
2597
2597
  if (policy.state === "unprovable") logger.warn("llm-fallbacks: agent \"%s\" subagent model-selection policy is on but unreadable — skipping role-inject", agent.id);
2598
2598
  else {
2599
2599
  const authorized = policy.state === "enabled" ? detectAuthorizedRoute(authorizedRouteView(ctx, agent)) : void 0;
@@ -2707,7 +2707,7 @@ function apply(ctx, config = defaultFallbacksConfig) {
2707
2707
  role,
2708
2708
  ...resolveChainForDiagnostic(config.roles.list, config.rootChain, role, logger.warn),
2709
2709
  slot: resolveSlotState(config, new Date(), config.tz ?? "Asia/Shanghai"),
2710
- switches: recentFallbacksSwitches(agent.session.events, 5),
2710
+ switches: recentFallbacksSwitches(agent.session.snapshotEvents(), 5),
2711
2711
  cooldown: state === void 0 ? [] : recovery === "half-open" ? [...state.cooldown.snapshot(), ...state.recovery.halfOpenEntries().map((entry) => ({
2712
2712
  key: entry.key,
2713
2713
  untilEpochMs: entry.untilEpochMs,
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "dsh",
6
6
  "dsh-plugin"
7
7
  ],
8
- "version": "0.4.0-alpha.1",
8
+ "version": "0.4.0",
9
9
  "type": "module",
10
10
  "main": "./dist/index.js",
11
11
  "types": "./dist/index.d.ts",
@@ -60,28 +60,28 @@
60
60
  },
61
61
  "peerDependencies": {
62
62
  "@deepseek-ai/cordis": "^4.0.2",
63
- "@deepseek-ai/dsh-agent": "^0.1.2-alpha.2",
64
- "@deepseek-ai/dsh-api-gateway": "^0.1.2-alpha.2",
65
- "@deepseek-ai/dsh-api-remotes": "^0.1.2-alpha.2",
66
- "@deepseek-ai/dsh-api-session-controller": "^0.1.2-alpha.2",
67
- "@deepseek-ai/dsh-client-connection": "^0.1.2-alpha.2",
68
- "@deepseek-ai/dsh-client-locale": "^0.1.2-alpha.2",
69
- "@deepseek-ai/dsh-client-store": "^0.1.2-alpha.2",
70
- "@deepseek-ai/dsh-client-ui-chat": "^0.1.2-alpha.2",
71
- "@deepseek-ai/dsh-client-ui-conversation": "^0.1.2-alpha.2",
72
- "@deepseek-ai/dsh-client-ui-primitives": "^0.1.2-alpha.2",
73
- "@deepseek-ai/dsh-client-ui-renderer": "^0.1.2-alpha.2",
74
- "@deepseek-ai/dsh-client-ui-settings": "^0.1.2-alpha.2",
75
- "@deepseek-ai/dsh-client-ui-settings-plugins": "^0.1.2-alpha.2",
76
- "@deepseek-ai/dsh-client-ui-slots": "^0.1.2-alpha.2",
77
- "@deepseek-ai/dsh-commands": "^0.1.2-alpha.2",
78
- "@deepseek-ai/dsh-llm": "^0.1.2-alpha.2",
79
- "@deepseek-ai/dsh-llm-retry": "^0.1.2-alpha.2",
80
- "@deepseek-ai/dsh-session": "^0.1.2-alpha.2",
81
- "@deepseek-ai/dsh-settings": "^0.1.2-alpha.2",
82
- "@deepseek-ai/dsh-tool-subagent": "^0.1.2-alpha.2",
83
- "@deepseek-ai/dsh-typert-protocol": "^0.1.2-alpha.2",
84
- "@deepseek-ai/dsh-typert-registry": "^0.1.2-alpha.2",
63
+ "@deepseek-ai/dsh-agent": "^0.1.2-rc.1",
64
+ "@deepseek-ai/dsh-api-gateway": "^0.1.2-rc.1",
65
+ "@deepseek-ai/dsh-api-remotes": "^0.1.2-rc.1",
66
+ "@deepseek-ai/dsh-api-session-controller": "^0.1.2-rc.1",
67
+ "@deepseek-ai/dsh-client-connection": "^0.1.2-rc.1",
68
+ "@deepseek-ai/dsh-client-locale": "^0.1.2-rc.1",
69
+ "@deepseek-ai/dsh-client-store": "^0.1.2-rc.1",
70
+ "@deepseek-ai/dsh-client-ui-chat": "^0.1.2-rc.1",
71
+ "@deepseek-ai/dsh-client-ui-conversation": "^0.1.2-rc.1",
72
+ "@deepseek-ai/dsh-client-ui-primitives": "^0.1.2-rc.1",
73
+ "@deepseek-ai/dsh-client-ui-renderer": "^0.1.2-rc.1",
74
+ "@deepseek-ai/dsh-client-ui-settings": "^0.1.2-rc.1",
75
+ "@deepseek-ai/dsh-client-ui-settings-plugins": "^0.1.2-rc.1",
76
+ "@deepseek-ai/dsh-client-ui-slots": "^0.1.2-rc.1",
77
+ "@deepseek-ai/dsh-commands": "^0.1.2-rc.1",
78
+ "@deepseek-ai/dsh-llm": "^0.1.2-rc.1",
79
+ "@deepseek-ai/dsh-llm-retry": "^0.1.2-rc.1",
80
+ "@deepseek-ai/dsh-session": "^0.1.2-rc.1",
81
+ "@deepseek-ai/dsh-settings": "^0.1.2-rc.1",
82
+ "@deepseek-ai/dsh-tool-subagent": "^0.1.2-rc.1",
83
+ "@deepseek-ai/dsh-typert-protocol": "^0.1.2-rc.1",
84
+ "@deepseek-ai/dsh-typert-registry": "^0.1.2-rc.1",
85
85
  "@deepseek-ai/schemastery": "^3.18.2",
86
86
  "react": "^18.2.0"
87
87
  },