-
Notifications
You must be signed in to change notification settings - Fork 0
Chat Interface
Relevant source files
The following files were used as context for generating this wiki page:
The Chat Interface provides a cluster-aware Read-Eval-Print Loop (REPL) and single-shot command interface for interacting with Large Language Models (LLMs). It integrates the AXIS fact plane, placement engine, and transport layers to provide a seamless advisory experience, including intelligent auto-routing of inference to remote nodes via SSH tunnels.
The chat interface acts as a consumer of the AXIS Advisory Plane (Layer 5). It utilizes the internal/chat package to manage conversations and communicate with Ollama-compatible backends.
A key feature of axis chat is its ability to route inference requests to the most suitable node in the cluster. If the local machine lacks the resources for a specific model, AXIS identifies a remote node, establishes an SSH tunnel, and forwards the local Ollama port (11434) to that node.
The following diagram illustrates the flow from a user query to the generation of a response, highlighting the integration with the placement and transport systems.
Figure 1: Chat Execution and Auto-Routing Flow
sequenceDiagram
participant User
participant CLI as "cmd/axis/chat.go"
participant Placement as "internal/placement"
participant Transport as "internal/transport/SSHExecutor"
participant Client as "internal/chat/Client"
participant Ollama as "Remote Ollama Daemon"
User->>CLI: axis chat "How is the cluster?"
CLI->>Placement: InferRequirements("ollama run <model>")
CLI->>Placement: SelectBestNode(reqs, snapshot, state)
alt Node is Remote
CLI->>Transport: NewSSHExecutor(target)
CLI->>Transport: ForwardLocal(ctx, 0, 11434)
Transport-->>CLI: boundPort (e.g. 56789)
Note over CLI, Client: Endpoint updated to localhost:56789
end
CLI->>Client: ChatStream(ctx, msgs, tools, stdout)
Client->>Ollama: POST /api/chat (via Tunnel)
Ollama-->>Client: NDJSON Stream
Client-->>User: Streaming Response
Sources: cmd/axis/chat.go:80-101, internal/chat/client.go:71-144, internal/transport/ssh.go:1-50
The interactive session is managed using the readline library, providing history and tab completion.
-
Slash Commands: Intercepted by
handleSlashCommandto perform administrative tasks without LLM intervention.-
/status: Injects achat.BuildClusterSummaryinto the view. -
/model <tag>: Switches the active model by creating a newchat.NewClient. -
/clear: Resets thechat.Conversationwhile preserving the system prompt.
-
AXIS follows a deterministic hierarchy to select the chat model:
-
Flag: User-provided
--modelargument. -
Config:
chat.default_modelin~/.axis/nodes.yaml. -
Auto-detection:
chat.ResolveDefaultModelqueries the local Ollama instance and matches againstrecommendedLocalModels(e.g.,qwen3.5:4b,llama3.1:8b).
The chat.Conversation class handles history persistence and context window management.
-
Persistence: Conversations are saved to
~/.axis/history/chat.jsonviaSaveToFileand can be reloaded using the--resumeflag. -
Context Compaction: To prevent exceeding context limits,
internal/chat/message.goimplementsCompactsOldToolResults, which truncates large tool outputs once they are no longer in the immediate message history.
Figure 2: Chat Logic Entity Map
classDiagram
class ChatCmd {
<<file: cmd/axis/chat.go>>
+runPlainREPL()
+handleSlashCommand()
}
class Client {
<<file: internal/chat/client.go>>
+Endpoint string
+Model string
+ChatStream()
+EnsureRunning()
}
class Conversation {
<<file: internal/chat/message.go>>
+Messages []Message
+Append(Message)
+SaveToFile(path)
+EstimateTokens()
}
class ModelCatalog {
<<file: internal/chat/models.go>>
+RecommendedLocal []ModelOption
+Installed []string
}
ChatCmd --> Client : initializes
ChatCmd --> Conversation : manages
ChatCmd ..> ModelCatalog : uses for /models
Client ..> Conversation : consumes messages
Sources: cmd/axis/chat.go:160-200, internal/chat/client.go:31-44, internal/chat/message.go:1-50, internal/chat/models.go:21-44
When auto-routing is active, AXIS utilizes executor.ForwardLocal to create a secure bridge to a remote inference provider. This allows the local chat.Client to remain agnostic of the physical location of the LLM, simply targeting a dynamically assigned local port.
| Function | File | Purpose |
|---|---|---|
resolveChatModel |
cmd/axis/chat.go:318-335 | Implements the resolution hierarchy (Flag > Config > Auto-detect). |
BuildSystemPrompt |
internal/chat/system.go:20-50 | Constructs the "Absolute Commander" prompt with optional cluster facts. |
EnsureRunning |
internal/chat/client.go:148-230 | Automatically calls ollama serve if the daemon is unresponsive. |
ChatStream |
internal/chat/client.go:71-144 | Handles NDJSON streaming from the Ollama /api/chat endpoint. |
The system maintains a list of recommendedLocalModels in internal/chat/models.go. These are prioritized based on their ability to support tool-calling (via toolCapablePrefixes) and their parameter size relative to typical AXIS node capabilities.
| Model Family | Role | Capability |
|---|---|---|
qwen3.5:4b |
Default | Tool-use, Balanced |
llama3.1:8b |
Alternative | Strong Reasoning |
qwen3:0.6b |
Fallback | Ultra-lightweight |
Sources: internal/chat/models.go:30-44, internal/chat/models.go:178-185
-
Initialization: The CLI loads the
runtimectxto get the currentClusterSnapshot. -
Routing: The
placement.SelectBestNodefunction determines if the selected model should run locally or via an SSH tunnel to a more powerful node. -
Context Injection: If
--use-contextis passed,chat.BuildClusterSummarygenerates a text representation of the cluster (Node count, Free RAM, Reachable nodes) to be injected into the system prompt. - REPL: The user enters queries; the system streams responses while maintaining a persistent JSON history for multi-turn coherence.
Sources: cmd/axis/chat.go:60-120, internal/chat/system.go:52-80