From 1460f80d1aabc724bf0b8a883233804c8004e95a Mon Sep 17 00:00:00 2001 From: Gab Date: Tue, 24 Mar 2026 18:27:16 +1100 Subject: [PATCH] feat: tf code --- packages/tfcode/src/cli/cmd/tui/app.tsx | 8 ++--- .../cli/cmd/tui/component/dialog-status.tsx | 2 +- .../src/cli/cmd/tui/routes/session/index.tsx | 2 +- .../cli/cmd/tui/routes/session/permission.tsx | 6 ++-- .../cli/cmd/tui/routes/session/sidebar.tsx | 2 +- packages/tfcode/src/provider/models.ts | 34 +++++++++++-------- 6 files changed, 29 insertions(+), 25 deletions(-) diff --git a/packages/tfcode/src/cli/cmd/tui/app.tsx b/packages/tfcode/src/cli/cmd/tui/app.tsx index 5422adf0d..4a6a6b208 100644 --- a/packages/tfcode/src/cli/cmd/tui/app.tsx +++ b/packages/tfcode/src/cli/cmd/tui/app.tsx @@ -268,20 +268,20 @@ function App() { if (!terminalTitleEnabled() || Flag.OPENCODE_DISABLE_TERMINAL_TITLE) return if (route.data.type === "home") { - renderer.setTerminalTitle("OpenCode") + renderer.setTerminalTitle("TF Code") return } if (route.data.type === "session") { const session = sync.session.get(route.data.sessionID) if (!session || SessionApi.isDefaultTitle(session.title)) { - renderer.setTerminalTitle("OpenCode") + renderer.setTerminalTitle("TF Code") return } // Truncate title to 40 chars max const title = session.title.length > 40 ? session.title.slice(0, 37) + "..." : session.title - renderer.setTerminalTitle(`OC | ${title}`) + renderer.setTerminalTitle(`TF | ${title}`) } }) @@ -784,7 +784,7 @@ function App() { await DialogAlert.show( dialog, "Update Complete", - `Successfully updated to OpenCode v${result.data.version}. Please restart the application.`, + `Successfully updated to TF Code v${result.data.version}. Please restart the application.`, ) exit() diff --git a/packages/tfcode/src/cli/cmd/tui/component/dialog-status.tsx b/packages/tfcode/src/cli/cmd/tui/component/dialog-status.tsx index 3b6b5ef21..dabc89d04 100644 --- a/packages/tfcode/src/cli/cmd/tui/component/dialog-status.tsx +++ b/packages/tfcode/src/cli/cmd/tui/component/dialog-status.tsx @@ -79,7 +79,7 @@ export function DialogStatus() { {(val) => val().error} Disabled in configuration - Needs authentication (run: opencode mcp auth {key}) + Needs authentication (run: tfcode mcp auth {key}) {(val) => (val() as { error: string }).error} diff --git a/packages/tfcode/src/cli/cmd/tui/routes/session/index.tsx b/packages/tfcode/src/cli/cmd/tui/routes/session/index.tsx index 0d9ddc746..5410614e9 100644 --- a/packages/tfcode/src/cli/cmd/tui/routes/session/index.tsx +++ b/packages/tfcode/src/cli/cmd/tui/routes/session/index.tsx @@ -253,7 +253,7 @@ export function Session() { `${logo[3] ?? ""}`, ``, ` ${weak("Session")}${UI.Style.TEXT_NORMAL_BOLD}${title}${UI.Style.TEXT_NORMAL}`, - ` ${weak("Continue")}${UI.Style.TEXT_NORMAL_BOLD}opencode -s ${session()?.id}${UI.Style.TEXT_NORMAL}`, + ` ${weak("Continue")}${UI.Style.TEXT_NORMAL_BOLD}tfcode -s ${session()?.id}${UI.Style.TEXT_NORMAL}`, ``, ].join("\n"), ) diff --git a/packages/tfcode/src/cli/cmd/tui/routes/session/permission.tsx b/packages/tfcode/src/cli/cmd/tui/routes/session/permission.tsx index a50cd96fc..a49f4b080 100644 --- a/packages/tfcode/src/cli/cmd/tui/routes/session/permission.tsx +++ b/packages/tfcode/src/cli/cmd/tui/routes/session/permission.tsx @@ -157,11 +157,11 @@ export function PermissionPrompt(props: { request: PermissionRequest }) { body={ - + - This will allow the following patterns until OpenCode is restarted + This will allow the following patterns until TF Code is restarted {(pattern) => ( @@ -501,7 +501,7 @@ function RejectPrompt(props: { onConfirm: (message: string) => void; onCancel: ( Reject permission - Tell OpenCode what to do differently + Tell TF Code what to do differently - OpenCode includes free models so you can start immediately. + TF Code includes free models so you can start immediately. Connect from 75+ providers to use other models, including Claude, GPT, Gemini etc diff --git a/packages/tfcode/src/provider/models.ts b/packages/tfcode/src/provider/models.ts index 8d20ba37a..da42fb359 100644 --- a/packages/tfcode/src/provider/models.ts +++ b/packages/tfcode/src/provider/models.ts @@ -97,6 +97,7 @@ export namespace ModelsDev { toolCalling: boolean maxTokens: number deprecated: boolean + deploymentType?: string pricing?: { inputPer1mTokens: number outputPer1mTokens: number @@ -123,26 +124,26 @@ export namespace ModelsDev { export async function get() { const result = await Data() const providers = result as Record - + // Try to fetch ToothFairyAI models dynamically // First check env vars, then stored credentials let tfApiKey = process.env.TF_API_KEY let tfRegion = process.env.TF_REGION || "au" - + // Try to load from stored credentials if (!tfApiKey) { try { const credPath = path.join(Global.Path.data, ".tfcode", "credentials.json") - const credData = await Bun.file(credPath).json() as { api_key?: string; region?: string } + const credData = (await Bun.file(credPath).json()) as { api_key?: string; region?: string } if (credData.api_key) { tfApiKey = credData.api_key tfRegion = credData.region || "au" } } catch {} } - + const tfBaseUrl = REGION_URLS[tfRegion] || REGION_URLS.au - + if (tfApiKey) { try { const tfResponse = await fetch(`${tfBaseUrl}/models_list`, { @@ -151,16 +152,19 @@ export namespace ModelsDev { }, signal: AbortSignal.timeout(10000), }) - + if (tfResponse.ok) { - const tfData = await tfResponse.json() as { templates: Record } + const tfData = (await tfResponse.json()) as { templates: Record } const tfModels: Record = {} - + for (const [key, model] of Object.entries(tfData.templates || {})) { if (model.deprecated) continue - + + // Only include serverless models + if (model.deploymentType && model.deploymentType !== "serverless") continue + const modelId = key.startsWith("z/") ? key.slice(2) : key - + tfModels[modelId] = { id: modelId, name: model.name, @@ -185,7 +189,7 @@ export namespace ModelsDev { }, } } - + providers["toothfairyai"] = { id: "toothfairyai", name: "ToothFairyAI", @@ -197,7 +201,7 @@ export namespace ModelsDev { log.error("Failed to fetch ToothFairyAI models", { error: e }) } } - + // Fallback to static models if dynamic fetch failed if (!providers["toothfairyai"] || Object.keys(providers["toothfairyai"].models).length === 0) { providers["toothfairyai"] = { @@ -205,7 +209,7 @@ export namespace ModelsDev { name: "ToothFairyAI", env: ["TF_API_KEY", "TF_WORKSPACE_ID"], models: { - "sorcerer": { + sorcerer: { id: "sorcerer", name: "TF Sorcerer", family: "groq", @@ -219,7 +223,7 @@ export namespace ModelsDev { limit: { context: 128000, output: 16000 }, modalities: { input: ["text", "image"], output: ["text"] }, }, - "mystica": { + mystica: { id: "mystica", name: "TF Mystica", family: "fireworks", @@ -236,7 +240,7 @@ export namespace ModelsDev { }, } } - + return providers }