Skip to main content

Subactor Shell 0.2.2

AI Cost Tracking

PyPI Version Python License AI Cost Human Time Model

  • 🤖 LLM usage: $0.3788 (7 commits)
  • 👤 Human dev: ~$2968 (29.7h @ $100/h, 30min dedup)

Generated on 2026-09-03 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 v1 zamiast swobodnego planowania w prozie;
  • routing: deterministic/cache → local 4B → cheap remote → large/chat provider;
  • ExecutionPlan tworzony wyłącznie przez lokalny kompilator;
  • nazwane connectory builtin, Subactor Control, process oraz HTTP;
  • brak shell=True i brak możliwości wskazania przez model dowolnej komendy;
  • plan hash, fingerprint stanu i jawne EXECUTE dla operacji zmieniających stan;
  • ExecutionReceipt zamiast 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

Jednolinijkowy instalator (zalecane)

Mac / Linux:

curl -fsSL https://subactor.github.io/shell/install.sh | sh

Windows:

powershell -ExecutionPolicy ByPass -c "irm https://subactor.github.io/shell/install.ps1 | iex"

Instalator domyślnie pobiera metadane z subactor.github.io/shell i w razie problemu przechodzi na GitHub Releases. Aby wymusić GitHub Releases:

curl -fsSL https://subactor.github.io/shell/install.sh | SUBACTOR_SHELL_INSTALLER_USE_GITHUB_IO=false sh
$env:SUBACTOR_SHELL_INSTALLER_USE_GITHUB_IO='false'; irm https://subactor.github.io/shell/install.ps1 | iex

Wymagania: Python 3.11+. Instalator tworzy izolowane środowisko w ~/.local/share/subactor-shell/venv i linkuje subactor-shell do ~/.local/bin.

Z wheel lub źródeł

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.

Scope node, konto GitHub i źródła konfiguracji

Shell pobiera wspólną, pozbawioną sekretów projekcję z usługi subactor/config. Po uruchomieniu jej lokalnego endpointu można sprawdzić bieżący komputer, osobno scope kodu i danych, ustawienia konta oraz federacyjny katalog właścicieli konfiguracji:

subactor-shell scope --node current
subactor-shell scope --node current --kind code --json
subactor-shell scope --node current --kind data
subactor-shell account github
subactor-shell account github --json
subactor-shell source list
subactor-shell source list --provides configuration.propose --json
subactor-shell source show credential-vault
subactor-shell resolve credential.metadata

Endpoint jest jawnie konfigurowany w ~/.config/subactor-shell/config.toml:

[system_config]
base_url = "http://127.0.0.1:8198"
timeout_seconds = 5.0

Port 8198 jest kanonicznym bindingiem subactor/config; 8098 pozostaje zajęty przez lokalny LLM Gateway.

Wynik konta pokazuje tylko skonfigurowany podmiot, znormalizowany stan uwierzytelnienia oraz bezpieczne lokalizacje ustawień. Token ani surowy wynik gh auth status nie są zwracane.

Resolver zwraca źródła, ich właścicieli i dostępność na bieżącym node. Wynik ma authority=evidence-only: pełny zakres decyzji Supervisora nie zastępuje zewnętrznego grantu wymaganego do mutacji.

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ą:

  1. status planu;
  2. plan_hash;
  3. dokładne EXECUTE dla zmian stanu;
  4. aktualny fingerprint SQLite, katalogu intentów i registry connectorów;
  5. allowlista connectora i operation;
  6. 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 deterministic i cache bez 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.

Metadata

Release files for subactor-shell 0.2.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for subactor-shell 0.2.3
File Size Uploaded
subactor_shell-0.2.3.tar.gz 115.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for subactor-shell 0.2.3
File Interpreter ABI Platform
subactor_shell-0.2.3-py3-none-any.whl Python 3 none any Details

Total release size: 222.6 kB

Release files / subactor_shell-0.2.3.tar.gz

Download URL subactor_shell-0.2.3.tar.gz
Size 115.8 kB
Tags Source
SHA-256 checksum
How to use checksums
f8b9187ea4517d6b14b097e9608dbf39cbaa9d9ca82f17d5128f26ce47e01ceb
BLAKE2b-256 checksum
How to use checksums
85bee6026a944be0c012b97ffbd660869576dc223cf52044dce9573fc468dfcf
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.7

Release files / subactor_shell-0.2.3-py3-none-any.whl

Download URL subactor_shell-0.2.3-py3-none-any.whl
Size 106.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
e704477486f3d94399860e20174a095546c2c14789a6abab396da099b4c29daf
BLAKE2b-256 checksum
How to use checksums
37409682e5a081619ab267c4ba36775e2b9cbdff0877bcfb8de9361daac90d7b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.7

Release history Release notifications | RSS feed

This release

0.2.3 This release

2 release files

0.2.2

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page