Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 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
3 changes: 2 additions & 1 deletion apps/server/src/git/Layers/ClaudeTextGeneration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { Effect, Layer, Option, Schema, Stream } from "effect";
import { ChildProcess, ChildProcessSpawner } from "effect/unstable/process";

import { ClaudeModelSelection } from "@t3tools/contracts";
import { resolveApiModelId } from "@t3tools/shared/model";
import { sanitizeBranchFragment, sanitizeFeatureBranchName } from "@t3tools/shared/git";

import { TextGenerationError } from "../Errors.ts";
Expand Down Expand Up @@ -103,7 +104,7 @@ const makeClaudeTextGeneration = Effect.gen(function* () {
"--json-schema",
jsonSchemaStr,
"--model",
modelSelection.model,
resolveApiModelId(modelSelection),
Comment thread
cursor[bot] marked this conversation as resolved.
...(normalizedOptions?.effort ? ["--effort", normalizedOptions.effort] : []),
...(Object.keys(settings).length > 0 ? ["--settings", JSON.stringify(settings)] : []),
"--dangerously-skip-permissions",
Expand Down
15 changes: 11 additions & 4 deletions apps/server/src/provider/Layers/ClaudeAdapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,12 @@ import {
type UserInputQuestion,
ClaudeCodeEffort,
} from "@t3tools/contracts";
import { hasEffortLevel, applyClaudePromptEffortPrefix, trimOrNull } from "@t3tools/shared/model";
import {
hasEffortLevel,
applyClaudePromptEffortPrefix,
resolveApiModelId,
trimOrNull,
} from "@t3tools/shared/model";
import {
Cause,
DateTime,
Expand Down Expand Up @@ -2727,6 +2732,7 @@ function makeClaudeAdapter(options?: ClaudeAdapterLiveOptions) {
const claudeBinaryPath = claudeSettings.binaryPath;
const modelSelection =
input.modelSelection?.provider === "claudeAgent" ? input.modelSelection : undefined;
const apiModelId = modelSelection ? resolveApiModelId(modelSelection) : undefined;
Comment thread
cursor[bot] marked this conversation as resolved.
Outdated
const requestedEffort = trimOrNull(modelSelection?.options?.effort ?? null);
const caps = getClaudeModelCapabilities(modelSelection?.model);
const effort =
Expand All @@ -2746,7 +2752,7 @@ function makeClaudeAdapter(options?: ClaudeAdapterLiveOptions) {

const queryOptions: ClaudeQueryOptions = {
...(input.cwd ? { cwd: input.cwd } : {}),
...(modelSelection?.model ? { model: modelSelection.model } : {}),
...(apiModelId ? { model: apiModelId } : {}),
pathToClaudeCodeExecutable: claudeBinaryPath,
settingSources: [...CLAUDE_SETTING_SOURCES],
...(effectiveEffort ? { effort: effectiveEffort } : {}),
Expand Down Expand Up @@ -2840,7 +2846,7 @@ function makeClaudeAdapter(options?: ClaudeAdapterLiveOptions) {
threadId,
payload: {
config: {
...(modelSelection?.model ? { model: modelSelection.model } : {}),
...(apiModelId ? { model: apiModelId } : {}),
...(input.cwd ? { cwd: input.cwd } : {}),
...(effectiveEffort ? { effort: effectiveEffort } : {}),
...(permissionMode ? { permissionMode } : {}),
Expand Down Expand Up @@ -2893,8 +2899,9 @@ function makeClaudeAdapter(options?: ClaudeAdapterLiveOptions) {
}

if (modelSelection?.model) {
const apiModelId = resolveApiModelId(modelSelection);
yield* Effect.tryPromise({
try: () => context.query.setModel(modelSelection.model),
try: () => context.query.setModel(apiModelId),
catch: (cause) => toRequestError(input.threadId, "turn/setModel", cause),
});
}
Expand Down
19 changes: 18 additions & 1 deletion apps/server/src/provider/Layers/ClaudeProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,12 @@ import type {
} from "@t3tools/contracts";
import { Effect, Equal, Layer, Option, Result, Stream } from "effect";
import { ChildProcess, ChildProcessSpawner } from "effect/unstable/process";
import { getDefaultEffort, hasEffortLevel, trimOrNull } from "@t3tools/shared/model";
import {
getDefaultEffort,
hasEffortLevel,
resolveContextWindow,
trimOrNull,
} from "@t3tools/shared/model";

import {
buildServerProvider,
Expand Down Expand Up @@ -42,6 +47,10 @@ const BUILT_IN_MODELS: ReadonlyArray<ServerProviderModel> = [
],
supportsFastMode: true,
supportsThinkingToggle: false,
contextWindowOptions: [
{ value: "200k", label: "200k", isDefault: true },
{ value: "1m", label: "1M" },
],
Comment thread
cursor[bot] marked this conversation as resolved.
promptInjectedEffortLevels: ["ultrathink"],
} satisfies ModelCapabilities,
},
Expand All @@ -58,6 +67,10 @@ const BUILT_IN_MODELS: ReadonlyArray<ServerProviderModel> = [
],
supportsFastMode: false,
supportsThinkingToggle: false,
contextWindowOptions: [
{ value: "200k", label: "200k", isDefault: true },
{ value: "1m", label: "1M" },
],
promptInjectedEffortLevels: ["ultrathink"],
} satisfies ModelCapabilities,
},
Expand All @@ -69,6 +82,7 @@ const BUILT_IN_MODELS: ReadonlyArray<ServerProviderModel> = [
reasoningEffortLevels: [],
supportsFastMode: false,
supportsThinkingToggle: true,
contextWindowOptions: [],
promptInjectedEffortLevels: [],
} satisfies ModelCapabilities,
},
Expand All @@ -81,6 +95,7 @@ export function getClaudeModelCapabilities(model: string | null | undefined): Mo
reasoningEffortLevels: [],
supportsFastMode: false,
supportsThinkingToggle: false,
contextWindowOptions: [],
promptInjectedEffortLevels: [],
}
);
Expand All @@ -104,10 +119,12 @@ export function normalizeClaudeModelOptions(
const thinking =
caps.supportsThinkingToggle && modelOptions?.thinking === false ? false : undefined;
const fastMode = caps.supportsFastMode && modelOptions?.fastMode === true ? true : undefined;
const contextWindow = resolveContextWindow(caps, modelOptions?.contextWindow);
const nextOptions: ClaudeModelOptions = {
...(thinking === false ? { thinking: false } : {}),
...(effort ? { effort } : {}),
...(fastMode ? { fastMode: true } : {}),
...(contextWindow ? { contextWindow } : {}),
};
return Object.keys(nextOptions).length > 0 ? nextOptions : undefined;
}
Expand Down
7 changes: 7 additions & 0 deletions apps/server/src/provider/Layers/CodexProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ const BUILT_IN_MODELS: ReadonlyArray<ServerProviderModel> = [
],
supportsFastMode: true,
supportsThinkingToggle: false,
contextWindowOptions: [],
promptInjectedEffortLevels: [],
},
},
Expand All @@ -64,6 +65,7 @@ const BUILT_IN_MODELS: ReadonlyArray<ServerProviderModel> = [
],
supportsFastMode: true,
supportsThinkingToggle: false,
contextWindowOptions: [],
promptInjectedEffortLevels: [],
},
},
Expand All @@ -80,6 +82,7 @@ const BUILT_IN_MODELS: ReadonlyArray<ServerProviderModel> = [
],
supportsFastMode: true,
supportsThinkingToggle: false,
contextWindowOptions: [],
promptInjectedEffortLevels: [],
},
},
Expand All @@ -96,6 +99,7 @@ const BUILT_IN_MODELS: ReadonlyArray<ServerProviderModel> = [
],
supportsFastMode: true,
supportsThinkingToggle: false,
contextWindowOptions: [],
promptInjectedEffortLevels: [],
},
},
Expand All @@ -112,6 +116,7 @@ const BUILT_IN_MODELS: ReadonlyArray<ServerProviderModel> = [
],
supportsFastMode: true,
supportsThinkingToggle: false,
contextWindowOptions: [],
promptInjectedEffortLevels: [],
},
},
Expand All @@ -128,6 +133,7 @@ const BUILT_IN_MODELS: ReadonlyArray<ServerProviderModel> = [
],
supportsFastMode: true,
supportsThinkingToggle: false,
contextWindowOptions: [],
promptInjectedEffortLevels: [],
},
},
Expand All @@ -140,6 +146,7 @@ export function getCodexModelCapabilities(model: string | null | undefined): Mod
reasoningEffortLevels: [],
supportsFastMode: false,
supportsThinkingToggle: false,
contextWindowOptions: [],
promptInjectedEffortLevels: [],
}
);
Expand Down
3 changes: 1 addition & 2 deletions apps/web/src/components/ChatView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import {
type MessageId,
type ModelSelection,
type ProjectScript,
type ModelSlug,
type ProviderKind,
type ProjectEntry,
type ProjectId,
Expand Down Expand Up @@ -3105,7 +3104,7 @@ export default function ChatView({ threadId }: ChatViewProps) {
]);

const onProviderModelSelect = useCallback(
(provider: ProviderKind, model: ModelSlug) => {
(provider: ProviderKind, model: string) => {
if (!activeThread) return;
if (lockedProvider !== null && provider !== lockedProvider) {
scheduleComposerFocus();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ async function mountMenu(props?: { modelSelection?: ModelSelection; prompt?: str
],
supportsFastMode: true,
supportsThinkingToggle: false,
contextWindowOptions: [],
promptInjectedEffortLevels: ["ultrathink"],
},
},
Expand All @@ -71,6 +72,7 @@ async function mountMenu(props?: { modelSelection?: ModelSelection; prompt?: str
reasoningEffortLevels: [],
supportsFastMode: false,
supportsThinkingToggle: true,
contextWindowOptions: [],
promptInjectedEffortLevels: [],
},
},
Expand All @@ -87,6 +89,7 @@ async function mountMenu(props?: { modelSelection?: ModelSelection; prompt?: str
],
supportsFastMode: false,
supportsThinkingToggle: false,
contextWindowOptions: [],
promptInjectedEffortLevels: ["ultrathink"],
},
},
Expand All @@ -103,6 +106,7 @@ async function mountMenu(props?: { modelSelection?: ModelSelection; prompt?: str
],
supportsFastMode: true,
supportsThinkingToggle: false,
contextWindowOptions: [],
promptInjectedEffortLevels: [],
},
},
Expand Down
4 changes: 2 additions & 2 deletions apps/web/src/components/chat/ComposerCommandMenu.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { type ProjectEntry, type ModelSlug, type ProviderKind } from "@t3tools/contracts";
import { type ProjectEntry, type ProviderKind } from "@t3tools/contracts";
import { memo } from "react";
import { type ComposerSlashCommand, type ComposerTriggerKind } from "../../composer-logic";
import { BotIcon } from "lucide-react";
Expand Down Expand Up @@ -27,7 +27,7 @@ export type ComposerCommandItem =
id: string;
type: "model";
provider: ProviderKind;
model: ModelSlug;
model: string;
label: string;
description: string;
};
Expand Down
9 changes: 7 additions & 2 deletions apps/web/src/components/chat/ProviderModelPicker.browser.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { type ModelSlug, type ProviderKind, type ServerProvider } from "@t3tools/contracts";
import { type ProviderKind, type ServerProvider } from "@t3tools/contracts";
import { page } from "vitest/browser";
import { afterEach, describe, expect, it, vi } from "vitest";
import { render } from "vitest-browser-react";
Expand Down Expand Up @@ -33,6 +33,7 @@ const TEST_PROVIDERS: ReadonlyArray<ServerProvider> = [
reasoningEffortLevels: [effort("low"), effort("medium", true), effort("high")],
supportsFastMode: true,
supportsThinkingToggle: false,
contextWindowOptions: [],
promptInjectedEffortLevels: [],
},
},
Expand All @@ -44,6 +45,7 @@ const TEST_PROVIDERS: ReadonlyArray<ServerProvider> = [
reasoningEffortLevels: [effort("low"), effort("medium", true), effort("high")],
supportsFastMode: true,
supportsThinkingToggle: false,
contextWindowOptions: [],
promptInjectedEffortLevels: [],
},
},
Expand Down Expand Up @@ -71,6 +73,7 @@ const TEST_PROVIDERS: ReadonlyArray<ServerProvider> = [
],
supportsFastMode: false,
supportsThinkingToggle: true,
contextWindowOptions: [],
promptInjectedEffortLevels: [],
},
},
Expand All @@ -87,6 +90,7 @@ const TEST_PROVIDERS: ReadonlyArray<ServerProvider> = [
],
supportsFastMode: false,
supportsThinkingToggle: true,
contextWindowOptions: [],
promptInjectedEffortLevels: [],
},
},
Expand All @@ -98,6 +102,7 @@ const TEST_PROVIDERS: ReadonlyArray<ServerProvider> = [
reasoningEffortLevels: [effort("low"), effort("medium", true), effort("high")],
supportsFastMode: false,
supportsThinkingToggle: true,
contextWindowOptions: [],
promptInjectedEffortLevels: [],
},
},
Expand All @@ -107,7 +112,7 @@ const TEST_PROVIDERS: ReadonlyArray<ServerProvider> = [

async function mountPicker(props: {
provider: ProviderKind;
model: ModelSlug;
model: string;
lockedProvider: ProviderKind | null;
providers?: ReadonlyArray<ServerProvider>;
triggerVariant?: "ghost" | "outline";
Expand Down
6 changes: 3 additions & 3 deletions apps/web/src/components/chat/ProviderModelPicker.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { type ModelSlug, type ProviderKind, type ServerProvider } from "@t3tools/contracts";
import { type ProviderKind, type ServerProvider } from "@t3tools/contracts";
import { resolveSelectableModel } from "@t3tools/shared/model";
import { memo, useState } from "react";
import type { VariantProps } from "class-variance-authority";
Expand Down Expand Up @@ -52,7 +52,7 @@ function providerIconClassName(

export const ProviderModelPicker = memo(function ProviderModelPicker(props: {
provider: ProviderKind;
model: ModelSlug;
model: string;
lockedProvider: ProviderKind | null;
providers?: ReadonlyArray<ServerProvider>;
modelOptionsByProvider: Record<ProviderKind, ReadonlyArray<{ slug: string; name: string }>>;
Expand All @@ -61,7 +61,7 @@ export const ProviderModelPicker = memo(function ProviderModelPicker(props: {
disabled?: boolean;
triggerVariant?: VariantProps<typeof buttonVariants>["variant"];
triggerClassName?: string;
onProviderModelChange: (provider: ProviderKind, model: ModelSlug) => void;
onProviderModelChange: (provider: ProviderKind, model: string) => void;
}) {
const [isMenuOpen, setIsMenuOpen] = useState(false);
const activeProvider = props.lockedProvider ?? props.provider;
Expand Down
4 changes: 4 additions & 0 deletions apps/web/src/components/chat/TraitsPicker.browser.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ const TEST_PROVIDERS: ReadonlyArray<ServerProvider> = [
],
supportsFastMode: true,
supportsThinkingToggle: false,
contextWindowOptions: [],
promptInjectedEffortLevels: [],
},
},
Expand Down Expand Up @@ -77,6 +78,7 @@ const TEST_PROVIDERS: ReadonlyArray<ServerProvider> = [
],
supportsFastMode: true,
supportsThinkingToggle: false,
contextWindowOptions: [],
Comment thread
juliusmarminge marked this conversation as resolved.
promptInjectedEffortLevels: ["ultrathink"],
},
},
Expand All @@ -93,6 +95,7 @@ const TEST_PROVIDERS: ReadonlyArray<ServerProvider> = [
],
supportsFastMode: false,
supportsThinkingToggle: false,
contextWindowOptions: [],
promptInjectedEffortLevels: ["ultrathink"],
},
},
Expand All @@ -104,6 +107,7 @@ const TEST_PROVIDERS: ReadonlyArray<ServerProvider> = [
reasoningEffortLevels: [],
supportsFastMode: false,
supportsThinkingToggle: true,
contextWindowOptions: [],
promptInjectedEffortLevels: [],
},
},
Expand Down
Loading