mirror of
https://gitea.toothfairyai.com/ToothFairyAI/tf_code.git
synced 2026-03-30 05:43:55 +00:00
feat: tf code
This commit is contained in:
parent
2ad192a312
commit
1460f80d1a
@ -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()
|
||||
|
||||
@ -79,7 +79,7 @@ export function DialogStatus() {
|
||||
<Match when={item.status === "failed" && item}>{(val) => val().error}</Match>
|
||||
<Match when={item.status === "disabled"}>Disabled in configuration</Match>
|
||||
<Match when={(item.status as string) === "needs_auth"}>
|
||||
Needs authentication (run: opencode mcp auth {key})
|
||||
Needs authentication (run: tfcode mcp auth {key})
|
||||
</Match>
|
||||
<Match when={(item.status as string) === "needs_client_registration" && item}>
|
||||
{(val) => (val() as { error: string }).error}
|
||||
|
||||
@ -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"),
|
||||
)
|
||||
|
||||
@ -157,11 +157,11 @@ export function PermissionPrompt(props: { request: PermissionRequest }) {
|
||||
body={
|
||||
<Switch>
|
||||
<Match when={props.request.always.length === 1 && props.request.always[0] === "*"}>
|
||||
<TextBody title={"This will allow " + props.request.permission + " until OpenCode is restarted."} />
|
||||
<TextBody title={"This will allow " + props.request.permission + " until TF Code is restarted."} />
|
||||
</Match>
|
||||
<Match when={true}>
|
||||
<box paddingLeft={1} gap={1}>
|
||||
<text fg={theme.textMuted}>This will allow the following patterns until OpenCode is restarted</text>
|
||||
<text fg={theme.textMuted}>This will allow the following patterns until TF Code is restarted</text>
|
||||
<box>
|
||||
<For each={props.request.always}>
|
||||
{(pattern) => (
|
||||
@ -501,7 +501,7 @@ function RejectPrompt(props: { onConfirm: (message: string) => void; onCancel: (
|
||||
<text fg={theme.text}>Reject permission</text>
|
||||
</box>
|
||||
<box paddingLeft={1}>
|
||||
<text fg={theme.textMuted}>Tell OpenCode what to do differently</text>
|
||||
<text fg={theme.textMuted}>Tell TF Code what to do differently</text>
|
||||
</box>
|
||||
</box>
|
||||
<box
|
||||
|
||||
@ -292,7 +292,7 @@ export function Sidebar(props: { sessionID: string; overlay?: boolean }) {
|
||||
✕
|
||||
</text>
|
||||
</box>
|
||||
<text fg={theme.textMuted}>OpenCode includes free models so you can start immediately.</text>
|
||||
<text fg={theme.textMuted}>TF Code includes free models so you can start immediately.</text>
|
||||
<text fg={theme.textMuted}>
|
||||
Connect from 75+ providers to use other models, including Claude, GPT, Gemini etc
|
||||
</text>
|
||||
|
||||
@ -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<string, Provider>
|
||||
|
||||
|
||||
// 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<string, TFModel> }
|
||||
const tfData = (await tfResponse.json()) as { templates: Record<string, TFModel> }
|
||||
const tfModels: Record<string, Model> = {}
|
||||
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user