1027 lines · 32.6 KB · TypeScript
RawDownload
import {  type ClaudeSettings,  type ModelCapabilities,  type ModelSelection,  type ServerProviderModel,  type ServerProviderSlashCommand,} from "@t3tools/contracts";import * as DateTime from "effect/DateTime";import * as Effect from "effect/Effect";import * as FileSystem from "effect/FileSystem";import * as Option from "effect/Option";import * as Path from "effect/Path";import * as Result from "effect/Result";import { ChildProcess, ChildProcessSpawner } from "effect/unstable/process";import {  createModelCapabilities,  getModelSelectionStringOptionValue,  getProviderOptionCurrentValue,  getProviderOptionDescriptors,} from "@t3tools/shared/model";import { resolveSpawnCommand } from "@t3tools/shared/shell";import { compareSemverVersions } from "@t3tools/shared/semver";import {  query as claudeQuery,  type Options as ClaudeQueryOptions,  type SlashCommand as ClaudeSlashCommand,  type SDKUserMessage,  type SettingSource,} from "@anthropic-ai/claude-agent-sdk"; import {  buildBooleanOptionDescriptor,  buildSelectOptionDescriptor,  buildServerProvider,  DEFAULT_TIMEOUT_MS,  isCommandMissingCause,  parseGenericCliVersion,  providerModelsFromSettings,  spawnAndCollect,  type ServerProviderDraft,} from "../providerSnapshot.ts";import { resolveClaudeSdkExecutablePath } from "../Drivers/ClaudeExecutable.ts";import { makeClaudeEnvironment } from "../Drivers/ClaudeHome.ts";import { discoverClaudeSkills } from "../Drivers/ClaudeSkills.ts"; const DEFAULT_CLAUDE_MODEL_CAPABILITIES: ModelCapabilities = createModelCapabilities({  optionDescriptors: [],}); const CLAUDE_PRESENTATION = {  displayName: "Claude",  showInteractionModeToggle: true,} as const;const MINIMUM_CLAUDE_OPUS_5_VERSION = "2.1.219";const MINIMUM_CLAUDE_FABLE_5_VERSION = "2.1.169";const MINIMUM_CLAUDE_OPUS_4_8_VERSION = "2.1.154";const MINIMUM_CLAUDE_OPUS_4_7_VERSION = "2.1.111"; const CLAUDE_MODEL_CATALOG: ReadonlyArray<ServerProviderModel> = [  {    slug: "claude-fable-5",    name: "Claude Fable 5",    isCustom: false,    capabilities: createModelCapabilities({      optionDescriptors: [        buildSelectOptionDescriptor({          id: "effort",          label: "Reasoning",          options: [            { value: "low", label: "Low" },            { value: "medium", label: "Medium" },            { value: "high", label: "High", isDefault: true },            { value: "xhigh", label: "Extra High" },            { value: "max", label: "Max" },            {              value: "ultracode",              label: "Ultracode",              description: "xhigh effort plus multi-agent workflow orchestration",            },            { value: "ultrathink", label: "Ultrathink" },          ],          promptInjectedValues: ["ultrathink"],        }),        buildSelectOptionDescriptor({          id: "contextWindow",          label: "Context Window",          options: [            { value: "200k", label: "200k" },            { value: "1m", label: "1M", isDefault: true },          ],        }),      ],    }),  },  {    slug: "claude-opus-5",    name: "Claude Opus 5",    isCustom: false,    capabilities: createModelCapabilities({      optionDescriptors: [        buildSelectOptionDescriptor({          id: "effort",          label: "Reasoning",          options: [            { value: "low", label: "Low" },            { value: "medium", label: "Medium" },            { value: "high", label: "High", isDefault: true },            { value: "xhigh", label: "Extra High" },            { value: "max", label: "Max" },            {              value: "ultracode",              label: "Ultracode",              description: "xhigh effort plus multi-agent workflow orchestration",            },            { value: "ultrathink", label: "Ultrathink" },          ],          promptInjectedValues: ["ultrathink"],        }),        buildBooleanOptionDescriptor({          id: "fastMode",          label: "Fast Mode",        }),        buildSelectOptionDescriptor({          id: "contextWindow",          label: "Context Window",          // Claude Code selects the 1M variant explicitly (`claude-opus-5[1m]`).          options: [            { value: "200k", label: "200k" },            { value: "1m", label: "1M", isDefault: true },          ],        }),      ],    }),  },  {    slug: "claude-opus-4-8",    name: "Claude Opus 4.8",    isCustom: false,    capabilities: createModelCapabilities({      optionDescriptors: [        buildSelectOptionDescriptor({          id: "effort",          label: "Reasoning",          options: [            { value: "low", label: "Low" },            { value: "medium", label: "Medium" },            { value: "high", label: "High", isDefault: true },            { value: "xhigh", label: "Extra High" },            { value: "max", label: "Max" },            {              value: "ultracode",              label: "Ultracode",              description: "xhigh effort plus multi-agent workflow orchestration",            },            { value: "ultrathink", label: "Ultrathink" },          ],          promptInjectedValues: ["ultrathink"],        }),        buildBooleanOptionDescriptor({          id: "fastMode",          label: "Fast Mode",        }),      ],    }),  },  {    slug: "claude-opus-4-7",    name: "Claude Opus 4.7",    isCustom: false,    capabilities: createModelCapabilities({      optionDescriptors: [        buildSelectOptionDescriptor({          id: "effort",          label: "Reasoning",          options: [            { value: "low", label: "Low" },            { value: "medium", label: "Medium" },            { value: "high", label: "High" },            { value: "xhigh", label: "Extra High", isDefault: true },            { value: "max", label: "Max" },            { value: "ultrathink", label: "Ultrathink" },          ],          promptInjectedValues: ["ultrathink"],        }),        buildBooleanOptionDescriptor({          id: "fastMode",          label: "Fast Mode",        }),      ],    }),  },  {    slug: "claude-opus-4-6",    name: "Claude Opus 4.6",    isCustom: false,    capabilities: createModelCapabilities({      optionDescriptors: [        buildSelectOptionDescriptor({          id: "effort",          label: "Reasoning",          options: [            { value: "low", label: "Low" },            { value: "medium", label: "Medium" },            { value: "high", label: "High", isDefault: true },            { value: "max", label: "Max" },            { value: "ultrathink", label: "Ultrathink" },          ],          promptInjectedValues: ["ultrathink"],        }),        buildBooleanOptionDescriptor({          id: "fastMode",          label: "Fast Mode",        }),        buildSelectOptionDescriptor({          id: "contextWindow",          label: "Context Window",          options: [            { value: "200k", label: "200k" },            { value: "1m", label: "1M", isDefault: true },          ],        }),      ],    }),  },  {    slug: "claude-opus-4-5",    name: "Claude Opus 4.5",    isCustom: false,    capabilities: createModelCapabilities({      optionDescriptors: [        buildSelectOptionDescriptor({          id: "effort",          label: "Reasoning",          options: [            { value: "low", label: "Low" },            { value: "medium", label: "Medium" },            { value: "high", label: "High", isDefault: true },            { value: "max", label: "Max" },          ],        }),        buildBooleanOptionDescriptor({          id: "fastMode",          label: "Fast Mode",        }),      ],    }),  },  {    slug: "claude-sonnet-5",    name: "Claude Sonnet 5",    isCustom: false,    capabilities: createModelCapabilities({      optionDescriptors: [        buildSelectOptionDescriptor({          id: "effort",          label: "Reasoning",          options: [            { value: "low", label: "Low" },            { value: "medium", label: "Medium" },            { value: "high", label: "High", isDefault: true },            { value: "xhigh", label: "Extra High" },            { value: "max", label: "Max" },            { value: "ultrathink", label: "Ultrathink" },          ],          promptInjectedValues: ["ultrathink"],        }),        buildSelectOptionDescriptor({          id: "contextWindow",          label: "Context Window",          // Sonnet is 200k-default in Claude Code (1M is opt-in there too).          options: [            { value: "200k", label: "200k", isDefault: true },            { value: "1m", label: "1M" },          ],        }),      ],    }),  },  {    slug: "claude-sonnet-4-6",    name: "Claude Sonnet 4.6",    isCustom: false,    capabilities: createModelCapabilities({      optionDescriptors: [        buildSelectOptionDescriptor({          id: "effort",          label: "Reasoning",          options: [            { value: "low", label: "Low" },            { value: "medium", label: "Medium" },            { value: "high", label: "High", isDefault: true },            { value: "max", label: "Max" },            { value: "ultrathink", label: "Ultrathink" },          ],          promptInjectedValues: ["ultrathink"],        }),        buildSelectOptionDescriptor({          id: "contextWindow",          label: "Context Window",          // Sonnet is 200k-default in Claude Code (1M is opt-in there too).          options: [            { value: "200k", label: "200k", isDefault: true },            { value: "1m", label: "1M" },          ],        }),      ],    }),  },  {    slug: "claude-haiku-4-5",    name: "Claude Haiku 4.5",    isCustom: false,    capabilities: createModelCapabilities({      optionDescriptors: [        buildBooleanOptionDescriptor({          id: "thinking",          label: "Thinking",        }),      ],    }),  },]; // Legacy classification happens at the driver boundary via `applyModelManifest`,// so the catalog itself carries no `isLegacy` flags.const BUILT_IN_MODELS: ReadonlyArray<ServerProviderModel> = CLAUDE_MODEL_CATALOG; function supportsClaudeOpus5(version: string | null | undefined): boolean {  return version ? compareSemverVersions(version, MINIMUM_CLAUDE_OPUS_5_VERSION) >= 0 : false;} function supportsClaudeFable5(version: string | null | undefined): boolean {  return version ? compareSemverVersions(version, MINIMUM_CLAUDE_FABLE_5_VERSION) >= 0 : false;} function supportsClaudeOpus48(version: string | null | undefined): boolean {  return version ? compareSemverVersions(version, MINIMUM_CLAUDE_OPUS_4_8_VERSION) >= 0 : false;} function supportsClaudeOpus47(version: string | null | undefined): boolean {  return version ? compareSemverVersions(version, MINIMUM_CLAUDE_OPUS_4_7_VERSION) >= 0 : false;} function getBuiltInClaudeModelsForVersion(  version: string | null | undefined,): ReadonlyArray<ServerProviderModel> {  return BUILT_IN_MODELS.filter((model) => {    if (model.slug === "claude-opus-5") {      return supportsClaudeOpus5(version);    }    if (model.slug === "claude-fable-5") {      return supportsClaudeFable5(version);    }    if (model.slug === "claude-opus-4-8") {      return supportsClaudeOpus48(version);    }    if (model.slug === "claude-opus-4-7") {      return supportsClaudeOpus47(version);    }    return true;  });} function formatClaudeOpus5UpgradeMessage(version: string | null): string {  const versionLabel = version ? `v${version}` : "the installed version";  return `Claude Code ${versionLabel} is too old for Claude Opus 5. Upgrade to v${MINIMUM_CLAUDE_OPUS_5_VERSION} or newer to access it.`;} function formatClaudeFable5UpgradeMessage(version: string | null): string {  const versionLabel = version ? `v${version}` : "the installed version";  return `Claude Code ${versionLabel} is too old for Claude Fable 5. Upgrade to v${MINIMUM_CLAUDE_FABLE_5_VERSION} or newer to access it.`;} function formatClaudeOpus48UpgradeMessage(version: string | null): string {  const versionLabel = version ? `v${version}` : "the installed version";  return `Claude Code ${versionLabel} is too old for Claude Opus 4.8. Upgrade to v${MINIMUM_CLAUDE_OPUS_4_8_VERSION} or newer to access it.`;} function formatClaudeOpus47UpgradeMessage(version: string | null): string {  const versionLabel = version ? `v${version}` : "the installed version";  return `Claude Code ${versionLabel} is too old for Claude Opus 4.7. Upgrade to v${MINIMUM_CLAUDE_OPUS_4_7_VERSION} or newer to access it.`;} export function getClaudeModelCapabilities(model: string | null | undefined): ModelCapabilities {  const slug = model?.trim();  return (    BUILT_IN_MODELS.find((candidate) => candidate.slug === slug)?.capabilities ??    DEFAULT_CLAUDE_MODEL_CAPABILITIES  );} export function resolveClaudeEffort(  caps: ModelCapabilities,  raw: string | null | undefined,): string | undefined {  const descriptors = getProviderOptionDescriptors({    caps,    ...(raw ? { selections: [{ id: "effort", value: raw }] } : {}),  });  const effortDescriptor = descriptors.find((descriptor) => descriptor.id === "effort");  const value = getProviderOptionCurrentValue(effortDescriptor);  return typeof value === "string" ? value : undefined;} /** * Normalize a resolved Claude effort value into one suitable for the Claude * CLI's `--effort` flag. * * Mirrors the mapping used when invoking the Claude Agent SDK * ({@link getEffectiveClaudeAgentEffort} in ClaudeAdapter): `ultracode` is a * Claude Code setting that pairs with `xhigh`, `ultrathink` is filtered out * because it is a prompt-prefix mode, and older model compatibility mappings * are preserved for current Claude Code behavior. */export function normalizeClaudeCliEffort(  effort: string | null | undefined,  model: string | null | undefined,): string | undefined {  if (!effort || effort === "ultrathink") {    return undefined;  }  if (effort === "ultracode") {    return "xhigh";  }  if (    effort === "xhigh" &&    model !== "claude-fable-5" &&    model !== "claude-opus-5" &&    model !== "claude-opus-4-8" &&    model !== "claude-sonnet-5"  ) {    return "max";  }  if (effort === "max" && model === "claude-sonnet-4-6") {    return "high";  }  return effort;} export function isClaudeUltracodeEffort(effort: string | null | undefined): boolean {  return effort === "ultracode";} export function resolveClaudeContextWindow(  modelSelection: ModelSelection | undefined,): string | undefined {  const caps = getClaudeModelCapabilities(modelSelection?.model);  const raw = getModelSelectionStringOptionValue(modelSelection, "contextWindow");  const descriptors = getProviderOptionDescriptors({    caps,    ...(raw ? { selections: [{ id: "contextWindow", value: raw }] } : {}),  });  const descriptor = descriptors.find((candidate) => candidate.id === "contextWindow");  const value = getProviderOptionCurrentValue(descriptor);  return typeof value === "string" ? value : undefined;} export function resolveClaudeApiModelId(modelSelection: ModelSelection): string {  switch (resolveClaudeContextWindow(modelSelection)) {    case "1m":      return `${modelSelection.model}[1m]`;    default:      return modelSelection.model;  }} function toTitleCaseWords(value: string): string {  const parts: Array<string> = [];  for (const part of value.split(/[\s_-]+/g)) {    if (part.length > 0) {      parts.push(part[0]!.toUpperCase() + part.slice(1).toLowerCase());    }  }  return parts.join(" ");} function claudeSubscriptionLabel(subscriptionType: string | undefined): string | undefined {  const normalized = subscriptionType?.toLowerCase().replace(/[\s_-]+/g, "");  if (!normalized) return undefined;   switch (normalized) {    case "claudemaxsubscription":      return "Max";    case "claudemax5xsubscription":      return "Max 5x";    case "claudemax20xsubscription":      return "Max 20x";    case "claudeenterprisesubscription":      return "Enterprise";    case "claudeteamsubscription":      return "Team";    case "claudeprosubscription":      return "Pro";    case "claudefreesubscription":      return "Free";    case "max":    case "maxplan":      return "Max";    case "max5":      return "Max 5x";

Lines 1–500 of 1027.