| author | |
| committer | |
| log | 2b6640af1e6e058f2c7206409d92bf5332fc9e90 |
| tree | 08b616fea8f7210e6d5b87aff4efa5d44a815980 |
| parent | 9e29c9d72895022322da52d8e961b38702bad9cc |
| signature | Signed by PGP key B5690EEEBB952194 |
2 files changed, 28 insertions(+), 0 deletions(-)
apps/server/src/provider/Layers/ClaudeAdapter.test.ts+21| ... | ... | @@ -272,6 +272,7 @@ describe("ClaudeAdapterLive", () => { |
| 272 | 272 | }); |
| 273 | 273 | |
| 274 | 274 | const createInput = harness.getLastCreateQueryInput(); |
| 275 | assert.deepEqual(createInput?.options.settingSources, ["user", "project", "local"]); | |
| 275 | 276 | assert.equal(createInput?.options.permissionMode, "bypassPermissions"); |
| 276 | 277 | assert.equal(createInput?.options.allowDangerouslySkipPermissions, true); |
| 277 | 278 | }).pipe( |
| ... | ... | @@ -280,6 +281,26 @@ describe("ClaudeAdapterLive", () => { |
| 280 | 281 | ); |
| 281 | 282 | }); |
| 282 | 283 | |
| 284 | it.effect("loads Claude filesystem settings sources for SDK sessions", () => { | |
| 285 | const harness = makeHarness(); | |
| 286 | return Effect.gen(function* () { | |
| 287 | const adapter = yield* ClaudeAdapter; | |
| 288 | yield* adapter.startSession({ | |
| 289 | threadId: THREAD_ID, | |
| 290 | provider: "claudeAgent", | |
| 291 | runtimeMode: "approval-required", | |
| 292 | }); | |
| 293 | ||
| 294 | const createInput = harness.getLastCreateQueryInput(); | |
| 295 | assert.deepEqual(createInput?.options.settingSources, ["user", "project", "local"]); | |
| 296 | assert.equal(createInput?.options.permissionMode, undefined); | |
| 297 | assert.equal(createInput?.options.allowDangerouslySkipPermissions, undefined); | |
| 298 | }).pipe( | |
| 299 | Effect.provideService(Random.Random, makeDeterministicRandomService()), | |
| 300 | Effect.provide(harness.layer), | |
| 301 | ); | |
| 302 | }); | |
| 303 | ||
| 283 | 304 | it.effect("keeps explicit claude permission mode over runtime-derived defaults", () => { |
| 284 | 305 | const harness = makeHarness(); |
| 285 | 306 | return Effect.gen(function* () { |
apps/server/src/provider/Layers/ClaudeAdapter.ts+7| ... | ... | @@ -15,6 +15,7 @@ import { |
| 15 | 15 | type PermissionUpdate, |
| 16 | 16 | type SDKMessage, |
| 17 | 17 | type SDKResultMessage, |
| 18 | type SettingSource, | |
| 18 | 19 | type SDKUserMessage, |
| 19 | 20 | } from "@anthropic-ai/claude-agent-sdk"; |
| 20 | 21 | import { |
| ... | ... | @@ -426,6 +427,11 @@ const SUPPORTED_CLAUDE_IMAGE_MIME_TYPES = new Set([ |
| 426 | 427 | "image/png", |
| 427 | 428 | "image/webp", |
| 428 | 429 | ]); |
| 430 | const CLAUDE_SETTING_SOURCES = [ | |
| 431 | "user", | |
| 432 | "project", | |
| 433 | "local", | |
| 434 | ] as const satisfies ReadonlyArray<SettingSource>; | |
| 429 | 435 | |
| 430 | 436 | function buildPromptText(input: ProviderSendTurnInput): string { |
| 431 | 437 | const requestedEffort = resolveReasoningEffortForProvider( |
| ... | ... | @@ -2562,6 +2568,7 @@ function makeClaudeAdapter(options?: ClaudeAdapterLiveOptions) { |
| 2562 | 2568 | ...(input.cwd ? { cwd: input.cwd } : {}), |
| 2563 | 2569 | ...(input.model ? { model: input.model } : {}), |
| 2564 | 2570 | pathToClaudeCodeExecutable: providerOptions?.binaryPath ?? "claude", |
| 2571 | settingSources: [...CLAUDE_SETTING_SOURCES], | |
| 2565 | 2572 | ...(effectiveEffort ? { effort: effectiveEffort } : {}), |
| 2566 | 2573 | ...(permissionMode ? { permissionMode } : {}), |
| 2567 | 2574 | ...(permissionMode === "bypassPermissions" |