heyasa 0.1.1__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.
- heyasa-0.1.1/LICENSE +110 -0
- heyasa-0.1.1/PKG-INFO +53 -0
- heyasa-0.1.1/README.md +33 -0
- heyasa-0.1.1/heyasa/__init__.py +31 -0
- heyasa-0.1.1/heyasa/__main__.py +8 -0
- heyasa-0.1.1/heyasa/cli.py +399 -0
- heyasa-0.1.1/heyasa/config.py +138 -0
- heyasa-0.1.1/heyasa/engines/__init__.py +2 -0
- heyasa-0.1.1/heyasa/engines/base.py +76 -0
- heyasa-0.1.1/heyasa/engines/extended_adapters.py +130 -0
- heyasa-0.1.1/heyasa/engines/subactor_adapter.py +140 -0
- heyasa-0.1.1/heyasa/engines/willman_adapter.py +131 -0
- heyasa-0.1.1/heyasa/engines/willpad_adapter.py +135 -0
- heyasa-0.1.1/heyasa/hud.py +647 -0
- heyasa-0.1.1/heyasa/interfaces/__init__.py +2 -0
- heyasa-0.1.1/heyasa/interfaces/grpc_server.py +138 -0
- heyasa-0.1.1/heyasa/interfaces/mcp_server.py +182 -0
- heyasa-0.1.1/heyasa/interfaces/rest_server.py +148 -0
- heyasa-0.1.1/heyasa/router.py +281 -0
- heyasa-0.1.1/heyasa/shell.py +223 -0
- heyasa-0.1.1/heyasa/standard/__init__.py +2 -0
- heyasa-0.1.1/heyasa/standard/api_registry.py +491 -0
- heyasa-0.1.1/heyasa/standard/governance.py +157 -0
- heyasa-0.1.1/heyasa/standard/nl_pipeline.py +362 -0
- heyasa-0.1.1/heyasa/standard/receipts.py +263 -0
- heyasa-0.1.1/heyasa.egg-info/PKG-INFO +53 -0
- heyasa-0.1.1/heyasa.egg-info/SOURCES.txt +32 -0
- heyasa-0.1.1/heyasa.egg-info/dependency_links.txt +1 -0
- heyasa-0.1.1/heyasa.egg-info/entry_points.txt +3 -0
- heyasa-0.1.1/heyasa.egg-info/requires.txt +15 -0
- heyasa-0.1.1/heyasa.egg-info/top_level.txt +1 -0
- heyasa-0.1.1/pyproject.toml +45 -0
- heyasa-0.1.1/setup.cfg +4 -0
- heyasa-0.1.1/tests/test_heyasa.py +242 -0
heyasa-0.1.1/LICENSE
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
PROPRIETARY AND CONFIDENTIAL SOURCE CODE LICENSE
|
|
2
|
+
STRICT ANTI-AI / ANTI-MINING RESERVATION OF RIGHTS
|
|
3
|
+
|
|
4
|
+
Copyright (c) 2026 Tomasz Sapletta Prototypowanie.pl NIP: 5881918662, REGON: 220665410. All rights reserved.
|
|
5
|
+
Właścicielem oprogramowania jest Tomasz Sapletta Prototypowanie.pl NIP: 5881918662, REGON: 220665410.
|
|
6
|
+
|
|
7
|
+
================================================================================
|
|
8
|
+
IMPORTANT NOTICE - PROPRIETARY AND CONFIDENTIAL
|
|
9
|
+
================================================================================
|
|
10
|
+
|
|
11
|
+
This software, source code, documentation, specifications, schemas, models,
|
|
12
|
+
algorithms, and associated digital assets ("the Software") are the confidential
|
|
13
|
+
and proprietary intellectual property of Tomasz Sapletta Prototypowanie.pl
|
|
14
|
+
(NIP: 5881918662, REGON: 220665410) and its licensors.
|
|
15
|
+
|
|
16
|
+
The Software is NOT licensed under any open source, free software, or
|
|
17
|
+
source-available license (such as MIT, Apache 2.0, BSD, GPL, AGPL, BSL, or SSPL).
|
|
18
|
+
All rights not expressly granted under a separate, signed written commercial
|
|
19
|
+
agreement executed by Tomasz Sapletta Prototypowanie.pl are strictly reserved.
|
|
20
|
+
|
|
21
|
+
================================================================================
|
|
22
|
+
SECTION 1. STRICT PROHIBITION ON ARTIFICIAL INTELLIGENCE & MACHINE LEARNING INGESTION
|
|
23
|
+
================================================================================
|
|
24
|
+
|
|
25
|
+
Under no circumstances may any portion of the Software, whether in human-readable
|
|
26
|
+
source code, compiled binary, abstract syntax tree (AST), intermediate representation,
|
|
27
|
+
documentation, ticket history, or commit metadata, be:
|
|
28
|
+
|
|
29
|
+
1.1. Ingested, scraped, crawled, harvested, indexed, tokenized, cached, or stored
|
|
30
|
+
for the purpose of training, pre-training, fine-tuning, evaluating, or weighting
|
|
31
|
+
any artificial intelligence system, machine learning model, large language
|
|
32
|
+
model (LLM), code-generation model, neural network, diffusion model, or
|
|
33
|
+
multimodal model.
|
|
34
|
+
|
|
35
|
+
1.2. Used by, or fed into the training datasets, prompt contexts, retrieval-augmented
|
|
36
|
+
generation (RAG) stores, vector databases, or telemetry caches of any commercial
|
|
37
|
+
or non-commercial AI system, including but not limited to:
|
|
38
|
+
- GitHub Copilot / Microsoft Copilot (Microsoft Corporation)
|
|
39
|
+
- OpenAI ChatGPT, Codex, GPT-4, GPT-5, o-series, and related APIs (OpenAI Inc.)
|
|
40
|
+
- Google Gemini, PaLM, Codey, Vertex AI, and DeepMind systems (Google LLC / Alphabet)
|
|
41
|
+
- Anthropic Claude, Constitutional AI, and related models (Anthropic PBC)
|
|
42
|
+
- Meta LLaMA, Code Llama, and related foundation models (Meta Platforms, Inc.)
|
|
43
|
+
- Amazon CodeWhisperer, Bedrock, and Titan models (Amazon.com, Inc.)
|
|
44
|
+
- Mistral AI, Cohere, Cursor AI, Tabnine, Replit Ghostwriter, or any automated
|
|
45
|
+
code-synthesis engine or AI coding assistant.
|
|
46
|
+
|
|
47
|
+
1.3. Processed or analyzed by any automated tool, bot, crawler, or scraper to generate
|
|
48
|
+
synthetic code, code suggestions, autocomplete suggestions, embeddings, or
|
|
49
|
+
derivative software models.
|
|
50
|
+
|
|
51
|
+
================================================================================
|
|
52
|
+
SECTION 2. STATUTORY RESERVATION OF RIGHTS (EU DIRECTIVE 2019/790)
|
|
53
|
+
================================================================================
|
|
54
|
+
|
|
55
|
+
2.1. In accordance with Article 4(3) of Directive (EU) 2019/790 of the European
|
|
56
|
+
Parliament and of the Council on copyright and related rights in the Digital
|
|
57
|
+
Single Market, the rights holder hereby EXPRESSLY RESERVES ALL RIGHTS
|
|
58
|
+
regarding Text and Data Mining (TDM) for this Software, its source repositories,
|
|
59
|
+
documentation, schemas, and all associated materials.
|
|
60
|
+
|
|
61
|
+
2.2. Any extraction, automated reading, indexing, or reproduction of the Software
|
|
62
|
+
for text and data mining purposes within the meaning of Directive (EU) 2019/790
|
|
63
|
+
is strictly prohibited without prior written authorization from the rights holder.
|
|
64
|
+
|
|
65
|
+
2.3. This reservation applies worldwide and is declared in machine-readable form
|
|
66
|
+
within the repository metadata, headers, and this License specification.
|
|
67
|
+
|
|
68
|
+
================================================================================
|
|
69
|
+
SECTION 3. HOSTING & PLATFORM PREEMPTION CLAUSE
|
|
70
|
+
================================================================================
|
|
71
|
+
|
|
72
|
+
3.1. The presence of this source code or repository on any third-party hosting service,
|
|
73
|
+
code forge, version control platform, or cloud provider (including but not
|
|
74
|
+
limited to GitHub, GitLab, Bitbucket, or AWS) does NOT constitute a waiver,
|
|
75
|
+
license grant, or implied consent to the hosting provider, its parent,
|
|
76
|
+
subsidiaries, or third parties to:
|
|
77
|
+
(a) use the Software for machine learning training, telemetry harvesting, or
|
|
78
|
+
model improvement;
|
|
79
|
+
(b) distribute or reproduce the Software to other users or automated agents;
|
|
80
|
+
(c) index the Software in any public search or retrieval system.
|
|
81
|
+
|
|
82
|
+
3.2. Any terms of service, platform agreements, or automated licenses purporting
|
|
83
|
+
to grant the platform operator an implied, royalty-free, or transferable
|
|
84
|
+
license to utilize hosted code for artificial intelligence development, model
|
|
85
|
+
training, or feature synthesis are hereby explicitly rejected, preempted,
|
|
86
|
+
and declared null and void with respect to this Software.
|
|
87
|
+
|
|
88
|
+
================================================================================
|
|
89
|
+
SECTION 4. PROHIBITED USES & RESTRICTIONS
|
|
90
|
+
================================================================================
|
|
91
|
+
|
|
92
|
+
Except as expressly authorized under a valid, executed commercial enterprise license
|
|
93
|
+
with Tomasz Sapletta Prototypowanie.pl, you may NOT:
|
|
94
|
+
- Copy, modify, adapt, translate, reverse engineer, decompile, or disassemble the Software.
|
|
95
|
+
- Distribute, sublicense, rent, lease, lend, sell, or publicly display the Software.
|
|
96
|
+
- Use the Software to provide competitive time-sharing, SaaS, cloud twin, or virtualization services.
|
|
97
|
+
- Remove, alter, or obscure any proprietary notices, copyright labels, or license files.
|
|
98
|
+
|
|
99
|
+
================================================================================
|
|
100
|
+
SECTION 5. ENFORCEMENT & REMEDIES
|
|
101
|
+
================================================================================
|
|
102
|
+
|
|
103
|
+
Any breach of this License, including unauthorized scraping, tokenization, or ingestion
|
|
104
|
+
into an artificial intelligence system, constitutes willful copyright infringement,
|
|
105
|
+
unauthorized access, and breach of contract. Tomasz Sapletta Prototypowanie.pl reserves
|
|
106
|
+
the right to seek immediate injunctive relief, statutory damages, compensation for commercial
|
|
107
|
+
harm, and mandatory destruction of all derivative model weights, embeddings, and training
|
|
108
|
+
caches containing representations of the Software.
|
|
109
|
+
|
|
110
|
+
For licensing inquiries and commercial authorization, contact: tom@prototypowanie.pl / legal@clonerd.com
|
heyasa-0.1.1/PKG-INFO
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: heyasa
|
|
3
|
+
Version: 0.1.1
|
|
4
|
+
Summary: Hey Asa — Unified Autonomous CLI Shell & Multi-Protocol Gateway for willman, willpad (willmux), and subactor standardized by wellmanifest/wellman and wellmanifest/nl-*
|
|
5
|
+
Author: Tom Sapletta
|
|
6
|
+
Author-email: Tom Sapletta <tom@sapletta.com>
|
|
7
|
+
License-Expression: Apache-2.0
|
|
8
|
+
Requires-Python: >=3.10
|
|
9
|
+
Description-Content-Type: text/markdown
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Provides-Extra: mcp
|
|
12
|
+
Requires-Dist: mcp>=1.0.0; extra == "mcp"
|
|
13
|
+
Provides-Extra: grpc
|
|
14
|
+
Requires-Dist: grpcio>=1.60.0; extra == "grpc"
|
|
15
|
+
Provides-Extra: dev
|
|
16
|
+
Requires-Dist: pytest>=7.0.0; extra == "dev"
|
|
17
|
+
Requires-Dist: goal>=2.1.0; python_version >= "3.12" and extra == "dev"
|
|
18
|
+
Requires-Dist: costs>=0.1.53; python_version >= "3.9" and extra == "dev"
|
|
19
|
+
Dynamic: license-file
|
|
20
|
+
|
|
21
|
+
# Hey Asa (`heyasa`)
|
|
22
|
+
|
|
23
|
+
**Unified Autonomous CLI Shell & Multi-Protocol Gateway** dla ekosystemów **`willman`**, **`willpad` (`willmux`)** oraz **`subactor`** (a także wtyczek **`dockuri`** i **`taskand`**), ustandaryzowany przez **`wellmanifest/wellman`**, **`wellmanifest/autonomy`** oraz rodzinę **`wellmanifest/nl-*`** (`nl-dsl-llm`, `nl-uri-dsl-llm`, `nl-api-llm`).
|
|
24
|
+
|
|
25
|
+
## Główne właściwości
|
|
26
|
+
|
|
27
|
+
- **Jedna nazwa i marka**: `heyasa` (asystent **Asa**, wake phrase: `Hey Asa`).
|
|
28
|
+
- **Wybór silnika autonomicznego (`-e` / `--engine`)**:
|
|
29
|
+
- `auto` (domyślny — deterministyczny klasyfikator intencji `nl-uri-dsl-llm` + `willuri`),
|
|
30
|
+
- `willman` — kolejka zadań DAG, cykl bodźców Koru (`stimulate`), obserwacyjna samonaprawa (`willman.observation-policy/v1`), flota projektów (`ProjectFleet`), artefakty,
|
|
31
|
+
- `willpad` — sterownik przestrzeni roboczej `willmux` (okna `A`–`F`, centralny pad w trybach `quad`/`radial`/`panel`, kompaktowy czat Table 4, narzędzia okien `shot`/`ocr`/`copy`/`record`, plany z zależnościami `chat_plan`/`chat_run`, Rynek),
|
|
32
|
+
- `subactor` — kontraktowa autonomia z `../subactor` (`IntentIR v1` → `ExecutionPlan` → bramka `AQL` → `OQL` → `urirun`, Founder Control `:8091`, `subactor-shell` ACP/SQLite/Vault),
|
|
33
|
+
- `dockuri` — modularne usługi autonomiczne `proc://.../v1` (`QueueHealService`, `SelfImprovementService`, `FinancialIntegrityService`, `ScannerIndexService`),
|
|
34
|
+
- `taskand` — kapsuły wykonawcze `proc://.../v1` i workflowy przeglądarkowe `task2willmux`.
|
|
35
|
+
- **Domyślne poziomy autonomii (`--autonomy`)**:
|
|
36
|
+
- **Tryb interaktywny (TTY / REPL)**: `confirm` — prezentuje plan i oczekuje na zgodę operatora przed wykonaniem mutacji,
|
|
37
|
+
- **Tryb wsadowy / agentowy (non-TTY / batch)**: `execute-once` — wykonuje maksymalnie jeden atomowy cykl i automatycznie wraca do stanu `safe`,
|
|
38
|
+
- Pozostałe tryby: `suggest` (tylko plan / `--dry-run`) oraz `auto` (w ramach jawnego grantu autonomii).
|
|
39
|
+
- **Wieloprotokołowe interfejsy**:
|
|
40
|
+
- `heyasa [polecenie]` / `heyasa shell` — CLI one-shot oraz interaktywny REPL,
|
|
41
|
+
- `heyasa mcp` — serwer MCP (`stdio` oraz `streamable-http` na `:7081`) zgodny z `NUL-015`,
|
|
42
|
+
- `heyasa serve` — zunifikowany serwer REST + SSE (`:7080`),
|
|
43
|
+
- `heyasa grpc` — serwer gRPC (`:7082` oraz UDS),
|
|
44
|
+
- `heyasa acp` — serwer Agent Client Protocol v1 (`stdin/stdout` JSON-RPC),
|
|
45
|
+
- `heyasa open <uri>` — dispatcher RFC 3986 Action URI (`heyasa://`, `willpad://`, `willmux://`, `willman://`, `subactor://`, `proc://`),
|
|
46
|
+
- `heyasa switch <tool|pane|preset|next|prev>` — błyskawiczne przełączanie narzędzi na ekranie (`chat`, `files`, `willman`, `subactor`, `dockuri`, `approval`, presety `ops`/`dev`/`compact`),
|
|
47
|
+
- `heyasa hud [--top|--bottom|--bench|--export-tauri]` — uruchamianie i przełączanie okna HUD (`willmux` / `willman`) zajmującego maksymalnie **50% wysokości ekranu** (Quake-style scratchpad / Tauri v2 Wry / Chromium `--app`).
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
## License
|
|
52
|
+
|
|
53
|
+
Licensed under Apache-2.0.
|
heyasa-0.1.1/README.md
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# Hey Asa (`heyasa`)
|
|
2
|
+
|
|
3
|
+
**Unified Autonomous CLI Shell & Multi-Protocol Gateway** dla ekosystemów **`willman`**, **`willpad` (`willmux`)** oraz **`subactor`** (a także wtyczek **`dockuri`** i **`taskand`**), ustandaryzowany przez **`wellmanifest/wellman`**, **`wellmanifest/autonomy`** oraz rodzinę **`wellmanifest/nl-*`** (`nl-dsl-llm`, `nl-uri-dsl-llm`, `nl-api-llm`).
|
|
4
|
+
|
|
5
|
+
## Główne właściwości
|
|
6
|
+
|
|
7
|
+
- **Jedna nazwa i marka**: `heyasa` (asystent **Asa**, wake phrase: `Hey Asa`).
|
|
8
|
+
- **Wybór silnika autonomicznego (`-e` / `--engine`)**:
|
|
9
|
+
- `auto` (domyślny — deterministyczny klasyfikator intencji `nl-uri-dsl-llm` + `willuri`),
|
|
10
|
+
- `willman` — kolejka zadań DAG, cykl bodźców Koru (`stimulate`), obserwacyjna samonaprawa (`willman.observation-policy/v1`), flota projektów (`ProjectFleet`), artefakty,
|
|
11
|
+
- `willpad` — sterownik przestrzeni roboczej `willmux` (okna `A`–`F`, centralny pad w trybach `quad`/`radial`/`panel`, kompaktowy czat Table 4, narzędzia okien `shot`/`ocr`/`copy`/`record`, plany z zależnościami `chat_plan`/`chat_run`, Rynek),
|
|
12
|
+
- `subactor` — kontraktowa autonomia z `../subactor` (`IntentIR v1` → `ExecutionPlan` → bramka `AQL` → `OQL` → `urirun`, Founder Control `:8091`, `subactor-shell` ACP/SQLite/Vault),
|
|
13
|
+
- `dockuri` — modularne usługi autonomiczne `proc://.../v1` (`QueueHealService`, `SelfImprovementService`, `FinancialIntegrityService`, `ScannerIndexService`),
|
|
14
|
+
- `taskand` — kapsuły wykonawcze `proc://.../v1` i workflowy przeglądarkowe `task2willmux`.
|
|
15
|
+
- **Domyślne poziomy autonomii (`--autonomy`)**:
|
|
16
|
+
- **Tryb interaktywny (TTY / REPL)**: `confirm` — prezentuje plan i oczekuje na zgodę operatora przed wykonaniem mutacji,
|
|
17
|
+
- **Tryb wsadowy / agentowy (non-TTY / batch)**: `execute-once` — wykonuje maksymalnie jeden atomowy cykl i automatycznie wraca do stanu `safe`,
|
|
18
|
+
- Pozostałe tryby: `suggest` (tylko plan / `--dry-run`) oraz `auto` (w ramach jawnego grantu autonomii).
|
|
19
|
+
- **Wieloprotokołowe interfejsy**:
|
|
20
|
+
- `heyasa [polecenie]` / `heyasa shell` — CLI one-shot oraz interaktywny REPL,
|
|
21
|
+
- `heyasa mcp` — serwer MCP (`stdio` oraz `streamable-http` na `:7081`) zgodny z `NUL-015`,
|
|
22
|
+
- `heyasa serve` — zunifikowany serwer REST + SSE (`:7080`),
|
|
23
|
+
- `heyasa grpc` — serwer gRPC (`:7082` oraz UDS),
|
|
24
|
+
- `heyasa acp` — serwer Agent Client Protocol v1 (`stdin/stdout` JSON-RPC),
|
|
25
|
+
- `heyasa open <uri>` — dispatcher RFC 3986 Action URI (`heyasa://`, `willpad://`, `willmux://`, `willman://`, `subactor://`, `proc://`),
|
|
26
|
+
- `heyasa switch <tool|pane|preset|next|prev>` — błyskawiczne przełączanie narzędzi na ekranie (`chat`, `files`, `willman`, `subactor`, `dockuri`, `approval`, presety `ops`/`dev`/`compact`),
|
|
27
|
+
- `heyasa hud [--top|--bottom|--bench|--export-tauri]` — uruchamianie i przełączanie okna HUD (`willmux` / `willman`) zajmującego maksymalnie **50% wysokości ekranu** (Quake-style scratchpad / Tauri v2 Wry / Chromium `--app`).
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
## License
|
|
32
|
+
|
|
33
|
+
Licensed under Apache-2.0.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"""Hey Asa — Unified Autonomous CLI Shell & Multi-Protocol Gateway."""
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
from .hud import (
|
|
5
|
+
HalfScreenWindowManager,
|
|
6
|
+
ScreenGeometry,
|
|
7
|
+
ToolSwitcher,
|
|
8
|
+
compute_half_screen_geometry,
|
|
9
|
+
launch_hud,
|
|
10
|
+
switch_tool,
|
|
11
|
+
)
|
|
12
|
+
from .router import HeyasaRouter
|
|
13
|
+
|
|
14
|
+
__version__ = "0.1.1"
|
|
15
|
+
__brand__ = "heyasa"
|
|
16
|
+
__assistant__ = "Asa"
|
|
17
|
+
__wake_phrase__ = "Hey Asa"
|
|
18
|
+
|
|
19
|
+
__all__ = [
|
|
20
|
+
"__version__",
|
|
21
|
+
"__brand__",
|
|
22
|
+
"__assistant__",
|
|
23
|
+
"__wake_phrase__",
|
|
24
|
+
"HeyasaRouter",
|
|
25
|
+
"ToolSwitcher",
|
|
26
|
+
"HalfScreenWindowManager",
|
|
27
|
+
"ScreenGeometry",
|
|
28
|
+
"compute_half_screen_geometry",
|
|
29
|
+
"switch_tool",
|
|
30
|
+
"launch_hud",
|
|
31
|
+
]
|
|
@@ -0,0 +1,399 @@
|
|
|
1
|
+
"""CLI entrypoint for `heyasa` — Unified Autonomous CLI Shell & Multi-Protocol Gateway."""
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
import argparse
|
|
5
|
+
import json
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
import sys
|
|
8
|
+
from typing import List, Optional
|
|
9
|
+
|
|
10
|
+
from .config import (
|
|
11
|
+
AUTONOMY_MODES,
|
|
12
|
+
ENGINE_CHOICES,
|
|
13
|
+
PROTOCOL_CHOICES,
|
|
14
|
+
WILLPAD_STYLES,
|
|
15
|
+
WILLPAD_TOOLS,
|
|
16
|
+
HeyasaConfig,
|
|
17
|
+
default_autonomy_mode,
|
|
18
|
+
)
|
|
19
|
+
from .hud import (
|
|
20
|
+
TOOL_TARGETS,
|
|
21
|
+
WINDOW_RUNTIMES_BENCHMARK,
|
|
22
|
+
WORKSPACE_PRESETS,
|
|
23
|
+
HalfScreenWindowManager,
|
|
24
|
+
ToolSwitcher,
|
|
25
|
+
)
|
|
26
|
+
from .interfaces.grpc_server import HEYASA_PROTO_SPEC, HeyasaGrpcService, serve_acp_stdio
|
|
27
|
+
from .interfaces.mcp_server import build_mcp_gateway_manifest, serve_mcp
|
|
28
|
+
from .interfaces.rest_server import serve_rest
|
|
29
|
+
from .router import HeyasaRouter
|
|
30
|
+
from .shell import format_engines_table, run_interactive_shell
|
|
31
|
+
from .standard.governance import run_wellman_governance
|
|
32
|
+
|
|
33
|
+
KNOWN_SUBCOMMANDS = {
|
|
34
|
+
"shell",
|
|
35
|
+
"engines",
|
|
36
|
+
"status",
|
|
37
|
+
"switch",
|
|
38
|
+
"hud",
|
|
39
|
+
"window",
|
|
40
|
+
"willpad",
|
|
41
|
+
"willman",
|
|
42
|
+
"subactor",
|
|
43
|
+
"dockuri",
|
|
44
|
+
"taskand",
|
|
45
|
+
"plan",
|
|
46
|
+
"run",
|
|
47
|
+
"dsl",
|
|
48
|
+
"uri",
|
|
49
|
+
"open",
|
|
50
|
+
"catalog",
|
|
51
|
+
"snapshot",
|
|
52
|
+
"receipts",
|
|
53
|
+
"gov",
|
|
54
|
+
"serve",
|
|
55
|
+
"mcp",
|
|
56
|
+
"grpc",
|
|
57
|
+
"acp",
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def build_parser() -> argparse.ArgumentParser:
|
|
62
|
+
parser = argparse.ArgumentParser(
|
|
63
|
+
prog="heyasa",
|
|
64
|
+
description=(
|
|
65
|
+
"Hey Asa (heyasa) — Zunifikowany CLI Shell i brama wieloprotokołowa dla "
|
|
66
|
+
"willman, willpad (willmux), subactor, dockuri i taskand."
|
|
67
|
+
),
|
|
68
|
+
)
|
|
69
|
+
parser.add_argument(
|
|
70
|
+
"-e",
|
|
71
|
+
"--engine",
|
|
72
|
+
choices=ENGINE_CHOICES,
|
|
73
|
+
default="auto",
|
|
74
|
+
help="Wybór silnika autonomicznego (domyślnie: auto)",
|
|
75
|
+
)
|
|
76
|
+
parser.add_argument(
|
|
77
|
+
"-a",
|
|
78
|
+
"--autonomy",
|
|
79
|
+
choices=AUTONOMY_MODES,
|
|
80
|
+
default=None,
|
|
81
|
+
help="Poziom autonomii: suggest, confirm (domyślny interaktywnie), execute-once (domyślny wsadowo), auto",
|
|
82
|
+
)
|
|
83
|
+
parser.add_argument(
|
|
84
|
+
"-p",
|
|
85
|
+
"--protocol",
|
|
86
|
+
choices=PROTOCOL_CHOICES,
|
|
87
|
+
default="auto",
|
|
88
|
+
help="Preferowany interfejs komunikacji z silnikiem (auto, shell, rest, mcp, grpc, acp, uri)",
|
|
89
|
+
)
|
|
90
|
+
parser.add_argument(
|
|
91
|
+
"-y",
|
|
92
|
+
"--yes",
|
|
93
|
+
action="store_true",
|
|
94
|
+
help="Potwierdź wykonanie planu zmieniającego stan (dla trybu confirm)",
|
|
95
|
+
)
|
|
96
|
+
parser.add_argument(
|
|
97
|
+
"--dry-run",
|
|
98
|
+
action="store_true",
|
|
99
|
+
help="Alias dla --autonomy suggest (tylko kompilacja planu i Action URI bez wykonania)",
|
|
100
|
+
)
|
|
101
|
+
parser.add_argument(
|
|
102
|
+
"--json",
|
|
103
|
+
action="store_true",
|
|
104
|
+
help="Wypisz odpowiedź jako sformatowany JSON",
|
|
105
|
+
)
|
|
106
|
+
return parser
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
def main(argv: Optional[List[str]] = None) -> int:
|
|
110
|
+
raw_argv = list(sys.argv[1:] if argv is None else argv)
|
|
111
|
+
config = HeyasaConfig()
|
|
112
|
+
router = HeyasaRouter(config)
|
|
113
|
+
|
|
114
|
+
if not raw_argv:
|
|
115
|
+
if sys.stdin and sys.stdin.isatty():
|
|
116
|
+
return run_interactive_shell(router, initial_engine="auto", initial_autonomy="confirm")
|
|
117
|
+
raw_argv = ["status", "--json"]
|
|
118
|
+
|
|
119
|
+
# Parse global flags + positional tokens flexibly so both `heyasa "zdanie"` and `heyasa subcmd ...` work
|
|
120
|
+
parser = build_parser()
|
|
121
|
+
known, rest = parser.parse_known_args(raw_argv)
|
|
122
|
+
|
|
123
|
+
autonomy = "suggest" if known.dry_run else (known.autonomy or default_autonomy_mode())
|
|
124
|
+
engine = known.engine
|
|
125
|
+
protocol = known.protocol
|
|
126
|
+
confirmed = known.yes
|
|
127
|
+
|
|
128
|
+
if not rest:
|
|
129
|
+
return run_interactive_shell(
|
|
130
|
+
router,
|
|
131
|
+
initial_engine=engine,
|
|
132
|
+
initial_autonomy=autonomy,
|
|
133
|
+
initial_protocol=protocol,
|
|
134
|
+
)
|
|
135
|
+
|
|
136
|
+
subcmd = rest[0]
|
|
137
|
+
sub_args = rest[1:]
|
|
138
|
+
|
|
139
|
+
if subcmd == "shell":
|
|
140
|
+
return run_interactive_shell(
|
|
141
|
+
router,
|
|
142
|
+
initial_engine=engine,
|
|
143
|
+
initial_autonomy=known.autonomy or "confirm",
|
|
144
|
+
initial_protocol=protocol,
|
|
145
|
+
)
|
|
146
|
+
|
|
147
|
+
if subcmd in ("engines", "status"):
|
|
148
|
+
statuses = router.list_engines_status()
|
|
149
|
+
if known.json:
|
|
150
|
+
print(
|
|
151
|
+
json.dumps(
|
|
152
|
+
{
|
|
153
|
+
"schema": "heyasa.status/v1",
|
|
154
|
+
"brand": "heyasa",
|
|
155
|
+
"assistant": "Asa",
|
|
156
|
+
"wake_phrase": "Hey Asa",
|
|
157
|
+
"default_autonomy_interactive": "confirm",
|
|
158
|
+
"default_autonomy_batch": "execute-once",
|
|
159
|
+
"active_autonomy": autonomy,
|
|
160
|
+
"engines": statuses,
|
|
161
|
+
},
|
|
162
|
+
ensure_ascii=False,
|
|
163
|
+
indent=2,
|
|
164
|
+
)
|
|
165
|
+
)
|
|
166
|
+
else:
|
|
167
|
+
print(format_engines_table(router))
|
|
168
|
+
return 0
|
|
169
|
+
|
|
170
|
+
if subcmd == "dsl":
|
|
171
|
+
query = " ".join(sub_args).strip()
|
|
172
|
+
res = router.pipeline.interpret(query, engine_override=engine, language=config.language)
|
|
173
|
+
print(json.dumps(res, ensure_ascii=False, indent=2))
|
|
174
|
+
return 0
|
|
175
|
+
|
|
176
|
+
if subcmd in ("uri", "open"):
|
|
177
|
+
target_uri = sub_args[0] if sub_args else "heyasa://willpad/pane/focus?pane=A"
|
|
178
|
+
receipt = router.dispatch(
|
|
179
|
+
target_uri,
|
|
180
|
+
engine=engine,
|
|
181
|
+
protocol=protocol,
|
|
182
|
+
autonomy_mode=autonomy,
|
|
183
|
+
confirmed=confirmed or (autonomy == "execute-once"),
|
|
184
|
+
origin="uri",
|
|
185
|
+
)
|
|
186
|
+
print(json.dumps(receipt, ensure_ascii=False, indent=2))
|
|
187
|
+
return 0
|
|
188
|
+
|
|
189
|
+
if subcmd == "plan":
|
|
190
|
+
query = " ".join(sub_args).strip()
|
|
191
|
+
plan = router.compile_plan(query, engine=engine, autonomy_mode=autonomy)
|
|
192
|
+
print(json.dumps(plan, ensure_ascii=False, indent=2))
|
|
193
|
+
return 0
|
|
194
|
+
|
|
195
|
+
if subcmd == "run":
|
|
196
|
+
if not sub_args:
|
|
197
|
+
print("heyasa: podaj ID planu lub polecenie do uruchomienia", file=sys.stderr)
|
|
198
|
+
return 2
|
|
199
|
+
plan_id = sub_args[0]
|
|
200
|
+
if plan_id in router.plans:
|
|
201
|
+
receipt = router.run_plan(plan_id, confirmed=True, autonomy_mode=autonomy, protocol=protocol)
|
|
202
|
+
else:
|
|
203
|
+
receipt = router.dispatch(
|
|
204
|
+
" ".join(sub_args),
|
|
205
|
+
engine=engine,
|
|
206
|
+
protocol=protocol,
|
|
207
|
+
autonomy_mode=autonomy,
|
|
208
|
+
confirmed=True,
|
|
209
|
+
origin="cli",
|
|
210
|
+
)
|
|
211
|
+
print(json.dumps(receipt, ensure_ascii=False, indent=2))
|
|
212
|
+
return 0
|
|
213
|
+
|
|
214
|
+
if subcmd == "switch":
|
|
215
|
+
switcher = ToolSwitcher(router)
|
|
216
|
+
if not sub_args or sub_args[0] in ("--list", "list"):
|
|
217
|
+
print(
|
|
218
|
+
json.dumps(
|
|
219
|
+
{"tools": TOOL_TARGETS, "presets": WORKSPACE_PRESETS},
|
|
220
|
+
ensure_ascii=False,
|
|
221
|
+
indent=2,
|
|
222
|
+
)
|
|
223
|
+
)
|
|
224
|
+
return 0
|
|
225
|
+
target = sub_args[0]
|
|
226
|
+
pane = sub_args[1] if len(sub_args) > 1 and len(sub_args[1]) == 1 else None
|
|
227
|
+
res = switcher.switch(target, pane=pane)
|
|
228
|
+
print(json.dumps(res, ensure_ascii=False, indent=2))
|
|
229
|
+
return 0
|
|
230
|
+
|
|
231
|
+
if subcmd in ("hud", "window"):
|
|
232
|
+
wm = HalfScreenWindowManager(config)
|
|
233
|
+
if "--bench" in sub_args or "bench" in sub_args:
|
|
234
|
+
print(json.dumps({"runtimes": WINDOW_RUNTIMES_BENCHMARK}, ensure_ascii=False, indent=2))
|
|
235
|
+
return 0
|
|
236
|
+
for i, tok in enumerate(sub_args):
|
|
237
|
+
if tok == "--export-tauri":
|
|
238
|
+
out_dir = Path(sub_args[i + 1]) if i + 1 < len(sub_args) else (Path.cwd() / "heyasa-tauri-hud")
|
|
239
|
+
print(json.dumps(wm.export_tauri_v2_scaffold(out_dir), ensure_ascii=False, indent=2))
|
|
240
|
+
return 0
|
|
241
|
+
position = "top" if "--top" in sub_args else "bottom"
|
|
242
|
+
target_app = "willman" if "willman" in sub_args else "willmux"
|
|
243
|
+
dry = known.dry_run or "--dry-run" in sub_args or "--geometry" in sub_args
|
|
244
|
+
res = wm.launch_or_toggle(target=target_app, position=position, height_ratio=0.48, dry_run=dry)
|
|
245
|
+
print(json.dumps(res, ensure_ascii=False, indent=2))
|
|
246
|
+
return 0
|
|
247
|
+
|
|
248
|
+
if subcmd == "willpad":
|
|
249
|
+
return _handle_willpad_subcommand(router, sub_args, protocol=protocol, as_json=known.json)
|
|
250
|
+
|
|
251
|
+
if subcmd in ("willman", "subactor", "dockuri", "taskand"):
|
|
252
|
+
query = " ".join(sub_args).strip() or "status"
|
|
253
|
+
receipt = router.dispatch(
|
|
254
|
+
query,
|
|
255
|
+
engine=subcmd,
|
|
256
|
+
protocol=protocol,
|
|
257
|
+
autonomy_mode=autonomy,
|
|
258
|
+
confirmed=confirmed,
|
|
259
|
+
origin="cli",
|
|
260
|
+
)
|
|
261
|
+
_print_receipt(receipt, as_json=known.json)
|
|
262
|
+
return 0
|
|
263
|
+
|
|
264
|
+
if subcmd == "catalog":
|
|
265
|
+
fmt = "json" if known.json else "table"
|
|
266
|
+
for i, tok in enumerate(sub_args):
|
|
267
|
+
if tok in ("--format", "-f") and i + 1 < len(sub_args):
|
|
268
|
+
fmt = sub_args[i + 1]
|
|
269
|
+
if fmt == "gbnf":
|
|
270
|
+
print(router.registry.export_gbnf_grammar(engine))
|
|
271
|
+
return 0
|
|
272
|
+
manifest = router.registry.export_nl_api_manifest(engine)
|
|
273
|
+
if fmt in ("json", "nl-api"):
|
|
274
|
+
print(json.dumps(manifest, ensure_ascii=False, indent=2))
|
|
275
|
+
else:
|
|
276
|
+
print(f"{'ENGINE':<10} {'ACTION URI':<44} {'EFFECT':<8} {'RISK':<7} {'OPIS'}")
|
|
277
|
+
print("-" * 105)
|
|
278
|
+
for ep in manifest["endpoints"]:
|
|
279
|
+
print(
|
|
280
|
+
f"{ep['engine']:<10} {ep['native_uri']:<44} {ep['effect']:<8} {ep['risk']:<7} {ep['summary_pl']}"
|
|
281
|
+
)
|
|
282
|
+
return 0
|
|
283
|
+
|
|
284
|
+
if subcmd == "snapshot":
|
|
285
|
+
snap = router.snapshot(engine=engine, autonomy=autonomy)
|
|
286
|
+
print(json.dumps(snap, ensure_ascii=False, indent=2))
|
|
287
|
+
return 0
|
|
288
|
+
|
|
289
|
+
if subcmd == "receipts":
|
|
290
|
+
limit = 20
|
|
291
|
+
items = router.receipt_store.list_receipts(limit=limit, engine=engine)
|
|
292
|
+
print(json.dumps({"receipts": items}, ensure_ascii=False, indent=2))
|
|
293
|
+
return 0
|
|
294
|
+
|
|
295
|
+
if subcmd == "gov":
|
|
296
|
+
action = sub_args[0] if sub_args else "standards"
|
|
297
|
+
root = Path.cwd()
|
|
298
|
+
res = run_wellman_governance(action, root=root)
|
|
299
|
+
print(json.dumps(res, ensure_ascii=False, indent=2))
|
|
300
|
+
return 0
|
|
301
|
+
|
|
302
|
+
if subcmd == "serve":
|
|
303
|
+
port = config.rest_port
|
|
304
|
+
host = config.rest_host
|
|
305
|
+
for i, tok in enumerate(sub_args):
|
|
306
|
+
if tok == "--port" and i + 1 < len(sub_args):
|
|
307
|
+
port = int(sub_args[i + 1])
|
|
308
|
+
elif tok == "--host" and i + 1 < len(sub_args):
|
|
309
|
+
host = sub_args[i + 1]
|
|
310
|
+
return serve_rest(router, host=host, port=port)
|
|
311
|
+
|
|
312
|
+
if subcmd == "mcp":
|
|
313
|
+
if "--manifest" in sub_args or known.json:
|
|
314
|
+
print(json.dumps(build_mcp_gateway_manifest(router), ensure_ascii=False, indent=2))
|
|
315
|
+
return 0
|
|
316
|
+
transport = "streamable-http" if "--http" in sub_args else "stdio"
|
|
317
|
+
return serve_mcp(router, transport=transport, host=config.rest_host, port=config.mcp_port)
|
|
318
|
+
|
|
319
|
+
if subcmd == "grpc":
|
|
320
|
+
if "--proto" in sub_args:
|
|
321
|
+
print(HEYASA_PROTO_SPEC)
|
|
322
|
+
return 0
|
|
323
|
+
svc = HeyasaGrpcService(router)
|
|
324
|
+
print(json.dumps({"service": "heyasa.v1.HeyasaService", "port": config.grpc_port, "state": svc.get_state()}, ensure_ascii=False, indent=2))
|
|
325
|
+
return 0
|
|
326
|
+
|
|
327
|
+
if subcmd == "acp":
|
|
328
|
+
return serve_acp_stdio(router)
|
|
329
|
+
|
|
330
|
+
# Free-form natural language sentence or DSL command
|
|
331
|
+
full_text = " ".join(rest).strip()
|
|
332
|
+
receipt = router.dispatch(
|
|
333
|
+
full_text,
|
|
334
|
+
engine=engine,
|
|
335
|
+
protocol=protocol,
|
|
336
|
+
autonomy_mode=autonomy,
|
|
337
|
+
confirmed=confirmed,
|
|
338
|
+
origin="cli",
|
|
339
|
+
)
|
|
340
|
+
_print_receipt(receipt, as_json=known.json)
|
|
341
|
+
return 0
|
|
342
|
+
|
|
343
|
+
|
|
344
|
+
def _handle_willpad_subcommand(
|
|
345
|
+
router: HeyasaRouter,
|
|
346
|
+
sub_args: List[str],
|
|
347
|
+
*,
|
|
348
|
+
protocol: str = "auto",
|
|
349
|
+
as_json: bool = False,
|
|
350
|
+
) -> int:
|
|
351
|
+
if not sub_args:
|
|
352
|
+
st = router.willpad.status()
|
|
353
|
+
print(json.dumps(st, ensure_ascii=False, indent=2))
|
|
354
|
+
return 0
|
|
355
|
+
|
|
356
|
+
verb = sub_args[0].lower()
|
|
357
|
+
if verb == "focus":
|
|
358
|
+
pane = sub_args[1].upper() if len(sub_args) > 1 else "A"
|
|
359
|
+
uri = f"willpad://pane/focus?pane={pane}"
|
|
360
|
+
elif verb == "style":
|
|
361
|
+
style = sub_args[1].lower() if len(sub_args) > 1 and sub_args[1].lower() in WILLPAD_STYLES else "quad"
|
|
362
|
+
uri = f"willpad://menu/style?style={style}"
|
|
363
|
+
elif verb == "layout":
|
|
364
|
+
layout = sub_args[1].lower() if len(sub_args) > 1 else "grid"
|
|
365
|
+
uri = f"willpad://layout/set?layout={layout}"
|
|
366
|
+
elif verb == "compact":
|
|
367
|
+
mode = sub_args[1].lower() if len(sub_args) > 1 else "compact"
|
|
368
|
+
uri = f"willpad://chat/compact?mode={mode}"
|
|
369
|
+
elif verb == "tool":
|
|
370
|
+
pane = sub_args[1].upper() if len(sub_args) > 1 else "B"
|
|
371
|
+
tool = sub_args[2].lower() if len(sub_args) > 2 and sub_args[2].lower() in WILLPAD_TOOLS else "shot"
|
|
372
|
+
uri = f"willpad://window/tool?pane={pane}&tool={tool}"
|
|
373
|
+
else:
|
|
374
|
+
uri = " ".join(sub_args)
|
|
375
|
+
|
|
376
|
+
receipt = router.dispatch(
|
|
377
|
+
uri,
|
|
378
|
+
engine="willpad",
|
|
379
|
+
protocol=protocol,
|
|
380
|
+
autonomy_mode="auto",
|
|
381
|
+
confirmed=True,
|
|
382
|
+
origin="cli",
|
|
383
|
+
)
|
|
384
|
+
_print_receipt(receipt, as_json=as_json)
|
|
385
|
+
return 0
|
|
386
|
+
|
|
387
|
+
|
|
388
|
+
def _print_receipt(receipt: dict, *, as_json: bool = False) -> None:
|
|
389
|
+
if as_json:
|
|
390
|
+
print(json.dumps(receipt, ensure_ascii=False, indent=2))
|
|
391
|
+
return
|
|
392
|
+
card = receipt.get("chat_card") or {}
|
|
393
|
+
print(f"[{receipt['engine']} | {receipt['autonomy_mode']} -> {receipt['post_execution_state']}] {card.get('summary', '')}")
|
|
394
|
+
print(f" URI: {receipt['resolved_action_uri']}")
|
|
395
|
+
print(f" Receipt: {receipt['receipt_ref']} ({receipt['process_urn']})")
|
|
396
|
+
if receipt["status"] == "pending_approval":
|
|
397
|
+
plan = (receipt.get("result") or {}).get("plan") or {}
|
|
398
|
+
if plan.get("id"):
|
|
399
|
+
print(f" Zatwierdź: heyasa run {plan['id']} --yes")
|