anna-app-core 0.2.0a1__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.
- anna_app_core-0.2.0a1/.gitignore +167 -0
- anna_app_core-0.2.0a1/PKG-INFO +38 -0
- anna_app_core-0.2.0a1/README.md +26 -0
- anna_app_core-0.2.0a1/pyproject.toml +25 -0
- anna_app_core-0.2.0a1/src/anna_app_core/__init__.py +58 -0
- anna_app_core-0.2.0a1/src/anna_app_core/acl.py +66 -0
- anna_app_core-0.2.0a1/src/anna_app_core/dispatcher.py +505 -0
- anna_app_core-0.2.0a1/src/anna_app_core/errors.py +33 -0
- anna_app_core-0.2.0a1/src/anna_app_core/manifest.py +163 -0
- anna_app_core-0.2.0a1/src/anna_app_core/protocols.py +50 -0
- anna_app_core-0.2.0a1/src/anna_app_core/runtime.py +73 -0
- anna_app_core-0.2.0a1/src/anna_app_core/versions.py +9 -0
- anna_app_core-0.2.0a1/tests/test_smoke.py +242 -0
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
# matrix agent repository
|
|
2
|
+
matrix/
|
|
3
|
+
|
|
4
|
+
# git diff files
|
|
5
|
+
git.diff
|
|
6
|
+
|
|
7
|
+
# Byte-compiled / optimized / DLL files
|
|
8
|
+
__pycache__/
|
|
9
|
+
*.py[cod]
|
|
10
|
+
*$py.class
|
|
11
|
+
|
|
12
|
+
# C extensions
|
|
13
|
+
*.so
|
|
14
|
+
|
|
15
|
+
# Distribution / packaging
|
|
16
|
+
.Python
|
|
17
|
+
build/
|
|
18
|
+
develop-eggs/
|
|
19
|
+
dist/
|
|
20
|
+
downloads/
|
|
21
|
+
eggs/
|
|
22
|
+
.eggs/
|
|
23
|
+
lib/
|
|
24
|
+
lib64/
|
|
25
|
+
parts/
|
|
26
|
+
sdist/
|
|
27
|
+
var/
|
|
28
|
+
wheels/
|
|
29
|
+
share/python-wheels/
|
|
30
|
+
*.egg-info/
|
|
31
|
+
.installed.cfg
|
|
32
|
+
*.egg
|
|
33
|
+
# setuptools sdist MANIFEST (only at repo root — must NOT swallow the
|
|
34
|
+
# packages/anna-app-schema/manifest/ schema bundle directory).
|
|
35
|
+
/MANIFEST
|
|
36
|
+
|
|
37
|
+
# PyInstaller
|
|
38
|
+
# Anchored to repo root for the same reason — `*.manifest` is too broad
|
|
39
|
+
# and was matching schema bundle files. Re-add specific paths if a real
|
|
40
|
+
# PyInstaller .manifest ever ships.
|
|
41
|
+
/*.manifest
|
|
42
|
+
*.spec
|
|
43
|
+
|
|
44
|
+
# Installer logs
|
|
45
|
+
pip-log.txt
|
|
46
|
+
pip-delete-this-directory.txt
|
|
47
|
+
|
|
48
|
+
# Unit test / coverage reports
|
|
49
|
+
htmlcov/
|
|
50
|
+
.tox/
|
|
51
|
+
.nox/
|
|
52
|
+
.coverage
|
|
53
|
+
.coverage.*
|
|
54
|
+
.cache
|
|
55
|
+
nosetests.xml
|
|
56
|
+
coverage.xml
|
|
57
|
+
*.cover
|
|
58
|
+
*.py,cover
|
|
59
|
+
.hypothesis/
|
|
60
|
+
.pytest_cache/
|
|
61
|
+
cover/
|
|
62
|
+
|
|
63
|
+
# Translations
|
|
64
|
+
*.mo
|
|
65
|
+
*.pot
|
|
66
|
+
|
|
67
|
+
# Django stuff:
|
|
68
|
+
*.log
|
|
69
|
+
local_settings.py
|
|
70
|
+
db.sqlite3
|
|
71
|
+
db.sqlite3-journal
|
|
72
|
+
|
|
73
|
+
# Flask stuff:
|
|
74
|
+
instance/
|
|
75
|
+
.webassets-cache
|
|
76
|
+
|
|
77
|
+
# Scrapy stuff:
|
|
78
|
+
.scrapy
|
|
79
|
+
|
|
80
|
+
# Sphinx documentation
|
|
81
|
+
docs/_build/
|
|
82
|
+
|
|
83
|
+
# PyBuilder
|
|
84
|
+
.pybuilder/
|
|
85
|
+
target/
|
|
86
|
+
|
|
87
|
+
# Jupyter Notebook
|
|
88
|
+
.ipynb_checkpoints
|
|
89
|
+
|
|
90
|
+
# IPython
|
|
91
|
+
profile_default/
|
|
92
|
+
ipython_config.py
|
|
93
|
+
|
|
94
|
+
# pyenv
|
|
95
|
+
.python-version
|
|
96
|
+
|
|
97
|
+
# pipenv
|
|
98
|
+
Pipfile.lock
|
|
99
|
+
|
|
100
|
+
# poetry
|
|
101
|
+
poetry.lock
|
|
102
|
+
|
|
103
|
+
# pdm
|
|
104
|
+
.pdm.toml
|
|
105
|
+
|
|
106
|
+
# PEP 582
|
|
107
|
+
__pypackages__/
|
|
108
|
+
|
|
109
|
+
# Celery stuff
|
|
110
|
+
celerybeat-schedule
|
|
111
|
+
celerybeat.pid
|
|
112
|
+
|
|
113
|
+
# SageMath parsed files
|
|
114
|
+
*.sage.py
|
|
115
|
+
|
|
116
|
+
# Environments
|
|
117
|
+
.env
|
|
118
|
+
.venv
|
|
119
|
+
env/
|
|
120
|
+
venv/
|
|
121
|
+
ENV/
|
|
122
|
+
env.bak/
|
|
123
|
+
venv.bak/
|
|
124
|
+
|
|
125
|
+
# Spyder project settings
|
|
126
|
+
.spyderproject
|
|
127
|
+
.spyproject
|
|
128
|
+
|
|
129
|
+
# Rope project settings
|
|
130
|
+
.ropeproject
|
|
131
|
+
|
|
132
|
+
# mkdocs documentation
|
|
133
|
+
/site
|
|
134
|
+
|
|
135
|
+
# mypy
|
|
136
|
+
.mypy_cache/
|
|
137
|
+
.dmypy.json
|
|
138
|
+
dmypy.json
|
|
139
|
+
|
|
140
|
+
# Pyre type checker
|
|
141
|
+
.pyre/
|
|
142
|
+
|
|
143
|
+
# pytype static type analyzer
|
|
144
|
+
.pytype/
|
|
145
|
+
|
|
146
|
+
# Cython debug symbols
|
|
147
|
+
cython_debug/
|
|
148
|
+
|
|
149
|
+
# IDE
|
|
150
|
+
.idea/
|
|
151
|
+
*.swp
|
|
152
|
+
*.swo
|
|
153
|
+
*~
|
|
154
|
+
.DS_Store
|
|
155
|
+
|
|
156
|
+
# Project specific
|
|
157
|
+
*.tmp
|
|
158
|
+
*.bak
|
|
159
|
+
|
|
160
|
+
# Security - RSA keys
|
|
161
|
+
private_key.pem
|
|
162
|
+
*.pem
|
|
163
|
+
!public_key.pem
|
|
164
|
+
|
|
165
|
+
scripts/nats_auth
|
|
166
|
+
# Anna App runtime cache
|
|
167
|
+
static/anna-apps-cache/
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: anna-app-core
|
|
3
|
+
Version: 0.2.0a1
|
|
4
|
+
Summary: Anna App platform core: manifest schemas, RPC dispatcher, protocols, errors. Shared by matrix-nexus and the local-dev runtime.
|
|
5
|
+
Project-URL: Documentation, https://github.com/talentai/matrix-nexus/blob/main/docs/design/anna-app-local-dev-and-test.md
|
|
6
|
+
Author: Talent AI
|
|
7
|
+
License: MIT
|
|
8
|
+
Keywords: anna,anna-app,executa
|
|
9
|
+
Requires-Python: >=3.10
|
|
10
|
+
Requires-Dist: pydantic<3.0,>=2.0
|
|
11
|
+
Description-Content-Type: text/markdown
|
|
12
|
+
|
|
13
|
+
# anna-app-core
|
|
14
|
+
|
|
15
|
+
Shared protocol/error/ACL primitives for the [Anna App](https://github.com/talentai/matrix-nexus/blob/main/docs/design/anna-app-local-dev-and-test.md) platform.
|
|
16
|
+
|
|
17
|
+
This package is intentionally tiny. It exposes the **stable contract surface**
|
|
18
|
+
that both `matrix-nexus` (production host) and `anna-app-runtime-local` (local
|
|
19
|
+
dev harness) can depend on without pulling each other's runtime.
|
|
20
|
+
|
|
21
|
+
## What's here (v0.1.x)
|
|
22
|
+
|
|
23
|
+
- `WindowStoreProtocol` — minimum surface RPC handlers expect from a window store
|
|
24
|
+
- `HostRpcError`, `WindowError`, `WindowPermissionError` — error types crossing the boundary
|
|
25
|
+
- `host_api_allows(manifest_dict, ns, method) -> bool` — pure ACL check (manifest passed as `dict`)
|
|
26
|
+
- `DISPATCHER_VERSION` / `SDK_VERSION` constants
|
|
27
|
+
|
|
28
|
+
## What's NOT here yet
|
|
29
|
+
|
|
30
|
+
- The full `dispatch()` function — still lives in `matrix-nexus`
|
|
31
|
+
(`src/services/anna_app_rpc_dispatcher.py`). Planned for `anna-app-core>=0.2`
|
|
32
|
+
once `event_stream` + `runtime_service` are abstracted behind protocols.
|
|
33
|
+
- Pydantic `AppManifest` — see `anna-app-schema` (JSON Schema bundle).
|
|
34
|
+
|
|
35
|
+
## Versioning
|
|
36
|
+
|
|
37
|
+
`0.1.0a1` is the first PyPI release (alpha). Pin policy lives in the central
|
|
38
|
+
[VERSIONS.md](../VERSIONS.md).
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# anna-app-core
|
|
2
|
+
|
|
3
|
+
Shared protocol/error/ACL primitives for the [Anna App](https://github.com/talentai/matrix-nexus/blob/main/docs/design/anna-app-local-dev-and-test.md) platform.
|
|
4
|
+
|
|
5
|
+
This package is intentionally tiny. It exposes the **stable contract surface**
|
|
6
|
+
that both `matrix-nexus` (production host) and `anna-app-runtime-local` (local
|
|
7
|
+
dev harness) can depend on without pulling each other's runtime.
|
|
8
|
+
|
|
9
|
+
## What's here (v0.1.x)
|
|
10
|
+
|
|
11
|
+
- `WindowStoreProtocol` — minimum surface RPC handlers expect from a window store
|
|
12
|
+
- `HostRpcError`, `WindowError`, `WindowPermissionError` — error types crossing the boundary
|
|
13
|
+
- `host_api_allows(manifest_dict, ns, method) -> bool` — pure ACL check (manifest passed as `dict`)
|
|
14
|
+
- `DISPATCHER_VERSION` / `SDK_VERSION` constants
|
|
15
|
+
|
|
16
|
+
## What's NOT here yet
|
|
17
|
+
|
|
18
|
+
- The full `dispatch()` function — still lives in `matrix-nexus`
|
|
19
|
+
(`src/services/anna_app_rpc_dispatcher.py`). Planned for `anna-app-core>=0.2`
|
|
20
|
+
once `event_stream` + `runtime_service` are abstracted behind protocols.
|
|
21
|
+
- Pydantic `AppManifest` — see `anna-app-schema` (JSON Schema bundle).
|
|
22
|
+
|
|
23
|
+
## Versioning
|
|
24
|
+
|
|
25
|
+
`0.1.0a1` is the first PyPI release (alpha). Pin policy lives in the central
|
|
26
|
+
[VERSIONS.md](../VERSIONS.md).
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "anna-app-core"
|
|
7
|
+
version = "0.2.0a1"
|
|
8
|
+
description = "Anna App platform core: manifest schemas, RPC dispatcher, protocols, errors. Shared by matrix-nexus and the local-dev runtime."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.10"
|
|
11
|
+
license = { text = "MIT" }
|
|
12
|
+
authors = [{ name = "Talent AI" }]
|
|
13
|
+
keywords = ["anna", "anna-app", "executa"]
|
|
14
|
+
|
|
15
|
+
# pydantic v2 is required for the AppManifest schema; everything else is
|
|
16
|
+
# pure stdlib.
|
|
17
|
+
dependencies = [
|
|
18
|
+
"pydantic>=2.0,<3.0",
|
|
19
|
+
]
|
|
20
|
+
|
|
21
|
+
[project.urls]
|
|
22
|
+
Documentation = "https://github.com/talentai/matrix-nexus/blob/main/docs/design/anna-app-local-dev-and-test.md"
|
|
23
|
+
|
|
24
|
+
[tool.hatch.build.targets.wheel]
|
|
25
|
+
packages = ["src/anna_app_core"]
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"""anna-app-core: stable contract surface shared by matrix-nexus and
|
|
2
|
+
anna-app-runtime-local.
|
|
3
|
+
|
|
4
|
+
v0.2.0a1 — full extraction. The complete RPC dispatcher, manifest pydantic
|
|
5
|
+
schemas, and helper functions now live here; matrix-nexus re-exports them
|
|
6
|
+
for backward compatibility (see README.md).
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from .acl import host_api_allows
|
|
10
|
+
from .dispatcher import dispatch
|
|
11
|
+
from .errors import HostRpcError, WindowError, WindowPermissionError
|
|
12
|
+
from .manifest import (
|
|
13
|
+
AppDevConfig,
|
|
14
|
+
AppManifest,
|
|
15
|
+
ManifestExecutaRef,
|
|
16
|
+
UiBundleSection,
|
|
17
|
+
UiHostApiSpec,
|
|
18
|
+
UiManifestSection,
|
|
19
|
+
UiSize,
|
|
20
|
+
UiViewSpec,
|
|
21
|
+
WindowViewMeta,
|
|
22
|
+
)
|
|
23
|
+
from .protocols import WindowStoreProtocol
|
|
24
|
+
from .runtime import scopes_from_manifest, select_view, view_meta
|
|
25
|
+
from .versions import DISPATCHER_VERSION, SDK_VERSION
|
|
26
|
+
|
|
27
|
+
__version__ = "0.2.0a1"
|
|
28
|
+
|
|
29
|
+
__all__ = [
|
|
30
|
+
# errors
|
|
31
|
+
"HostRpcError",
|
|
32
|
+
"WindowError",
|
|
33
|
+
"WindowPermissionError",
|
|
34
|
+
# protocols
|
|
35
|
+
"WindowStoreProtocol",
|
|
36
|
+
# acl
|
|
37
|
+
"host_api_allows",
|
|
38
|
+
# dispatcher
|
|
39
|
+
"dispatch",
|
|
40
|
+
# manifest schemas
|
|
41
|
+
"AppManifest",
|
|
42
|
+
"AppDevConfig",
|
|
43
|
+
"ManifestExecutaRef",
|
|
44
|
+
"UiBundleSection",
|
|
45
|
+
"UiHostApiSpec",
|
|
46
|
+
"UiManifestSection",
|
|
47
|
+
"UiSize",
|
|
48
|
+
"UiViewSpec",
|
|
49
|
+
"WindowViewMeta",
|
|
50
|
+
# runtime helpers
|
|
51
|
+
"select_view",
|
|
52
|
+
"scopes_from_manifest",
|
|
53
|
+
"view_meta",
|
|
54
|
+
# versions
|
|
55
|
+
"DISPATCHER_VERSION",
|
|
56
|
+
"SDK_VERSION",
|
|
57
|
+
"__version__",
|
|
58
|
+
]
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"""Host-API ACL check.
|
|
2
|
+
|
|
3
|
+
Accepts either a typed ``AppManifest`` (preferred — production + harness)
|
|
4
|
+
or a plain ``dict`` (e.g. JSON-loaded manifest before pydantic validation).
|
|
5
|
+
|
|
6
|
+
Mirrors the pre-extraction implementation in
|
|
7
|
+
``matrix-nexus/src/services/anna_app_runtime_service.py::host_api_allows``.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from __future__ import annotations
|
|
11
|
+
|
|
12
|
+
from typing import Any, Union
|
|
13
|
+
|
|
14
|
+
from .manifest import AppManifest
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def _ui_host_api(
|
|
18
|
+
manifest: Union[AppManifest, dict[str, Any]],
|
|
19
|
+
) -> dict[str, list[str]] | None:
|
|
20
|
+
"""Return the ``ui.host_api`` mapping (ns -> list[method]) or ``None``
|
|
21
|
+
if the manifest has no UI section."""
|
|
22
|
+
if isinstance(manifest, AppManifest):
|
|
23
|
+
if manifest.ui is None:
|
|
24
|
+
return None
|
|
25
|
+
api = manifest.ui.host_api
|
|
26
|
+
return {
|
|
27
|
+
"tools": api.tools,
|
|
28
|
+
"chat": api.chat,
|
|
29
|
+
"artifact": api.artifact,
|
|
30
|
+
"llm": api.llm,
|
|
31
|
+
"fs": api.fs,
|
|
32
|
+
"storage": api.storage,
|
|
33
|
+
"prefs": api.prefs,
|
|
34
|
+
}
|
|
35
|
+
ui = manifest.get("ui") if isinstance(manifest, dict) else None
|
|
36
|
+
if ui is None:
|
|
37
|
+
return None
|
|
38
|
+
return ui.get("host_api") or {}
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def host_api_allows(
|
|
42
|
+
manifest: Union[AppManifest, dict[str, Any]],
|
|
43
|
+
ns: str,
|
|
44
|
+
method: str,
|
|
45
|
+
) -> bool:
|
|
46
|
+
"""Return ``True`` iff ``ns.method`` is granted by the manifest's ACL.
|
|
47
|
+
|
|
48
|
+
`window.*` is always granted. ``tools.invoke`` and ``tools.list`` are
|
|
49
|
+
granted whenever the ``tools`` set is non-empty (per-tool gating happens
|
|
50
|
+
inside the handler).
|
|
51
|
+
"""
|
|
52
|
+
if ns == "window":
|
|
53
|
+
return True
|
|
54
|
+
api_map = _ui_host_api(manifest)
|
|
55
|
+
if api_map is None:
|
|
56
|
+
return False
|
|
57
|
+
methods = api_map.get(ns)
|
|
58
|
+
if not methods:
|
|
59
|
+
return False
|
|
60
|
+
if "*" in methods:
|
|
61
|
+
return True
|
|
62
|
+
if method in methods:
|
|
63
|
+
return True
|
|
64
|
+
if ns == "tools" and method in ("invoke", "list"):
|
|
65
|
+
return True
|
|
66
|
+
return False
|