Metadata-Version: 2.4
Name: talos-ai
Version: 0.64.0
Summary: Talos: Fixit's terminal AI agent for coding and business work, model-routed by the ai.fixit.gr controller
Author-email: "Fixit E.E." <info@fixit.gr>
License: Proprietary
Project-URL: Homepage, https://www.fixit.gr
Project-URL: Documentation, https://ai.fixit.gr
Keywords: llm,coding-assistant,fine-tuning
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Provides-Extra: teacher
Requires-Dist: anthropic>=0.40; extra == "teacher"
Provides-Extra: files
Requires-Dist: openpyxl>=3.1; extra == "files"
Requires-Dist: python-docx>=1.1; extra == "files"
Dynamic: license-file

# Talos CLI

Fixit's AI agent for your terminal — coding, your stack, and business work. The ai.fixit.gr
controller routes each request to the right model behind a stable alias, so you get a strong
answer without picking a model. Your reviewed sessions feed the knowledge base and evals.

It is a thin, config-driven client. The model, training, and GPU run on the managed Talos
backend; the CLI only talks to it over HTTPS with your API key. Your data trains your own
private, tenant-isolated adapter and is never shared with other tenants.

## Install

```bash
pipx install talos-ai
talos login
```

`talos login` opens a device-authorization flow: it prints a URL and a code, you approve in
the browser at your Talos account, and the token is stored for you. (Advanced: `talos init`
writes the config by hand instead.)

`talos init` writes `~/.talos/config.toml`:

| Key | Meaning | Default |
|-----|---------|---------|
| `gateway_url` | Talos backend endpoint | `https://ai.fixit.gr` |
| `api_key` | Your tenant API key | — |
| `model` | Model alias | `chat-primary` |
| `code_root` | Where your repos live | `~/Code` |
| `token_budget` | Weekly cap for the practice loop | `100000` |
| `persona` | `developer` / `business` / `hybrid` | inferred from role |
| `autotrain` | Learn from your sessions in the background | asked once at login |
| `show_tokens` | force per-step token + tool detail on/off | by persona |

Every value can be overridden by an env var (`TALOS_GATEWAY_URL`, `TALOS_API_KEY`, ...).

### Personas

The same Talos serves two audiences; the persona tailors the system prompt and how much detail it
shows:

- **developer** — the coding agent: writes and reviews code, runs tests/builds, and prints the
  per-step token and tool details.
- **business** — a plain-language business assistant: reads your documents and spreadsheets, writes
  reports and content, and keeps the output quiet (no code, no token spam).
- **hybrid** — both.

The persona is taken from `persona` in your config, otherwise inferred from your profile role,
otherwise `developer`. `talos persona` shows the current one and the options; `talos persona
business` sets it; inside a chat, `/persona business` switches live. `show_tokens = true|false`
overrides the per-step detail regardless of persona (you can also toggle it for a session with
`/verbose`).

## Commands

Just run `talos` with no arguments to drop straight into the interactive session (same as
`talos chat`) — it opens clean, no command dump. Type `help` (or `/help`) any time to see the
role-aware list of what you can do: a customer sees chat, knowledge base, profile and sync; an
admin also sees training, eval, promote and the system commands, built from your key's real
scopes. If you are not logged in yet it runs `talos login` first. (Piped or non-interactive —
`talos | head`, CI — it prints the static command list instead.)

| Command | What it does |
|---------|--------------|
| `talos` | Enter the interactive session directly (type `help` for what your role can do) |
| `talos login` | Authorize via device code; stores the token |
| `talos init` | Write or update the config file by hand |
| `talos update` | Upgrade in place (see Updates below) |
| `talos status` | Show gateway, model, and your key's client_id and scopes |
| `talos status --system` | (admin) What is running: training state, GPU, loaded models, services |
| `talos chat ["prompt"]` | Interactive chat, or one-shot if a prompt is given |
| `talos backfill` | Convert existing Claude Code transcripts to training rows |
| `talos submit` | Upload staged training rows to the backend |
| `talos loop` | Run the bounded practice loop (teacher-reviewed self-training) |
| `talos dpo-export` | Convert collected DPO rows into prompt/chosen/rejected pairs |
| `talos autotrain` | Learn from your own sessions in the background (`on`/`off`/`now`) |

## Agent capabilities

In a session Talos can read and edit code, run shell/ssh commands, find files (`glob`),
fetch web pages (`web_fetch`), drive Bitbucket (`bitbucket`), consult the knowledge base
(`kb_search`), and read structured
documents with `read_file` — Excel (`.xlsx`/`.xlsm`), Word (`.docx`), `.csv`/`.tsv`, `.json`
and `.pdf` (pdf needs `pdftotext`). Spreadsheets and Word files are parsed with the standard
library, no extra packages.

It can also **write** real Office and data files with `write_doc`: `.xlsx` (Excel) and
`.csv`/`.tsv` from tab-separated rows (numbers stored as numbers, so totals work) and `.docx`
(Word) with one paragraph per line. `.xlsx`/`.docx` need the optional extra — install with
`pip install talos-ai[files]` (openpyxl + python-docx); `.csv`/`.tsv` work out of the box. So the
business skills can read your Excel/Word and hand back a finished spreadsheet or document.

### Updates

`talos update` (and the quiet check on `talos` / `talos login`) upgrades in place. Which source it
uses is decided in this order:

1. **A git checkout** — if `cli_source` (or `TALOS_CLI_SOURCE`) points at a directory with a `.git`,
   it pulls and reinstalls from there. This is the developer path and always wins.
2. **`update_channel = "pypi"`** (the default) — asks `https://pypi.org/pypi/talos-ai/json` for the
   newest version and, only if it is newer than yours, runs `pipx upgrade talos-ai` (or
   `pip install --upgrade`). The download, TLS and hash checking are pip's, not ours.
3. **`update_channel = "dist"`** — reads `latest.json` from `dist_url` (the self-hosted wheels on
   ai.fixit.gr). Here we do own the verification: the wheel URL must be https on the same host as
   `dist_url`, and its sha256 must match the manifest before pip is allowed near it.

An update check never blocks the CLI: an unreachable index, a bad manifest or a failed reinstall
prints at most one line and carries on.

### Bitbucket

The `bitbucket` tool lets Talos run the full branch -> PR -> review -> merge workflow with your
own Bitbucket credentials, locally — it talks to the Bitbucket API directly (same trust model as
git/ssh), never through the gateway. It can list repos, list and read pull requests with their
review comments, create a PR, reply to a review, merge, check pipeline/CI status, and create a
branch. Configure it once:

```toml
bitbucket_user = "your-atlassian-account-email"
bitbucket_token = "atlassian-api-token-with-bitbucket-scopes"
bitbucket_workspace = "your-workspace"   # optional; lets you pass just the repo slug
```

Atlassian has removed Bitbucket app passwords. Create the credential at id.atlassian.com →
Security → API tokens, with **"Create API token with scopes"** and the Bitbucket app selected —
the plain "Create API token" button issues a token with no Bitbucket scopes, which answers `401
API Token provided has no Bitbucket scopes`. It pairs with your account **email**, not your
Bitbucket username, and is sent as HTTP Basic.

Grant it read **and** write on both repositories and pull requests. Read alone is not enough
for half the workflow: `create_branch` writes a ref, and `merge_pr` writes to the pull request.
A token that can only read fails at the step you were reaching for, not at configuration time.

(or `TALOS_BITBUCKET_USER` / `TALOS_BITBUCKET_TOKEN` / `TALOS_BITBUCKET_WORKSPACE`). The tool
defaults to `ask`, so each action is confirmed before it runs. A PR's outcome (merged / declined)
also becomes a training label for the self-improving loop.

### MCP tool servers

Talos can use tools from any [Model Context Protocol](https://modelcontextprotocol.io) server,
either remote (HTTP) or local (a subprocess over stdio). Declare one block per server in
`~/.talos/config.toml`:

```toml
# remote HTTP server
[mcp.myshop]
url = "https://your-host/mcp"
token = "optional-bearer-token"   # sent as Authorization: Bearer ...
# enabled = false                 # temporarily turn a server off
# timeout = 30

# local stdio server (a subprocess speaking newline-delimited JSON-RPC)
[mcp.notes]
command = "python3"
args = ["/path/to/your/mcp-server.py"]
[mcp.notes.env]                   # optional environment for the subprocess
NOTES_DIR = "/path/to/your/notes"
```

On startup Talos connects to each server (`initialize` → `tools/list`), and its tools are offered
to the model namespaced as `<server>__<tool>` (e.g. `myshop__get_order_details`). When the model
calls one, Talos forwards it as an MCP `tools/call` and feeds the result back. MCP tools default to
`ask` (each external call is confirmed). Both plain-JSON and `text/event-stream` (Streamable HTTP)
responses are handled, and a `Mcp-Session-Id` is captured and resent. `talos mcp` lists the
configured servers and tests connectivity; `/mcp` does the same inside a chat. A server that is
unreachable at startup is skipped with a warning — it never blocks the CLI. Local stdio servers are
launched as a subprocess and shut down cleanly when the chat ends.

### Streaming

In plain chat (`/agent off`) the reply streams in token by token as the model produces it, so you
see the answer forming instead of waiting for the whole thing; a spinner shows until the first
token and it falls back to a buffered reply if the gateway is not streaming. The agentic tool-loop
turn stays buffered because it needs the complete response to detect tool calls.

### Sub-agent delegation

For a big task the agent can call `delegate` to hand a focused, self-contained piece of work to a
fresh sub-agent that has the same tools but its own clean context (e.g. "analyse module X and
summarise its API"). The sub-agent shares your gateway, permissions and weekly token budget, runs
with a smaller step cap, and returns its answer to the main agent; it cannot delegate further. This
keeps the main conversation focused instead of filling it with exploration.

### Sync across machines

Your setup follows you. `talos sync push` uploads your config (model, kb_project, token budget),
shortcuts, per-tool permissions, your global `~/.talos/TALOS.md` and your skills to your account;
`talos sync pull` restores them on another machine (`talos sync status` shows what is stored). A
fresh `talos login` pulls them automatically, so a new machine is ready instantly. Secrets — your
API key and Bitbucket token — are never uploaded, and machine-local paths stay local.

### Profile

Tell Talos who you are once and it adapts to you: `talos profile --role developer --about "I run
a Magento shop" --preferences "answer in Greek, be terse"` (run `talos profile` to view). Your role
(developer / marketing / founder / ...), a short about, and your preferences are loaded at the start
of every session and honoured by the agent. It is stored on your account and synced across machines,
and it is the same data the customer-portal onboarding wizard fills — so even a non-developer gets a
Talos pointed in the right direction from the first message.

### Memory

Talos keeps a persistent memory of durable facts and preferences about you — your role, your stack,
how you like answers, standing instructions. It loads them at the start of every session and works
with them in mind, and saves a new one (via its `remember` tool) when you tell it something lasting.
`/remember` shows what is stored and `/remember <fact>` adds one by hand. Memory lives on your
account (keyed by your client_id), so it follows you to every machine you log in from; it is distinct
from the knowledge base (documents you ingest) — this is who *you* are.

### Learned rules

Where memory is about *you*, rules are about *how to write the code*. When Talos learns a durable
convention during a session — from a correction, a repeated review note, a project standard — it
proposes it with its `propose_rule` tool instead of quietly drifting. Proposals are not applied
automatically: `talos rules` lists them, `talos rules accept <id>` adds the rule to your
`~/.talos/TALOS.md` (which Talos loads as project rules, so it takes effect next session), and
`talos rules reject <id>` files it in a rejected buffer so it is never proposed again. You are the
gate; nothing changes how Talos behaves until you accept it.

### Knowledge base

`kb_search` retrieves relevant facts, conventions and examples from the managed knowledge base
so the agent is grounded in your stack and project, not just the base model. Set `kb_project`
in the config to the project whose knowledge you want queried. A shared layer is available to
every tenant; your own project's knowledge stays isolated to your key.

Point it at a git repo: `talos kb index git:<url>[@ref][#subdir]` shallow-clones and ingests it,
e.g. `talos kb index git:https://github.com/laravel/docs.git@11.x` or `...next.js.git@canary#docs`.
Re-running re-clones; the ref is part of each document id, so only changed files re-embed and a new
tag ingests cleanly.

You can also feed it from the cloud, privately: `talos kb index rclone:<remote>:<path>` pulls from
Google Drive, Dropbox, OneDrive, S3 or any of rclone's 70+ backends. It runs on your machine via
your own `rclone` config — Talos copies the files to a temp dir locally, ingests them through your
token, and deletes the copy. We never see or store your cloud credentials and never handle your raw
files; only the embedded chunks land in your isolated tenant. The incremental manifest keeps re-runs
cheap, so pointing it at a folder repeatedly is a real keep-in-sync flow.

Keep it in sync automatically: list your sources in `kb_sync_sources` (local folders or
`rclone:` cloud stores) and `talos kb sync` ingests them incrementally — pair it with the
systemd-user timer in `contrib/systemd/` and a file dropped in your Drive/Dropbox shows up in your
KB a few hours later, no manual step. `talos kb sources` shows what you have configured, whether
each source is reachable, and how many documents are already tracked — a quick offline view of what
Talos is learning from, no key required. When you are logged in it also lists the shared knowledge
Talos ships with (the managed source registry served by the gateway).

Feed it with `talos kb add <file|url> ...` or `talos kb index <folder>`: your documents go to
the gateway in one authenticated call, which chunks and embeds them server-side into your tenant
— files never leave through anything but the API, and the database is never exposed. Text, code
and structured files (Excel/Word/CSV/JSON/PDF) and web pages are supported. `--dry-run` previews,
`--project` targets a project, `--append` keeps existing entries.

### Skills

Skills are reusable instruction packs. Create `~/.talos/skills/<name>/SKILL.md` (global) or
`<project>/.talos/skills/<name>/SKILL.md` with frontmatter:

```
---
name: my-skill
description: One line shown in the catalog
---
# Instructions the agent follows when this skill applies
```

Talos lists installed skills by name and description in the system prompt and pulls the full
instructions on demand (so idle skills cost almost no tokens). `/skills` lists them. Talos ships
with nine bundled skills (email-reply, doc-draft, pdf-extract, data-clean, invoice-read,
meeting-notes, translate, xlsx-summary, pr-ready) — they are in the catalog out of the box, and
a skill of your own with the same name overrides the bundled one. Skills work alongside your
`TALOS.md` project rules.

## How learning works

1. Your coding sessions are captured locally (a Claude Code hook plus `talos backfill`).
2. Coding sessions are converted to chat-format training rows and submitted to the backend.
3. The backend trains a private adapter for your tenant on a schedule.
4. The improved adapter serves your next sessions.

Steps 1–2 run on their own once you turn them on. `talos login` asks once; after that, every
time you start Talos it checks how long it has been and, if more than `autotrain_interval_h`
(6 by default), runs `backfill` + `submit` in a background thread while you work. There is no
timer to install and nothing to remember — it is the same on Linux, macOS and Windows.

`talos autotrain` shows the state and when it last ran; `talos autotrain on|off` changes it and
`talos autotrain now` forces one sync. `TALOS_NO_AUTOTRAIN=1` holds it off for a single run.
Both halves are incremental and `submit` keeps a manifest of what it has already sent, so a run
that is interrupted costs nothing and nothing is uploaded twice. If a sync fails, the session
starts anyway — the error is recorded and the next run picks up what this one missed.

It is off until you say yes, because this uploads your session transcripts. Two passes stand
between a transcript and the upload: `redact_secrets` scrubs private keys, quoted secrets, bearer
headers, URL credentials and known token shapes when the row is built, and `submit` then holds
back any row that *still* looks like it carries a credential — an unquoted `API_KEY=...`, a JWT,
an unterminated PEM block. The first pass is conservative on purpose (it will not touch a bare
`key=value`, which would redact ordinary code), so the second is what makes unattended uploading
safe. Rows are also dropped unless they edited real source under your `code_root`.

A stronger teacher model reviews the assistant's answers; its corrections become the
preferred training signal, so the model learns from mistakes rather than its own output.

Your own verdict counts too. When you rate an answer in chat with `/good` or `/bad`, that
verdict shapes the training data: `talos backfill` also reads Talos's own agent sessions
(`~/.talos/sessions/`), keeps a turn you rated good as a positive example (even a plain answer
with no code edits), and drops a turn you rated bad. This closes the loop — your feedback is the
label the next training cycle learns from.

Real outcomes are labels too. Talos records what happens at each tool call — whether you accepted
or rejected a write/edit, a command's exit code, and whether a verification command (tests, linter,
build) passed. `talos backfill` turns these into free labels: a change you rejected is dropped, a
turn whose verification passed is kept as a `verified` positive example, a failed verification
stays unlabeled. So the model is reinforced on work that demonstrably passed and filtered away from
work that failed or you threw away — no manual thumbs-up needed.

### Training-data quality

`talos backfill` only keeps a turn when it edited real source under your `code_root`. Edits to
memory files, logs, lockfiles, images, build artefacts, and paths like `.claude/`, `vendor/`,
`node_modules/`, or `.git/` are dropped, and infrastructure shell commands (`ssh`, `rsync`,
`systemctl`, deploy scripts) are stripped from the answer. The run reports how many noise edits
and non-code turns it skipped.

The practice loop's teacher corrections are preference pairs: the corrected answer is *chosen*,
the model's own attempt is *rejected*. They are staged locally to `~/.talos/staging/coder-dpo.jsonl`
as they are produced. `talos dpo-export` turns them into `{prompt, chosen, rejected}` rows
(`~/.talos/staging/coder-dpo-pairs.jsonl`) ready for DPO/preference training.
