programmatic subagents
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat(core)!: require explicit spawn model and remove defaultModel config

+30 -35
+3 -4
SPEC.md
··· 161 161 162 162 export default defineConfig({ 163 163 defaultDriver: "default", 164 - defaultModel: "openai/gpt-5.3-codex", 165 164 defaultExecutor: "direct", 166 165 167 166 drivers: { ··· 211 210 { 212 211 "discoveryVersion": 1, 213 212 "programApi": { 214 - "spawnRequired": ["agent", "systemPrompt", "prompt"], 215 - "spawnOptional": ["model"], 213 + "spawnRequired": ["agent", "systemPrompt", "prompt", "model"], 214 + "spawnOptional": [], 216 215 "resultFields": ["text", "sessionRef", "agent", "model", "driver", "exitCode", "stopReason"] 217 216 }, 218 217 "drivers": { ··· 278 277 agent: Schema.NonEmptyString, 279 278 systemPrompt: Schema.NonEmptyString, 280 279 prompt: Schema.NonEmptyString, 281 - model: Schema.optional(Schema.NonEmptyString), 280 + model: Schema.NonEmptyString, 282 281 }); 283 282 284 283 export type SpawnOptions = Schema.Schema.Type<typeof SpawnOptions>;
+1 -1
docs/design-docs/mill-v0-architecture-and-boundaries.md
··· 45 45 agent: Schema.NonEmptyString, 46 46 systemPrompt: Schema.NonEmptyString, 47 47 prompt: Schema.NonEmptyString, 48 - model: Schema.optional(Schema.NonEmptyString), 48 + model: Schema.NonEmptyString, 49 49 }); 50 50 51 51 export type SpawnOptions = Schema.Schema.Type<typeof SpawnOptions>;
-1
docs/product-specs/mill-v0-product-spec.md
··· 155 155 // Optional overrides: 156 156 // defaultDriver: "pi", 157 157 // defaultExecutor: "direct", 158 - // defaultModel: "openai-codex/gpt-5.3-codex", 159 158 authoring: { 160 159 instructions: 161 160 "Use systemPrompt for WHO (role/method), prompt for WHAT (explicit task + scope + validation).",
+1 -1
packages/core/src/domain/spawn.schema.ts
··· 4 4 agent: Schema.NonEmptyString, 5 5 systemPrompt: Schema.NonEmptyString, 6 6 prompt: Schema.NonEmptyString, 7 - model: Schema.optional(Schema.NonEmptyString), 7 + model: Schema.NonEmptyString, 8 8 }); 9 9 10 10 export type SpawnOptions = Schema.Schema.Type<typeof SpawnOptions>;
+3 -7
packages/core/src/internal/engine.effect.test.ts
··· 49 49 50 50 const engine = makeMillEngine({ 51 51 runsDirectory, 52 - defaultModel: "openai/gpt-5.3-codex", 53 52 driverName: "default", 54 53 executorName: "direct", 55 54 driver: testDriver, ··· 77 76 78 77 const engine = makeMillEngine({ 79 78 runsDirectory, 80 - defaultModel: "openai/gpt-5.3-codex", 81 79 driverName: "default", 82 80 executorName: "direct", 83 81 driver: testDriver, ··· 95 93 agent: "scout", 96 94 systemPrompt: "You are concise.", 97 95 prompt: "Summarize this file.", 96 + model: "openai/gpt-5.3-codex", 98 97 }); 99 98 100 99 expect(result.sessionRef.length).toBeGreaterThan(0); ··· 173 172 const store = makeRunStore({ runsDirectory }); 174 173 const engine = makeMillEngine({ 175 174 runsDirectory, 176 - defaultModel: "openai/gpt-5.3-codex", 177 175 driverName: "default", 178 176 executorName: "direct", 179 177 driver: testDriver, ··· 269 267 const store = makeRunStore({ runsDirectory }); 270 268 const engine = makeMillEngine({ 271 269 runsDirectory, 272 - defaultModel: "openai/gpt-5.3-codex", 273 270 driverName: "default", 274 271 executorName: "direct", 275 272 driver: testDriver, ··· 316 313 317 314 const engine = makeMillEngine({ 318 315 runsDirectory, 319 - defaultModel: "openai/gpt-5.3-codex", 320 316 driverName: "default", 321 317 executorName: "direct", 322 318 driver: testDriver, ··· 334 330 agent: "scout", 335 331 systemPrompt: "You are concise.", 336 332 prompt: "Inspect this run", 333 + model: "openai/gpt-5.3-codex", 337 334 }), 338 335 () => Effect.void, 339 336 ), ··· 401 398 402 399 const engine = makeMillEngine({ 403 400 runsDirectory, 404 - defaultModel: "openai/gpt-5.3-codex", 405 401 driverName: "default", 406 402 executorName: "direct", 407 403 driver: driverWithRaw, ··· 439 435 agent: "scout", 440 436 systemPrompt: "You are concise.", 441 437 prompt: "watch this run", 438 + model: "openai/gpt-5.3-codex", 442 439 }), 443 440 () => Effect.void, 444 441 ), ··· 477 474 const store = makeRunStore({ runsDirectory }); 478 475 const engine = makeMillEngine({ 479 476 runsDirectory, 480 - defaultModel: "openai/gpt-5.3-codex", 481 477 driverName: "default", 482 478 executorName: "direct", 483 479 driver: testDriver,
+2 -3
packages/core/src/internal/engine.effect.ts
··· 135 135 readonly runsDirectory: string; 136 136 readonly driverName: string; 137 137 readonly executorName: string; 138 - readonly defaultModel: string; 139 138 readonly driver: DriverRuntime; 140 139 readonly extensions: ReadonlyArray<ExtensionRegistration>; 141 140 } ··· 743 742 spawnId, 744 743 driver: input.driver.name, 745 744 agent: spawnInput.agent, 746 - model: spawnInput.model ?? input.defaultModel, 745 + model: spawnInput.model, 747 746 }); 748 747 749 748 const driverOutputExit = yield* Effect.exit( ··· 755 754 agent: spawnInput.agent, 756 755 systemPrompt: spawnInput.systemPrompt, 757 756 prompt: spawnInput.prompt, 758 - model: spawnInput.model ?? input.defaultModel, 757 + model: spawnInput.model, 759 758 }), 760 759 (error) => 761 760 new ProgramExecutionError({
+2
packages/core/src/internal/lifecycle-guard.effect.test.ts
··· 54 54 agent: "scout", 55 55 systemPrompt: "You are concise.", 56 56 prompt: "summarize", 57 + model: "openai/gpt-5.3-codex", 57 58 }, 58 59 }, 59 60 }), ··· 201 202 agent: "scout", 202 203 systemPrompt: "You are concise.", 203 204 prompt: "summarize", 205 + model: "openai/gpt-5.3-codex", 204 206 }, 205 207 }, 206 208 }),
-3
packages/core/src/public/config-loader.api.test.ts
··· 9 9 const makeDefaults = (): MillConfig => ({ 10 10 defaultDriver: "default", 11 11 defaultExecutor: "direct", 12 - defaultModel: "openai/gpt-5.3-codex", 13 12 drivers: { 14 13 default: { 15 14 description: "Catalog-backed test driver", ··· 207 206 "export default defineConfig({", 208 207 ' defaultDriver: "module-driver",', 209 208 ' defaultExecutor: "module-executor",', 210 - ' defaultModel: "provider/module-model",', 211 209 " maxRunDepth: 3,", 212 210 " drivers: {", 213 211 " 'module-driver': processDriver({", ··· 263 261 expect(resolved.configPath).toBe(configPath); 264 262 expect(resolved.config.defaultDriver).toBe("module-driver"); 265 263 expect(resolved.config.defaultExecutor).toBe("module-executor"); 266 - expect(resolved.config.defaultModel).toBe("provider/module-model"); 267 264 expect(resolved.config.maxRunDepth).toBe(3); 268 265 expect(resolved.config.authoring.instructions).toBe("Use module config"); 269 266 expect(Object.keys(resolved.config.drivers)).toContain("default");
-3
packages/core/src/public/config-loader.api.ts
··· 135 135 [ 136 136 "defaultDriver", 137 137 "defaultExecutor", 138 - "defaultModel", 139 138 "maxRunDepth", 140 139 "drivers", 141 140 "executors", ··· 180 179 return { 181 180 defaultDriver: readStringField(value, "defaultDriver"), 182 181 defaultExecutor: readStringField(value, "defaultExecutor"), 183 - defaultModel: readStringField(value, "defaultModel"), 184 182 maxRunDepth: readPositiveIntegerField(value, "maxRunDepth"), 185 183 drivers: readRecordField(value, "drivers") as Readonly<Record<string, DriverRegistration>>, 186 184 executors: readRecordField(value, "executors") as MillConfig["executors"], ··· 241 239 ...defaults, 242 240 defaultDriver: overrides.defaultDriver ?? defaults.defaultDriver, 243 241 defaultExecutor: overrides.defaultExecutor ?? defaults.defaultExecutor, 244 - defaultModel: overrides.defaultModel ?? defaults.defaultModel, 245 242 maxRunDepth: overrides.maxRunDepth ?? defaults.maxRunDepth, 246 243 drivers: { 247 244 ...defaults.drivers,
+2 -3
packages/core/src/public/discovery.api.test.ts
··· 6 6 const makeDefaults = (): MillConfig => ({ 7 7 defaultDriver: "default", 8 8 defaultExecutor: "direct", 9 - defaultModel: "openai/gpt-5.3-codex", 10 9 drivers: { 11 10 default: { 12 11 description: "Catalog-backed test driver", ··· 65 64 }); 66 65 67 66 expect(payload.discoveryVersion).toBe(1); 68 - expect(payload.programApi.spawnRequired).toEqual(["agent", "systemPrompt", "prompt"]); 69 - expect(payload.programApi.spawnOptional).toEqual(["model"]); 67 + expect(payload.programApi.spawnRequired).toEqual(["agent", "systemPrompt", "prompt", "model"]); 68 + expect(payload.programApi.spawnOptional).toEqual([]); 70 69 expect(payload.programApi.resultFields).toEqual([ 71 70 "text", 72 71 "sessionRef",
+2 -2
packages/core/src/public/discovery.api.ts
··· 50 50 return { 51 51 discoveryVersion: 1, 52 52 programApi: { 53 - spawnRequired: ["agent", "systemPrompt", "prompt"], 54 - spawnOptional: ["model"], 53 + spawnRequired: ["agent", "systemPrompt", "prompt", "model"], 54 + spawnOptional: [], 55 55 resultFields: ["text", "sessionRef", "agent", "model", "driver", "exitCode", "stopReason"], 56 56 }, 57 57 drivers,
+1
packages/core/src/public/mill.api.test.ts
··· 9 9 agent: "scout", 10 10 systemPrompt: "You are concise.", 11 11 prompt: "Say hello", 12 + model: "openai/gpt-5.3-codex", 12 13 }); 13 14 14 15 expect(result.driver).toBe("default");
+1 -1
packages/core/src/public/mill.api.ts
··· 7 7 text: `noop response for ${input.agent}`, 8 8 sessionRef: "session/noop", 9 9 agent: input.agent, 10 - model: input.model ?? "openai/gpt-5.3-codex", 10 + model: input.model, 11 11 driver: "default", 12 12 exitCode: 0, 13 13 });
+10 -1
packages/core/src/public/run.api.test.ts
··· 44 44 const makeConfig = (): MillConfig => ({ 45 45 defaultDriver: "default", 46 46 defaultExecutor: "direct", 47 - defaultModel: "openai/gpt-5.3-codex", 48 47 maxRunDepth: 1, 49 48 drivers: { 50 49 default: { ··· 161 160 const tempDirectory = await mkdtemp(join(tmpdir(), "mill-run-api-")); 162 161 const homeDirectory = join(tempDirectory, "home"); 163 162 const programPath = join(tempDirectory, "program.ts"); 163 + const previousDepth = process.env.MILL_RUN_DEPTH; 164 + 165 + delete process.env.MILL_RUN_DEPTH; 164 166 165 167 await writeFile( 166 168 programPath, ··· 170 172 ' agent: "scout",', 171 173 ' systemPrompt: "You are concise.",', 172 174 " prompt: note,", 175 + ' model: "openai/gpt-5.3-codex",', 173 176 "});", 174 177 'return JSON.stringify({ note, driver: spawned.driver, executor: globalThis.__millExecutorName ?? "unknown" });', 175 178 ].join("\n"), ··· 231 234 expect(hostMarker).toContain("process-host:bun"); 232 235 expect(hostMarker).toContain(`executor=${output.run.executor}`); 233 236 } finally { 237 + if (previousDepth === undefined) { 238 + delete process.env.MILL_RUN_DEPTH; 239 + } else { 240 + process.env.MILL_RUN_DEPTH = previousDepth; 241 + } 242 + 234 243 await rm(tempDirectory, { recursive: true, force: true }); 235 244 } 236 245 });
-1
packages/core/src/public/run.api.ts
··· 443 443 runsDirectory, 444 444 driverName: selectedDriver.name, 445 445 executorName: selectedExecutor.name, 446 - defaultModel: resolvedConfig.config.defaultModel, 447 446 driver: selectedDriver.runtime, 448 447 extensions: resolvedConfig.config.extensions, 449 448 }),
+1 -3
packages/core/src/public/types.ts
··· 4 4 readonly agent: string; 5 5 readonly systemPrompt: string; 6 6 readonly prompt: string; 7 - readonly model?: string; 7 + readonly model: string; 8 8 } 9 9 10 10 export interface SpawnOutput { ··· 117 117 export interface MillConfig { 118 118 readonly defaultDriver: string; 119 119 readonly defaultExecutor: string; 120 - readonly defaultModel: string; 121 120 readonly maxRunDepth?: number; 122 121 readonly drivers: Readonly<Record<string, DriverRegistration>>; 123 122 readonly executors: Readonly<Record<string, ExecutorRegistration>>; ··· 168 167 export interface ConfigFileOverrides { 169 168 readonly defaultDriver?: string; 170 169 readonly defaultExecutor?: string; 171 - readonly defaultModel?: string; 172 170 readonly maxRunDepth?: number; 173 171 readonly drivers?: Readonly<Record<string, DriverRegistration>>; 174 172 readonly executors?: Readonly<Record<string, ExecutorRegistration>>;
+1 -1
packages/core/src/runtime/worker.effect.test.ts
··· 40 40 const store = makeRunStore({ runsDirectory }); 41 41 const engine = makeMillEngine({ 42 42 runsDirectory, 43 - defaultModel: "openai/gpt-5.3-codex", 44 43 driverName: "default", 45 44 executorName: "direct", 46 45 driver: testDriver, ··· 71 70 agent: "scout", 72 71 systemPrompt: "You are concise.", 73 72 prompt: "Say hello", 73 + model: "openai/gpt-5.3-codex", 74 74 }); 75 75 76 76 expect(result.sessionRef.length).toBeGreaterThan(0);