@cortexkit/opencode-magic-context 0.25.0 → 0.26.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/dist/agents/permissions.d.ts +6 -0
- package/dist/agents/permissions.d.ts.map +1 -1
- package/dist/config/schema/magic-context.d.ts +22 -0
- package/dist/config/schema/magic-context.d.ts.map +1 -1
- package/dist/features/magic-context/compartment-chunk-embedding.d.ts +17 -0
- package/dist/features/magic-context/compartment-chunk-embedding.d.ts.map +1 -1
- package/dist/features/magic-context/compartment-embedding.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/task-prompts.d.ts.map +1 -1
- package/dist/features/magic-context/memory/embedding-local.d.ts +3 -3
- package/dist/features/magic-context/memory/embedding-local.d.ts.map +1 -1
- package/dist/features/magic-context/memory/embedding-openai.d.ts +8 -4
- package/dist/features/magic-context/memory/embedding-openai.d.ts.map +1 -1
- package/dist/features/magic-context/memory/embedding-provider.d.ts +8 -4
- package/dist/features/magic-context/memory/embedding-provider.d.ts.map +1 -1
- package/dist/features/magic-context/memory/embedding.d.ts.map +1 -1
- package/dist/features/magic-context/memory/relocate-memory.d.ts +58 -0
- package/dist/features/magic-context/memory/relocate-memory.d.ts.map +1 -0
- package/dist/features/magic-context/migrations.d.ts.map +1 -1
- package/dist/features/magic-context/project-embedding-registry.d.ts +3 -3
- package/dist/features/magic-context/project-embedding-registry.d.ts.map +1 -1
- package/dist/features/magic-context/storage-db.d.ts +2 -1
- package/dist/features/magic-context/storage-db.d.ts.map +1 -1
- package/dist/features/magic-context/storage-meta-persisted.d.ts +37 -0
- package/dist/features/magic-context/storage-meta-persisted.d.ts.map +1 -1
- package/dist/features/magic-context/storage-meta-session.d.ts.map +1 -1
- package/dist/features/magic-context/storage-meta-shared.d.ts +3 -1
- package/dist/features/magic-context/storage-meta-shared.d.ts.map +1 -1
- package/dist/features/magic-context/storage-meta.d.ts +1 -1
- package/dist/features/magic-context/storage-meta.d.ts.map +1 -1
- package/dist/features/magic-context/storage-tags.d.ts +48 -2
- package/dist/features/magic-context/storage-tags.d.ts.map +1 -1
- package/dist/features/magic-context/storage.d.ts +3 -3
- package/dist/features/magic-context/storage.d.ts.map +1 -1
- package/dist/features/magic-context/tagger.d.ts +1 -1
- package/dist/features/magic-context/tagger.d.ts.map +1 -1
- package/dist/features/magic-context/transform-decision-log.d.ts +49 -0
- package/dist/features/magic-context/transform-decision-log.d.ts.map +1 -0
- package/dist/features/magic-context/v22-deferred-backfill.d.ts.map +1 -1
- package/dist/hooks/magic-context/auto-search-runner.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-incremental.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-trigger.d.ts +1 -1
- package/dist/hooks/magic-context/compartment-trigger.d.ts.map +1 -1
- package/dist/hooks/magic-context/derive-budgets.d.ts +5 -9
- package/dist/hooks/magic-context/derive-budgets.d.ts.map +1 -1
- package/dist/hooks/magic-context/event-handler.d.ts.map +1 -1
- package/dist/hooks/magic-context/event-payloads.d.ts +1 -0
- package/dist/hooks/magic-context/event-payloads.d.ts.map +1 -1
- package/dist/hooks/magic-context/heuristic-cleanup.d.ts +1 -0
- package/dist/hooks/magic-context/heuristic-cleanup.d.ts.map +1 -1
- package/dist/hooks/magic-context/hook.d.ts.map +1 -1
- package/dist/hooks/magic-context/protected-tail-boundary.d.ts +10 -0
- package/dist/hooks/magic-context/protected-tail-boundary.d.ts.map +1 -1
- package/dist/hooks/magic-context/read-session-chunk.d.ts.map +1 -1
- package/dist/hooks/magic-context/tag-id-fallback.d.ts.map +1 -1
- package/dist/hooks/magic-context/tag-messages.d.ts +10 -0
- package/dist/hooks/magic-context/tag-messages.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform-compartment-phase.d.ts +32 -1
- package/dist/hooks/magic-context/transform-compartment-phase.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform-postprocess-phase.d.ts +6 -0
- package/dist/hooks/magic-context/transform-postprocess-phase.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform.d.ts.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +675 -216
- package/dist/plugin/dream-timer.d.ts.map +1 -1
- package/dist/plugin/hooks/create-session-hooks.d.ts.map +1 -1
- package/dist/plugin/rpc-handlers.d.ts.map +1 -1
- package/dist/shared/announcement.d.ts +1 -1
- package/dist/shared/index.d.ts +0 -1
- package/dist/shared/index.d.ts.map +1 -1
- package/dist/shared/resolve-fallbacks.d.ts +16 -16
- package/dist/shared/resolve-fallbacks.d.ts.map +1 -1
- package/dist/tools/ctx-search/tools.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/shared/announcement.ts +6 -6
- package/src/shared/index.ts +0 -1
- package/src/shared/resolve-fallbacks.test.ts +37 -71
- package/src/shared/resolve-fallbacks.ts +16 -26
- package/src/tui/slots/sidebar-content.tsx +11 -7
- package/dist/shared/model-requirements.d.ts +0 -26
- package/dist/shared/model-requirements.d.ts.map +0 -1
- package/src/shared/model-requirements.ts +0 -86
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dream-timer.d.ts","sourceRoot":"","sources":["../../src/plugin/dream-timer.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"dream-timer.d.ts","sourceRoot":"","sources":["../../src/plugin/dream-timer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAkBpE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAK7C;;;;;GAKG;AACH,UAAU,mBAAmB;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;IACxB,MAAM,EAAE,aAAa,CAAC,QAAQ,CAAC,CAAC;IAChC,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,wBAAwB,CAAC,EAAE;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,kBAAkB,EAAE,MAAM,CAAA;KAAE,CAAC;IAC5E,uBAAuB,CAAC,EAAE;QACtB,OAAO,EAAE,OAAO,CAAC;QACjB,YAAY,EAAE,MAAM,CAAC;QACrB,SAAS,EAAE,MAAM,CAAC;KACrB,CAAC;IACF,iBAAiB,CAAC,EAAE;QAChB,OAAO,EAAE,OAAO,CAAC;QACjB,UAAU,EAAE,MAAM,CAAC;QACnB,WAAW,EAAE,MAAM,CAAC;KACvB,CAAC;IACF,gBAAgB,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,EAAE,QAAQ,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACxE;AA2BD;;;;;;;;;;GAUG;AACH,wBAAsB,uBAAuB,CACzC,IAAI,EAAE,mBAAmB,GAC1B,OAAO,CAAC,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS,CAAC,CA6DnC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create-session-hooks.d.ts","sourceRoot":"","sources":["../../../src/plugin/hooks/create-session-hooks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,cAAc,CAAC;AAO7D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,8CAA8C,CAAC;AACrF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAE9C,wBAAgB,kBAAkB,CAAC,IAAI,EAAE;IACrC,GAAG,EAAE,aAAa,CAAC;IACnB,YAAY,EAAE,wBAAwB,CAAC;IACvC,gBAAgB,EAAE,gBAAgB,CAAC;CACtC;;;;;;qBAuDizK,CAAC;;;;;;;;;;;;qBAA93D,CAAC;mBAAyB,CAAC;iBAAuB,CAAC;iBAAuB,CAAC;0BAAc,CAAC;uBAAiB,CAAC;;;;;;
|
|
1
|
+
{"version":3,"file":"create-session-hooks.d.ts","sourceRoot":"","sources":["../../../src/plugin/hooks/create-session-hooks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,cAAc,CAAC;AAO7D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,8CAA8C,CAAC;AACrF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAE9C,wBAAgB,kBAAkB,CAAC,IAAI,EAAE;IACrC,GAAG,EAAE,aAAa,CAAC;IACnB,YAAY,EAAE,wBAAwB,CAAC;IACvC,gBAAgB,EAAE,gBAAgB,CAAC;CACtC;;;;;;qBAuDizK,CAAC;;;;;;;;;;;;qBAA93D,CAAC;mBAAyB,CAAC;iBAAuB,CAAC;iBAAuB,CAAC;0BAAc,CAAC;uBAAiB,CAAC;;;;;;0BAA+ykC,CAAC;;;;;;EADh1rC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rpc-handlers.d.ts","sourceRoot":"","sources":["../../src/plugin/rpc-handlers.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AAGzE,OAAO,EACH,KAAK,eAAe,IAAI,QAAQ,EAGnC,MAAM,mCAAmC,CAAC;AAc3C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2CAA2C,CAAC;AAqBlF,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAClE,OAAO,KAAK,EAAe,eAAe,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AA0FtF,wBAAgB,oBAAoB,CAChC,EAAE,EAAE,QAAQ,EACZ,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,gBAAgB,CAAC,EAAE,gBAAgB,EACnC,qBAAqB,CAAC,EAAE,MAAM,EAK9B,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACjC,eAAe,CA2VjB;AAED,wBAAgB,iBAAiB,CAC7B,EAAE,EAAE,QAAQ,EACZ,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,QAAQ,CAAC,EAAE,MAAM,EACjB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,gBAAgB,CAAC,EAAE,gBAAgB,EACnC,qBAAqB,CAAC,EAAE,MAAM,GAC/B,YAAY,CA+Jd;AA4BD;;GAEG;AACH,wBAAgB,mBAAmB,CAC/B,SAAS,EAAE,qBAAqB,EAChC,IAAI,EAAE;IACF,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,kBAAkB,CAAC;IAC3B,MAAM,EAAE,OAAO,CAAC;IAChB,gBAAgB,EAAE,gBAAgB,CAAC;CACtC,GACF,IAAI,
|
|
1
|
+
{"version":3,"file":"rpc-handlers.d.ts","sourceRoot":"","sources":["../../src/plugin/rpc-handlers.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AAGzE,OAAO,EACH,KAAK,eAAe,IAAI,QAAQ,EAGnC,MAAM,mCAAmC,CAAC;AAc3C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2CAA2C,CAAC;AAqBlF,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAClE,OAAO,KAAK,EAAe,eAAe,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AA0FtF,wBAAgB,oBAAoB,CAChC,EAAE,EAAE,QAAQ,EACZ,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,gBAAgB,CAAC,EAAE,gBAAgB,EACnC,qBAAqB,CAAC,EAAE,MAAM,EAK9B,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACjC,eAAe,CA2VjB;AAED,wBAAgB,iBAAiB,CAC7B,EAAE,EAAE,QAAQ,EACZ,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,QAAQ,CAAC,EAAE,MAAM,EACjB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,gBAAgB,CAAC,EAAE,gBAAgB,EACnC,qBAAqB,CAAC,EAAE,MAAM,GAC/B,YAAY,CA+Jd;AA4BD;;GAEG;AACH,wBAAgB,mBAAmB,CAC/B,SAAS,EAAE,qBAAqB,EAChC,IAAI,EAAE;IACF,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,kBAAkB,CAAC;IAC3B,MAAM,EAAE,OAAO,CAAC;IAChB,gBAAgB,EAAE,gBAAgB,CAAC;CACtC,GACF,IAAI,CA4ON"}
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
* Bump only when there are user-visible changes worth a startup dialog.
|
|
19
19
|
* Does NOT need to match the published package version.
|
|
20
20
|
*/
|
|
21
|
-
export declare const ANNOUNCEMENT_VERSION = "0.
|
|
21
|
+
export declare const ANNOUNCEMENT_VERSION = "0.26.0";
|
|
22
22
|
/**
|
|
23
23
|
* Short, user-facing bullet strings. Keep each line ~80 chars or shorter so the
|
|
24
24
|
* TUI dialog renders cleanly without horizontal scroll on a typical terminal.
|
package/dist/shared/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/shared/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/shared/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,0BAA0B,CAAC;AACzC,cAAc,0BAA0B,CAAC;AACzC,cAAc,qBAAqB,CAAC"}
|
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Resolve the
|
|
3
|
-
* call.
|
|
2
|
+
* Resolve the fallback model list to attempt for a hidden-agent (historian /
|
|
3
|
+
* dreamer / sidekick) call when its configured primary fails.
|
|
4
4
|
*
|
|
5
|
-
* Policy
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
5
|
+
* Policy: ONLY the user's explicitly-configured `fallback_models` for this
|
|
6
|
+
* agent. There is NO builtin provider-agnostic chain — a hardcoded chain
|
|
7
|
+
* inevitably names providers the user doesn't have (e.g. a metapi-only user got
|
|
8
|
+
* a chain of google/github-copilot/opencode entries, every one a
|
|
9
|
+
* `Model not found` retry), which produced confusing errors and wasted
|
|
10
|
+
* attempts. If the user configured nothing, this returns an empty list and the
|
|
11
|
+
* runner's session-model last resort (the model the user is actually using) is
|
|
12
|
+
* the only fallback.
|
|
11
13
|
*
|
|
12
|
-
* The returned list does NOT include the primary model — it's the ordered
|
|
13
|
-
*
|
|
14
|
-
* "provider/modelID" form.
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
* "provider/modelID" shape (must contain a "/" with non-empty parts) are
|
|
18
|
-
* also dropped — defensive guard against malformed user config.
|
|
14
|
+
* The returned list does NOT include the primary model — it's the ordered list
|
|
15
|
+
* of *alternates* to try after the primary fails. Each entry is
|
|
16
|
+
* "provider/modelID" form. Duplicates and empty strings are filtered; entries
|
|
17
|
+
* that don't match the "provider/modelID" shape (a "/" with non-empty parts) are
|
|
18
|
+
* dropped as a defensive guard against malformed user config.
|
|
19
19
|
*/
|
|
20
|
-
export declare function resolveFallbackChain(
|
|
20
|
+
export declare function resolveFallbackChain(userFallbacks: readonly string[] | string | undefined): string[];
|
|
21
21
|
/**
|
|
22
22
|
* Parse a "provider/modelID" string into the OpenCode `model` object shape.
|
|
23
23
|
* Returns null on invalid input.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolve-fallbacks.d.ts","sourceRoot":"","sources":["../../src/shared/resolve-fallbacks.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"resolve-fallbacks.d.ts","sourceRoot":"","sources":["../../src/shared/resolve-fallbacks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,oBAAoB,CAChC,aAAa,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,GAAG,SAAS,GACtD,MAAM,EAAE,CAGV;AA2BD;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAO/F"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../../src/tools/ctx-search/tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,cAAc,EAAQ,MAAM,qBAAqB,CAAC;AAahE,OAAO,KAAK,EAAkC,iBAAiB,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../../src/tools/ctx-search/tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,cAAc,EAAQ,MAAM,qBAAqB,CAAC;AAahE,OAAO,KAAK,EAAkC,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAyLjF,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,iBAAiB,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAI5F"}
|
package/package.json
CHANGED
|
@@ -23,18 +23,18 @@ import { getMagicContextStorageDir } from "./data-path";
|
|
|
23
23
|
* Bump only when there are user-visible changes worth a startup dialog.
|
|
24
24
|
* Does NOT need to match the published package version.
|
|
25
25
|
*/
|
|
26
|
-
export const ANNOUNCEMENT_VERSION = "0.
|
|
26
|
+
export const ANNOUNCEMENT_VERSION = "0.26.0";
|
|
27
27
|
|
|
28
28
|
/**
|
|
29
29
|
* Short, user-facing bullet strings. Keep each line ~80 chars or shorter so the
|
|
30
30
|
* TUI dialog renders cleanly without horizontal scroll on a typical terminal.
|
|
31
31
|
*/
|
|
32
32
|
export const ANNOUNCEMENT_FEATURES: ReadonlyArray<string> = [
|
|
33
|
-
"
|
|
34
|
-
"
|
|
35
|
-
"
|
|
36
|
-
"
|
|
37
|
-
"
|
|
33
|
+
"Faster on large sessions: per-message transform overhead is at least 2x lower on typical passes and up to ~10x lower when history summarization fires (no more multi-second pause on big sessions).",
|
|
34
|
+
"No more surprise models: the built-in fallback chain is gone. Hidden agents only use the model (and fallback_models) you configure — no confusing 'model not found' for providers you never set up. `doctor` now records every historian run so real failures are visible.",
|
|
35
|
+
"Anthropic thinking-block fix: clearing old reasoning no longer risks a stale-signature rejection on Claude / Bedrock / proxied-Claude routes. Plus fewer prompt-cache busts.",
|
|
36
|
+
"Community fixes: TUI crash on the upgrade progress panel (#168), historian.disallowed_tools for weak models that loop on tool calls (#166), and a Pi-only config key leak (#167).",
|
|
37
|
+
"New: doctor migrate-session re-homes a session (and optionally its memories) to another project, with a dry-run preview.",
|
|
38
38
|
];
|
|
39
39
|
|
|
40
40
|
/**
|
package/src/shared/index.ts
CHANGED
|
@@ -1,98 +1,64 @@
|
|
|
1
1
|
import { describe, expect, test } from "bun:test";
|
|
2
2
|
|
|
3
|
-
import { DREAMER_AGENT } from "../agents/dreamer";
|
|
4
|
-
import { HISTORIAN_AGENT } from "../agents/historian";
|
|
5
|
-
import { SIDEKICK_AGENT } from "../agents/sidekick";
|
|
6
3
|
import { parseProviderModel, resolveFallbackChain } from "./resolve-fallbacks";
|
|
7
4
|
|
|
8
5
|
describe("resolveFallbackChain", () => {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
}
|
|
6
|
+
// Policy: user-config-only. There is NO builtin provider-agnostic chain —
|
|
7
|
+
// when the user configures no fallback_models the result is EMPTY, and the
|
|
8
|
+
// runner's session-model last resort (a model the user actually has) is the
|
|
9
|
+
// only fallback. A hardcoded chain named providers the user may not have and
|
|
10
|
+
// produced `Model not found` retry storms.
|
|
11
|
+
test("returns empty when user provides nothing (no builtin chain)", () => {
|
|
12
|
+
expect(resolveFallbackChain(undefined)).toEqual([]);
|
|
17
13
|
});
|
|
18
14
|
|
|
19
|
-
test("returns
|
|
20
|
-
|
|
21
|
-
expect(chain.length).toBeGreaterThan(0);
|
|
15
|
+
test("returns empty for empty string", () => {
|
|
16
|
+
expect(resolveFallbackChain("")).toEqual([]);
|
|
22
17
|
});
|
|
23
18
|
|
|
24
|
-
test("returns
|
|
25
|
-
|
|
26
|
-
expect(chain.length).toBeGreaterThan(0);
|
|
19
|
+
test("returns empty for empty array", () => {
|
|
20
|
+
expect(resolveFallbackChain([])).toEqual([]);
|
|
27
21
|
});
|
|
28
22
|
|
|
29
23
|
test("user-only when user provides valid fallback_models string", () => {
|
|
30
|
-
|
|
31
|
-
|
|
24
|
+
expect(resolveFallbackChain("anthropic/claude-sonnet-4-6")).toEqual([
|
|
25
|
+
"anthropic/claude-sonnet-4-6",
|
|
26
|
+
]);
|
|
32
27
|
});
|
|
33
28
|
|
|
34
29
|
test("user-only when user provides valid fallback_models array", () => {
|
|
35
|
-
|
|
36
|
-
"anthropic/claude-sonnet-4-6",
|
|
37
|
-
|
|
38
|
-
]);
|
|
39
|
-
expect(chain).toEqual(["anthropic/claude-sonnet-4-6", "google/gemini-3-flash"]);
|
|
30
|
+
expect(
|
|
31
|
+
resolveFallbackChain(["anthropic/claude-sonnet-4-6", "google/gemini-3-flash"]),
|
|
32
|
+
).toEqual(["anthropic/claude-sonnet-4-6", "google/gemini-3-flash"]);
|
|
40
33
|
});
|
|
41
34
|
|
|
42
35
|
test("dedupes user-provided list", () => {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
36
|
+
expect(
|
|
37
|
+
resolveFallbackChain([
|
|
38
|
+
"anthropic/claude-sonnet-4-6",
|
|
39
|
+
"anthropic/claude-sonnet-4-6",
|
|
40
|
+
"google/gemini-3-flash",
|
|
41
|
+
]),
|
|
42
|
+
).toEqual(["anthropic/claude-sonnet-4-6", "google/gemini-3-flash"]);
|
|
49
43
|
});
|
|
50
44
|
|
|
51
45
|
test("strips invalid 'provider/model' entries", () => {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
46
|
+
expect(
|
|
47
|
+
resolveFallbackChain([
|
|
48
|
+
"anthropic/claude-sonnet-4-6",
|
|
49
|
+
"no-slash-here",
|
|
50
|
+
"/leading-slash",
|
|
51
|
+
"trailing-slash/",
|
|
52
|
+
"",
|
|
53
|
+
" ",
|
|
54
|
+
]),
|
|
55
|
+
).toEqual(["anthropic/claude-sonnet-4-6"]);
|
|
61
56
|
});
|
|
62
57
|
|
|
63
58
|
test("trims whitespace in user entries", () => {
|
|
64
|
-
|
|
65
|
-
" anthropic/claude-sonnet-4-6 ",
|
|
66
|
-
|
|
67
|
-
]);
|
|
68
|
-
expect(chain).toEqual(["anthropic/claude-sonnet-4-6", "google/gemini-3-flash"]);
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
test("returns empty array for unknown agent with no user fallbacks", () => {
|
|
72
|
-
const chain = resolveFallbackChain("unknown-agent", undefined);
|
|
73
|
-
expect(chain).toEqual([]);
|
|
74
|
-
});
|
|
75
|
-
|
|
76
|
-
test("returns user fallbacks for unknown agent when provided", () => {
|
|
77
|
-
const chain = resolveFallbackChain("unknown-agent", ["foo/bar"]);
|
|
78
|
-
expect(chain).toEqual(["foo/bar"]);
|
|
79
|
-
});
|
|
80
|
-
|
|
81
|
-
test("HISTORIAN_AGENT has builtin chain", () => {
|
|
82
|
-
const chain = resolveFallbackChain(HISTORIAN_AGENT, undefined);
|
|
83
|
-
expect(chain.length).toBeGreaterThan(0);
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
test("SIDEKICK_AGENT has builtin chain", () => {
|
|
87
|
-
const chain = resolveFallbackChain(SIDEKICK_AGENT, undefined);
|
|
88
|
-
expect(chain.length).toBeGreaterThan(0);
|
|
89
|
-
});
|
|
90
|
-
|
|
91
|
-
test("user-only policy: builtin not appended even if user set short list", () => {
|
|
92
|
-
const chain = resolveFallbackChain(DREAMER_AGENT, ["anthropic/claude-sonnet-4-6"]);
|
|
93
|
-
expect(chain).toEqual(["anthropic/claude-sonnet-4-6"]);
|
|
94
|
-
// Confirm length is exactly 1, not user+builtin
|
|
95
|
-
expect(chain.length).toBe(1);
|
|
59
|
+
expect(
|
|
60
|
+
resolveFallbackChain([" anthropic/claude-sonnet-4-6 ", "\tgoogle/gemini-3-flash\n"]),
|
|
61
|
+
).toEqual(["anthropic/claude-sonnet-4-6", "google/gemini-3-flash"]);
|
|
96
62
|
});
|
|
97
63
|
});
|
|
98
64
|
|
|
@@ -1,37 +1,27 @@
|
|
|
1
|
-
import { getAgentFallbackModels } from "./model-requirements";
|
|
2
|
-
|
|
3
1
|
/**
|
|
4
|
-
* Resolve the
|
|
5
|
-
* call.
|
|
6
|
-
*
|
|
7
|
-
* Policy (decided 2026-05-10):
|
|
8
|
-
* - If user configured explicit `fallback_models` in their magic-context.jsonc
|
|
9
|
-
* for this agent: use ONLY those. Respects user intent, no surprise
|
|
10
|
-
* providers.
|
|
11
|
-
* - If user did NOT configure any: fall back to the plugin's builtin
|
|
12
|
-
* provider-agnostic chain (`AGENT_MODEL_REQUIREMENTS`).
|
|
2
|
+
* Resolve the fallback model list to attempt for a hidden-agent (historian /
|
|
3
|
+
* dreamer / sidekick) call when its configured primary fails.
|
|
13
4
|
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
5
|
+
* Policy: ONLY the user's explicitly-configured `fallback_models` for this
|
|
6
|
+
* agent. There is NO builtin provider-agnostic chain — a hardcoded chain
|
|
7
|
+
* inevitably names providers the user doesn't have (e.g. a metapi-only user got
|
|
8
|
+
* a chain of google/github-copilot/opencode entries, every one a
|
|
9
|
+
* `Model not found` retry), which produced confusing errors and wasted
|
|
10
|
+
* attempts. If the user configured nothing, this returns an empty list and the
|
|
11
|
+
* runner's session-model last resort (the model the user is actually using) is
|
|
12
|
+
* the only fallback.
|
|
17
13
|
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
14
|
+
* The returned list does NOT include the primary model — it's the ordered list
|
|
15
|
+
* of *alternates* to try after the primary fails. Each entry is
|
|
16
|
+
* "provider/modelID" form. Duplicates and empty strings are filtered; entries
|
|
17
|
+
* that don't match the "provider/modelID" shape (a "/" with non-empty parts) are
|
|
18
|
+
* dropped as a defensive guard against malformed user config.
|
|
21
19
|
*/
|
|
22
20
|
export function resolveFallbackChain(
|
|
23
|
-
agentName: string,
|
|
24
21
|
userFallbacks: readonly string[] | string | undefined,
|
|
25
22
|
): string[] {
|
|
26
23
|
const userList = normalizeUserFallbacks(userFallbacks);
|
|
27
|
-
|
|
28
|
-
if (userList.length > 0) {
|
|
29
|
-
return dedupe(userList.filter(isValidModelSpec));
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
const builtin = getAgentFallbackModels(agentName);
|
|
33
|
-
if (!builtin || builtin.length === 0) return [];
|
|
34
|
-
return dedupe(builtin.filter(isValidModelSpec));
|
|
24
|
+
return dedupe(userList.filter(isValidModelSpec));
|
|
35
25
|
}
|
|
36
26
|
|
|
37
27
|
function normalizeUserFallbacks(userFallbacks: readonly string[] | string | undefined): string[] {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/** @jsxImportSource @opentui/solid */
|
|
2
|
-
import { createEffect, createMemo, createSignal, on, onCleanup } from "solid-js"
|
|
2
|
+
import { Show, createEffect, createMemo, createSignal, on, onCleanup } from "solid-js"
|
|
3
3
|
import type { TuiSlotPlugin, TuiPluginApi, TuiThemeCurrent } from "@opencode-ai/plugin/tui"
|
|
4
4
|
import packageJson from "../../../package.json"
|
|
5
5
|
import { loadSidebarSnapshot, type SidebarSnapshot } from "../data/context-db"
|
|
@@ -755,9 +755,11 @@ const SidebarContent = (props: {
|
|
|
755
755
|
C:{s()?.compartmentCount ?? 0} Q:{s()?.pendingOpsCount ?? 0} N:{s()?.sessionNoteCount ?? 0}
|
|
756
756
|
</text>
|
|
757
757
|
</box>
|
|
758
|
-
{s()?.recompProgress
|
|
759
|
-
|
|
760
|
-
|
|
758
|
+
<Show when={s()?.recompProgress}>
|
|
759
|
+
{(progress) => (
|
|
760
|
+
<RecompProgressSection theme={props.theme} progress={progress()} />
|
|
761
|
+
)}
|
|
762
|
+
</Show>
|
|
761
763
|
</box>
|
|
762
764
|
)}
|
|
763
765
|
|
|
@@ -789,9 +791,11 @@ const SidebarContent = (props: {
|
|
|
789
791
|
/>
|
|
790
792
|
|
|
791
793
|
{/* Recomp / session-upgrade live progress */}
|
|
792
|
-
{s()?.recompProgress
|
|
793
|
-
|
|
794
|
-
|
|
794
|
+
<Show when={s()?.recompProgress}>
|
|
795
|
+
{(progress) => (
|
|
796
|
+
<RecompProgressSection theme={props.theme} progress={progress()} />
|
|
797
|
+
)}
|
|
798
|
+
</Show>
|
|
795
799
|
</>
|
|
796
800
|
)}
|
|
797
801
|
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Provider-agnostic fallback chain entry.
|
|
3
|
-
* Each entry specifies a model and the providers to try in priority order.
|
|
4
|
-
* Follows oh-my-opencode's FallbackEntry pattern — `opencode` acts as a
|
|
5
|
-
* catch-all proxy provider and is listed last in most entries.
|
|
6
|
-
*/
|
|
7
|
-
export type FallbackEntry = {
|
|
8
|
-
providers: string[];
|
|
9
|
-
model: string;
|
|
10
|
-
variant?: string;
|
|
11
|
-
};
|
|
12
|
-
export type AgentModelRequirement = {
|
|
13
|
-
fallbackChain: FallbackEntry[];
|
|
14
|
-
};
|
|
15
|
-
export declare const AGENT_MODEL_REQUIREMENTS: Record<string, AgentModelRequirement>;
|
|
16
|
-
/**
|
|
17
|
-
* Expand a provider-agnostic fallback chain into a flat `provider/model` list
|
|
18
|
-
* that OpenCode's agent config accepts as `fallback_models`.
|
|
19
|
-
*/
|
|
20
|
-
export declare function expandFallbackChain(chain: FallbackEntry[]): string[];
|
|
21
|
-
/**
|
|
22
|
-
* Get the expanded fallback_models list for an agent.
|
|
23
|
-
* Returns undefined if no requirement is defined.
|
|
24
|
-
*/
|
|
25
|
-
export declare function getAgentFallbackModels(agent: string): string[] | undefined;
|
|
26
|
-
//# sourceMappingURL=model-requirements.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"model-requirements.d.ts","sourceRoot":"","sources":["../../src/shared/model-requirements.ts"],"names":[],"mappings":"AAIA;;;;;GAKG;AACH,MAAM,MAAM,aAAa,GAAG;IACxB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAChC,aAAa,EAAE,aAAa,EAAE,CAAC;CAClC,CAAC;AAqCF,eAAO,MAAM,wBAAwB,EAAE,MAAM,CAAC,MAAM,EAAE,qBAAqB,CAM1E,CAAC;AAEF;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,aAAa,EAAE,GAAG,MAAM,EAAE,CAQpE;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAI1E"}
|
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
import { DREAMER_AGENT } from "../agents/dreamer";
|
|
2
|
-
import { HISTORIAN_AGENT, HISTORIAN_EDITOR_AGENT } from "../agents/historian";
|
|
3
|
-
import { SIDEKICK_AGENT } from "../agents/sidekick";
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Provider-agnostic fallback chain entry.
|
|
7
|
-
* Each entry specifies a model and the providers to try in priority order.
|
|
8
|
-
* Follows oh-my-opencode's FallbackEntry pattern — `opencode` acts as a
|
|
9
|
-
* catch-all proxy provider and is listed last in most entries.
|
|
10
|
-
*/
|
|
11
|
-
export type FallbackEntry = {
|
|
12
|
-
providers: string[];
|
|
13
|
-
model: string;
|
|
14
|
-
variant?: string;
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
export type AgentModelRequirement = {
|
|
18
|
-
fallbackChain: FallbackEntry[];
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
// Historian: quality matters, single long prompt.
|
|
22
|
-
// Copilot first (request-based pricing, ideal for single-prompt background work).
|
|
23
|
-
const HISTORIAN_FALLBACK_CHAIN: FallbackEntry[] = [
|
|
24
|
-
{ providers: ["github-copilot", "anthropic", "opencode"], model: "claude-sonnet-4-6" },
|
|
25
|
-
{ providers: ["opencode-go"], model: "minimax-m2.7" },
|
|
26
|
-
{
|
|
27
|
-
providers: ["zai-coding-plan", "bailian-coding-plan", "opencode-go", "opencode"],
|
|
28
|
-
model: "glm-5",
|
|
29
|
-
},
|
|
30
|
-
{ providers: ["openai", "github-copilot", "opencode"], model: "gpt-5.4" },
|
|
31
|
-
{ providers: ["google", "github-copilot", "opencode"], model: "gemini-3.1-pro" },
|
|
32
|
-
];
|
|
33
|
-
|
|
34
|
-
// Dreamer: runs overnight during idle time, can be slow.
|
|
35
|
-
// Copilot first (request-based pricing). Local models also work well here.
|
|
36
|
-
const DREAMER_FALLBACK_CHAIN: FallbackEntry[] = [
|
|
37
|
-
{ providers: ["github-copilot", "anthropic", "opencode"], model: "claude-sonnet-4-6" },
|
|
38
|
-
{ providers: ["google", "github-copilot", "opencode"], model: "gemini-3-flash" },
|
|
39
|
-
{
|
|
40
|
-
providers: ["zai-coding-plan", "bailian-coding-plan", "opencode-go", "opencode"],
|
|
41
|
-
model: "glm-5",
|
|
42
|
-
},
|
|
43
|
-
{ providers: ["opencode-go"], model: "minimax-m2.7" },
|
|
44
|
-
{ providers: ["github-copilot", "openai", "opencode"], model: "gpt-5.4-mini" },
|
|
45
|
-
];
|
|
46
|
-
|
|
47
|
-
// Sidekick: speed is critical — fast inference providers first.
|
|
48
|
-
// No Copilot preference (low token count, request-based pricing doesn't help).
|
|
49
|
-
const SIDEKICK_FALLBACK_CHAIN: FallbackEntry[] = [
|
|
50
|
-
{ providers: ["cerebras"], model: "qwen-3-235b-a22b-instruct-2507" },
|
|
51
|
-
{ providers: ["google", "github-copilot", "opencode"], model: "gemini-3-flash" },
|
|
52
|
-
{ providers: ["openai", "github-copilot", "opencode"], model: "gpt-5.4-mini" },
|
|
53
|
-
{ providers: ["opencode"], model: "gpt-5-nano" },
|
|
54
|
-
];
|
|
55
|
-
|
|
56
|
-
export const AGENT_MODEL_REQUIREMENTS: Record<string, AgentModelRequirement> = {
|
|
57
|
-
[HISTORIAN_AGENT]: { fallbackChain: HISTORIAN_FALLBACK_CHAIN },
|
|
58
|
-
// Editor reuses historian's fallback chain — same input profile (long single prompt).
|
|
59
|
-
[HISTORIAN_EDITOR_AGENT]: { fallbackChain: HISTORIAN_FALLBACK_CHAIN },
|
|
60
|
-
[DREAMER_AGENT]: { fallbackChain: DREAMER_FALLBACK_CHAIN },
|
|
61
|
-
[SIDEKICK_AGENT]: { fallbackChain: SIDEKICK_FALLBACK_CHAIN },
|
|
62
|
-
};
|
|
63
|
-
|
|
64
|
-
/**
|
|
65
|
-
* Expand a provider-agnostic fallback chain into a flat `provider/model` list
|
|
66
|
-
* that OpenCode's agent config accepts as `fallback_models`.
|
|
67
|
-
*/
|
|
68
|
-
export function expandFallbackChain(chain: FallbackEntry[]): string[] {
|
|
69
|
-
const models: string[] = [];
|
|
70
|
-
for (const entry of chain) {
|
|
71
|
-
for (const provider of entry.providers) {
|
|
72
|
-
models.push(`${provider}/${entry.model}`);
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
return models;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
/**
|
|
79
|
-
* Get the expanded fallback_models list for an agent.
|
|
80
|
-
* Returns undefined if no requirement is defined.
|
|
81
|
-
*/
|
|
82
|
-
export function getAgentFallbackModels(agent: string): string[] | undefined {
|
|
83
|
-
const requirement = AGENT_MODEL_REQUIREMENTS[agent];
|
|
84
|
-
if (!requirement) return undefined;
|
|
85
|
-
return expandFallbackChain(requirement.fallbackChain);
|
|
86
|
-
}
|