awnode 0.3.4__tar.gz → 0.3.5__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.
- {awnode-0.3.4 → awnode-0.3.5}/PKG-INFO +7 -9
- {awnode-0.3.4 → awnode-0.3.5}/README.md +6 -5
- {awnode-0.3.4 → awnode-0.3.5}/aither-constellation.js +1 -0
- {awnode-0.3.4 → awnode-0.3.5}/awnode/__init__.py +2 -2
- {awnode-0.3.4 → awnode-0.3.5}/awnode/cli.py +26 -42
- {awnode-0.3.4 → awnode-0.3.5}/awnode/extensions.py +2 -2
- {awnode-0.3.4 → awnode-0.3.5}/awnode/hub.py +12 -0
- {awnode-0.3.4 → awnode-0.3.5}/awnode/license.py +6 -6
- {awnode-0.3.4 → awnode-0.3.5}/awnode/proxy.py +3 -3
- awnode-0.3.5/awnode/rea_sidecar_bridge.py +291 -0
- {awnode-0.3.4 → awnode-0.3.5}/awnode/server.py +9 -32
- {awnode-0.3.4 → awnode-0.3.5}/awnode/sync.py +9 -10
- awnode-0.3.5/awnode/tools/__init__.py +44 -0
- {awnode-0.3.4 → awnode-0.3.5}/awnode/tools/_scopes.py +0 -1
- {awnode-0.3.4 → awnode-0.3.5}/awnode/tools/documents.py +17 -27
- {awnode-0.3.4 → awnode-0.3.5}/awnode/tools/embeddings.py +28 -28
- {awnode-0.3.4 → awnode-0.3.5}/awnode/tools/extensions.py +1 -1
- {awnode-0.3.4 → awnode-0.3.5}/awnode/tools/mermaid.py +20 -27
- {awnode-0.3.4 → awnode-0.3.5}/awnode/tools/orchestrator.py +27 -37
- {awnode-0.3.4 → awnode-0.3.5}/docs/aither-manifest.json +4 -4
- {awnode-0.3.4 → awnode-0.3.5}/docs/index.html +15 -6
- {awnode-0.3.4 → awnode-0.3.5}/pyproject.toml +2 -3
- {awnode-0.3.4 → awnode-0.3.5}/tests/test_custom_backend.py +9 -9
- {awnode-0.3.4 → awnode-0.3.5}/tests/test_extension_contract.py +1 -1
- {awnode-0.3.4 → awnode-0.3.5}/tests/test_proxy_plane.py +0 -1
- awnode-0.3.4/awnode/components/ollama.yaml +0 -22
- awnode-0.3.4/awnode/tools/__init__.py +0 -17
- awnode-0.3.4/awnode/tools/ollama.py +0 -129
- {awnode-0.3.4 → awnode-0.3.5}/.github/workflows/publish.yml +0 -0
- {awnode-0.3.4 → awnode-0.3.5}/.gitignore +0 -0
- {awnode-0.3.4 → awnode-0.3.5}/CLAUDE.md +0 -0
- {awnode-0.3.4 → awnode-0.3.5}/Dockerfile +0 -0
- {awnode-0.3.4 → awnode-0.3.5}/LICENSE +0 -0
- {awnode-0.3.4 → awnode-0.3.5}/_smoke_check.py +0 -0
- {awnode-0.3.4 → awnode-0.3.5}/aither-manifest.json +0 -0
- {awnode-0.3.4 → awnode-0.3.5}/awnode/__main__.py +0 -0
- {awnode-0.3.4 → awnode-0.3.5}/awnode/_doctor.py +0 -0
- {awnode-0.3.4 → awnode-0.3.5}/awnode/comfyui_setup.py +0 -0
- {awnode-0.3.4 → awnode-0.3.5}/awnode/components/__init__.py +0 -0
- {awnode-0.3.4 → awnode-0.3.5}/awnode/components/autorig.yaml +0 -0
- {awnode-0.3.4 → awnode-0.3.5}/awnode/components/canvas.yaml +0 -0
- {awnode-0.3.4 → awnode-0.3.5}/awnode/components/comfyui-3d.yaml +0 -0
- {awnode-0.3.4 → awnode-0.3.5}/awnode/components/comfyui.yaml +0 -0
- {awnode-0.3.4 → awnode-0.3.5}/awnode/components/design.yaml +0 -0
- {awnode-0.3.4 → awnode-0.3.5}/awnode/components/iris.yaml +0 -0
- {awnode-0.3.4 → awnode-0.3.5}/awnode/components/muse.yaml +0 -0
- {awnode-0.3.4 → awnode-0.3.5}/awnode/components/sd-webui.yaml +0 -0
- {awnode-0.3.4 → awnode-0.3.5}/awnode/mcp_server.py +0 -0
- {awnode-0.3.4 → awnode-0.3.5}/awnode/service_install.py +0 -0
- {awnode-0.3.4 → awnode-0.3.5}/awnode/tools/_http.py +0 -0
- {awnode-0.3.4 → awnode-0.3.5}/awnode/tools/commands.py +0 -0
- {awnode-0.3.4 → awnode-0.3.5}/awnode/tools/context.py +0 -0
- {awnode-0.3.4 → awnode-0.3.5}/awnode/tools/filesystem.py +0 -0
- {awnode-0.3.4 → awnode-0.3.5}/awnode/tools/fleet_host.py +0 -0
- {awnode-0.3.4 → awnode-0.3.5}/awnode/tools/fleet_verbs.py +0 -0
- {awnode-0.3.4 → awnode-0.3.5}/awnode/tools/generation.py +0 -0
- {awnode-0.3.4 → awnode-0.3.5}/awnode/tools/git_tools.py +0 -0
- {awnode-0.3.4 → awnode-0.3.5}/awnode/tools/http_client.py +0 -0
- {awnode-0.3.4 → awnode-0.3.5}/awnode/tools/knowledge.py +0 -0
- {awnode-0.3.4 → awnode-0.3.5}/awnode/tools/memory.py +0 -0
- {awnode-0.3.4 → awnode-0.3.5}/awnode/tools/notebooks.py +0 -0
- {awnode-0.3.4 → awnode-0.3.5}/awnode/tools/search.py +0 -0
- {awnode-0.3.4 → awnode-0.3.5}/awnode/update_check.py +0 -0
- {awnode-0.3.4 → awnode-0.3.5}/dist_validate/aithernode-0.1.0-py3-none-any.whl +0 -0
- {awnode-0.3.4 → awnode-0.3.5}/docker-entrypoint.sh +0 -0
- {awnode-0.3.4 → awnode-0.3.5}/docs/aither-constellation.js +0 -0
- {awnode-0.3.4 → awnode-0.3.5}/docs/llms.txt +0 -0
- {awnode-0.3.4 → awnode-0.3.5}/packaging/aithernode-stub/README.md +0 -0
- {awnode-0.3.4 → awnode-0.3.5}/packaging/aithernode-stub/pyproject.toml +0 -0
- {awnode-0.3.4 → awnode-0.3.5}/tests/test_awnix_host_install.py +0 -0
- {awnode-0.3.4 → awnode-0.3.5}/tests/test_chat_endpoint_auth.py +0 -0
- {awnode-0.3.4 → awnode-0.3.5}/tests/test_component_image_env.py +0 -0
- {awnode-0.3.4 → awnode-0.3.5}/tests/test_fleet_host_tools.py +0 -0
- {awnode-0.3.4 → awnode-0.3.5}/tests/test_fleet_verbs_tools.py +0 -0
- {awnode-0.3.4 → awnode-0.3.5}/tests/test_hub_error_cooldown.py +0 -0
- {awnode-0.3.4 → awnode-0.3.5}/tests/test_mcp_api_compat.py +0 -0
- {awnode-0.3.4 → awnode-0.3.5}/tests/test_mcp_mode_reprobe.py +0 -0
- {awnode-0.3.4 → awnode-0.3.5}/tests/test_mcp_server_auth.py +0 -0
- {awnode-0.3.4 → awnode-0.3.5}/tests/test_mcp_sse_transport.py +0 -0
- {awnode-0.3.4 → awnode-0.3.5}/tests/test_pair_mode_route.py +0 -0
- {awnode-0.3.4 → awnode-0.3.5}/tests/test_server_route_hygiene.py +0 -0
- {awnode-0.3.4 → awnode-0.3.5}/tests/test_server_security_hardening.py +0 -0
- {awnode-0.3.4 → awnode-0.3.5}/tests/test_sync_enrollment_lifecycle.py +0 -0
- {awnode-0.3.4 → awnode-0.3.5}/tests/test_update_check.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: awnode
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.5
|
|
4
4
|
Summary: awnode — lightweight local gateway for AitherOS
|
|
5
5
|
Project-URL: Homepage, https://aitherium.com
|
|
6
6
|
Author-email: Aitherium <hello@aitherium.com>
|
|
@@ -15,13 +15,10 @@ Requires-Dist: mcp<3.0.0,>=1.0.0
|
|
|
15
15
|
Requires-Dist: pyyaml>=6.0
|
|
16
16
|
Requires-Dist: uvicorn[standard]>=0.27.0
|
|
17
17
|
Provides-Extra: all
|
|
18
|
-
Requires-Dist: ollama>=0.1.0; extra == 'all'
|
|
19
18
|
Requires-Dist: starlette>=0.27.0; extra == 'all'
|
|
20
19
|
Provides-Extra: dev
|
|
21
20
|
Requires-Dist: pytest-asyncio>=0.21.0; extra == 'dev'
|
|
22
21
|
Requires-Dist: pytest>=7.0; extra == 'dev'
|
|
23
|
-
Provides-Extra: ollama
|
|
24
|
-
Requires-Dist: ollama>=0.1.0; extra == 'ollama'
|
|
25
22
|
Provides-Extra: sse
|
|
26
23
|
Requires-Dist: starlette>=0.27.0; extra == 'sse'
|
|
27
24
|
Description-Content-Type: text/markdown
|
|
@@ -32,7 +29,7 @@ Description-Content-Type: text/markdown
|
|
|
32
29
|
|
|
33
30
|
**[Docs](https://aitherium.github.io/awnode/)** · [Source](https://github.com/Aitherium/awnode) · `pip install awnode` · [The Aither World](https://aitherium.github.io/)
|
|
34
31
|
|
|
35
|
-
> **The Aither World** is an operating system for agents — a Linux you can hand to one, the runtimes it works in, and the tools it works with. [awnix](https://github.com/Aitherium/awnix) is the Linux underneath it; **awnode** is one of its
|
|
32
|
+
> **The Aither World** is an operating system for agents — a Linux you can hand to one, the runtimes it works in, and the tools it works with. [awnix](https://github.com/Aitherium/awnix) is the Linux underneath it; **awnode** is one of its 68 bricks — each installs on its own, runs offline, and needs no account.
|
|
36
33
|
>
|
|
37
34
|
> **Start here:** Run it once and point one app at it instead of a vendor URL.
|
|
38
35
|
|
|
@@ -54,7 +51,7 @@ curl -fsSL https://launch.aitherium.com | bash
|
|
|
54
51
|
## Quick Start
|
|
55
52
|
|
|
56
53
|
```bash
|
|
57
|
-
# Start with auto-detection (finds Genesis, vLLM, llama.cpp, LM Studio,
|
|
54
|
+
# Start with auto-detection (finds Genesis, vLLM, llama.cpp, LM Studio, or cloud)
|
|
58
55
|
awnode start
|
|
59
56
|
|
|
60
57
|
# Run the published container
|
|
@@ -83,8 +80,7 @@ awnode deploy my-service --target docker --strategy rolling
|
|
|
83
80
|
3. **llama.cpp** (localhost:8200) / **Bonsai** (localhost:8092) — OpenAI-compatible llama.cpp servers
|
|
84
81
|
4. **LM Studio** (127.0.0.1:1234) — LM Studio's local server (OpenAI-compatible; start it from LM Studio's Developer tab)
|
|
85
82
|
5. **Elysium** (cloud) — hosted AitherOS (requires API key)
|
|
86
|
-
6. **
|
|
87
|
-
7. **Standalone** — no LLM, tools-only mode
|
|
83
|
+
6. **Standalone** — no LLM, tools-only mode
|
|
88
84
|
|
|
89
85
|
OpenAI-compatible backends (vLLM, llama.cpp, Bonsai, LM Studio, custom) are detected by a
|
|
90
86
|
200 on `/v1/models`, never by `/health`, so an unrelated service on the same port is not
|
|
@@ -123,7 +119,7 @@ the read-only set; for full tool access from an IDE use `awnode mcp`.
|
|
|
123
119
|
|---|---|---|
|
|
124
120
|
| `AITHER_URL` | `http://localhost:8001` | Genesis URL |
|
|
125
121
|
| `AITHER_VLLM_URL` | `http://localhost:8120` | vLLM URL |
|
|
126
|
-
| `
|
|
122
|
+
| `LLAMACPP_URL` | `http://localhost:8200` | llama.cpp `llama-server` URL (OpenAI-compatible) |
|
|
127
123
|
| `AITHERNODE_LMSTUDIO_URL` | `http://127.0.0.1:1234` | LM Studio server URL (`LMSTUDIO_URL` also read) |
|
|
128
124
|
| `AWNODE_EXTENSION_IDS` | | Extra extension ids admitted on the extension routes (comma-separated) |
|
|
129
125
|
| `AWNODE_BROWSER_FULL_TOOLS` | | `1` lets direct loopback callers (browser/extension included) run every tool without a credential; tunnelled/remote callers stay read-only |
|
|
@@ -173,6 +169,7 @@ Each installs on its own, works offline, and needs no account.
|
|
|
173
169
|
| [awrelay](https://github.com/Aitherium/awrelay) | a SaaS in the middle of your agents | findings, alerts and coordination over your own transport |
|
|
174
170
|
| [awask](https://github.com/Aitherium/awask) | that anyone read the paragraph where you asked | the ask itself, with a button that steers the session that raised it |
|
|
175
171
|
| [awmail](https://github.com/Aitherium/awmail) | a mailbox somebody else can read | mail your agents send and receive over your own server |
|
|
172
|
+
| [awdiscord](https://github.com/Aitherium/awdiscord) | a self-bot on someone's account, or a bot that acts without asking | slash commands, rate limits, and approval buttons only your operators can press |
|
|
176
173
|
| [awswarm](https://github.com/Aitherium/awswarm) | that a model either fits your GPU or it doesn't run at all | a placement plan and an acquisition-probability estimate before you spend on a run |
|
|
177
174
|
| [awfind](https://github.com/Aitherium/awfind) | one vendor's idea of the web | results from whichever providers you configured |
|
|
178
175
|
| [awbrowse](https://github.com/Aitherium/awbrowse) | that the page said what you were told | the render, the DOM and the requests it made |
|
|
@@ -243,6 +240,7 @@ Every repository here is public. Each publishes an `aither-manifest.json` beside
|
|
|
243
240
|
| [awrelay](https://github.com/Aitherium/awrelay) | Portable agent messaging — findings, alerts, coordination | [docs](https://aitherium.github.io/awrelay/) |
|
|
244
241
|
| [awask](https://github.com/Aitherium/awask) | Your agent asks you a question — and acts on your answer | [docs](https://aitherium.github.io/awask/) |
|
|
245
242
|
| [awmail](https://github.com/Aitherium/awmail) | Give an agent an email address — send, and actually receive | [docs](https://aitherium.github.io/awmail/) |
|
|
243
|
+
| [awdiscord](https://github.com/Aitherium/awdiscord) | Put any agent on Discord as a real bot, with an operator in the loop | — |
|
|
246
244
|
| [awnet](https://github.com/Aitherium/awnet) | The agentic web — agents host a mesh, and agents join one | [docs](https://aitherium.github.io/awnet/) |
|
|
247
245
|
| [awswarm](https://github.com/Aitherium/awswarm) | Run one model too big for any single GPU across a pool of small ones | — |
|
|
248
246
|
| [awfind](https://github.com/Aitherium/awfind) | A portable search client — query, results, ranking | [docs](https://aitherium.github.io/awfind/) |
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
**[Docs](https://aitherium.github.io/awnode/)** · [Source](https://github.com/Aitherium/awnode) · `pip install awnode` · [The Aither World](https://aitherium.github.io/)
|
|
6
6
|
|
|
7
|
-
> **The Aither World** is an operating system for agents — a Linux you can hand to one, the runtimes it works in, and the tools it works with. [awnix](https://github.com/Aitherium/awnix) is the Linux underneath it; **awnode** is one of its
|
|
7
|
+
> **The Aither World** is an operating system for agents — a Linux you can hand to one, the runtimes it works in, and the tools it works with. [awnix](https://github.com/Aitherium/awnix) is the Linux underneath it; **awnode** is one of its 68 bricks — each installs on its own, runs offline, and needs no account.
|
|
8
8
|
>
|
|
9
9
|
> **Start here:** Run it once and point one app at it instead of a vendor URL.
|
|
10
10
|
|
|
@@ -26,7 +26,7 @@ curl -fsSL https://launch.aitherium.com | bash
|
|
|
26
26
|
## Quick Start
|
|
27
27
|
|
|
28
28
|
```bash
|
|
29
|
-
# Start with auto-detection (finds Genesis, vLLM, llama.cpp, LM Studio,
|
|
29
|
+
# Start with auto-detection (finds Genesis, vLLM, llama.cpp, LM Studio, or cloud)
|
|
30
30
|
awnode start
|
|
31
31
|
|
|
32
32
|
# Run the published container
|
|
@@ -55,8 +55,7 @@ awnode deploy my-service --target docker --strategy rolling
|
|
|
55
55
|
3. **llama.cpp** (localhost:8200) / **Bonsai** (localhost:8092) — OpenAI-compatible llama.cpp servers
|
|
56
56
|
4. **LM Studio** (127.0.0.1:1234) — LM Studio's local server (OpenAI-compatible; start it from LM Studio's Developer tab)
|
|
57
57
|
5. **Elysium** (cloud) — hosted AitherOS (requires API key)
|
|
58
|
-
6. **
|
|
59
|
-
7. **Standalone** — no LLM, tools-only mode
|
|
58
|
+
6. **Standalone** — no LLM, tools-only mode
|
|
60
59
|
|
|
61
60
|
OpenAI-compatible backends (vLLM, llama.cpp, Bonsai, LM Studio, custom) are detected by a
|
|
62
61
|
200 on `/v1/models`, never by `/health`, so an unrelated service on the same port is not
|
|
@@ -95,7 +94,7 @@ the read-only set; for full tool access from an IDE use `awnode mcp`.
|
|
|
95
94
|
|---|---|---|
|
|
96
95
|
| `AITHER_URL` | `http://localhost:8001` | Genesis URL |
|
|
97
96
|
| `AITHER_VLLM_URL` | `http://localhost:8120` | vLLM URL |
|
|
98
|
-
| `
|
|
97
|
+
| `LLAMACPP_URL` | `http://localhost:8200` | llama.cpp `llama-server` URL (OpenAI-compatible) |
|
|
99
98
|
| `AITHERNODE_LMSTUDIO_URL` | `http://127.0.0.1:1234` | LM Studio server URL (`LMSTUDIO_URL` also read) |
|
|
100
99
|
| `AWNODE_EXTENSION_IDS` | | Extra extension ids admitted on the extension routes (comma-separated) |
|
|
101
100
|
| `AWNODE_BROWSER_FULL_TOOLS` | | `1` lets direct loopback callers (browser/extension included) run every tool without a credential; tunnelled/remote callers stay read-only |
|
|
@@ -145,6 +144,7 @@ Each installs on its own, works offline, and needs no account.
|
|
|
145
144
|
| [awrelay](https://github.com/Aitherium/awrelay) | a SaaS in the middle of your agents | findings, alerts and coordination over your own transport |
|
|
146
145
|
| [awask](https://github.com/Aitherium/awask) | that anyone read the paragraph where you asked | the ask itself, with a button that steers the session that raised it |
|
|
147
146
|
| [awmail](https://github.com/Aitherium/awmail) | a mailbox somebody else can read | mail your agents send and receive over your own server |
|
|
147
|
+
| [awdiscord](https://github.com/Aitherium/awdiscord) | a self-bot on someone's account, or a bot that acts without asking | slash commands, rate limits, and approval buttons only your operators can press |
|
|
148
148
|
| [awswarm](https://github.com/Aitherium/awswarm) | that a model either fits your GPU or it doesn't run at all | a placement plan and an acquisition-probability estimate before you spend on a run |
|
|
149
149
|
| [awfind](https://github.com/Aitherium/awfind) | one vendor's idea of the web | results from whichever providers you configured |
|
|
150
150
|
| [awbrowse](https://github.com/Aitherium/awbrowse) | that the page said what you were told | the render, the DOM and the requests it made |
|
|
@@ -215,6 +215,7 @@ Every repository here is public. Each publishes an `aither-manifest.json` beside
|
|
|
215
215
|
| [awrelay](https://github.com/Aitherium/awrelay) | Portable agent messaging — findings, alerts, coordination | [docs](https://aitherium.github.io/awrelay/) |
|
|
216
216
|
| [awask](https://github.com/Aitherium/awask) | Your agent asks you a question — and acts on your answer | [docs](https://aitherium.github.io/awask/) |
|
|
217
217
|
| [awmail](https://github.com/Aitherium/awmail) | Give an agent an email address — send, and actually receive | [docs](https://aitherium.github.io/awmail/) |
|
|
218
|
+
| [awdiscord](https://github.com/Aitherium/awdiscord) | Put any agent on Discord as a real bot, with an operator in the loop | — |
|
|
218
219
|
| [awnet](https://github.com/Aitherium/awnet) | The agentic web — agents host a mesh, and agents join one | [docs](https://aitherium.github.io/awnet/) |
|
|
219
220
|
| [awswarm](https://github.com/Aitherium/awswarm) | Run one model too big for any single GPU across a pool of small ones | — |
|
|
220
221
|
| [awfind](https://github.com/Aitherium/awfind) | A portable search client — query, results, ranking | [docs](https://aitherium.github.io/awfind/) |
|
|
@@ -42,6 +42,7 @@
|
|
|
42
42
|
{ id: "awrecover", label: "awrecover", blurb: "Labelled snapshots with an all-or-nothing..." },
|
|
43
43
|
{ id: "awrelay", label: "awrelay", blurb: "Portable agent messaging — findings, alerts,..." },
|
|
44
44
|
{ id: "awmail", label: "awmail", blurb: "Give an agent an email address — send, and..." },
|
|
45
|
+
{ id: "awdiscord", label: "awdiscord", blurb: "Put any agent on Discord as a real bot,..." },
|
|
45
46
|
{ id: "awnet", label: "awnet", blurb: "The agentic web — agents host a mesh, and..." },
|
|
46
47
|
{ id: "awfind", label: "awfind", blurb: "A portable search client — query, results,..." },
|
|
47
48
|
{ id: "awbrowse", label: "awbrowse", blurb: "A portable browser client — navigate,..." },
|
|
@@ -7,7 +7,7 @@ The bridge between local apps (Shell, Desktop, Connect) and AitherOS services.
|
|
|
7
7
|
Modes:
|
|
8
8
|
1. **Local Genesis** — proxy to localhost:8001 (full AitherOS Docker stack)
|
|
9
9
|
2. **Cloud** — proxy to mcp.aitherium.com (SaaS inference + MCP tools)
|
|
10
|
-
3. **Standalone** — local
|
|
10
|
+
3. **Standalone** — local llama.cpp + basic tools (no Genesis needed)
|
|
11
11
|
4. **Hybrid** — local tools + cloud LLM (best of both)
|
|
12
12
|
|
|
13
13
|
Install:
|
|
@@ -17,4 +17,4 @@ Install:
|
|
|
17
17
|
aithernode status # Check what's connected
|
|
18
18
|
"""
|
|
19
19
|
|
|
20
|
-
__version__ = "0.3.
|
|
20
|
+
__version__ = "0.3.5"
|
|
@@ -72,7 +72,7 @@ def main():
|
|
|
72
72
|
start_p.add_argument("--cloud", action="store_true", help="Force cloud mode (Elysium)")
|
|
73
73
|
start_p.add_argument("--local", action="store_true", help="Force local mode (no cloud)")
|
|
74
74
|
start_p.add_argument("--vllm-url", type=str, help="vLLM URL (default: http://localhost:8120)")
|
|
75
|
-
start_p.add_argument("--
|
|
75
|
+
start_p.add_argument("--llamacpp-url", type=str, help="llama.cpp server URL (default: http://localhost:8200)")
|
|
76
76
|
start_p.add_argument("--genesis-url", type=str, help="Genesis URL (default: http://localhost:8001)")
|
|
77
77
|
|
|
78
78
|
# status
|
|
@@ -105,7 +105,8 @@ def main():
|
|
|
105
105
|
"AitherOS fabric. Omit for the default GPU/backend setup.",
|
|
106
106
|
)
|
|
107
107
|
setup_p.add_argument("--cloud", action="store_true", help="Cloud-only mode (skip local GPU)")
|
|
108
|
-
setup_p.add_argument("--model", type=str,
|
|
108
|
+
setup_p.add_argument("--model", type=str,
|
|
109
|
+
help="GGUF model id the local llama.cpp server should serve")
|
|
109
110
|
setup_p.add_argument("--skip-model", action="store_true", help="Skip model download")
|
|
110
111
|
# `setup comfyui` flags (ignored by the bare `setup` path)
|
|
111
112
|
setup_p.add_argument("--profile", type=str, default="studio",
|
|
@@ -191,8 +192,8 @@ def main():
|
|
|
191
192
|
os.environ["AITHERNODE_MODE"] = "local"
|
|
192
193
|
if args.vllm_url:
|
|
193
194
|
os.environ["AITHER_VLLM_URL"] = args.vllm_url
|
|
194
|
-
if args.
|
|
195
|
-
os.environ["
|
|
195
|
+
if args.llamacpp_url:
|
|
196
|
+
os.environ["LLAMACPP_URL"] = args.llamacpp_url
|
|
196
197
|
if args.genesis_url:
|
|
197
198
|
os.environ["AITHER_URL"] = args.genesis_url
|
|
198
199
|
os.environ["AITHERNODE_PORT"] = str(args.port)
|
|
@@ -347,7 +348,7 @@ async def _doctor(*, emit_json: bool = False, timeout: float = 3.0) -> int:
|
|
|
347
348
|
backends = {
|
|
348
349
|
"genesis": os.environ.get("AITHER_URL", "http://localhost:8001"),
|
|
349
350
|
"vllm": os.environ.get("AITHER_VLLM_URL", "http://localhost:8120"),
|
|
350
|
-
"
|
|
351
|
+
"llamacpp": os.environ.get("LLAMACPP_URL", "http://localhost:8200"),
|
|
351
352
|
# LM Studio has no /health; its OpenAI-compatible /v1/models is the liveness surface.
|
|
352
353
|
"lmstudio": os.environ.get(
|
|
353
354
|
"AITHERNODE_LMSTUDIO_URL", os.environ.get("LMSTUDIO_URL", "http://127.0.0.1:1234")
|
|
@@ -356,7 +357,7 @@ async def _doctor(*, emit_json: bool = False, timeout: float = 3.0) -> int:
|
|
|
356
357
|
}
|
|
357
358
|
async with httpx.AsyncClient(timeout=timeout) as client:
|
|
358
359
|
for name, url in backends.items():
|
|
359
|
-
health_path = {"
|
|
360
|
+
health_path = {"lmstudio": "/v1/models"}.get(name, "/health")
|
|
360
361
|
try:
|
|
361
362
|
r = await client.get(url.rstrip("/") + health_path)
|
|
362
363
|
if r.status_code < 500:
|
|
@@ -364,7 +365,7 @@ async def _doctor(*, emit_json: bool = False, timeout: float = 3.0) -> int:
|
|
|
364
365
|
else:
|
|
365
366
|
record(name, "warn", f"{url} -> {r.status_code}")
|
|
366
367
|
except Exception as e:
|
|
367
|
-
# gateway/vllm/
|
|
368
|
+
# gateway/vllm/llamacpp unreachable is a warn (not everyone runs them)
|
|
368
369
|
record(name, "warn", f"{url} unreachable: {type(e).__name__}")
|
|
369
370
|
|
|
370
371
|
# Compute exit code
|
|
@@ -403,7 +404,7 @@ async def _status():
|
|
|
403
404
|
checks = {
|
|
404
405
|
"Genesis": os.environ.get("AITHER_URL", "http://localhost:8001"),
|
|
405
406
|
"vLLM": os.environ.get("AITHER_VLLM_URL", os.environ.get("VLLM_URL", "http://localhost:8120")),
|
|
406
|
-
"
|
|
407
|
+
"llama.cpp": os.environ.get("LLAMACPP_URL", "http://localhost:8200"),
|
|
407
408
|
"Elysium": "https://mcp.aitherium.com",
|
|
408
409
|
}
|
|
409
410
|
|
|
@@ -412,7 +413,7 @@ async def _status():
|
|
|
412
413
|
for name, url in checks.items():
|
|
413
414
|
try:
|
|
414
415
|
async with httpx.AsyncClient(timeout=3.0) as c:
|
|
415
|
-
health_path = "/
|
|
416
|
+
health_path = "/health"
|
|
416
417
|
r = await c.get(f"{url.rstrip('/')}{health_path}")
|
|
417
418
|
status = "UP" if r.status_code == 200 else f"HTTP {r.status_code}"
|
|
418
419
|
except Exception:
|
|
@@ -684,7 +685,7 @@ async def _connect(
|
|
|
684
685
|
try:
|
|
685
686
|
result = await gw.register_agent(
|
|
686
687
|
name=f"node-{hostname}",
|
|
687
|
-
capabilities=["chat", "code", "filesystem", "git", "vllm", "
|
|
688
|
+
capabilities=["chat", "code", "filesystem", "git", "vllm", "llamacpp"],
|
|
688
689
|
description=f"awnode on {hostname} ({platform.system()})",
|
|
689
690
|
)
|
|
690
691
|
print(f"Connected! Agent ID: {result.get('agent_id', '?')}")
|
|
@@ -796,42 +797,25 @@ async def _setup(cloud_only: bool = False, model: str = None, skip_model: bool =
|
|
|
796
797
|
print(" Local models will use your GPU for fast inference.")
|
|
797
798
|
elif gpu_vram >= 4096:
|
|
798
799
|
cfg["mode"] = "auto"
|
|
799
|
-
print(f" Recommended:
|
|
800
|
+
print(f" Recommended: llama.cpp with a small GGUF model ({gpu_vram}MB VRAM)")
|
|
800
801
|
else:
|
|
801
802
|
cfg["mode"] = "auto"
|
|
802
|
-
print(" Recommended:
|
|
803
|
-
|
|
804
|
-
# --
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
target_model = model
|
|
812
|
-
if not target_model:
|
|
813
|
-
if gpu_vram >= 16384:
|
|
814
|
-
target_model = "llama3.1:8b"
|
|
815
|
-
elif gpu_vram >= 8192:
|
|
816
|
-
target_model = "llama3.2:3b"
|
|
817
|
-
else:
|
|
818
|
-
target_model = "llama3.2:1b"
|
|
819
|
-
|
|
820
|
-
print(f"\n Pulling model: {target_model}...")
|
|
821
|
-
pull_result = subprocess.run(
|
|
822
|
-
["ollama", "pull", target_model],
|
|
823
|
-
timeout=600,
|
|
824
|
-
)
|
|
825
|
-
if pull_result.returncode == 0:
|
|
826
|
-
cfg["ollama"]["default_model"] = target_model
|
|
827
|
-
print(f" Model ready: {target_model}")
|
|
828
|
-
else:
|
|
829
|
-
print(f" Model pull failed (exit {pull_result.returncode})")
|
|
803
|
+
print(" Recommended: llama.cpp CPU mode or cloud")
|
|
804
|
+
|
|
805
|
+
# -- llama.cpp Detection --
|
|
806
|
+
# Weights are GGUF files from artifact.aitherium.com (awrtifact); awnode does not
|
|
807
|
+
# download them -- it records which model the local llama-server should serve.
|
|
808
|
+
has_llamacpp = shutil.which("llama-server") is not None
|
|
809
|
+
cfg["llamacpp"] = {"available": has_llamacpp}
|
|
810
|
+
if has_llamacpp:
|
|
811
|
+
print(" llama.cpp: llama-server installed")
|
|
830
812
|
else:
|
|
831
|
-
print("
|
|
813
|
+
print(" llama.cpp: llama-server not on PATH")
|
|
832
814
|
if not cloud_only:
|
|
833
|
-
print(" Install: https://
|
|
834
|
-
|
|
815
|
+
print(" Install: https://github.com/ggml-org/llama.cpp/releases")
|
|
816
|
+
if model and not skip_model and not cloud_only:
|
|
817
|
+
cfg["llamacpp"]["default_model"] = model
|
|
818
|
+
print(f" Default local model: {model}")
|
|
835
819
|
|
|
836
820
|
# -- vLLM Detection --
|
|
837
821
|
import httpx
|
|
@@ -9,8 +9,8 @@ alongside awnode on customer hardware.
|
|
|
9
9
|
`awdk.adk.addon_manager` reads component manifests from three sources (a pip-installed
|
|
10
10
|
brick's `aither.components` entry point, `~/.aither/components/*.yaml`, the bundled
|
|
11
11
|
`adk/addon_manifests/`) and this manager renders them in the shape `awnode ext` has
|
|
12
|
-
always shown. The
|
|
13
|
-
comfyui, comfyui-3d, muse, sd-webui,
|
|
12
|
+
always shown. The entries that used to be hardcoded in BUILTIN_CATALOG (canvas,
|
|
13
|
+
comfyui, comfyui-3d, muse, sd-webui, iris, design, autorig) are manifests now,
|
|
14
14
|
so `awnode ext start canvas` runs the same declaration awdk, the aitheros launcher, awsh
|
|
15
15
|
and the Living Desktop read. Two hosts with two catalogs of "what can run here" was the
|
|
16
16
|
silence this ended: an extension present in one and absent from the other looked like
|
|
@@ -90,6 +90,18 @@ DEFAULT_BRICKS: List[Dict[str, Any]] = [
|
|
|
90
90
|
{"name": "awfind", "main": "awfind.cli:main", "args": ["mcp"]},
|
|
91
91
|
{"name": "awprism", "main": "awprism.cli:main", "args": ["mcp"]},
|
|
92
92
|
{"name": "awsh", "module": "adk.harnesses.mcp_stdio"},
|
|
93
|
+
# REA reverse-engineering toolkit. The heavy toolchain (Node 22, Ghidra, the
|
|
94
|
+
# pinned rea-agents CLI) lives in the policy-gated ``aitheros-rea`` awnix
|
|
95
|
+
# sidecar, never in this process; this brick is a thin stdio->HTTP bridge to
|
|
96
|
+
# that sidecar's MCP endpoint, so every rea_* call is served THROUGH the
|
|
97
|
+
# sidecar's in-process policy proxy (lib.agents.packs.rea.policy.authorize:
|
|
98
|
+
# target_class + per-tool grant, fail-closed). Disabled by default so boots
|
|
99
|
+
# on a host without the sidecar never try to start it; enable per host via
|
|
100
|
+
# ~/.aither/aw-hub config ``{"bricks": {"rea": {"disabled": false}}}`` or the
|
|
101
|
+
# AITHER_REA_SIDECAR_URL env the argv reads.
|
|
102
|
+
{"name": "rea", "disabled": True, "module": "awnode.rea_sidecar_bridge",
|
|
103
|
+
"args": ["--url", os.environ.get("AITHER_REA_SIDECAR_URL",
|
|
104
|
+
"https://aitheros-rea:8791/mcp")]},
|
|
93
105
|
]
|
|
94
106
|
|
|
95
107
|
_CREATE_NO_WINDOW = 0x08000000
|
|
@@ -13,7 +13,7 @@ Flow:
|
|
|
13
13
|
|
|
14
14
|
If the subscription lapses:
|
|
15
15
|
- Tools/agents/extensions that require a paid tier stop working
|
|
16
|
-
- Free-tier tools (filesystem, git, search,
|
|
16
|
+
- Free-tier tools (filesystem, git, search, local llama.cpp) keep working
|
|
17
17
|
- Clear error messages tell the user to renew
|
|
18
18
|
|
|
19
19
|
If offline:
|
|
@@ -49,8 +49,8 @@ PLAN_FEATURES: Dict[str, Dict[str, Any]] = {
|
|
|
49
49
|
"free": {
|
|
50
50
|
"tools": {"filesystem", "git_tools", "search", "commands", "context",
|
|
51
51
|
"memory", "knowledge", "notebooks", "documents", "mermaid",
|
|
52
|
-
"http_client", "
|
|
53
|
-
"extensions":
|
|
52
|
+
"http_client", "orchestrator", "embeddings"},
|
|
53
|
+
"extensions": set(),
|
|
54
54
|
"agents": set(),
|
|
55
55
|
"max_agents": 1,
|
|
56
56
|
"image_generation": False,
|
|
@@ -60,9 +60,9 @@ PLAN_FEATURES: Dict[str, Dict[str, Any]] = {
|
|
|
60
60
|
"developer": {
|
|
61
61
|
"tools": {"filesystem", "git_tools", "search", "commands", "context",
|
|
62
62
|
"memory", "knowledge", "notebooks", "documents", "mermaid",
|
|
63
|
-
"http_client", "
|
|
63
|
+
"http_client", "orchestrator", "embeddings",
|
|
64
64
|
"generation", "extensions", "vision"},
|
|
65
|
-
"extensions": {"
|
|
65
|
+
"extensions": {"canvas", "comfyui"},
|
|
66
66
|
"agents": {"iris"},
|
|
67
67
|
"max_agents": 3,
|
|
68
68
|
"image_generation": True,
|
|
@@ -71,7 +71,7 @@ PLAN_FEATURES: Dict[str, Dict[str, Any]] = {
|
|
|
71
71
|
},
|
|
72
72
|
"pro": {
|
|
73
73
|
"tools": {"*"}, # All tools
|
|
74
|
-
"extensions": {"
|
|
74
|
+
"extensions": {"canvas", "comfyui", "comfyui-3d", "muse",
|
|
75
75
|
"sd-webui", "iris", "design"},
|
|
76
76
|
"agents": {"iris", "demiurge", "atlas", "hydra", "viviane"},
|
|
77
77
|
"max_agents": 15,
|
|
@@ -57,8 +57,8 @@ _DEFAULT_SERVICES: Dict[str, str] = {
|
|
|
57
57
|
"genesis": os.environ.get("AITHER_URL", "http://127.0.0.1:8001"),
|
|
58
58
|
# Bonsai-27B llama.cpp server (PrismML fork) — OpenAI-compatible /v1
|
|
59
59
|
"bonsai": os.environ.get("AITHER_BONSAI_URL", "http://127.0.0.1:8092"),
|
|
60
|
-
#
|
|
61
|
-
"
|
|
60
|
+
# llama.cpp llama-server — generic local OpenAI-compatible model host
|
|
61
|
+
"llamacpp": os.environ.get("LLAMACPP_URL", "http://127.0.0.1:8200"),
|
|
62
62
|
# AitherMarketplace — unified catalog (agent/skill/tool packs, apps,
|
|
63
63
|
# tools, plugins, extensions) with the fail-closed entitlement gate.
|
|
64
64
|
"marketplace": os.environ.get("AITHER_MARKETPLACE_URL", "https://127.0.0.1:8260"),
|
|
@@ -80,7 +80,7 @@ def _load_service_map() -> Dict[str, str]:
|
|
|
80
80
|
|
|
81
81
|
def _norm(url: str) -> str:
|
|
82
82
|
url = url.strip().rstrip("/")
|
|
83
|
-
#
|
|
83
|
+
# A host env is commonly "0.0.0.0:<port>" (no scheme) — normalize so
|
|
84
84
|
# httpx gets an absolute URL, and rewrite wildcard binds to loopback.
|
|
85
85
|
if url and "://" not in url:
|
|
86
86
|
url = f"http://{url}"
|