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
4 changes: 4 additions & 0 deletions apps/server/src/mcp/OrchestratorMcpService.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import * as NodeServices from "@effect/platform-node/NodeServices";
import { assert, describe, it } from "@effect/vitest";
import {
CommandId,
DEFAULT_SERVER_SETTINGS,
EnvironmentId,
MessageId,
NodeId,
Expand Down Expand Up @@ -3002,6 +3003,9 @@ describe("OrchestratorMcpService provider resolution", () => {
},
];
const resolved = resolveRoles({
settings: DEFAULT_SERVER_SETTINGS,
projectId,
nowMs: 0,
file: parseModelsFile(
"architect runners: claudeAgent/claude-opus-5-5 effort=xhigh, codex/gpt-6-astra reasoningEffort=high",
),
Expand Down
125 changes: 124 additions & 1 deletion apps/server/src/pstack/PstackPack.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import * as FileSystem from "effect/FileSystem";
import * as Path from "effect/Path";
import * as PstackPack from "./PstackPack.ts";
import * as ServerSettings from "../serverSettings.ts";
import { ProjectId } from "@t3tools/contracts";
import { ProjectId, ProviderInstanceId, type ServerProvider } from "@t3tools/contracts";
import { claudeProvider, makeFixture } from "./PstackPack.testkit.ts";
import { BUILT_IN_DRIVERS } from "../provider/builtInDrivers.ts";

Expand Down Expand Up @@ -347,6 +347,129 @@ it.layer(NodeServices.layer)("PstackPack", (it) => {
}).pipe(Effect.provide(Layer.merge(fixture.layer, fixture.settingsLayer)));
}),
);
it.effect("default roles skip cooling instances and choose a ready instance", () =>
Effect.gen(function* () {
const ready = {
...claudeProvider,
instanceId: ProviderInstanceId.make("claudeAgent_ready"),
};
const fixture = yield* makeFixture(
[{ ...claudeProvider, limitedUntil: "2099-01-01T00:00:00Z" }, ready],
ServerSettings.layerTest({
pstackEnabled: true,
providerInstances: {
[ready.instanceId]: { driver: ready.driver, enabled: true, config: {} },
},
}),
);
const expansion = yield* Effect.gen(function* () {
return yield* (yield* PstackPack.PstackPack).expandComposer(
{ text: "$pstack:architect", records: [], projectId: ProjectId.make("pack-test") },
{ createdBy: "user" },
);
}).pipe(Effect.provide(fixture.layer));
assert.include(
expansion.text,
'- architect runners: [1] {"providerInstanceId":"claudeAgent_ready"',
);
assert.notInclude(expansion.text, "Fallback: architect runners seat 1");
}),
);
it.effect("explicit cooling targets fall back to the parent", () =>
Effect.gen(function* () {
const fixture = yield* makeFixture([
{ ...claudeProvider, limitedUntil: "2099-01-01T00:00:00Z" },
]);
const fs = yield* FileSystem.FileSystem;
yield* fs.makeDirectory(`${fixture.stateDir}/pstack`, { recursive: true });
yield* fs.writeFileString(
`${fixture.stateDir}/pstack/models.md`,
"architect runners: claudeAgent/claude-opus-5-5",
);
const expansion = yield* Effect.gen(function* () {
return yield* (yield* PstackPack.PstackPack).expandComposer(
{ text: "$pstack:architect", records: [], projectId: ProjectId.make("pack-test") },
{ createdBy: "user" },
);
}).pipe(Effect.provide(fixture.layer));
assert.include(expansion.text, "- architect runners: [1] inherit");
assert.include(expansion.text, "Provider is rate limited. Retry after its cooldown expires.");
}),
);
it.effect.each(["all cooling", "healthy member disabled", "healthy member available"] as const)(
"pool roles use project-aware delegation availability: %s",
(scenario) =>
Effect.gen(function* () {
const projectId = ProjectId.make("pack-test");
const poolId = ProviderInstanceId.make("pool_claudeAgent");
const workId = ProviderInstanceId.make("claudeAgent_work");
const members: ServerProvider[] = [claudeProvider.instanceId, workId].map(
(instanceId, index) => ({
...claudeProvider,
instanceId,
pool: { role: "member", poolInstanceId: poolId },
...(index === 0 || scenario === "all cooling"
? { limitedUntil: "2099-01-01T00:00:00Z" }
: {}),
}),
);
const fixture = yield* makeFixture(
[
...members,
{
...claudeProvider,
instanceId: poolId,
pool: {
role: "pool",
memberInstanceIds: members.map((member) => member.instanceId),
droppedModels: [],
},
},
],
ServerSettings.layerTest({
pstackEnabled: true,
providerInstances: {
[workId]: { driver: claudeProvider.driver, enabled: true, config: {} },
},
providerPools: {
[claudeProvider.driver]: {
enabled: true,
memberInstanceIds: members.map((member) => member.instanceId),
},
},
projectSettingsOverrides: {
[projectId]: {
providerInstances: {
[workId]: { enabled: scenario !== "healthy member disabled" },
},
},
},
}),
);
const fs = yield* FileSystem.FileSystem;
yield* fs.makeDirectory(`${fixture.stateDir}/pstack`, { recursive: true });
yield* fs.writeFileString(
`${fixture.stateDir}/pstack/models.md`,
"architect runners: pool_claudeAgent/claude-opus-5-5",
);
const expansion = yield* Effect.gen(function* () {
return yield* (yield* PstackPack.PstackPack).expandComposer(
{ text: "$pstack:architect", records: [], projectId },
{ createdBy: "user" },
);
}).pipe(Effect.provide(fixture.layer));
if (scenario === "healthy member available") {
assert.include(
expansion.text,
'- architect runners: [1] {"providerInstanceId":"pool_claudeAgent"',
);
assert.notInclude(expansion.text, "Fallback:");
} else {
assert.include(expansion.text, "- architect runners: [1] inherit");
assert.include(expansion.text, "Every available pool member is rate limited.");
}
}),
);
it.effect("concurrent materializers tolerate a losing rename and keep the stable pack", () =>
Effect.gen(function* () {
const fixture = yield* makeFixture();
Expand Down
4 changes: 4 additions & 0 deletions apps/server/src/pstack/PstackPack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
} from "@t3tools/pstack";
import { parseSkillFrontmatter } from "@t3tools/shared/skillFrontmatter";
import * as Cause from "effect/Cause";
import * as Clock from "effect/Clock";
import * as Context from "effect/Context";
import * as Effect from "effect/Effect";
import * as FileSystem from "effect/FileSystem";
Expand Down Expand Up @@ -299,6 +300,9 @@ const make = Effect.fn("PstackPack.make")(function* (sourceRoot?: string) {
resolved: resolveRoles({
file: file === undefined ? undefined : parseModelsFile(file),
defaults: pack.defaults,
settings: currentSettings,
projectId: input.projectId,
nowMs: yield* Clock.currentTimeMillis,
...providers,
providers: providers.providers.map((provider) => ({
...provider,
Expand Down
43 changes: 40 additions & 3 deletions apps/server/src/pstack/pstackModels.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { assert, it } from "@effect/vitest";
import {
DEFAULT_SERVER_SETTINGS,
ProjectId,
ProviderDriverKind,
ProviderInstanceId,
type ProviderOptionDescriptor,
Expand Down Expand Up @@ -62,12 +64,18 @@ const defaults = [
},
];
const capableInstanceIds = new Set(providers.map((provider) => provider.instanceId));
const availability = {
settings: DEFAULT_SERVER_SETTINGS,
projectId: ProjectId.make("pstack"),
nowMs: Date.parse("2026-10-25T00:00:00Z"),
};
const file =
"# budget: balanced\narchitect runners: claudeAgent/claude-opus-5-5 effort=xhigh, codex/gpt-6-astra reasoningEffort=high";

it.effect("completes every omitted Opus and Astra option with its advertised current value", () =>
Effect.sync(() => {
const resolved = resolveRoles({
...availability,
file: parseModelsFile(file),
defaults,
providers,
Expand Down Expand Up @@ -101,6 +109,7 @@ it.effect("completes every omitted Opus and Astra option with its advertised cur
it.effect("disabled providers fall back visibly without shrinking panels", () =>
Effect.sync(() => {
const result = resolveRoles({
...availability,
file: parseModelsFile(file),
defaults,
providers: providers.map((provider) => ({ ...provider, enabled: false })),
Expand All @@ -115,7 +124,13 @@ it.effect("disabled providers fall back visibly without shrinking panels", () =>
);
it.effect("missing models file maps upstream family, effort and fast defaults", () =>
Effect.sync(() => {
const result = resolveRoles({ file: undefined, defaults, providers, capableInstanceIds });
const result = resolveRoles({
...availability,
file: undefined,
defaults,
providers,
capableInstanceIds,
});
assert.deepEqual(result.diagnostics, []);
const seat = result.roles[0]!.seats[1]!;
assert.deepEqual(seat, {
Expand All @@ -136,6 +151,7 @@ it.effect.each(["effort=ultra", "unknown=true", "fastMode=yes", "effort=high eff
(option) =>
Effect.sync(() => {
const result = resolveRoles({
...availability,
file: parseModelsFile(`architect runners: claudeAgent/claude-opus-5-5 ${option}`),
defaults,
providers,
Expand All @@ -150,7 +166,13 @@ it.effect("preserves explicit panel cardinality, aliases, comments and model sla
const parsed = parseModelsFile(
"# budget: high\narchitect runners: auto, inherit-parent, missing/vendor/model option=false # note",
);
const result = resolveRoles({ file: parsed, defaults, providers, capableInstanceIds });
const result = resolveRoles({
...availability,
file: parsed,
defaults,
providers,
capableInstanceIds,
});
assert.equal(result.roles[0]!.seats.length, 3);
assert.include(result.diagnostics[0]!, "missing/vendor/model");
}),
Expand All @@ -159,6 +181,7 @@ it.effect("recognizes Pi-style thinking as effort and drops unadvertised fast hi
Effect.sync(() => {
const piStyle = provider("custom-codex", "codex", "gpt-6-astra", [effort("thinking")]);
const result = resolveRoles({
...availability,
file: undefined,
defaults: [{ label: "runner", defaultValue: "gpt-6-astra-xhigh-fast" }],
providers: [piStyle],
Expand All @@ -180,6 +203,7 @@ it.effect("recognizes Pi-style thinking as effort and drops unadvertised fast hi
it.effect("unregistered adapters and missing current values cannot leak parent options", () =>
Effect.sync(() => {
const unsupported = resolveRoles({
...availability,
file: parseModelsFile(file),
defaults,
providers,
Expand All @@ -195,6 +219,7 @@ it.effect("unregistered adapters and missing current values cannot leak parent o
},
]);
const result = resolveRoles({
...availability,
file: parseModelsFile("architect runners: codex/gpt-6-astra"),
defaults,
providers: [incomplete],
Expand Down Expand Up @@ -235,6 +260,7 @@ it.effect.each(["claude-opus-5-5", "claude-sonnet-4-6"])(
(model) =>
Effect.sync(() => {
const result = resolveRoles({
...availability,
file: parseModelsFile(`architect runners: claudeAgent/${model}`),
defaults,
providers,
Expand Down Expand Up @@ -263,6 +289,7 @@ it.effect("completes a Pi thinking select from isDefault", () =>
Effect.sync(() => {
const pi = provider("pi", "pi", "vendor/model", [effort("thinking")]);
const result = resolveRoles({
...availability,
file: parseModelsFile("architect runners: pi/vendor/model"),
defaults,
providers: [pi],
Expand Down Expand Up @@ -291,6 +318,7 @@ it.effect("default seats skip unhealthy and incapable instances offering the mod
};
const incapable = { ...first, instanceId: ProviderInstanceId.make("incapable") };
const result = resolveRoles({
...availability,
file: undefined,
defaults,
providers: [unhealthy, incapable, ...providers],
Expand Down Expand Up @@ -325,6 +353,7 @@ it.effect("clamps default effort below its budget and accepts the advertised fas
},
]);
const result = resolveRoles({
...availability,
file: undefined,
defaults: [{ label: "architect runners", defaultValue: "gpt-6-astra-xhigh-fast" }],
providers: [codex],
Expand All @@ -349,6 +378,7 @@ it.effect("clamps default effort below its budget and accepts the advertised fas
it.effect("reports unknown role labels and ignores empty comma entries", () =>
Effect.sync(() => {
const result = resolveRoles({
...availability,
file: parseModelsFile("archtect runners: auto\narchitect runners: auto,, inherit-parent, "),
defaults,
providers,
Expand All @@ -364,12 +394,19 @@ it.effect.each(["", " ,,", " # comment"])(
(value) =>
Effect.sync(() => {
const result = resolveRoles({
...availability,
file: parseModelsFile(`architect runners:${value}`),
defaults,
providers,
capableInstanceIds,
});
const expected = resolveRoles({ file: undefined, defaults, providers, capableInstanceIds });
const expected = resolveRoles({
...availability,
file: undefined,
defaults,
providers,
capableInstanceIds,
});
assert.deepEqual(result.roles, expected.roles);
assert.include(result.diagnostics.join("\n"), "empty role architect runners; using defaults");
}),
Expand Down
Loading
Loading