Skip to content
This repository was archived by the owner on Aug 6, 2026. It is now read-only.

Commit 6daf8ce

Browse files
refactor(core): own composer model policy
Generated-By: PostHog Code Task-Id: c1bbe3cf-742b-4b24-bf96-d11a18b4cf22
1 parent f88f416 commit 6daf8ce

5 files changed

Lines changed: 83 additions & 36 deletions

File tree

‎apps/mobile/src/app/task/index.tsx‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import {
33
DEFAULT_CLAUDE_EXECUTION_MODE,
44
getAvailableModes,
55
} from "@posthog/core/sessions/executionModes";
6+
import { resolveCloudComposerModelChange } from "@posthog/core/task-detail/composerModelPolicy";
67
import {
78
DEFAULT_GATEWAY_MODEL,
89
DEFAULT_REASONING_EFFORT,
@@ -60,7 +61,6 @@ import {
6061
getComposerModelOptions,
6162
getConfigOptionLabel,
6263
getModelConfigOption,
63-
resolveComposerModelChange,
6464
} from "@/features/tasks/composer/options";
6565
import { Pill } from "@/features/tasks/composer/Pill";
6666
import { RepositoryPickerInline } from "@/features/tasks/composer/RepositoryPickerInline";
@@ -216,7 +216,7 @@ export default function NewTaskScreen() {
216216

217217
useEffect(() => {
218218
if (!hasLiveConfig) return;
219-
const next = resolveComposerModelChange({
219+
const next = resolveCloudComposerModelChange({
220220
adapter: "claude",
221221
modelOption: modelConfigOption,
222222
requestedModel: model,
@@ -778,7 +778,7 @@ export default function NewTaskScreen() {
778778
title="Model"
779779
value={model}
780780
onChange={(value) => {
781-
const next = resolveComposerModelChange({
781+
const next = resolveCloudComposerModelChange({
782782
adapter: "claude",
783783
modelOption: modelConfigOption,
784784
requestedModel: value,

‎apps/mobile/src/features/tasks/composer/TaskChatComposer.tsx‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import {
33
DEFAULT_CLAUDE_EXECUTION_MODE,
44
getAvailableModes,
55
} from "@posthog/core/sessions/executionModes";
6+
import { resolveCloudComposerModelChange } from "@posthog/core/task-detail/composerModelPolicy";
67
import {
78
DEFAULT_GATEWAY_MODEL,
89
DEFAULT_REASONING_EFFORT,
@@ -60,7 +61,6 @@ import {
6061
getComposerModelOptions,
6162
getConfigOptionLabel,
6263
getModelConfigOption,
63-
resolveComposerModelChange,
6464
resolveComposerPrimaryAction,
6565
} from "./options";
6666
import { Pill } from "./Pill";
@@ -207,7 +207,7 @@ export function TaskChatComposer({
207207

208208
useEffect(() => {
209209
if (!hasLiveConfig) return;
210-
const next = resolveComposerModelChange({
210+
const next = resolveCloudComposerModelChange({
211211
adapter: "claude",
212212
modelOption: modelConfigOption,
213213
requestedModel: model,
@@ -499,7 +499,7 @@ export function TaskChatComposer({
499499
title="Model"
500500
value={model}
501501
onChange={(v) => {
502-
const next = resolveComposerModelChange({
502+
const next = resolveCloudComposerModelChange({
503503
adapter: "claude",
504504
modelOption: modelConfigOption,
505505
requestedModel: v,

‎apps/mobile/src/features/tasks/composer/options.ts‎

Lines changed: 0 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,7 @@
11
import type { ModeInfo } from "@posthog/core/sessions/executionModes";
22
import {
3-
type Adapter,
43
type CloudTaskConfigOption,
5-
DEFAULT_REASONING_EFFORT,
64
isRestrictedModelOption,
7-
isSupportedReasoningEffort,
8-
type SupportedReasoningEffort,
95
} from "@posthog/shared";
106

117
export interface MobileModelOption {
@@ -49,32 +45,6 @@ export function getConfigOptionLabel(
4945
return options.find((option) => option.value === value)?.name ?? value;
5046
}
5147

52-
export function resolveComposerModelChange({
53-
adapter,
54-
modelOption,
55-
requestedModel,
56-
reasoning,
57-
}: {
58-
adapter: Adapter;
59-
modelOption: CloudTaskConfigOption;
60-
requestedModel: string;
61-
reasoning: SupportedReasoningEffort;
62-
}): { model: string; reasoning: SupportedReasoningEffort } {
63-
const selected = modelOption.options.find(
64-
(option) => option.value === requestedModel,
65-
);
66-
const model =
67-
selected && !isRestrictedModelOption(selected._meta)
68-
? requestedModel
69-
: modelOption.currentValue;
70-
return {
71-
model,
72-
reasoning: isSupportedReasoningEffort(adapter, model, reasoning)
73-
? reasoning
74-
: DEFAULT_REASONING_EFFORT,
75-
};
76-
}
77-
7848
export type ComposerPrimaryAction =
7949
| "send"
8050
| "stop"
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import {
2+
type Adapter,
3+
type CloudTaskConfigOption,
4+
DEFAULT_GATEWAY_MODEL,
5+
restrictedModelMeta,
6+
type SupportedReasoningEffort,
7+
} from "@posthog/shared";
8+
import { expect, it } from "vitest";
9+
import { resolveCloudComposerModelChange } from "./composerModelPolicy";
10+
11+
const modelOption: CloudTaskConfigOption = {
12+
id: "model",
13+
name: "Model",
14+
type: "select",
15+
currentValue: DEFAULT_GATEWAY_MODEL,
16+
options: [
17+
{ value: DEFAULT_GATEWAY_MODEL, name: "Claude" },
18+
{ value: "restricted", name: "Restricted", _meta: restrictedModelMeta() },
19+
{ value: "gpt-5.3-codex", name: "Codex" },
20+
],
21+
category: "model",
22+
description: "Choose a model",
23+
};
24+
25+
it.each([
26+
["claude", DEFAULT_GATEWAY_MODEL, "high", DEFAULT_GATEWAY_MODEL, "high"],
27+
["claude", "restricted", "high", DEFAULT_GATEWAY_MODEL, "high"],
28+
["claude", "missing", "high", DEFAULT_GATEWAY_MODEL, "high"],
29+
["codex", "gpt-5.3-codex", "xhigh", "gpt-5.3-codex", "high"],
30+
] as const)(
31+
"resolves %s model %s with %s reasoning",
32+
(adapter, requestedModel, reasoning, expectedModel, expectedReasoning) => {
33+
expect(
34+
resolveCloudComposerModelChange({
35+
adapter: adapter as Adapter,
36+
modelOption,
37+
requestedModel,
38+
reasoning: reasoning as SupportedReasoningEffort,
39+
}),
40+
).toEqual({ model: expectedModel, reasoning: expectedReasoning });
41+
},
42+
);
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import {
2+
type Adapter,
3+
type CloudTaskConfigOption,
4+
DEFAULT_REASONING_EFFORT,
5+
isRestrictedModelOption,
6+
isSupportedReasoningEffort,
7+
type SupportedReasoningEffort,
8+
} from "@posthog/shared";
9+
10+
export function resolveCloudComposerModelChange({
11+
adapter,
12+
modelOption,
13+
requestedModel,
14+
reasoning,
15+
}: {
16+
adapter: Adapter;
17+
modelOption: CloudTaskConfigOption;
18+
requestedModel: string;
19+
reasoning: SupportedReasoningEffort;
20+
}): { model: string; reasoning: SupportedReasoningEffort } {
21+
const selected = modelOption.options.find(
22+
(option) => option.value === requestedModel,
23+
);
24+
const model =
25+
selected && !isRestrictedModelOption(selected._meta)
26+
? requestedModel
27+
: modelOption.currentValue;
28+
29+
return {
30+
model,
31+
reasoning: isSupportedReasoningEffort(adapter, model, reasoning)
32+
? reasoning
33+
: DEFAULT_REASONING_EFFORT,
34+
};
35+
}

0 commit comments

Comments
 (0)