Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@

## Unreleased

### Fixes

- Offer catalog models that carry a named profile. Muse 1.3.0 tags every live `providerCatalog` row with the catalog's profile, so the model menu showed only the current model and no catalog choice could be selected. Profiled rows are now advertised and selectable, and the profile travels with the selection through `session/setModel`.
- Default to `muse-spark-1.3` when neither the session nor Muse settings name a model. Muse's own catalog default can be a `-contributor` variant, whose content may be used for product improvement, so the adapter keeps an explicit non-contributor default rather than following it.

## [0.6.1](https://github.com/bex-co/muse-code-acp/compare/v0.6.0...v0.6.1) (2026-09-16)

### Fixes
Expand Down
2 changes: 1 addition & 1 deletion docs/capability-audit.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ The table records the m6 audit snapshot; subsequent owner evidence can supersede
| list, close | Native discovery with pagination; close releases the host and retains history | `session-discovery-live.test.ts`; native deletion is absent, future w1/012 |
| fork | Native full or completed-turn boundary fork, gated by SDK host support; separate owner/MCP inventory | `session-fork-live.test.ts`; no extra roots or silent recreation |
| model/provider | Adapter settings overlay plus explicit public setter; provider-qualified IDs; idle replacement | w2/m5 shipped; actual model requests verified on both hosts even when resume metadata already agrees |
| named model profiles | Identity retained; selection unavailable because effective routing is unverified | w2/m5 explicit failure; rerun with a real public profile catalog before enabling |
| named model profiles | Catalog rows keep their profile identity and are selectable; setModel carries the profile | Muse 1.3.0-R3401.1: every live providerCatalog row carries the catalog profile; selecting one served that model |
| effort | Requested preference; 1.1.1 omits main effort, 1.2.1 maps none→minimal and ultra→max | w2/m5 provider matrix; no per-model restrictions inferred; future w1/010 |
| client gateway and recommendations | Negotiated adapter-owned isolated settings/keys and advisory choice provenance | w2/m5; no automatic selection, account/tier/quota claim or endpoint fallback |
| mode / native approval policy | Adapter automatic once choices are independent of native policy; dangerous modes guarded | w2/m4 tool effects; m6 policy menu/rejection share version decisions; 1.1.1 offers native onRequest only |
Expand Down
6 changes: 4 additions & 2 deletions docs/sdk-migration.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,10 @@ including a reused multi-turn session. Failed admission starts no turn and does
not persist the selection as successfully applied. Config options represent requested
settings; negotiated `muse/sessionState` reports native observations separately.
The overlay remains until its retained host closes; user settings stay intact.
Named profile identity is preserved in discovery, but effective routing is unverified;
named-profile selections are unavailable with an actionable explanation.
Named profile identity is preserved in discovery and in the selection sent through
`session/setModel`. `model/list` reports the profile per catalog, and on Muse
1.3.0 every live provider-catalog row carries it, so profiled rows are offered and
selectable like any other choice.

Form elicitation supports single selections, bounded multiple selections, and
free text up to 500 characters. Invalid responses fail the turn and cancel the
Expand Down
9 changes: 2 additions & 7 deletions src/config-options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export function isReasoningEffort(value: unknown): value is MuseReasoningEffort
return typeof value === "string" && (EFFORT_LEVELS as readonly string[]).includes(value);
}

const DEFAULT_MODEL = "muse-spark-1.2";
const DEFAULT_MODEL = "muse-spark-1.3";
const DEFAULT_EFFORT = "high";

export interface SessionConfig {
Expand Down Expand Up @@ -55,7 +55,7 @@ export function buildConfigOptions(
const discovered: readonly DiscoveredModel[] =
backend === "sdk"
? discovery?.status === "available"
? discovery.models.filter((model) => model.profileId == null)
? discovery.models
: []
: KNOWN_MODELS.map((id) => ({ id, name: id }));
const current = discovered.filter(
Expand Down Expand Up @@ -174,11 +174,6 @@ export function selectModel(
);
if (matches.length === 1) {
const model = matches[0];
if (model.profileId != null)
throw RequestError.invalidParams(
undefined,
"Named model profile routing is unverified on supported Muse hosts; choose a provider model without a named profile",
);
return { ...config, model: model.id, providerId: model.providerId, profileId: model.profileId };
}
if (
Expand Down
4 changes: 0 additions & 4 deletions src/muse-sdk-host.ts
Original file line number Diff line number Diff line change
Expand Up @@ -301,10 +301,6 @@ export class MuseSdkHost {

private async open(preparing: () => void): Promise<HostLease> {
const options = this.options;
if (options.profileId != null)
throw new Error(
"Named model profile routing is unverified on supported Muse hosts; choose a provider model without a named profile. No turn was started",
);
// Only probed when the host check runs: spawning the real binary for a
// version string is exactly what `checkHost: false` exists to avoid.
const hostVersion =
Expand Down
2 changes: 1 addition & 1 deletion src/tests/config-options.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ describe("defaultSessionConfig", () => {
defaultSessionConfig({ model: "muse-spark-1.2-contributor", reasoningEffort: "ultra" }),
).toEqual({ model: "muse-spark-1.2-contributor", reasoningEffort: "ultra" });
expect(defaultSessionConfig({ reasoningEffort: "bogus" })).toEqual({
model: "muse-spark-1.2",
model: "muse-spark-1.3",
reasoningEffort: "high",
});
});
Expand Down
18 changes: 12 additions & 6 deletions src/tests/model-identity.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,13 +99,19 @@ it("recommendations retain explicit values and use only advertised choices", asy
).toMatchObject({ source: "retainedSelection", applied: false });
});

it("does not advertise unverified named-profile routing or lose its identity", () => {
it("advertises and selects catalog models that carry a named profile", () => {
// Muse 1.3.0 provider catalogs tag every row with the account's catalog
// profile, so filtering profiled rows left only the synthetic current model.
const profiled = { id: "named", name: "Named", providerId: "meta", profileId: "team" };
const catalog = { status: "available" as const, source: "providerCatalog", models: [profiled] };
const value = modelChoice(profiled);
const options = buildConfigOptions(config, "sdk", catalog);
expect(JSON.stringify(options)).not.toContain(value);
expect(() => selectModel(config, value, catalog)).toThrow(
/Named model profile routing is unverified/,
);
const option = buildConfigOptions(config, "sdk", catalog).find((o) => o.id === "model")!;
if (option.type !== "select") throw Error("wrong type");
expect(option.options.map((o) => ("value" in o ? o.value : undefined))).toContain(value);
expect(selectModel(config, value, catalog)).toMatchObject({
model: "named",
providerId: "meta",
profileId: "team",
});
expect(selectModel(config, "named", catalog)).toMatchObject({ profileId: "team" });
});