| ... | ... | @@ -47,7 +47,9 @@ const personalSkill = { |
| 47 | 47 | }; |
| 48 | 48 | |
| 49 | 49 | // Respond through the real stdio transport, with a distinct command catalog for each cwd. |
| 50 | | const makePiSpawner = Effect.gen(function* () { |
| 50 | const makePiSpawner = Effect.fnUntraced(function* ( |
| 51 | discovery: { readonly state?: unknown; readonly models?: ReadonlyArray<unknown> } = {}, |
| 52 | ) { |
| 51 | 53 | const pendingCommand = yield* Deferred.make<void>(); |
| 52 | 54 | const launches: Array<ChildProcess.StandardCommand> = []; |
| 53 | 55 | const spawner = ChildProcessSpawner.make((command) => |
| ... | ... | @@ -92,8 +94,10 @@ const makePiSpawner = Effect.gen(function* () { |
| 92 | 94 | ], |
| 93 | 95 | } |
| 94 | 96 | : request.type === "get_available_models" |
| 95 | | ? { models: [{ provider: "test", id: "model" }] } |
| 96 | | : {}; |
| 97 | ? { models: discovery.models ?? [{ provider: "test", id: "model" }] } |
| 98 | : request.type === "get_state" |
| 99 | ? (discovery.state ?? {}) |
| 100 | : {}; |
| 97 | 101 | return Queue.offer( |
| 98 | 102 | stdout, |
| 99 | 103 | encoder.encode( |
| ... | ... | @@ -125,7 +129,7 @@ const create = (config: Partial<PiSettings> = {}, enabled = true) => |
| 125 | 129 | it.layer(layerTest)("PiDriver workspace discovery", (it) => { |
| 126 | 130 | it.effect("keeps each workspace's skills and commands separate from the machine catalog", () => |
| 127 | 131 | Effect.gen(function* () { |
| 128 | | const { spawner, launches } = yield* makePiSpawner; |
| 132 | const { spawner, launches } = yield* makePiSpawner(); |
| 129 | 133 | const instance = yield* create({ launchArgs: '--approve --skill "extra skill"' }).pipe( |
| 130 | 134 | Effect.provideService(ChildProcessSpawner.ChildProcessSpawner, spawner), |
| 131 | 135 | ); |
| ... | ... | @@ -186,11 +190,50 @@ it.layer(layerTest)("PiDriver workspace discovery", (it) => { |
| 186 | 190 | }).pipe(Effect.scoped), |
| 187 | 191 | ); |
| 188 | 192 | |
| 193 | it.effect.each([true, false])( |
| 194 | "limits discovered thinking defaults to the known active model, known=%s", |
| 195 | (known) => |
| 196 | Effect.gen(function* () { |
| 197 | const { spawner } = yield* makePiSpawner({ |
| 198 | state: { |
| 199 | thinkingLevel: "high", |
| 200 | ...(known ? { model: { provider: "test", id: "model" } } : {}), |
| 201 | }, |
| 202 | models: [ |
| 203 | { provider: "test", id: "model", reasoning: true }, |
| 204 | { provider: "other", id: "model", reasoning: true }, |
| 205 | { provider: "test", id: "other", reasoning: true }, |
| 206 | ], |
| 207 | }); |
| 208 | const instance = yield* create().pipe( |
| 209 | Effect.provideService(ChildProcessSpawner.ChildProcessSpawner, spawner), |
| 210 | ); |
| 211 | yield* instance.snapshot.refresh; |
| 212 | const snapshot = yield* instance.snapshot.getSnapshot; |
| 213 | assert.deepEqual( |
| 214 | snapshot.models.map((model) => [ |
| 215 | model.slug, |
| 216 | (model.capabilities?.optionDescriptors ?? []).flatMap((descriptor) => |
| 217 | descriptor.type === "select" |
| 218 | ? descriptor.options.filter((option) => option.isDefault).map((option) => option.id) |
| 219 | : [], |
| 220 | ), |
| 221 | ]), |
| 222 | [ |
| 223 | ["default", []], |
| 224 | ["test/model", known ? ["high"] : []], |
| 225 | ["other/model", []], |
| 226 | ["test/other", []], |
| 227 | ], |
| 228 | ); |
| 229 | }).pipe(Effect.scoped), |
| 230 | ); |
| 231 | |
| 189 | 232 | it.effect( |
| 190 | 233 | "fails command discovery instead of returning an empty successful workspace catalog", |
| 191 | 234 | () => |
| 192 | 235 | Effect.gen(function* () { |
| 193 | | const { spawner } = yield* makePiSpawner; |
| 236 | const { spawner } = yield* makePiSpawner(); |
| 194 | 237 | const instance = yield* create().pipe( |
| 195 | 238 | Effect.provideService(ChildProcessSpawner.ChildProcessSpawner, spawner), |
| 196 | 239 | ); |
| ... | ... | @@ -208,7 +251,7 @@ it.layer(layerTest)("PiDriver workspace discovery", (it) => { |
| 208 | 251 | |
| 209 | 252 | it.effect("times out workspace discovery that needs interactive input", () => |
| 210 | 253 | Effect.gen(function* () { |
| 211 | | const { spawner, pendingCommand } = yield* makePiSpawner; |
| 254 | const { spawner, pendingCommand } = yield* makePiSpawner(); |
| 212 | 255 | const instance = yield* create().pipe( |
| 213 | 256 | Effect.provideService(ChildProcessSpawner.ChildProcessSpawner, spawner), |
| 214 | 257 | ); |