Safetensors
GGUF
Turkish
llama
Llama-3
instruct
finetune
chatml
gpt4
synthetic data
distillation
function calling
json mode
axolotl
roleplaying
chat
Instructions to use tda45/TdAI with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- llama-cpp-python
How to use tda45/TdAI with llama-cpp-python:
# !pip install llama-cpp-python from llama_cpp import Llama llm = Llama.from_pretrained( repo_id="tda45/TdAI", filename="llama.cpp/models/ggml-vocab-aquila.gguf", )
output = llm( "Once upon a time,", max_tokens=512, echo=True ) print(output)
- Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- llama.cpp
How to use tda45/TdAI with llama.cpp:
Install (macOS, Linux)
curl -LsSf https://llama.app/install.sh | sh # Start a local OpenAI-compatible server with a web UI: llama serve -hf tda45/TdAI # Run inference directly in the terminal: llama cli -hf tda45/TdAI
Install from WinGet (Windows)
winget install llama.cpp # Start a local OpenAI-compatible server with a web UI: llama serve -hf tda45/TdAI # Run inference directly in the terminal: llama cli -hf tda45/TdAI
Use pre-built binary
# Download pre-built binary from: # https://github.com/ggerganov/llama.cpp/releases # Start a local OpenAI-compatible server with a web UI: ./llama-server -hf tda45/TdAI # Run inference directly in the terminal: ./llama-cli -hf tda45/TdAI
Build from source code
git clone https://github.com/ggerganov/llama.cpp.git cd llama.cpp cmake -B build cmake --build build -j --target llama-server llama-cli # Start a local OpenAI-compatible server with a web UI: ./build/bin/llama-server -hf tda45/TdAI # Run inference directly in the terminal: ./build/bin/llama-cli -hf tda45/TdAI
Use Docker
docker model run hf.co/tda45/TdAI
- LM Studio
- Jan
- Ollama
How to use tda45/TdAI with Ollama:
ollama run hf.co/tda45/TdAI
- Unsloth Studio
How to use tda45/TdAI with Unsloth Studio:
Install Unsloth Studio (macOS, Linux, WSL)
curl -fsSL https://unsloth.ai/install.sh | sh # Run unsloth studio unsloth studio -H 0.0.0.0 -p 8888 # Then open http://localhost:8888 in your browser # Search for tda45/TdAI to start chatting
Install Unsloth Studio (Windows)
irm https://unsloth.ai/install.ps1 | iex # Run unsloth studio unsloth studio -H 0.0.0.0 -p 8888 # Then open http://localhost:8888 in your browser # Search for tda45/TdAI to start chatting
Using HuggingFace Spaces for Unsloth
# No setup required # Open https://huggingface.co/spaces/unsloth/studio in your browser # Search for tda45/TdAI to start chatting
- Atomic Chat new
- Docker Model Runner
How to use tda45/TdAI with Docker Model Runner:
docker model run hf.co/tda45/TdAI
- Lemonade
How to use tda45/TdAI with Lemonade:
Pull the model
# Download Lemonade from https://lemonade-server.ai/ lemonade pull tda45/TdAI
Run and chat with the model
lemonade run user.TdAI-{{QUANT_TAG}}List all available models
lemonade list
| import { AgenticSectionType, ContinueIntentKind, MessageRole } from '$lib/enums'; | |
| import { ATTACHMENT_SAVED_REGEX, NEWLINE_SEPARATOR } from '$lib/constants'; | |
| import type { ApiChatCompletionToolCall } from '$lib/types/api'; | |
| import type { | |
| DatabaseMessage, | |
| DatabaseMessageExtra, | |
| DatabaseMessageExtraImageFile | |
| } from '$lib/types/database'; | |
| import { AttachmentType } from '$lib/enums'; | |
| /** | |
| * Represents a parsed section of agentic content for display | |
| */ | |
| export interface AgenticSection { | |
| type: AgenticSectionType; | |
| content: string; | |
| toolName?: string; | |
| toolArgs?: string; | |
| toolResult?: string; | |
| toolResultExtras?: DatabaseMessageExtra[]; | |
| wasInterrupted?: boolean; | |
| } | |
| /** | |
| * Represents a tool result line that may reference an image attachment | |
| */ | |
| export type ToolResultLine = { | |
| text: string; | |
| image?: DatabaseMessageExtraImageFile; | |
| }; | |
| /** | |
| * Derives display sections from a single assistant message and its direct tool results. | |
| * | |
| * @param message - The assistant message | |
| * @param toolMessages - Tool result messages for this assistant's tool_calls | |
| * @param streamingToolCalls - Partial tool calls during streaming (not yet persisted) | |
| */ | |
| function deriveSingleTurnSections( | |
| message: DatabaseMessage, | |
| toolMessages: DatabaseMessage[] = [], | |
| streamingToolCalls: ApiChatCompletionToolCall[] = [], | |
| isStreaming: boolean = false | |
| ): AgenticSection[] { | |
| const sections: AgenticSection[] = []; | |
| // 1. Reasoning content (from dedicated field) | |
| if (message.reasoningContent) { | |
| const toolCalls = parseToolCalls(message.toolCalls); | |
| const hasContentAfterReasoning = | |
| !!message.content?.trim() || toolCalls.length > 0 || streamingToolCalls.length > 0; | |
| const isPending = isStreaming && !hasContentAfterReasoning; | |
| sections.push({ | |
| type: isPending ? AgenticSectionType.REASONING_PENDING : AgenticSectionType.REASONING, | |
| content: message.reasoningContent, | |
| wasInterrupted: !isStreaming && !hasContentAfterReasoning | |
| }); | |
| } | |
| // 2. Text content | |
| if (message.content?.trim()) { | |
| sections.push({ | |
| type: AgenticSectionType.TEXT, | |
| content: message.content | |
| }); | |
| } | |
| // 3. Persisted tool calls (from message.toolCalls field) | |
| const toolCalls = parseToolCalls(message.toolCalls); | |
| for (const tc of toolCalls) { | |
| const resultMsg = toolMessages.find((m) => m.toolCallId === tc.id); | |
| // Only show as pending/loading if we're actively streaming; otherwise it's just a tool call without result | |
| const type = resultMsg | |
| ? AgenticSectionType.TOOL_CALL | |
| : isStreaming | |
| ? AgenticSectionType.TOOL_CALL_PENDING | |
| : AgenticSectionType.TOOL_CALL; | |
| sections.push({ | |
| type, | |
| content: resultMsg?.content || '', | |
| toolName: tc.function?.name, | |
| toolArgs: tc.function?.arguments, | |
| toolResult: resultMsg?.content, | |
| toolResultExtras: resultMsg?.extra | |
| }); | |
| } | |
| // 4. Streaming tool calls (not yet persisted - currently being received) | |
| for (const tc of streamingToolCalls) { | |
| // Skip if already in persisted tool calls | |
| if (tc.id && toolCalls.find((t) => t.id === tc.id)) continue; | |
| sections.push({ | |
| type: AgenticSectionType.TOOL_CALL_STREAMING, | |
| content: '', | |
| toolName: tc.function?.name, | |
| toolArgs: tc.function?.arguments | |
| }); | |
| } | |
| return sections; | |
| } | |
| /** | |
| * Derives display sections from structured message data. | |
| * | |
| * Handles both single-turn (one assistant + its tool results) and multi-turn | |
| * agentic sessions (multiple assistant + tool messages grouped together). | |
| * | |
| * When `toolMessages` contains continuation assistant messages (from multi-turn | |
| * agentic flows), they are processed in order to produce sections across all turns. | |
| * | |
| * @param message - The first/anchor assistant message | |
| * @param toolMessages - Tool result messages and continuation assistant messages | |
| * @param streamingToolCalls - Partial tool calls during streaming (not yet persisted) | |
| * @param isStreaming - Whether the message is currently being streamed | |
| */ | |
| export function deriveAgenticSections( | |
| message: DatabaseMessage, | |
| toolMessages: DatabaseMessage[] = [], | |
| streamingToolCalls: ApiChatCompletionToolCall[] = [], | |
| isStreaming: boolean = false | |
| ): AgenticSection[] { | |
| const hasAssistantContinuations = toolMessages.some((m) => m.role === MessageRole.ASSISTANT); | |
| if (!hasAssistantContinuations) { | |
| return deriveSingleTurnSections(message, toolMessages, streamingToolCalls, isStreaming); | |
| } | |
| const sections: AgenticSection[] = []; | |
| const firstTurnToolMsgs = collectToolMessages(toolMessages, 0); | |
| sections.push(...deriveSingleTurnSections(message, firstTurnToolMsgs)); | |
| let i = firstTurnToolMsgs.length; | |
| while (i < toolMessages.length) { | |
| const msg = toolMessages[i]; | |
| if (msg.role === MessageRole.ASSISTANT) { | |
| const turnToolMsgs = collectToolMessages(toolMessages, i + 1); | |
| const isLastTurn = i + 1 + turnToolMsgs.length >= toolMessages.length; | |
| sections.push( | |
| ...deriveSingleTurnSections( | |
| msg, | |
| turnToolMsgs, | |
| isLastTurn ? streamingToolCalls : [], | |
| isLastTurn && isStreaming | |
| ) | |
| ); | |
| i += 1 + turnToolMsgs.length; | |
| } else { | |
| i++; | |
| } | |
| } | |
| return sections; | |
| } | |
| /** | |
| * Collect consecutive tool messages starting at `startIndex`. | |
| */ | |
| function collectToolMessages(messages: DatabaseMessage[], startIndex: number): DatabaseMessage[] { | |
| const result: DatabaseMessage[] = []; | |
| for (let i = startIndex; i < messages.length; i++) { | |
| if (messages[i].role === MessageRole.TOOL) { | |
| result.push(messages[i]); | |
| } else { | |
| break; | |
| } | |
| } | |
| return result; | |
| } | |
| /** | |
| * Parse tool result text into lines, matching image attachments by name. | |
| */ | |
| export function parseToolResultWithImages( | |
| toolResult: string, | |
| extras?: DatabaseMessageExtra[] | |
| ): ToolResultLine[] { | |
| const lines = toolResult.split(NEWLINE_SEPARATOR); | |
| return lines.map((line) => { | |
| const match = line.match(ATTACHMENT_SAVED_REGEX); | |
| if (!match || !extras) return { text: line }; | |
| const attachmentName = match[1]; | |
| const image = extras.find( | |
| (e): e is DatabaseMessageExtraImageFile => | |
| e.type === AttachmentType.IMAGE && e.name === attachmentName | |
| ); | |
| return { text: line, image }; | |
| }); | |
| } | |
| /** | |
| * Safely parse the toolCalls JSON string from a DatabaseMessage. | |
| */ | |
| function parseToolCalls(toolCallsJson?: string): ApiChatCompletionToolCall[] { | |
| if (!toolCallsJson) return []; | |
| try { | |
| const parsed = JSON.parse(toolCallsJson); | |
| return Array.isArray(parsed) ? parsed : []; | |
| } catch { | |
| return []; | |
| } | |
| } | |
| /** | |
| * Check if a message has agentic content (tool calls or is part of an agentic flow). | |
| */ | |
| export function hasAgenticContent( | |
| message: DatabaseMessage, | |
| toolMessages: DatabaseMessage[] = [] | |
| ): boolean { | |
| if (message.toolCalls) { | |
| const tc = parseToolCalls(message.toolCalls); | |
| if (tc.length > 0) return true; | |
| } | |
| return toolMessages.length > 0; | |
| } | |
| /** | |
| * Classification of how a Continue click on an assistant message should resume | |
| * generation. The caller dispatches the resume path based on this value. | |
| * | |
| * append_text -> the target is a plain text turn, resume with | |
| * continue_final_message and rehydrate the persisted | |
| * tool_calls and attachments through the regular DB to API | |
| * message converter. | |
| * rerun_turn -> the target carries tool_calls that were never resolved by | |
| * tool result messages. The agentic stream was cut mid turn, | |
| * so we drop the target and rerun the loop from the previous | |
| * history. truncateAfter is the last kept index, inclusive. | |
| * next_turn -> the target's tool_calls were already resolved by trailing | |
| * tool results. Hand the history up to and including the | |
| * last consecutive tool result back to the agentic loop so it | |
| * starts the next turn naturally. truncateAfter points at | |
| * that last tool result. | |
| */ | |
| export type ContinueIntent = | |
| | { kind: ContinueIntentKind.APPEND_TEXT } | |
| | { kind: ContinueIntentKind.RERUN_TURN; truncateAfter: number } | |
| | { kind: ContinueIntentKind.NEXT_TURN; truncateAfter: number }; | |
| /** | |
| * Decide how a Continue click on messages[idx] should resume generation. | |
| * Pure function over the persisted history snapshot. | |
| */ | |
| export function classifyContinueIntent(messages: DatabaseMessage[], idx: number): ContinueIntent { | |
| const target = messages[idx]; | |
| // Defensive default: callers already filter by role, stay deterministic. | |
| if (!target || target.role !== MessageRole.ASSISTANT) { | |
| return { kind: ContinueIntentKind.APPEND_TEXT }; | |
| } | |
| const hasToolCalls = parseToolCalls(target.toolCalls).length > 0; | |
| if (!hasToolCalls) { | |
| return { kind: ContinueIntentKind.APPEND_TEXT }; | |
| } | |
| // Walk consecutive trailing tool results. The agentic loop only emits tool | |
| // messages directly after the assistant turn that owns them, so the first | |
| // non tool message marks the boundary. | |
| let lastTrailingTool = idx; | |
| for (let i = idx + 1; i < messages.length; i++) { | |
| if (messages[i].role === MessageRole.TOOL) { | |
| lastTrailingTool = i; | |
| } else { | |
| break; | |
| } | |
| } | |
| if (lastTrailingTool > idx) { | |
| return { kind: ContinueIntentKind.NEXT_TURN, truncateAfter: lastTrailingTool }; | |
| } | |
| return { kind: ContinueIntentKind.RERUN_TURN, truncateAfter: idx - 1 }; | |
| } | |