Subactor Shell 0.2.2
AI Cost Tracking
- 🤖 LLM usage: $0.0595 (3 commits)
- 👤 Human dev: ~$953 (9.5h @ $100/h, 30min dedup)
Generated on 2026-08-29 using openrouter/qwen/qwen3-coder-next
Subactor Shell jest trwałą warstwą rozmowy i orkiestracji dla terminala oraz klientów ACP. Wersja 0.2.2 integruje pytania operacyjne z zarządzanym CLI Subactora, poprawia obsługę kończenia sesji i nie przejmuje nazwy Founder Chat.
polecenie użytkownika
→ exact/template/phrase match (0 tokenów)
→ lokalny lub tani parser NL → IntentIR v1
→ lokalna walidacja JSON Schema
→ deterministyczny ExecutionPlan
→ policy + capability/connector preflight
→ nazwany connector
→ krótki ExecutionReceipt
→ duży LLM tylko przy niepewności lub zadaniu konwersacyjnym
Pełny transcript nadal jest zapisywany w SQLite, ale provider rozmowy dostaje tylko ograniczony WorkingState, kilka ostatnich wiadomości, krótką informację o trasie oraz lokalnie wybrane fragmenty danych i artefaktów.
Najważniejsze właściwości
- lokalny fast path bez LLM dla znanych poleceń;
- typowany i walidowany
IntentIR v1zamiast swobodnego planowania w prozie; - routing: deterministic/cache → local 4B → cheap remote → large/chat provider;
ExecutionPlantworzony wyłącznie przez lokalny kompilator;- nazwane connectory
builtin, Subactor Control, process oraz HTTP; - brak
shell=Truei brak możliwości wskazania przez model dowolnej komendy; - plan hash, fingerprint stanu i jawne
EXECUTEdla operacji zmieniających stan; ExecutionReceiptzamiast przekazywania pełnych logów między modelami;- telemetria tokenów, cached input, szacowanego kosztu i udziału tras bez LLM;
- trwałe sesje, jawne dane, artefakty oraz referencje Vault;
- ACP v1 po
stdin/stdout, wraz z rozszerzeniami katalogu, planów, receiptów i metryk; - migracja istniejącej bazy 0.1 bez usuwania sesji ani wiadomości.
Instalacja
Pakiet instaluje wyłącznie polecenie subactor-shell. Nazwa subactor jest
zarezerwowana dla Founder Chat dostarczanego przez Platformę, dzięki czemu
subactor chat zachowuje swój interfejs, pełną diagnostykę i kontrakt sesji.
Powłokę z trwałym stanem, Vault, lokalnym routingiem i ACP uruchamia się
jawnie przez subactor-shell chat.
Z wheel:
python -m venv .venv
. .venv/bin/activate
pip install ./subactor_shell_bridge-0.2.0-py3-none-any.whl
subactor-shell init
Ze źródeł:
python -m venv .venv
. .venv/bin/activate
pip install -e .
subactor-shell init
Domyślne lokalizacje:
~/.config/subactor-shell/config.toml
~/.local/share/subactor-shell/subactor-shell.sqlite3
~/.local/share/subactor-shell/artifacts/
Katalog danych otrzymuje tryb 0700, a config, SQLite i artefakty 0600, o ile system plików wspiera te tryby.
Szybki start
subactor-shell chat
Przykładowe polecenia w REPL:
pokaż sesje
pokaż zużycie tokenów
/status
/plans
/receipts
/catalog
/connectors
/route
Jedna wiadomość bez REPL:
subactor-shell one 'pokaż sesje'
Przy znanym intencie read-only wynik może zostać wykonany lokalnie bez wywołania providera rozmowy.
Routing modeli
Minimalna konfiguracja lokalnego parsera OpenAI-compatible:
[orchestration]
enabled = true
mode = "active"
local_parser_provider = "local_4b"
local_parser_model = "local-4b-instruct"
cheap_parser_provider = ""
large_provider = ""
top_k = 5
max_parser_output_tokens = 192
[providers.local_4b]
kind = "openai_compat"
base_url = "http://127.0.0.1:8000/v1"
endpoint = "/chat/completions"
auth_required = false
api_key_ref = ""
model = "local-4b-instruct"
max_output_tokens = 192
structured_mode = "json_schema"
Tani i duży fallback można dodać jako kolejne profile:
[orchestration]
local_parser_provider = "local_4b"
cheap_parser_provider = "budget_remote"
large_provider = "planner_remote"
[providers.budget_remote]
kind = "openai_compat"
base_url = "https://provider.example/v1"
endpoint = "/chat/completions"
api_key_ref = "env://BUDGET_LLM_API_KEY"
auth_required = true
model = "budget-model"
max_output_tokens = 192
structured_mode = "json_schema"
input_cost_per_million = 0.0
cached_input_cost_per_million = 0.0
output_cost_per_million = 0.0
[providers.planner_remote]
kind = "openai_compat"
base_url = "https://provider.example/v1"
endpoint = "/chat/completions"
api_key_ref = "env://PLANNER_LLM_API_KEY"
auth_required = true
model = "large-planner"
max_output_tokens = 800
structured_mode = "json_schema"
Stawki w configu są wyłącznie danymi użytkownika do lokalnego szacowania kosztu. Projekt nie pobiera automatycznie cenników.
Tryby orkiestracji:
active— wykonuje poprawne lokalne plany;shadow— zapisuje routing i IntentIR, ale odpowiedź nadal prowadzi provider rozmowy;off— zachowanie konwersacyjne bez DSL.
IntentIR v1
Model parsera może zwrócić tylko obiekt zgodny z schemas/intent-ir.v1.schema.json, na przykład:
{
"v": 1,
"intent_id": "project.deploy",
"mode": "plan",
"args": {
"project_ref": "project://docs",
"environment": "prod"
},
"requirements": ["verify_tls"],
"constraints": ["no_secret_export"],
"unresolved": []
}
Model nie wybiera komendy, ścieżki wykonywalnej, URL, connectora ani secret ref. Te elementy pochodzą z lokalnego katalogu intentów i konfiguracji connectorów.
Katalog intentów
Wbudowane intenty obejmują pomoc, sesje, dane, bindingi sekretów, metryki oraz cli.status/cli.plan istniejącego Subactor Control.
Dodatkowe katalogi wskazuje się w configu:
[orchestration]
intent_catalog_paths = ["./intent-catalog.v1.json"]
Przykład znajduje się w examples/intent-catalog.v1.json. Loader akceptuje własny format {"intents": [...]} oraz kilka typowych nazw pól spotykanych w intent packach, ale dokładna integracja z repozytorium nadrzędnym wymaga rzeczywistych plików JSON, nie samej mapy symboli.
Named connectors
Process connector
[connectors.project_ops]
kind = "process"
command = ["/opt/subactor/bin/project-connector", "--json-stdin"]
allowed_operations = ["project.inspect", "project.apply"]
effect = "external_write"
inherit_env = false
pass_env = ["PATH", "LANG", "LC_ALL", "TZ"]
timeout_seconds = 30.0
output_limit_bytes = 65536
[connectors.project_ops.env_refs]
PROJECT_API_TOKEN = "vault://secret/subactor/project#token"
Pierwszy element command musi być ścieżką absolutną. Runtime uruchamia stałe argv przez create_subprocess_exec, bez powłoki. Domyślnie nie dziedziczy całego środowiska procesu; przepuszcza tylko nazwy z pass_env oraz jawne env_refs. Connector dostaje JSON przez stdin:
{
"plan_id": "plan_...",
"plan_hash": "...",
"session_id": "...",
"intent_id": "project.apply",
"operation": "project.apply",
"args": {}
}
Minimalny przykład implementacji: examples/process-connector.py.
HTTP connector
[connectors.project_http]
kind = "http"
base_url = "https://connector.internal"
path = "/v1/execute"
method = "POST"
bearer_ref = "file://~/.config/subactor-shell/project-http.token"
allowed_operations = ["project.inspect", "project.apply"]
effect = "external_write"
Subactor Control
subactor_control pozostaje specjalnym connectorom z dokładną allowlistą:
[control]
allowed_tools = ["cli.status", "cli.plan", "cli.execute"]
Bridge wykonuje tools/list przed wywołaniem i odrzuca endpoint, który reklamuje inny zestaw narzędzi. cli.execute wymaga zaakceptowanego planu.
Plan i apply
Operacja read-only może wykonać się automatycznie. Operacja zmieniająca stan zapisuje plan:
subactor-shell plans list
subactor-shell plans show PLAN_ID
subactor-shell plans apply PLAN_ID --confirm EXECUTE
subactor-shell receipts list
subactor-shell receipts show RECEIPT_ID
Przed apply sprawdzane są:
- status planu;
plan_hash;- dokładne
EXECUTEdla zmian stanu; - aktualny fingerprint SQLite, katalogu intentów i registry connectorów;
- allowlista connectora i operation;
- lokalna policy.
Ograniczanie kontekstu
Pełna historia jest przechowywana, lecz nie jest ponownie wysyłana przy każdej turze. Limity ustawia sekcja:
[context]
recent_messages = 6
max_history_chars = 12000
max_message_chars = 4000
max_data_chars = 6000
max_attachment_prompt_chars = 8000
artifact_chunk_chars = 1800
max_artifact_chunks = 4
max_embedded_context_chars = 8000
max_route_context_chars = 4000
{{data:NAME}} i załączniki są dzielone lokalnie na fragmenty i wybierane leksykalnie względem bieżącego polecenia. Model otrzymuje tylko wynik mieszczący się w budżecie. To nie jest pełny silnik semantyczny; dla rozbudowanego repozytorium należy podłączyć istniejące DOQL/DQL lub własny retriever jako nazwany connector.
Dane i artefakty
subactor-shell data set ENVIRONMENT staging
subactor-shell data put SPEC ./specification.md
subactor-shell data list
W rozmowie:
Przeanalizuj ustawienia {{data:ENVIRONMENT}} oraz sekcję deployment w {{data:SPEC}}.
Jawne dane mogą zostać wysłane do providera po lokalnym wyborze fragmentów. Nie należy zapisywać w tej warstwie sekretów.
Vault i jednorazowe granty
Binding zapisuje wyłącznie referencję:
subactor-shell vault bind DB_PASSWORD 'vault://secret/subactor/prod/database#password'
Zapis wartości do Vault KV v2 pobiera ją bez echa:
subactor-shell vault put DB_PASSWORD 'vault://secret/subactor/prod/database#password'
W REPL:
/vault grant DB_PASSWORD
Sprawdź format {{secret:DB_PASSWORD}}, ale jej nie powtarzaj.
Grant jest jednorazowy i przechowywany wyłącznie w pamięci procesu. Placeholder w zapisanych danych, pliku lub embedded resource ACP nie może sam zużyć grantu. Lokalne fast path nie odczytuje sekretu i nie konsumuje grantu.
Metryki
subactor-shell metrics --json
subactor-shell metrics --session SESSION_ID --json
Wynik obejmuje:
- liczbę wywołań providerów;
- input, cached input i output tokens;
- wywołania z usage oszacowanym lokalnie;
- koszt według stawek wpisanych w configu;
- rozkład tras;
- udział tras
deterministicicachebez LLM.
ACP
subactor-shell acp-agent
Oprócz ACP v1 (initialize, session/new, session/load, session/prompt, session/cancel) agent obsługuje rozszerzenia:
subactor/data/set
subactor/data/list
subactor/secret/bind
subactor/secret/grant
subactor/secret/list
subactor/catalog/list
subactor/connectors/list
subactor/route/get
subactor/metrics/get
subactor/plan/list
subactor/plan/get
subactor/plan/apply
subactor/receipt/list
subactor/receipt/get
subactor/plan/apply używa tej samej walidacji i wymaga pola confirmation: "EXECUTE" dla zmian stanu. stdout procesu ACP jest zarezerwowany dla jednoliniowych komunikatów JSON-RPC.
Migracja z 0.1
Po wskazaniu istniejącego --data-dir Store automatycznie dodaje tabele:
session_state
routing_decisions
provider_usage
execution_plans
execution_receipts
router_feedback
context_cache
Istniejące sessions, messages, artifacts, jawne dane i bindingi sekretów pozostają zachowane. Przed migracją produkcyjną zalecana jest kopia pliku SQLite.
Testy
python -m pip install -e '.[dev]'
pytest -q
Pakiet wydaniowy 0.2.0 został sprawdzony testami jednostkowymi i integracyjnymi oraz instalacją wheel do izolowanego katalogu pakietów, uruchomioną poza drzewem źródeł. Integracje z prawdziwymi kontami Vault/LLM/Subactor należy dodatkowo sprawdzić w docelowym środowisku.
Więcej szczegółów:
docs/TOKEN_ROUTING.md— routing, WorkingState i budżety;docs/INTEGRATION.md— dopasowanie do aktualnej mapy repozytorium Subactor;SECURITY.md— granice zaufania i model zagrożeń;CHANGELOG.md— zakres wersji 0.2.0.
License
Licensed under Apache-2.0.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file subactor_shell-0.2.2.tar.gz.
File metadata
- Download URL: subactor_shell-0.2.2.tar.gz
- Upload date:
- Size: 92.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.2.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
07b6f97884cc0ac70c4d097b1eaf8f0318054b1536a664794d04797e63cd9bd0
|
|
| MD5 |
217c9ddd726394b63730c8af73abc19f
|
|
| BLAKE2b-256 |
0732c0cf25afbd46ffcd9e6ba5f3429bd1075bdb95a1d7817d5b13379a7ab8be
|
File details
Details for the file subactor_shell-0.2.2-py3-none-any.whl.
File metadata
- Download URL: subactor_shell-0.2.2-py3-none-any.whl
- Upload date:
- Size: 89.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.2.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6136c2c0591484ad856c89cefa6a0a1dbdb7be1b2b329ea9caa71f5c73ed8ad0
|
|
| MD5 |
2e922b0394edf7e2282fc274605977a3
|
|
| BLAKE2b-256 |
6154d1a4c1a0ee06a4163e06e3b136c23cfb295ffd4e859ae67c31550a02c77f
|