alia-ai 1.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- alia_ai-1.1.0/.github/workflows/release.yaml +35 -0
- alia_ai-1.1.0/.github/workflows/tests.yaml +21 -0
- alia_ai-1.1.0/.gitignore +8 -0
- alia_ai-1.1.0/AGENTS.md +85 -0
- alia_ai-1.1.0/Makefile +32 -0
- alia_ai-1.1.0/PKG-INFO +141 -0
- alia_ai-1.1.0/README.md +131 -0
- alia_ai-1.1.0/install.sh +67 -0
- alia_ai-1.1.0/pyproject.toml +35 -0
- alia_ai-1.1.0/scripts/alia-launch.sh +10 -0
- alia_ai-1.1.0/scripts/install-shortcut.sh +48 -0
- alia_ai-1.1.0/src/alia/__init__.py +7 -0
- alia_ai-1.1.0/src/alia/__main__.py +6 -0
- alia_ai-1.1.0/src/alia/agent.py +96 -0
- alia_ai-1.1.0/src/alia/app.py +115 -0
- alia_ai-1.1.0/src/alia/host.py +115 -0
- alia_ai-1.1.0/src/alia/hud.py +212 -0
- alia_ai-1.1.0/src/alia/persona.py +37 -0
- alia_ai-1.1.0/src/alia/policy.py +113 -0
- alia_ai-1.1.0/src/alia/setup.py +103 -0
- alia_ai-1.1.0/src/alia/static/assets/highlight-theme.css +10 -0
- alia_ai-1.1.0/src/alia/static/assets/highlight.min.js +1213 -0
- alia_ai-1.1.0/src/alia/static/assets/marked.min.js +69 -0
- alia_ai-1.1.0/src/alia/static/transcript.html +136 -0
- alia_ai-1.1.0/tests/test_agent.py +132 -0
- alia_ai-1.1.0/tests/test_policy.py +69 -0
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
name: Release Pipeline
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
release:
|
|
5
|
+
types: [created]
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
test:
|
|
9
|
+
runs-on: ubuntu-latest
|
|
10
|
+
steps:
|
|
11
|
+
- uses: actions/checkout@v4
|
|
12
|
+
- uses: actions/setup-python@v5
|
|
13
|
+
with: { python-version: "3.13" }
|
|
14
|
+
- name: Install uv
|
|
15
|
+
run: curl -LsSf https://astral.sh/uv/install.sh | sh
|
|
16
|
+
- name: Install dependencies
|
|
17
|
+
run: uv sync --all-extras --all-groups --no-editable --prerelease allow
|
|
18
|
+
- name: Run tests
|
|
19
|
+
run: uv run pytest -q
|
|
20
|
+
|
|
21
|
+
publish-pypi:
|
|
22
|
+
needs: test
|
|
23
|
+
runs-on: ubuntu-latest
|
|
24
|
+
permissions:
|
|
25
|
+
id-token: write # OIDC — Trusted Publishing, no token
|
|
26
|
+
steps:
|
|
27
|
+
- uses: actions/checkout@v4
|
|
28
|
+
- uses: actions/setup-python@v5
|
|
29
|
+
with: { python-version: "3.13" }
|
|
30
|
+
- name: Install uv
|
|
31
|
+
run: curl -LsSf https://astral.sh/uv/install.sh | sh
|
|
32
|
+
- name: Build package
|
|
33
|
+
run: uv build
|
|
34
|
+
- name: Publish to PyPI
|
|
35
|
+
run: uv publish
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
name: Run Tests
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push: { branches: [main] }
|
|
5
|
+
pull_request: { branches: [main] }
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
test:
|
|
9
|
+
runs-on: ubuntu-latest
|
|
10
|
+
steps:
|
|
11
|
+
- uses: actions/checkout@v4
|
|
12
|
+
- uses: actions/setup-python@v5
|
|
13
|
+
with: { python-version: "3.13" }
|
|
14
|
+
- name: Install uv
|
|
15
|
+
run: curl -LsSf https://astral.sh/uv/install.sh | sh
|
|
16
|
+
# GTK is not needed for the unit tests (agent core + policy); they never
|
|
17
|
+
# import alia.hud / alia.app's GTK paths.
|
|
18
|
+
- name: Install dependencies
|
|
19
|
+
run: uv sync --all-extras --all-groups --no-editable --prerelease allow
|
|
20
|
+
- name: Run tests
|
|
21
|
+
run: uv run pytest -q
|
alia_ai-1.1.0/.gitignore
ADDED
alia_ai-1.1.0/AGENTS.md
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# AGENTS.md — alia
|
|
2
|
+
|
|
3
|
+
You're an AI agent picking up **alia**. This file is the door.
|
|
4
|
+
|
|
5
|
+
## What it is
|
|
6
|
+
|
|
7
|
+
**ALIA** — the cognitive partner of the AI-n-Box desktop: a native GNOME agent
|
|
8
|
+
surface (HUD summoned by a key) on top of the `lingo` engine. Standalone product
|
|
9
|
+
(`syalia-srl/alia`), dev/tested on GNOME, later baked into the `ainbox-os`
|
|
10
|
+
`desktop` variant. ALIA is the *persona/product*; `lovelaice`/`lingo` is the
|
|
11
|
+
*engine*. She is **not** part of the AInBox app suite and does **not** talk to
|
|
12
|
+
superbot/magpie — her store is `$HOME`.
|
|
13
|
+
|
|
14
|
+
Vision doc (canonical):
|
|
15
|
+
`vault/Atlas/Architecture/2026-06-25-alia-cognitive-partner-vision.md`.
|
|
16
|
+
|
|
17
|
+
## Conventions
|
|
18
|
+
|
|
19
|
+
- **Ships directly to `main`** — no PR cycle (same as the other SYALIA repos).
|
|
20
|
+
- **Vertical-slice-first.** Build the thinnest end-to-end path, then widen.
|
|
21
|
+
- Agent core is unit-tested (lingo `MockLLM`, offline); the GTK HUD is
|
|
22
|
+
smoke-tested by hand. Keep tests inline — don't delegate them.
|
|
23
|
+
|
|
24
|
+
## Layout
|
|
25
|
+
|
|
26
|
+
src/alia/host.py create_alia_agent — assembles a lovelaice Agent (persona, tools)
|
|
27
|
+
src/alia/agent.py AliaAgent — in-process ACP client driving the lovelaice runtime
|
|
28
|
+
src/alia/persona.py the system prompt (base passed to assemble_system_prompt)
|
|
29
|
+
src/alia/hud.py the borderless GTK4 HUD (transcript + entry)
|
|
30
|
+
src/alia/app.py resident single-instance Gtk.Application + asyncio bridge
|
|
31
|
+
src/alia/__main__.py python -m alia
|
|
32
|
+
scripts/install-shortcut.sh binds a GNOME key (<Super>i) → ALIA
|
|
33
|
+
scripts/alia-launch.sh logging launcher used by the shortcut
|
|
34
|
+
tests/test_agent.py agent-core unit tests (offline via MockLLM)
|
|
35
|
+
Makefile install / test / run / shortcut
|
|
36
|
+
|
|
37
|
+
## Engine notes
|
|
38
|
+
|
|
39
|
+
- Built on the **lovelaice agent runtime**, not bare lingo and not the legacy
|
|
40
|
+
`lovelaice.core.Lovelaice`. The chain is:
|
|
41
|
+
`host.create_alia_agent` → `lovelaice.agent.Agent` (ReActNative loop, JSONL
|
|
42
|
+
session) → driven via `AcpServer` + `InProcessAcpClient` (same path
|
|
43
|
+
lovelaice's CLI uses). This gives sessions, persistence, tool dispatch,
|
|
44
|
+
hooks, and MCP for free — we do NOT re-implement an agent loop.
|
|
45
|
+
- **Persona** is the `system_prompt` base on `AgentConfig`; lovelaice's
|
|
46
|
+
`assemble_system_prompt` appends tool descriptions. No `Lingo.format()` here,
|
|
47
|
+
so the persona prompt is plain text (brace constraint no longer applies, but
|
|
48
|
+
keep it clean).
|
|
49
|
+
- **Streaming:** ACP emits `agent_message_chunk` with the *finalized* assistant
|
|
50
|
+
text (one chunk per turn in VS1), tool calls as their own notifications. The
|
|
51
|
+
HUD shows the chunk when it arrives. Token-level streaming is a later rung.
|
|
52
|
+
- **Tools / MCP** wire into `host.create_alia_agent` (currently `tools=[]`).
|
|
53
|
+
- Sessions persist to `~/.alia/sessions/<ts>.jsonl` (ALIA's `$HOME` store). The
|
|
54
|
+
beaverdb `ConversationStore` is the richer next layer (pass
|
|
55
|
+
`conversation_store=` to `AcpServer`).
|
|
56
|
+
- Model/endpoint resolve from env (`ALIA_*` → generic → defaults: Haiku over
|
|
57
|
+
OpenRouter).
|
|
58
|
+
|
|
59
|
+
## Runtime/env gotcha
|
|
60
|
+
|
|
61
|
+
GTK PyGObject (`gi`) comes from the **system** (distro `python3-gobject`), not
|
|
62
|
+
pip — so the venv is built with `--system-site-packages` (see Makefile). A plain
|
|
63
|
+
isolated venv won't find `gi`.
|
|
64
|
+
|
|
65
|
+
## Capability surface (v1.0)
|
|
66
|
+
|
|
67
|
+
- Tools: `read` (auto-allowed) + `bash` (approval-gated). Gate is an async
|
|
68
|
+
`tool_call` hook in `host.create_alia_agent`. Order: `bash_prefix_guard`
|
|
69
|
+
(hard red-line) → policy check → `approval_handler`.
|
|
70
|
+
- `policy.py` decides auto-approval: `is_auto_safe` (read-only allowlist +
|
|
71
|
+
safe sub-commands) and `matches_prefix` (session-approved prefixes). A
|
|
72
|
+
command with shell operators (`;|><&&$(`) NEVER auto-approves — always
|
|
73
|
+
prompts. Tests in `test_policy.py` (pure, safety-critical).
|
|
74
|
+
- The handler returns `"deny" | "once" | "session"`; `"session"` adds
|
|
75
|
+
`approval_prefix(command)` to a per-launch set (`AliaAgent.approved_prefixes`)
|
|
76
|
+
shared with the hook. The HUD bar shows three buttons.
|
|
77
|
+
- NOTE: lovelaice's own `AskUser`/`session/request_permission` is VS2 / not
|
|
78
|
+
wired, so we do NOT use it — ALIA owns the approval bridge in-process.
|
|
79
|
+
|
|
80
|
+
## Out of scope (still ahead)
|
|
81
|
+
|
|
82
|
+
Screen perception (screenshots/vision, AT-SPI), mouse/keyboard control, the full
|
|
83
|
+
autonomy dial (session-allow / allow-lists), persistent `$HOME` *memory* (vs
|
|
84
|
+
session transcripts), named desktop tools (launch_app/notify/…), .deb packaging,
|
|
85
|
+
KDE. All in the vision doc as next rungs.
|
alia_ai-1.1.0/Makefile
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# ALIA — dev makefile.
|
|
2
|
+
#
|
|
3
|
+
# The venv is created with --system-site-packages so the distro's GTK4
|
|
4
|
+
# PyGObject (python3-gobject) is visible without compiling it into the venv.
|
|
5
|
+
|
|
6
|
+
VENV := .venv
|
|
7
|
+
PY := $(VENV)/bin/python
|
|
8
|
+
PIP := $(VENV)/bin/pip
|
|
9
|
+
|
|
10
|
+
.PHONY: install test run shortcut clean
|
|
11
|
+
|
|
12
|
+
install: $(VENV)/.stamp
|
|
13
|
+
|
|
14
|
+
$(VENV)/.stamp: pyproject.toml
|
|
15
|
+
python3 -m venv --system-site-packages $(VENV)
|
|
16
|
+
-$(PIP) install -U pip
|
|
17
|
+
$(PIP) install -e .
|
|
18
|
+
$(PIP) install pytest pytest-asyncio
|
|
19
|
+
touch $@
|
|
20
|
+
|
|
21
|
+
test: install
|
|
22
|
+
$(PY) -m pytest -q
|
|
23
|
+
|
|
24
|
+
run: install
|
|
25
|
+
$(PY) -m alia
|
|
26
|
+
|
|
27
|
+
# Bind a GNOME shortcut (default <Super>a) that summons ALIA.
|
|
28
|
+
shortcut: install
|
|
29
|
+
./scripts/install-shortcut.sh
|
|
30
|
+
|
|
31
|
+
clean:
|
|
32
|
+
rm -rf $(VENV)
|
alia_ai-1.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: alia-ai
|
|
3
|
+
Version: 1.1.0
|
|
4
|
+
Summary: ALIA — the cognitive partner of the AI-n-Box desktop. A native GNOME agent surface on the lingo/lovelaice engine.
|
|
5
|
+
Author-email: Alejandro Piad <apiad@apiad.net>
|
|
6
|
+
Requires-Python: >=3.13
|
|
7
|
+
Requires-Dist: lovelaice>=2.1.0
|
|
8
|
+
Requires-Dist: python-dotenv>=1.0
|
|
9
|
+
Description-Content-Type: text/markdown
|
|
10
|
+
|
|
11
|
+
# ALIA
|
|
12
|
+
|
|
13
|
+
**ALIA** — the cognitive partner of the AI-n-Box desktop. A native GNOME agent
|
|
14
|
+
you summon with a key, backed by the [lovelaice](https://github.com/apiad/lovelaice)
|
|
15
|
+
agent runtime (sessions, persistence, tools, MCP) over its ACP engine.
|
|
16
|
+
|
|
17
|
+
This repo is the **standalone** slice: ALIA installs and runs on any recent
|
|
18
|
+
GNOME, independent of AI-n-Box OS (where she'll later be baked in and pre-wired
|
|
19
|
+
to the local Ollama daemon).
|
|
20
|
+
|
|
21
|
+
> Vision: `vault/Atlas/Architecture/2026-06-25-alia-cognitive-partner-vision.md`
|
|
22
|
+
> in the Workspace.
|
|
23
|
+
|
|
24
|
+
## What works today (v1.0)
|
|
25
|
+
|
|
26
|
+
- A borderless GNOME HUD with a **WebKit transcript** — real markdown +
|
|
27
|
+
syntax highlighting (reuses superbot's `marked`/`highlight`), an in-page
|
|
28
|
+
"working…" spinner, and input locked while a turn runs. **Enter** sends,
|
|
29
|
+
**Esc** hides.
|
|
30
|
+
- A resident single-instance app — pressing the shortcut again toggles the HUD;
|
|
31
|
+
the agent stays alive in the background.
|
|
32
|
+
- **She acts on your machine via the shell**, with you in the loop:
|
|
33
|
+
- `read(path)` — reads any file, **silently** (observation is free).
|
|
34
|
+
- `bash(command)` — runs a shell command. **Well-known read-only commands
|
|
35
|
+
auto-run** (`ls`, `cat`, `df`, `git status`, …); anything else shows an
|
|
36
|
+
inline bar with **Deny / Approve / Permitir «prefix» esta sesión**. Picking
|
|
37
|
+
the session option auto-approves that command *prefix* (e.g. `git push`,
|
|
38
|
+
`npm install`) for the rest of the run. This is how she manages files,
|
|
39
|
+
launches apps, changes GNOME settings, inspects the system, uses git, …
|
|
40
|
+
- **Safety floor:** any command containing shell operators (`;`, `|`, `>`,
|
|
41
|
+
`&&`, `$(…)`) always prompts — a safe lead can't smuggle a dangerous tail.
|
|
42
|
+
Hard red-lines (`sudo`, `rm -rf /` …) are blocked outright. Tool activity is
|
|
43
|
+
shown in the transcript as it happens.
|
|
44
|
+
- Conversation persists per session to `~/.alia/sessions/<ts>.jsonl`.
|
|
45
|
+
- Model-agnostic via the lovelaice engine: defaults to **Haiku over OpenRouter**
|
|
46
|
+
(`anthropic/claude-haiku-4.5`), points anywhere OpenAI-compatible.
|
|
47
|
+
|
|
48
|
+
**Not yet:** she can't *see* the screen (no screenshots/vision) or control the
|
|
49
|
+
mouse/keyboard/click — those are the next rungs. She says so when asked.
|
|
50
|
+
|
|
51
|
+
## Requirements
|
|
52
|
+
|
|
53
|
+
- GNOME with **GTK 4** and its Python bindings (`python3-gobject` / PyGObject —
|
|
54
|
+
from your distro, not pip).
|
|
55
|
+
- **WebKitGTK 6.0** for the transcript (`gir1.2-webkit-6.0` on Debian/Ubuntu;
|
|
56
|
+
`webkitgtk6.0` on Fedora).
|
|
57
|
+
- Python ≥ 3.13.
|
|
58
|
+
|
|
59
|
+
## Install
|
|
60
|
+
|
|
61
|
+
```sh
|
|
62
|
+
git clone https://github.com/syalia-srl/alia && cd alia
|
|
63
|
+
./install.sh
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
`install.sh` installs ALIA user-local (no sudo for the app itself):
|
|
67
|
+
|
|
68
|
+
- system GTK 4 + PyGObject + WebKitGTK 6.0 via `apt`/`dnf` — **only if missing**
|
|
69
|
+
(the one step that uses sudo);
|
|
70
|
+
- a venv at `~/.local/share/alia/venv` with `alia` + the engine
|
|
71
|
+
(`lovelaice`/`lingo`/`beaver`) resolved from **PyPI**;
|
|
72
|
+
- a launcher at `~/.local/bin/alia`, an app entry, and the `<Super>i` shortcut.
|
|
73
|
+
|
|
74
|
+
Then configure a key and summon it:
|
|
75
|
+
|
|
76
|
+
```sh
|
|
77
|
+
mkdir -p ~/.config/alia
|
|
78
|
+
echo 'ALIA_API_KEY=sk-or-...' >> ~/.config/alia/env # any OpenAI-compatible key
|
|
79
|
+
# ALIA_MODEL=anthropic/claude-haiku-4.5 (optional)
|
|
80
|
+
# ALIA_BASE_URL=https://openrouter.ai/api/v1 (optional)
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Press **`<Super>i`** (or run `alia`).
|
|
84
|
+
|
|
85
|
+
## Install with pipx
|
|
86
|
+
|
|
87
|
+
Requires the system GTK 4 + WebKitGTK libraries (see Requirements) — pipx's venv
|
|
88
|
+
borrows them via `--system-site-packages`:
|
|
89
|
+
|
|
90
|
+
```sh
|
|
91
|
+
pipx install --system-site-packages alia # PyPI (once published)
|
|
92
|
+
# or, from the private repo:
|
|
93
|
+
# pipx install --system-site-packages git+ssh://git@github.com/syalia-srl/alia
|
|
94
|
+
alia setup # wires the <Super>i shortcut, .desktop entry, and config
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
`alia setup` is also safe to re-run anytime (re-checks deps, re-installs the
|
|
98
|
+
shortcut). `install.sh` calls it under the hood.
|
|
99
|
+
|
|
100
|
+
## Run from source (dev)
|
|
101
|
+
|
|
102
|
+
```sh
|
|
103
|
+
export ALIA_API_KEY="sk-or-..."
|
|
104
|
+
make run # builds .venv (--system-site-packages) and launches
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
`make run` starts the resident app. To summon it with a key:
|
|
108
|
+
|
|
109
|
+
```sh
|
|
110
|
+
make shortcut # binds <Super>i → ALIA
|
|
111
|
+
BINDING='<Super>j' make shortcut # or pick your own free key
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
**Picking a key.** Many obvious combos are already grabbed and will silently do
|
|
115
|
+
nothing if you bind a custom shortcut to them: the bare Super/Windows key
|
|
116
|
+
(Activities overview), `<Super>space` (ibus input-source switch — an
|
|
117
|
+
*independent* grabber, so freeing the WM binding isn't enough), and often F12
|
|
118
|
+
(terminal dropdowns). The default is **`<Super>i`** (mnemonic for *IA*). If a
|
|
119
|
+
binding seems dead, it's almost certainly already taken — check
|
|
120
|
+
`/tmp/alia-launch.log`: the launcher logs every time the shortcut actually
|
|
121
|
+
fires, so an empty log means the key never reached ALIA.
|
|
122
|
+
|
|
123
|
+
## Config
|
|
124
|
+
|
|
125
|
+
| Env var | Default | Purpose |
|
|
126
|
+
|---|---|---|
|
|
127
|
+
| `ALIA_API_KEY` / `OPENROUTER_API_KEY` / `API_KEY` | — | API key |
|
|
128
|
+
| `ALIA_MODEL` / `MODEL` | `anthropic/claude-haiku-4.5` | model slug |
|
|
129
|
+
| `ALIA_BASE_URL` / `BASE_URL` | `https://openrouter.ai/api/v1` | endpoint |
|
|
130
|
+
|
|
131
|
+
## Develop
|
|
132
|
+
|
|
133
|
+
```sh
|
|
134
|
+
make test # agent-core unit tests (offline, via lingo's MockLLM)
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
The GTK HUD is smoke-tested manually (`make run`); the agent core is unit-tested.
|
|
138
|
+
|
|
139
|
+
## Status
|
|
140
|
+
|
|
141
|
+
Conventions: ships to `main`, vertical-slice-first. See `AGENTS.md`.
|
alia_ai-1.1.0/README.md
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
# ALIA
|
|
2
|
+
|
|
3
|
+
**ALIA** — the cognitive partner of the AI-n-Box desktop. A native GNOME agent
|
|
4
|
+
you summon with a key, backed by the [lovelaice](https://github.com/apiad/lovelaice)
|
|
5
|
+
agent runtime (sessions, persistence, tools, MCP) over its ACP engine.
|
|
6
|
+
|
|
7
|
+
This repo is the **standalone** slice: ALIA installs and runs on any recent
|
|
8
|
+
GNOME, independent of AI-n-Box OS (where she'll later be baked in and pre-wired
|
|
9
|
+
to the local Ollama daemon).
|
|
10
|
+
|
|
11
|
+
> Vision: `vault/Atlas/Architecture/2026-06-25-alia-cognitive-partner-vision.md`
|
|
12
|
+
> in the Workspace.
|
|
13
|
+
|
|
14
|
+
## What works today (v1.0)
|
|
15
|
+
|
|
16
|
+
- A borderless GNOME HUD with a **WebKit transcript** — real markdown +
|
|
17
|
+
syntax highlighting (reuses superbot's `marked`/`highlight`), an in-page
|
|
18
|
+
"working…" spinner, and input locked while a turn runs. **Enter** sends,
|
|
19
|
+
**Esc** hides.
|
|
20
|
+
- A resident single-instance app — pressing the shortcut again toggles the HUD;
|
|
21
|
+
the agent stays alive in the background.
|
|
22
|
+
- **She acts on your machine via the shell**, with you in the loop:
|
|
23
|
+
- `read(path)` — reads any file, **silently** (observation is free).
|
|
24
|
+
- `bash(command)` — runs a shell command. **Well-known read-only commands
|
|
25
|
+
auto-run** (`ls`, `cat`, `df`, `git status`, …); anything else shows an
|
|
26
|
+
inline bar with **Deny / Approve / Permitir «prefix» esta sesión**. Picking
|
|
27
|
+
the session option auto-approves that command *prefix* (e.g. `git push`,
|
|
28
|
+
`npm install`) for the rest of the run. This is how she manages files,
|
|
29
|
+
launches apps, changes GNOME settings, inspects the system, uses git, …
|
|
30
|
+
- **Safety floor:** any command containing shell operators (`;`, `|`, `>`,
|
|
31
|
+
`&&`, `$(…)`) always prompts — a safe lead can't smuggle a dangerous tail.
|
|
32
|
+
Hard red-lines (`sudo`, `rm -rf /` …) are blocked outright. Tool activity is
|
|
33
|
+
shown in the transcript as it happens.
|
|
34
|
+
- Conversation persists per session to `~/.alia/sessions/<ts>.jsonl`.
|
|
35
|
+
- Model-agnostic via the lovelaice engine: defaults to **Haiku over OpenRouter**
|
|
36
|
+
(`anthropic/claude-haiku-4.5`), points anywhere OpenAI-compatible.
|
|
37
|
+
|
|
38
|
+
**Not yet:** she can't *see* the screen (no screenshots/vision) or control the
|
|
39
|
+
mouse/keyboard/click — those are the next rungs. She says so when asked.
|
|
40
|
+
|
|
41
|
+
## Requirements
|
|
42
|
+
|
|
43
|
+
- GNOME with **GTK 4** and its Python bindings (`python3-gobject` / PyGObject —
|
|
44
|
+
from your distro, not pip).
|
|
45
|
+
- **WebKitGTK 6.0** for the transcript (`gir1.2-webkit-6.0` on Debian/Ubuntu;
|
|
46
|
+
`webkitgtk6.0` on Fedora).
|
|
47
|
+
- Python ≥ 3.13.
|
|
48
|
+
|
|
49
|
+
## Install
|
|
50
|
+
|
|
51
|
+
```sh
|
|
52
|
+
git clone https://github.com/syalia-srl/alia && cd alia
|
|
53
|
+
./install.sh
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
`install.sh` installs ALIA user-local (no sudo for the app itself):
|
|
57
|
+
|
|
58
|
+
- system GTK 4 + PyGObject + WebKitGTK 6.0 via `apt`/`dnf` — **only if missing**
|
|
59
|
+
(the one step that uses sudo);
|
|
60
|
+
- a venv at `~/.local/share/alia/venv` with `alia` + the engine
|
|
61
|
+
(`lovelaice`/`lingo`/`beaver`) resolved from **PyPI**;
|
|
62
|
+
- a launcher at `~/.local/bin/alia`, an app entry, and the `<Super>i` shortcut.
|
|
63
|
+
|
|
64
|
+
Then configure a key and summon it:
|
|
65
|
+
|
|
66
|
+
```sh
|
|
67
|
+
mkdir -p ~/.config/alia
|
|
68
|
+
echo 'ALIA_API_KEY=sk-or-...' >> ~/.config/alia/env # any OpenAI-compatible key
|
|
69
|
+
# ALIA_MODEL=anthropic/claude-haiku-4.5 (optional)
|
|
70
|
+
# ALIA_BASE_URL=https://openrouter.ai/api/v1 (optional)
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Press **`<Super>i`** (or run `alia`).
|
|
74
|
+
|
|
75
|
+
## Install with pipx
|
|
76
|
+
|
|
77
|
+
Requires the system GTK 4 + WebKitGTK libraries (see Requirements) — pipx's venv
|
|
78
|
+
borrows them via `--system-site-packages`:
|
|
79
|
+
|
|
80
|
+
```sh
|
|
81
|
+
pipx install --system-site-packages alia # PyPI (once published)
|
|
82
|
+
# or, from the private repo:
|
|
83
|
+
# pipx install --system-site-packages git+ssh://git@github.com/syalia-srl/alia
|
|
84
|
+
alia setup # wires the <Super>i shortcut, .desktop entry, and config
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
`alia setup` is also safe to re-run anytime (re-checks deps, re-installs the
|
|
88
|
+
shortcut). `install.sh` calls it under the hood.
|
|
89
|
+
|
|
90
|
+
## Run from source (dev)
|
|
91
|
+
|
|
92
|
+
```sh
|
|
93
|
+
export ALIA_API_KEY="sk-or-..."
|
|
94
|
+
make run # builds .venv (--system-site-packages) and launches
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
`make run` starts the resident app. To summon it with a key:
|
|
98
|
+
|
|
99
|
+
```sh
|
|
100
|
+
make shortcut # binds <Super>i → ALIA
|
|
101
|
+
BINDING='<Super>j' make shortcut # or pick your own free key
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
**Picking a key.** Many obvious combos are already grabbed and will silently do
|
|
105
|
+
nothing if you bind a custom shortcut to them: the bare Super/Windows key
|
|
106
|
+
(Activities overview), `<Super>space` (ibus input-source switch — an
|
|
107
|
+
*independent* grabber, so freeing the WM binding isn't enough), and often F12
|
|
108
|
+
(terminal dropdowns). The default is **`<Super>i`** (mnemonic for *IA*). If a
|
|
109
|
+
binding seems dead, it's almost certainly already taken — check
|
|
110
|
+
`/tmp/alia-launch.log`: the launcher logs every time the shortcut actually
|
|
111
|
+
fires, so an empty log means the key never reached ALIA.
|
|
112
|
+
|
|
113
|
+
## Config
|
|
114
|
+
|
|
115
|
+
| Env var | Default | Purpose |
|
|
116
|
+
|---|---|---|
|
|
117
|
+
| `ALIA_API_KEY` / `OPENROUTER_API_KEY` / `API_KEY` | — | API key |
|
|
118
|
+
| `ALIA_MODEL` / `MODEL` | `anthropic/claude-haiku-4.5` | model slug |
|
|
119
|
+
| `ALIA_BASE_URL` / `BASE_URL` | `https://openrouter.ai/api/v1` | endpoint |
|
|
120
|
+
|
|
121
|
+
## Develop
|
|
122
|
+
|
|
123
|
+
```sh
|
|
124
|
+
make test # agent-core unit tests (offline, via lingo's MockLLM)
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
The GTK HUD is smoke-tested manually (`make run`); the agent core is unit-tested.
|
|
128
|
+
|
|
129
|
+
## Status
|
|
130
|
+
|
|
131
|
+
Conventions: ships to `main`, vertical-slice-first. See `AGENTS.md`.
|
alia_ai-1.1.0/install.sh
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Install ALIA as a user-local app: system deps + a venv + launcher + shortcut.
|
|
3
|
+
#
|
|
4
|
+
# ./install.sh
|
|
5
|
+
#
|
|
6
|
+
# Installs into ~/.local (no sudo for the app itself; sudo is used ONLY to add
|
|
7
|
+
# the GTK4/WebKit system libraries, and only if they're missing). The engine
|
|
8
|
+
# (lovelaice + lingo + beaver) resolves from PyPI.
|
|
9
|
+
set -euo pipefail
|
|
10
|
+
|
|
11
|
+
REPO_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
12
|
+
PREFIX="${ALIA_PREFIX:-$HOME/.local/share/alia}"
|
|
13
|
+
VENV="$PREFIX/venv"
|
|
14
|
+
BINDIR="$HOME/.local/bin"
|
|
15
|
+
LAUNCHER="$BINDIR/alia"
|
|
16
|
+
BINDING="${ALIA_BINDING:-<Super>i}"
|
|
17
|
+
|
|
18
|
+
say() { printf ' %s\n' "$*"; }
|
|
19
|
+
|
|
20
|
+
have_gui_deps() {
|
|
21
|
+
python3 - <<'PY' 2>/dev/null
|
|
22
|
+
import gi
|
|
23
|
+
gi.require_version("Gtk", "4.0")
|
|
24
|
+
gi.require_version("WebKit", "6.0")
|
|
25
|
+
from gi.repository import Gtk, WebKit # noqa
|
|
26
|
+
PY
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
install_system_deps() {
|
|
30
|
+
if have_gui_deps; then say "✓ GTK 4 + WebKitGTK 6.0 already present"; return; fi
|
|
31
|
+
say "Installing GTK 4 + PyGObject + WebKitGTK 6.0 (needs sudo)…"
|
|
32
|
+
if command -v apt >/dev/null 2>&1; then
|
|
33
|
+
sudo apt update && sudo apt install -y \
|
|
34
|
+
python3-venv python3-gi gir1.2-gtk-4.0 gir1.2-webkit-6.0
|
|
35
|
+
elif command -v dnf >/dev/null 2>&1; then
|
|
36
|
+
sudo dnf install -y python3 python3-gobject gtk4 webkitgtk6.0
|
|
37
|
+
else
|
|
38
|
+
echo "Unsupported distro — install GTK 4 + PyGObject + WebKitGTK 6.0 manually." >&2
|
|
39
|
+
exit 1
|
|
40
|
+
fi
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
echo "ALIA installer → $PREFIX"
|
|
44
|
+
install_system_deps
|
|
45
|
+
|
|
46
|
+
say "building venv…"
|
|
47
|
+
rm -rf "$VENV"
|
|
48
|
+
python3 -m venv --system-site-packages "$VENV"
|
|
49
|
+
"$VENV/bin/pip" install -qU pip
|
|
50
|
+
"$VENV/bin/pip" install -q "$REPO_DIR" # alia + engine from PyPI
|
|
51
|
+
|
|
52
|
+
mkdir -p "$BINDIR"
|
|
53
|
+
cat > "$LAUNCHER" <<EOF
|
|
54
|
+
#!/usr/bin/env bash
|
|
55
|
+
exec "$VENV/bin/python" -m alia "\$@"
|
|
56
|
+
EOF
|
|
57
|
+
chmod +x "$LAUNCHER"
|
|
58
|
+
say "✓ launcher: $LAUNCHER"
|
|
59
|
+
|
|
60
|
+
# Wire .desktop + GNOME shortcut + config template (shared with pip/pipx installs).
|
|
61
|
+
ALIA_BINDING="$BINDING" "$LAUNCHER" setup
|
|
62
|
+
|
|
63
|
+
echo
|
|
64
|
+
echo "Done."
|
|
65
|
+
echo " • Configure a key in ~/.config/alia/env (ALIA_API_KEY=…)"
|
|
66
|
+
echo " • Summon with ${BINDING}, or run: alia"
|
|
67
|
+
case ":$PATH:" in *":$BINDIR:"*) : ;; *) echo " • NOTE: add $BINDIR to PATH to run 'alia' directly" ;; esac
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
# Distribution name (PyPI): "alia" is taken. The import package and the CLI
|
|
3
|
+
# command both stay `alia`.
|
|
4
|
+
name = "alia-ai"
|
|
5
|
+
version = "1.1.0"
|
|
6
|
+
description = "ALIA — the cognitive partner of the AI-n-Box desktop. A native GNOME agent surface on the lingo/lovelaice engine."
|
|
7
|
+
readme = "README.md"
|
|
8
|
+
requires-python = ">=3.13"
|
|
9
|
+
authors = [{ name = "Alejandro Piad", email = "apiad@apiad.net" }]
|
|
10
|
+
dependencies = [
|
|
11
|
+
# The agent runtime: sessions, persistence, tools, MCP, hooks. ALIA is a
|
|
12
|
+
# consumer of lovelaice's ACP engine, not a re-implementation on bare lingo.
|
|
13
|
+
"lovelaice>=2.1.0",
|
|
14
|
+
"python-dotenv>=1.0",
|
|
15
|
+
]
|
|
16
|
+
# NOTE: PyGObject (the GTK4 binding) is NOT a pip dependency on purpose.
|
|
17
|
+
# It comes from the system (distro `python3-gobject` + GTK4), and the venv
|
|
18
|
+
# is created with --system-site-packages so it's visible. See the Makefile.
|
|
19
|
+
|
|
20
|
+
[dependency-groups]
|
|
21
|
+
dev = ["pytest>=8.3", "pytest-asyncio>=0.24"]
|
|
22
|
+
|
|
23
|
+
[project.scripts]
|
|
24
|
+
alia = "alia.app:main"
|
|
25
|
+
|
|
26
|
+
[build-system]
|
|
27
|
+
requires = ["hatchling"]
|
|
28
|
+
build-backend = "hatchling.build"
|
|
29
|
+
|
|
30
|
+
[tool.hatch.build.targets.wheel]
|
|
31
|
+
packages = ["src/alia"]
|
|
32
|
+
|
|
33
|
+
[tool.pytest.ini_options]
|
|
34
|
+
asyncio_mode = "auto"
|
|
35
|
+
testpaths = ["tests"]
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Launcher used by the GNOME keybinding. Logs each invocation (so we can tell
|
|
3
|
+
# whether the shortcut fired at all) then hands off to the resident app.
|
|
4
|
+
LOG="${ALIA_LAUNCH_LOG:-/tmp/alia-launch.log}"
|
|
5
|
+
REPO_DIR="$(cd "$(dirname "$0")/.." && pwd)"
|
|
6
|
+
{
|
|
7
|
+
echo "----"
|
|
8
|
+
echo "$(date '+%F %T') fired | WAYLAND_DISPLAY=${WAYLAND_DISPLAY:-} DISPLAY=${DISPLAY:-} DBUS=${DBUS_SESSION_BUS_ADDRESS:-}"
|
|
9
|
+
} >> "$LOG" 2>&1
|
|
10
|
+
exec "${REPO_DIR}/.venv/bin/python" -m alia >> "$LOG" 2>&1
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Register a GNOME custom keyboard shortcut that summons ALIA.
|
|
3
|
+
#
|
|
4
|
+
# Default binding: <Super>i (mnemonic for IA). Note that many obvious combos
|
|
5
|
+
# are already grabbed and won't fire a custom shortcut:
|
|
6
|
+
# - the bare Super key -> GNOME Activities overview
|
|
7
|
+
# - <Super>space -> ibus input-source switch (independent grabber)
|
|
8
|
+
# - F12 -> often a terminal-dropdown shortcut
|
|
9
|
+
# If your chosen binding does nothing, it's almost certainly already taken.
|
|
10
|
+
# Override with: BINDING='<Super>j' ./scripts/install-shortcut.sh
|
|
11
|
+
set -euo pipefail
|
|
12
|
+
|
|
13
|
+
REPO_DIR="$(cd "$(dirname "$0")/.." && pwd)"
|
|
14
|
+
BINDING="${BINDING:-<Super>i}"
|
|
15
|
+
# Launch via the wrapper (logs each fire to /tmp/alia-launch.log; handy for
|
|
16
|
+
# diagnosing whether the shortcut fired at all).
|
|
17
|
+
COMMAND="${REPO_DIR}/scripts/alia-launch.sh"
|
|
18
|
+
SLOT="alia"
|
|
19
|
+
BASE="org.gnome.settings-daemon.plugins.media-keys"
|
|
20
|
+
PATH_PREFIX="/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings"
|
|
21
|
+
KEYPATH="${PATH_PREFIX}/${SLOT}/"
|
|
22
|
+
|
|
23
|
+
if ! command -v gsettings >/dev/null 2>&1; then
|
|
24
|
+
echo "gsettings not found — are you on GNOME?" >&2
|
|
25
|
+
exit 1
|
|
26
|
+
fi
|
|
27
|
+
|
|
28
|
+
# Append our slot to the custom-keybindings list without clobbering existing ones.
|
|
29
|
+
python3 - "$BASE" "$KEYPATH" <<'PY'
|
|
30
|
+
import ast, subprocess, sys
|
|
31
|
+
base, keypath = sys.argv[1], sys.argv[2]
|
|
32
|
+
cur = subprocess.check_output(["gsettings", "get", base, "custom-keybindings"]).decode().strip()
|
|
33
|
+
try:
|
|
34
|
+
items = ast.literal_eval(cur) if cur and cur != "@as []" else []
|
|
35
|
+
except (ValueError, SyntaxError):
|
|
36
|
+
items = []
|
|
37
|
+
if keypath not in items:
|
|
38
|
+
items.append(keypath)
|
|
39
|
+
subprocess.check_call(["gsettings", "set", base, "custom-keybindings", str(items)])
|
|
40
|
+
PY
|
|
41
|
+
|
|
42
|
+
SCHEMA="${BASE}.custom-keybinding:${KEYPATH}"
|
|
43
|
+
gsettings set "$SCHEMA" name "ALIA"
|
|
44
|
+
gsettings set "$SCHEMA" command "$COMMAND"
|
|
45
|
+
gsettings set "$SCHEMA" binding "$BINDING"
|
|
46
|
+
|
|
47
|
+
echo "Bound ${BINDING} → ${COMMAND}"
|
|
48
|
+
echo "Change it in Settings → Keyboard → Custom Shortcuts, or re-run with BINDING=..."
|