| ... | @@ -4,11 +4,12 @@ import { it } from "@effect/vitest"; | ... | @@ -4,11 +4,12 @@ import { it } from "@effect/vitest"; |
| 4 | import * as Effect from "effect/Effect"; | 4 | import * as Effect from "effect/Effect"; |
| 5 | import * as Schema from "effect/Schema"; | 5 | import * as Schema from "effect/Schema"; |
| 6 | import { describe } from "vite-plus/test"; | 6 | import { describe } from "vite-plus/test"; |
| 7 | import { ThreadId } from "@t3tools/contracts"; | 7 | import { DEFAULT_MODEL, ThreadId } from "@t3tools/contracts"; |
| 8 | import * as CodexErrors from "effect-codex-app-server/errors"; | 8 | import * as CodexErrors from "effect-codex-app-server/errors"; |
| 9 | import * as CodexRpc from "effect-codex-app-server/rpc"; | 9 | import * as CodexRpc from "effect-codex-app-server/rpc"; |
| 10 | | 10 | |
| 11 | import { | 11 | import { |
| | 12 | buildCodexDeveloperInstructions, |
| 12 | CODEX_DEFAULT_MODE_DEVELOPER_INSTRUCTIONS, | 13 | CODEX_DEFAULT_MODE_DEVELOPER_INSTRUCTIONS, |
| 13 | CODEX_PLAN_MODE_DEVELOPER_INSTRUCTIONS, | 14 | CODEX_PLAN_MODE_DEVELOPER_INSTRUCTIONS, |
| 14 | } from "../CodexDeveloperInstructions.ts"; | 15 | } from "../CodexDeveloperInstructions.ts"; |
| ... | @@ -118,7 +119,10 @@ describe("buildTurnStartParams", () => { | ... | @@ -118,7 +119,10 @@ describe("buildTurnStartParams", () => { |
| 118 | settings: { | 119 | settings: { |
| 119 | model: "gpt-5.3-codex", | 120 | model: "gpt-5.3-codex", |
| 120 | reasoning_effort: "medium", | 121 | reasoning_effort: "medium", |
| 121 | developer_instructions: CODEX_PLAN_MODE_DEVELOPER_INSTRUCTIONS, | 122 | developer_instructions: buildCodexDeveloperInstructions("plan", { |
| | 123 | model: "gpt-5.3-codex", |
| | 124 | reasoningEffort: "medium", |
| | 125 | }), |
| 122 | }, | 126 | }, |
| 123 | }, | 127 | }, |
| 124 | }); | 128 | }); |
| ... | @@ -163,12 +167,31 @@ describe("buildTurnStartParams", () => { | ... | @@ -163,12 +167,31 @@ describe("buildTurnStartParams", () => { |
| 163 | settings: { | 167 | settings: { |
| 164 | model: "gpt-5.3-codex", | 168 | model: "gpt-5.3-codex", |
| 165 | reasoning_effort: "medium", | 169 | reasoning_effort: "medium", |
| 166 | developer_instructions: CODEX_DEFAULT_MODE_DEVELOPER_INSTRUCTIONS, | 170 | developer_instructions: buildCodexDeveloperInstructions("default", { |
| | 171 | model: "gpt-5.3-codex", |
| | 172 | reasoningEffort: "medium", |
| | 173 | }), |
| 167 | }, | 174 | }, |
| 168 | }, | 175 | }, |
| 169 | }); | 176 | }); |
| 170 | }); | 177 | }); |
| 171 | | 178 | |
| | 179 | it("reports the same fallback model and effort in settings and instructions", () => { |
| | 180 | const params = Effect.runSync( |
| | 181 | buildTurnStartParams({ |
| | 182 | threadId: "provider-thread-1", |
| | 183 | runtimeMode: "full-access", |
| | 184 | prompt: "Go", |
| | 185 | interactionMode: "default", |
| | 186 | }), |
| | 187 | ); |
| | 188 | |
| | 189 | const settings = params.collaborationMode?.settings; |
| | 190 | NodeAssert.equal(settings?.model, DEFAULT_MODEL); |
| | 191 | NodeAssert.equal(settings?.reasoning_effort, "medium"); |
| | 192 | NodeAssert.ok(settings?.developer_instructions?.includes(`as ${DEFAULT_MODEL} with medium`)); |
| | 193 | }); |
| | 194 | |
| 172 | it("omits collaboration mode when interaction mode is absent", () => { | 195 | it("omits collaboration mode when interaction mode is absent", () => { |
| 173 | const params = Effect.runSync( | 196 | const params = Effect.runSync( |
| 174 | buildTurnStartParams({ | 197 | buildTurnStartParams({ |
| ... | @@ -194,6 +217,53 @@ describe("buildTurnStartParams", () => { | ... | @@ -194,6 +217,53 @@ describe("buildTurnStartParams", () => { |
| 194 | }); | 217 | }); |
| 195 | }); | 218 | }); |
| 196 | | 219 | |
| | 220 | describe("buildCodexDeveloperInstructions", () => { |
| | 221 | it("appends runtime info after the mode instructions", () => { |
| | 222 | const instructions = buildCodexDeveloperInstructions("default", { |
| | 223 | model: "gpt-5.3-codex", |
| | 224 | reasoningEffort: "high", |
| | 225 | }); |
| | 226 | |
| | 227 | NodeAssert.ok(instructions.startsWith(CODEX_DEFAULT_MODE_DEVELOPER_INSTRUCTIONS)); |
| | 228 | NodeAssert.match(instructions, /T3 Code/); |
| | 229 | NodeAssert.match(instructions, /Codex harness/); |
| | 230 | NodeAssert.match(instructions, /as gpt-5\.3-codex with high reasoning effort/); |
| | 231 | }); |
| | 232 | |
| | 233 | it("includes runtime info alongside plan mode instructions", () => { |
| | 234 | const instructions = buildCodexDeveloperInstructions("plan", { |
| | 235 | model: "gpt-5.3-codex", |
| | 236 | reasoningEffort: "medium", |
| | 237 | }); |
| | 238 | |
| | 239 | NodeAssert.ok(instructions.startsWith(CODEX_PLAN_MODE_DEVELOPER_INSTRUCTIONS)); |
| | 240 | NodeAssert.match(instructions, /as gpt-5\.3-codex with medium reasoning effort/); |
| | 241 | }); |
| | 242 | |
| | 243 | it("varies with the model and effort of each turn", () => { |
| | 244 | const first = buildCodexDeveloperInstructions("default", { |
| | 245 | model: "gpt-5.3-codex", |
| | 246 | reasoningEffort: "medium", |
| | 247 | }); |
| | 248 | const second = buildCodexDeveloperInstructions("default", { |
| | 249 | model: "gpt-5.4", |
| | 250 | reasoningEffort: "high", |
| | 251 | }); |
| | 252 | |
| | 253 | NodeAssert.notEqual(first, second); |
| | 254 | }); |
| | 255 | |
| | 256 | it("flattens multiline metadata into single-line runtime info", () => { |
| | 257 | const instructions = buildCodexDeveloperInstructions("default", { |
| | 258 | model: "gpt\n5.3\ncodex", |
| | 259 | reasoningEffort: " high\neffort ", |
| | 260 | }); |
| | 261 | |
| | 262 | NodeAssert.match(instructions, /as gpt 5\.3 codex with high effort reasoning effort/); |
| | 263 | NodeAssert.doesNotMatch(instructions, /<runtime_info>[^<]*\n/); |
| | 264 | }); |
| | 265 | }); |
| | 266 | |
| 197 | describe("T3 browser developer instructions", () => { | 267 | describe("T3 browser developer instructions", () => { |
| 198 | it("prefers the product-native preview tools in both collaboration modes", () => { | 268 | it("prefers the product-native preview tools in both collaboration modes", () => { |
| 199 | for (const instructions of [ | 269 | for (const instructions of [ |