Skip to content
Merged
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
65 changes: 65 additions & 0 deletions packages/agent/src/server/agent-server.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,9 @@ interface TestableServer {
): string | { append: string };
buildCodexInstructions(systemPrompt: string | { append: string }): string;
getRuntimeAdapter(): "claude" | "codex";
buildClaudeCodeSessionMeta(
runtimeAdapter: "claude" | "codex",
): { claudeCode: { options: Record<string, unknown> } } | undefined;
}

let nextTestPort = 20000;
Expand Down Expand Up @@ -1140,6 +1143,68 @@ describe("AgentServer HTTP Mode", () => {
});
});

describe("buildClaudeCodeSessionMeta", () => {
it("sends claude reasoning effort even when no plugins are configured", () => {
const s = createServer({ reasoningEffort: "high" });

const meta = (s as unknown as TestableServer).buildClaudeCodeSessionMeta(
"claude",
);

expect(meta?.claudeCode.options).toEqual({ effort: "high" });
});

it("does not send claudeCode effort for codex runs", () => {
const s = createServer({ reasoningEffort: "high" });

const meta = (s as unknown as TestableServer).buildClaudeCodeSessionMeta(
"codex",
);

expect(meta).toBeUndefined();
});

it("returns undefined when neither plugins nor effort are set", () => {
const s = createServer();

const meta = (s as unknown as TestableServer).buildClaudeCodeSessionMeta(
"claude",
);

expect(meta).toBeUndefined();
});

it("includes both plugins and effort for claude runs", () => {
const s = createServer({
reasoningEffort: "medium",
claudeCode: { plugins: [{ type: "local", path: "/tmp/plugin" }] },
});

const meta = (s as unknown as TestableServer).buildClaudeCodeSessionMeta(
"claude",
);

expect(meta?.claudeCode.options).toEqual({
plugins: [{ type: "local", path: "/tmp/plugin" }],
effort: "medium",
});
});

it("returns only plugins when effort is not set", () => {
const s = createServer({
claudeCode: { plugins: [{ type: "local", path: "/tmp/plugin" }] },
});

const meta = (s as unknown as TestableServer).buildClaudeCodeSessionMeta(
"claude",
);

expect(meta?.claudeCode.options).toEqual({
plugins: [{ type: "local", path: "/tmp/plugin" }],
});
});
});
Comment thread
charlesvien marked this conversation as resolved.

describe("detectedPrUrl tracking", () => {
it("stores PR URL when gh pr create produces it", () => {
const s = createServer();
Expand Down
40 changes: 27 additions & 13 deletions packages/agent/src/server/agent-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1067,19 +1067,7 @@ export class AgentServer {
jsonSchema: preTask?.json_schema ?? null,
permissionMode: initialPermissionMode,
...(this.config.baseBranch && { baseBranch: this.config.baseBranch }),
...(this.config.claudeCode?.plugins?.length && {
claudeCode: {
options: {
...(this.config.claudeCode?.plugins?.length && {
plugins: this.config.claudeCode.plugins,
}),
...(runtimeAdapter === "claude" &&
this.config.reasoningEffort && {
effort: this.config.reasoningEffort,
}),
},
},
}),
...this.buildClaudeCodeSessionMeta(runtimeAdapter),
},
});

Expand Down Expand Up @@ -1670,6 +1658,32 @@ export class AgentServer {
: systemPrompt.append;
}

/**
* Builds the optional `claudeCode` session meta. Reasoning effort and plugins
* are independent: effort must reach Claude even when no plugins are set, so
* it cannot sit behind a plugins guard.
*/
private buildClaudeCodeSessionMeta(
runtimeAdapter: "claude" | "codex",
): { claudeCode: { options: Record<string, unknown> } } | undefined {
const plugins = this.config.claudeCode?.plugins;
const effort =
runtimeAdapter === "claude" ? this.config.reasoningEffort : undefined;

if (!plugins?.length && !effort) {
return undefined;
}

const options: Record<string, unknown> = {};
if (plugins?.length) {
options.plugins = plugins;
}
if (effort) {
options.effort = effort;
}
return { claudeCode: { options } };
}

private getCloudInteractionOrigin(): string | undefined {
return (
process.env.POSTHOG_CODE_INTERACTION_ORIGIN ??
Expand Down
Loading