ya-environment-relay 0.74.0__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.
- ya_environment_relay-0.74.0/.gitignore +169 -0
- ya_environment_relay-0.74.0/PKG-INFO +36 -0
- ya_environment_relay-0.74.0/README.md +18 -0
- ya_environment_relay-0.74.0/pyproject.toml +60 -0
- ya_environment_relay-0.74.0/spec/01-overview.md +147 -0
- ya_environment_relay-0.74.0/spec/02-protocol.md +376 -0
- ya_environment_relay-0.74.0/spec/03-environment.md +216 -0
- ya_environment_relay-0.74.0/spec/04-security-and-policy.md +177 -0
- ya_environment_relay-0.74.0/spec/05-implementation-plan.md +129 -0
- ya_environment_relay-0.74.0/spec/README.md +56 -0
- ya_environment_relay-0.74.0/ya_environment_relay/__init__.py +5 -0
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
docs/source
|
|
2
|
+
|
|
3
|
+
# From https://raw.githubusercontent.com/github/gitignore/main/Python.gitignore
|
|
4
|
+
|
|
5
|
+
# Byte-compiled / optimized / DLL files
|
|
6
|
+
__pycache__/
|
|
7
|
+
*.py[cod]
|
|
8
|
+
*$py.class
|
|
9
|
+
|
|
10
|
+
# C extensions
|
|
11
|
+
*.so
|
|
12
|
+
|
|
13
|
+
# Distribution / packaging
|
|
14
|
+
.Python
|
|
15
|
+
build/
|
|
16
|
+
develop-eggs/
|
|
17
|
+
dist/
|
|
18
|
+
downloads/
|
|
19
|
+
eggs/
|
|
20
|
+
.eggs/
|
|
21
|
+
lib/
|
|
22
|
+
!apps/
|
|
23
|
+
!apps/ya-claw-web/
|
|
24
|
+
!apps/ya-claw-web/src/
|
|
25
|
+
!apps/ya-claw-web/src/lib/
|
|
26
|
+
!apps/ya-claw-web/src/lib/**
|
|
27
|
+
lib64/
|
|
28
|
+
parts/
|
|
29
|
+
sdist/
|
|
30
|
+
var/
|
|
31
|
+
wheels/
|
|
32
|
+
share/python-wheels/
|
|
33
|
+
*.egg-info/
|
|
34
|
+
.installed.cfg
|
|
35
|
+
*.egg
|
|
36
|
+
MANIFEST
|
|
37
|
+
|
|
38
|
+
# PyInstaller
|
|
39
|
+
# Usually these files are written by a python script from a template
|
|
40
|
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
|
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
|
+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
|
95
|
+
__pypackages__/
|
|
96
|
+
|
|
97
|
+
# Celery stuff
|
|
98
|
+
celerybeat-schedule
|
|
99
|
+
celerybeat.pid
|
|
100
|
+
|
|
101
|
+
# SageMath parsed files
|
|
102
|
+
*.sage.py
|
|
103
|
+
|
|
104
|
+
# Environments
|
|
105
|
+
.env
|
|
106
|
+
.yaai/
|
|
107
|
+
**/.yaai/
|
|
108
|
+
.venv
|
|
109
|
+
env/
|
|
110
|
+
venv/
|
|
111
|
+
ENV/
|
|
112
|
+
env.bak/
|
|
113
|
+
venv.bak/
|
|
114
|
+
|
|
115
|
+
# Spyder project settings
|
|
116
|
+
.spyderproject
|
|
117
|
+
.spyproject
|
|
118
|
+
|
|
119
|
+
# Rope project settings
|
|
120
|
+
.ropeproject
|
|
121
|
+
|
|
122
|
+
# mkdocs documentation
|
|
123
|
+
/site
|
|
124
|
+
|
|
125
|
+
# mypy
|
|
126
|
+
.mypy_cache/
|
|
127
|
+
.pyright/
|
|
128
|
+
.dmypy.json
|
|
129
|
+
dmypy.json
|
|
130
|
+
|
|
131
|
+
# Pyre type checker
|
|
132
|
+
.pyre/
|
|
133
|
+
|
|
134
|
+
# pytype static type analyzer
|
|
135
|
+
.pytype/
|
|
136
|
+
|
|
137
|
+
# Cython debug symbols
|
|
138
|
+
cython_debug/
|
|
139
|
+
|
|
140
|
+
# Vscode config files
|
|
141
|
+
# .vscode/
|
|
142
|
+
|
|
143
|
+
# PyCharm
|
|
144
|
+
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
|
145
|
+
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
|
146
|
+
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
|
147
|
+
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
|
148
|
+
#.idea/
|
|
149
|
+
|
|
150
|
+
TO-DO.json
|
|
151
|
+
dev/
|
|
152
|
+
ya_agent_sdk/sandbox/shell/templates/public
|
|
153
|
+
|
|
154
|
+
# Sync automaticlly
|
|
155
|
+
yaacli/yaacli/skills/building-agents
|
|
156
|
+
|
|
157
|
+
# Frontend
|
|
158
|
+
node_modules/
|
|
159
|
+
apps/*/dist/
|
|
160
|
+
!apps/ya-desktop/
|
|
161
|
+
!apps/ya-desktop/src/
|
|
162
|
+
!apps/ya-desktop/src/**
|
|
163
|
+
!apps/ya-desktop/src-tauri/
|
|
164
|
+
!apps/ya-desktop/src-tauri/resources/
|
|
165
|
+
!apps/ya-desktop/src-tauri/resources/uv/
|
|
166
|
+
!apps/ya-desktop/src-tauri/resources/uv/.gitkeep
|
|
167
|
+
apps/ya-desktop/src-tauri/resources/uv/uv
|
|
168
|
+
apps/ya-desktop/src-tauri/resources/uv/uv.exe
|
|
169
|
+
*.tsbuildinfo
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: ya-environment-relay
|
|
3
|
+
Version: 0.74.0
|
|
4
|
+
Summary: Provider-neutral relay protocol for YA agent environments
|
|
5
|
+
Project-URL: Repository, https://github.com/wh1isper/ya-mono
|
|
6
|
+
Author-email: wh1isper <jizhongsheng957@gmail.com>
|
|
7
|
+
Keywords: agent,environment,protocol,python,relay
|
|
8
|
+
Classifier: Intended Audience :: Developers
|
|
9
|
+
Classifier: Programming Language :: Python
|
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
14
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
15
|
+
Requires-Python: <3.14,>=3.11
|
|
16
|
+
Requires-Dist: pydantic>=2.0.0
|
|
17
|
+
Description-Content-Type: text/markdown
|
|
18
|
+
|
|
19
|
+
# ya-environment-relay
|
|
20
|
+
|
|
21
|
+
Provider-neutral relay protocol for YA agent environments.
|
|
22
|
+
|
|
23
|
+
`ya-environment-relay` defines how external execution capabilities are exposed to an agent runtime as Environment components.
|
|
24
|
+
|
|
25
|
+
Capability families:
|
|
26
|
+
|
|
27
|
+
- file operations
|
|
28
|
+
- shell execution
|
|
29
|
+
- custom tools
|
|
30
|
+
- resources
|
|
31
|
+
- artifacts
|
|
32
|
+
- computer use
|
|
33
|
+
|
|
34
|
+
The protocol string is `ya-environment-relay.v1`.
|
|
35
|
+
|
|
36
|
+
See [`spec/`](spec/) for the protocol documents.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# ya-environment-relay
|
|
2
|
+
|
|
3
|
+
Provider-neutral relay protocol for YA agent environments.
|
|
4
|
+
|
|
5
|
+
`ya-environment-relay` defines how external execution capabilities are exposed to an agent runtime as Environment components.
|
|
6
|
+
|
|
7
|
+
Capability families:
|
|
8
|
+
|
|
9
|
+
- file operations
|
|
10
|
+
- shell execution
|
|
11
|
+
- custom tools
|
|
12
|
+
- resources
|
|
13
|
+
- artifacts
|
|
14
|
+
- computer use
|
|
15
|
+
|
|
16
|
+
The protocol string is `ya-environment-relay.v1`.
|
|
17
|
+
|
|
18
|
+
See [`spec/`](spec/) for the protocol documents.
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "ya-environment-relay"
|
|
3
|
+
dynamic = ["version"]
|
|
4
|
+
description = "Provider-neutral relay protocol for YA agent environments"
|
|
5
|
+
authors = [{ name = "wh1isper", email = "jizhongsheng957@gmail.com" }]
|
|
6
|
+
readme = "README.md"
|
|
7
|
+
keywords = ["python", "agent", "environment", "relay", "protocol"]
|
|
8
|
+
requires-python = ">=3.11,<3.14"
|
|
9
|
+
classifiers = [
|
|
10
|
+
"Intended Audience :: Developers",
|
|
11
|
+
"Programming Language :: Python",
|
|
12
|
+
"Programming Language :: Python :: 3",
|
|
13
|
+
"Programming Language :: Python :: 3.11",
|
|
14
|
+
"Programming Language :: Python :: 3.12",
|
|
15
|
+
"Programming Language :: Python :: 3.13",
|
|
16
|
+
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
17
|
+
]
|
|
18
|
+
|
|
19
|
+
dependencies = [
|
|
20
|
+
"pydantic>=2.0.0",
|
|
21
|
+
]
|
|
22
|
+
|
|
23
|
+
[project.urls]
|
|
24
|
+
Repository = "https://github.com/wh1isper/ya-mono"
|
|
25
|
+
|
|
26
|
+
[dependency-groups]
|
|
27
|
+
dev = [
|
|
28
|
+
"deptry>=0.22.0",
|
|
29
|
+
"pyright>=1.1.0",
|
|
30
|
+
"ruff>=0.9.2",
|
|
31
|
+
]
|
|
32
|
+
|
|
33
|
+
[build-system]
|
|
34
|
+
requires = ["hatchling", "uv-dynamic-versioning>=0.7.0"]
|
|
35
|
+
build-backend = "hatchling.build"
|
|
36
|
+
|
|
37
|
+
[tool.hatch.version]
|
|
38
|
+
source = "uv-dynamic-versioning"
|
|
39
|
+
|
|
40
|
+
[tool.uv-dynamic-versioning]
|
|
41
|
+
vcs = "git"
|
|
42
|
+
style = "pep440"
|
|
43
|
+
bump = true
|
|
44
|
+
|
|
45
|
+
[tool.hatch.build.targets.sdist]
|
|
46
|
+
include = [
|
|
47
|
+
"README.md",
|
|
48
|
+
"pyproject.toml",
|
|
49
|
+
"spec",
|
|
50
|
+
"ya_environment_relay",
|
|
51
|
+
]
|
|
52
|
+
|
|
53
|
+
[tool.hatch.build.targets.wheel]
|
|
54
|
+
packages = ["ya_environment_relay"]
|
|
55
|
+
force-include = { "spec" = "spec" }
|
|
56
|
+
|
|
57
|
+
[tool.deptry]
|
|
58
|
+
ignore = ["DEP001", "DEP002"]
|
|
59
|
+
package_module_name_map = { "pydantic" = "pydantic", "ya-environment-relay" = "ya_environment_relay" }
|
|
60
|
+
per_rule_ignores = { DEP004 = ["pytest"] }
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
# 01. YA Environment Relay Overview
|
|
2
|
+
|
|
3
|
+
## Goal
|
|
4
|
+
|
|
5
|
+
YA Environment Relay connects an agent runtime to capabilities that execute in another process, device, sandbox, or host. It turns those external capabilities into `ya-agent-sdk` Environment components so the agent can use them through normal file, shell, resource, and tool abstractions.
|
|
6
|
+
|
|
7
|
+
YA Environment Relay is protocol-level infrastructure. Product integrations such as YA Desktop, YA Claw, cloud workers, or sandbox services implement the protocol for their own deployment models.
|
|
8
|
+
|
|
9
|
+
## Parties
|
|
10
|
+
|
|
11
|
+
```mermaid
|
|
12
|
+
flowchart TB
|
|
13
|
+
Runtime[Agent Runtime] --> RelayServer[Relay Server]
|
|
14
|
+
RelayServer <--> RelayClient[Relay Client]
|
|
15
|
+
RelayClient --> Provider[Capability Provider]
|
|
16
|
+
Provider --> Target[Local Device / Sandbox / External System]
|
|
17
|
+
|
|
18
|
+
Runtime --> SDK[ya-agent-sdk Environment]
|
|
19
|
+
SDK --> RelayEnvironment[RelayEnvironment]
|
|
20
|
+
RelayEnvironment --> RelayServer
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Definitions:
|
|
24
|
+
|
|
25
|
+
- Agent Runtime: process that runs the model loop and tool calls.
|
|
26
|
+
- Relay Server: endpoint that accepts relay client connections and routes requests.
|
|
27
|
+
- Relay Client: process that connects to the relay server and advertises capabilities.
|
|
28
|
+
- Capability Provider: implementation behind the relay client, such as local filesystem, shell, OS automation, browser, VM, or custom tool host.
|
|
29
|
+
- Relay Environment: SDK Environment implementation backed by relay requests.
|
|
30
|
+
|
|
31
|
+
## Capability Families
|
|
32
|
+
|
|
33
|
+
YA Environment Relay uses capability families to group provider methods:
|
|
34
|
+
|
|
35
|
+
```text
|
|
36
|
+
fileops
|
|
37
|
+
shell
|
|
38
|
+
tools
|
|
39
|
+
resources
|
|
40
|
+
artifacts
|
|
41
|
+
computer
|
|
42
|
+
browser
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Initial protocol should define the first six families. Browser can be added as a specialized provider or implemented as custom tools.
|
|
46
|
+
|
|
47
|
+
## Relationship to ya-agent-sdk
|
|
48
|
+
|
|
49
|
+
`ya-agent-sdk` already has core runtime abstractions:
|
|
50
|
+
|
|
51
|
+
- Environment
|
|
52
|
+
- FileOperator
|
|
53
|
+
- Shell
|
|
54
|
+
- ResourceRegistry
|
|
55
|
+
- Toolset
|
|
56
|
+
- resumable resources
|
|
57
|
+
|
|
58
|
+
YA Environment Relay should provide remote implementations of these abstractions:
|
|
59
|
+
|
|
60
|
+
```python
|
|
61
|
+
RelayEnvironment(Environment)
|
|
62
|
+
RelayFileOperator(FileOperator)
|
|
63
|
+
RelayShell(Shell)
|
|
64
|
+
RelayResourceRegistry(ResourceRegistry)
|
|
65
|
+
RelayToolset(Toolset)
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
This keeps agent code and profiles stable while moving execution to a connected provider.
|
|
69
|
+
|
|
70
|
+
## Relationship to Claw
|
|
71
|
+
|
|
72
|
+
Claw can use YA Environment Relay as one `WorkspaceProvider` backend:
|
|
73
|
+
|
|
74
|
+
```text
|
|
75
|
+
WorkspaceProvider kind = relay
|
|
76
|
+
Environment = RelayEnvironment
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Claw remains responsible for:
|
|
80
|
+
|
|
81
|
+
- sessions and runs.
|
|
82
|
+
- profile selection.
|
|
83
|
+
- model execution.
|
|
84
|
+
- HITL approvals.
|
|
85
|
+
- durable trace.
|
|
86
|
+
- artifact storage.
|
|
87
|
+
- provider registry and connection routing.
|
|
88
|
+
|
|
89
|
+
A relay client supplies execution capabilities. Claw exposes them to the agent through SDK abstractions.
|
|
90
|
+
|
|
91
|
+
## Relationship to Desktop
|
|
92
|
+
|
|
93
|
+
YA Desktop can act as a relay client. It can advertise local capabilities:
|
|
94
|
+
|
|
95
|
+
- selected folders as workspace roots.
|
|
96
|
+
- sandboxed local shell.
|
|
97
|
+
- native OS computer use.
|
|
98
|
+
- Desktop-managed custom tools.
|
|
99
|
+
- local artifact upload.
|
|
100
|
+
|
|
101
|
+
Desktop owns user consent, local grants, and native permission UX. Claw owns runtime authorization and trace.
|
|
102
|
+
|
|
103
|
+
## Relationship to MCP
|
|
104
|
+
|
|
105
|
+
MCP and YA Environment Relay address overlapping but different surfaces:
|
|
106
|
+
|
|
107
|
+
| Surface | MCP | YA Environment Relay |
|
|
108
|
+
| ------------------------------ | --------------------------- | -------------------- |
|
|
109
|
+
| Tool discovery | yes | yes |
|
|
110
|
+
| JSON Schema tool input | yes | yes |
|
|
111
|
+
| FileOperator abstraction | product-specific | built in |
|
|
112
|
+
| Shell streaming | server-specific | built in |
|
|
113
|
+
| Environment/resource lifecycle | limited by server | built in |
|
|
114
|
+
| Runtime artifact ownership | external or custom | built in |
|
|
115
|
+
| User device relay | possible with custom server | primary use case |
|
|
116
|
+
|
|
117
|
+
A relay client can wrap MCP servers and register selected tools into YA Environment Relay. A Claw profile can use MCP servers and relay capabilities together.
|
|
118
|
+
|
|
119
|
+
## High-Level Flow
|
|
120
|
+
|
|
121
|
+
```mermaid
|
|
122
|
+
sequenceDiagram
|
|
123
|
+
participant Client as Relay Client
|
|
124
|
+
participant Server as Relay Server
|
|
125
|
+
participant Runtime as Agent Runtime
|
|
126
|
+
participant Provider as Provider
|
|
127
|
+
|
|
128
|
+
Client->>Server: WebSocket connect
|
|
129
|
+
Client->>Server: hello capabilities
|
|
130
|
+
Server-->>Client: accepted capabilities
|
|
131
|
+
Runtime->>Server: file/shell/tool/computer request
|
|
132
|
+
Server->>Client: relay request
|
|
133
|
+
Client->>Provider: execute
|
|
134
|
+
Provider-->>Client: result / stream
|
|
135
|
+
Client-->>Server: response / stream
|
|
136
|
+
Server-->>Runtime: Environment result
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
## Design Principles
|
|
140
|
+
|
|
141
|
+
- The protocol is provider-neutral.
|
|
142
|
+
- The runtime controls model-facing tool exposure.
|
|
143
|
+
- The provider controls local execution and local policy.
|
|
144
|
+
- Capabilities are explicitly advertised and accepted.
|
|
145
|
+
- Streaming and cancellation are first-class.
|
|
146
|
+
- Artifacts are owned by the runtime store when the call belongs to a run.
|
|
147
|
+
- Security is scoped by device, connection, space/workspace, capability, and root grants.
|
|
@@ -0,0 +1,376 @@
|
|
|
1
|
+
# 02. ya-environment-relay.v1 Protocol
|
|
2
|
+
|
|
3
|
+
## Transport
|
|
4
|
+
|
|
5
|
+
`ya-environment-relay.v1` uses WebSocket as its primary transport. The protocol requires bidirectional request/response, streaming output, cancellation, heartbeat, provider events, and artifact coordination.
|
|
6
|
+
|
|
7
|
+
Connection endpoint shape for a host runtime:
|
|
8
|
+
|
|
9
|
+
```http
|
|
10
|
+
GET /api/v1/relay/connect
|
|
11
|
+
Authorization: Bearer <relay-token>
|
|
12
|
+
Upgrade: websocket
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Products can expose a different path, but the frame format should remain stable.
|
|
16
|
+
|
|
17
|
+
## Frame Types
|
|
18
|
+
|
|
19
|
+
```ts
|
|
20
|
+
type RelayFrame =
|
|
21
|
+
| HelloFrame
|
|
22
|
+
| EventFrame
|
|
23
|
+
| RequestFrame
|
|
24
|
+
| ResponseFrame
|
|
25
|
+
| StreamFrame
|
|
26
|
+
| CancelFrame
|
|
27
|
+
| PingFrame
|
|
28
|
+
| PongFrame;
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
All frames are JSON text frames unless a method explicitly negotiates binary transfer. Large artifacts should use artifact upload methods instead of raw WebSocket binary in the first version.
|
|
32
|
+
|
|
33
|
+
## Hello
|
|
34
|
+
|
|
35
|
+
The relay client sends `hello` immediately after connection:
|
|
36
|
+
|
|
37
|
+
```json
|
|
38
|
+
{
|
|
39
|
+
"type": "hello",
|
|
40
|
+
"protocol": "ya-environment-relay.v1",
|
|
41
|
+
"client_id": "client_macbook_123",
|
|
42
|
+
"client_kind": "ya_desktop",
|
|
43
|
+
"client_version": "0.1.0",
|
|
44
|
+
"capabilities": {
|
|
45
|
+
"fileops": {
|
|
46
|
+
"enabled": true,
|
|
47
|
+
"roots": [
|
|
48
|
+
{
|
|
49
|
+
"root_id": "main",
|
|
50
|
+
"label": "ya-mono",
|
|
51
|
+
"virtual_path": "/workspace/main",
|
|
52
|
+
"mode": "rw"
|
|
53
|
+
}
|
|
54
|
+
]
|
|
55
|
+
},
|
|
56
|
+
"shell": {
|
|
57
|
+
"enabled": true,
|
|
58
|
+
"runtime": "sandboxed_local_shell",
|
|
59
|
+
"interactive": true
|
|
60
|
+
},
|
|
61
|
+
"tools": {
|
|
62
|
+
"enabled": true,
|
|
63
|
+
"tool_count": 2
|
|
64
|
+
},
|
|
65
|
+
"computer": {
|
|
66
|
+
"enabled": true,
|
|
67
|
+
"platform": "macos",
|
|
68
|
+
"screenshots": true,
|
|
69
|
+
"accessibility_tree": true,
|
|
70
|
+
"semantic_actions": true,
|
|
71
|
+
"coordinate_input": true
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
The relay server responds with an event:
|
|
78
|
+
|
|
79
|
+
```json
|
|
80
|
+
{
|
|
81
|
+
"type": "event",
|
|
82
|
+
"event": "relay.accepted",
|
|
83
|
+
"payload": {
|
|
84
|
+
"connection_id": "relay_conn_123",
|
|
85
|
+
"accepted_capabilities": ["fileops", "shell", "tools", "computer"],
|
|
86
|
+
"server_time": "2026-05-11T15:40:00Z"
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Request
|
|
92
|
+
|
|
93
|
+
Either side may send requests when authorized. The most common direction is runtime to provider.
|
|
94
|
+
|
|
95
|
+
```json
|
|
96
|
+
{
|
|
97
|
+
"type": "request",
|
|
98
|
+
"id": "req_123",
|
|
99
|
+
"method": "file.read",
|
|
100
|
+
"params": {
|
|
101
|
+
"root_id": "main",
|
|
102
|
+
"path": "README.md",
|
|
103
|
+
"encoding": "utf-8"
|
|
104
|
+
},
|
|
105
|
+
"context": {
|
|
106
|
+
"session_id": "session_abc",
|
|
107
|
+
"run_id": "run_def",
|
|
108
|
+
"tool_call_id": "call_ghi"
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
`id` must be unique within a live connection until the request reaches terminal response or cancellation.
|
|
114
|
+
|
|
115
|
+
## Response
|
|
116
|
+
|
|
117
|
+
Successful response:
|
|
118
|
+
|
|
119
|
+
```json
|
|
120
|
+
{
|
|
121
|
+
"type": "response",
|
|
122
|
+
"id": "req_123",
|
|
123
|
+
"result": {
|
|
124
|
+
"content": "# Project\n...",
|
|
125
|
+
"encoding": "utf-8"
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
Error response:
|
|
131
|
+
|
|
132
|
+
```json
|
|
133
|
+
{
|
|
134
|
+
"type": "response",
|
|
135
|
+
"id": "req_123",
|
|
136
|
+
"error": {
|
|
137
|
+
"code": "permission_denied",
|
|
138
|
+
"message": "The path is outside the selected roots.",
|
|
139
|
+
"recoverable": true,
|
|
140
|
+
"details": {
|
|
141
|
+
"root_id": "main"
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
Common error codes:
|
|
148
|
+
|
|
149
|
+
```text
|
|
150
|
+
invalid_request
|
|
151
|
+
unknown_method
|
|
152
|
+
capability_unavailable
|
|
153
|
+
permission_denied
|
|
154
|
+
approval_required
|
|
155
|
+
policy_blocked
|
|
156
|
+
not_found
|
|
157
|
+
timeout
|
|
158
|
+
cancelled
|
|
159
|
+
provider_error
|
|
160
|
+
relay_disconnected
|
|
161
|
+
artifact_error
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
## Stream
|
|
165
|
+
|
|
166
|
+
Long-running requests can emit stream frames before the terminal response.
|
|
167
|
+
|
|
168
|
+
```json
|
|
169
|
+
{
|
|
170
|
+
"type": "stream",
|
|
171
|
+
"id": "req_shell_1",
|
|
172
|
+
"event": "stdout",
|
|
173
|
+
"data": "Running tests...\n"
|
|
174
|
+
}
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
Common stream event names:
|
|
178
|
+
|
|
179
|
+
```text
|
|
180
|
+
stdout
|
|
181
|
+
stderr
|
|
182
|
+
progress
|
|
183
|
+
artifact
|
|
184
|
+
status
|
|
185
|
+
log
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
Terminal completion uses `response`:
|
|
189
|
+
|
|
190
|
+
```json
|
|
191
|
+
{
|
|
192
|
+
"type": "response",
|
|
193
|
+
"id": "req_shell_1",
|
|
194
|
+
"result": {
|
|
195
|
+
"exit_code": 0,
|
|
196
|
+
"duration_ms": 1234
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
## Cancel
|
|
202
|
+
|
|
203
|
+
Either side can cancel an active request:
|
|
204
|
+
|
|
205
|
+
```json
|
|
206
|
+
{
|
|
207
|
+
"type": "cancel",
|
|
208
|
+
"id": "req_shell_1",
|
|
209
|
+
"reason": "user_cancelled"
|
|
210
|
+
}
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
The receiver should attempt cancellation and then send a terminal response:
|
|
214
|
+
|
|
215
|
+
```json
|
|
216
|
+
{
|
|
217
|
+
"type": "response",
|
|
218
|
+
"id": "req_shell_1",
|
|
219
|
+
"error": {
|
|
220
|
+
"code": "cancelled",
|
|
221
|
+
"message": "Request cancelled by user.",
|
|
222
|
+
"recoverable": true
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
## Heartbeat
|
|
228
|
+
|
|
229
|
+
Heartbeat frames keep the connection alive and measure latency.
|
|
230
|
+
|
|
231
|
+
```json
|
|
232
|
+
{
|
|
233
|
+
"type": "ping",
|
|
234
|
+
"id": "ping_1",
|
|
235
|
+
"ts": "2026-05-11T15:45:00Z"
|
|
236
|
+
}
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
```json
|
|
240
|
+
{
|
|
241
|
+
"type": "pong",
|
|
242
|
+
"id": "ping_1",
|
|
243
|
+
"ts": "2026-05-11T15:45:00Z"
|
|
244
|
+
}
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
## Events
|
|
248
|
+
|
|
249
|
+
Events are one-way notifications outside request/response.
|
|
250
|
+
|
|
251
|
+
```json
|
|
252
|
+
{
|
|
253
|
+
"type": "event",
|
|
254
|
+
"event": "capability.updated",
|
|
255
|
+
"payload": {
|
|
256
|
+
"capability": "computer",
|
|
257
|
+
"state": "permission_required"
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
Common events:
|
|
263
|
+
|
|
264
|
+
```text
|
|
265
|
+
relay.accepted
|
|
266
|
+
capability.updated
|
|
267
|
+
provider.paused
|
|
268
|
+
provider.resumed
|
|
269
|
+
artifact.uploaded
|
|
270
|
+
tool.registered
|
|
271
|
+
tool.unregistered
|
|
272
|
+
resource.updated
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
## Method Namespaces
|
|
276
|
+
|
|
277
|
+
```text
|
|
278
|
+
file.read
|
|
279
|
+
file.write
|
|
280
|
+
file.list
|
|
281
|
+
file.stat
|
|
282
|
+
file.mkdir
|
|
283
|
+
file.delete
|
|
284
|
+
file.search
|
|
285
|
+
file.watch
|
|
286
|
+
|
|
287
|
+
shell.start
|
|
288
|
+
shell.input
|
|
289
|
+
shell.resize
|
|
290
|
+
shell.signal
|
|
291
|
+
shell.cancel
|
|
292
|
+
shell.status
|
|
293
|
+
|
|
294
|
+
tool.list
|
|
295
|
+
tool.register
|
|
296
|
+
tool.unregister
|
|
297
|
+
tool.call
|
|
298
|
+
tool.cancel
|
|
299
|
+
|
|
300
|
+
resource.list
|
|
301
|
+
resource.get
|
|
302
|
+
resource.create
|
|
303
|
+
resource.dispose
|
|
304
|
+
resource.export_state
|
|
305
|
+
resource.restore_state
|
|
306
|
+
|
|
307
|
+
computer.status
|
|
308
|
+
computer.see
|
|
309
|
+
computer.act
|
|
310
|
+
computer.pause
|
|
311
|
+
computer.resume
|
|
312
|
+
computer.takeover
|
|
313
|
+
computer.release
|
|
314
|
+
|
|
315
|
+
artifact.reserve
|
|
316
|
+
artifact.upload
|
|
317
|
+
artifact.complete
|
|
318
|
+
artifact.abort
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
## Artifact Coordination
|
|
322
|
+
|
|
323
|
+
Large artifacts should be transferred out-of-band through runtime-owned storage.
|
|
324
|
+
|
|
325
|
+
Reserve request:
|
|
326
|
+
|
|
327
|
+
```json
|
|
328
|
+
{
|
|
329
|
+
"type": "request",
|
|
330
|
+
"id": "req_artifact_1",
|
|
331
|
+
"method": "artifact.reserve",
|
|
332
|
+
"params": {
|
|
333
|
+
"run_id": "run_123",
|
|
334
|
+
"kind": "screenshot",
|
|
335
|
+
"mime_type": "image/png",
|
|
336
|
+
"metadata": {
|
|
337
|
+
"source": "computer.see"
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
Reserve response:
|
|
344
|
+
|
|
345
|
+
```json
|
|
346
|
+
{
|
|
347
|
+
"type": "response",
|
|
348
|
+
"id": "req_artifact_1",
|
|
349
|
+
"result": {
|
|
350
|
+
"artifact_id": "art_123",
|
|
351
|
+
"upload_url": "https://runtime.example/upload/art_123",
|
|
352
|
+
"headers": {
|
|
353
|
+
"Authorization": "Bearer upload-token"
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
Complete request:
|
|
360
|
+
|
|
361
|
+
```json
|
|
362
|
+
{
|
|
363
|
+
"type": "request",
|
|
364
|
+
"id": "req_artifact_2",
|
|
365
|
+
"method": "artifact.complete",
|
|
366
|
+
"params": {
|
|
367
|
+
"artifact_id": "art_123",
|
|
368
|
+
"size_bytes": 203456,
|
|
369
|
+
"sha256": "..."
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
## Versioning
|
|
375
|
+
|
|
376
|
+
The protocol string is `ya-environment-relay.v1`. Breaking changes should use `ya-environment-relay.v2`. Additive method fields can be negotiated through the `hello.capabilities` payload.
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
# 03. Relay Environment
|
|
2
|
+
|
|
3
|
+
## Goal
|
|
4
|
+
|
|
5
|
+
Relay Environment maps `ya-environment-relay.v1` capabilities into `ya-agent-sdk` runtime abstractions. Agents and toolsets should interact with normal SDK interfaces while execution happens through a connected relay provider.
|
|
6
|
+
|
|
7
|
+
## Environment Shape
|
|
8
|
+
|
|
9
|
+
```python
|
|
10
|
+
class RelayEnvironment(Environment):
|
|
11
|
+
file_operator: RelayFileOperator
|
|
12
|
+
shell: RelayShell
|
|
13
|
+
resources: RelayResourceRegistry
|
|
14
|
+
toolsets: list[RelayToolset]
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
The environment should be created from a binding:
|
|
18
|
+
|
|
19
|
+
```python
|
|
20
|
+
class RelayEnvironmentBinding(BaseModel):
|
|
21
|
+
connection_id: str
|
|
22
|
+
client_id: str
|
|
23
|
+
roots: list[RelayRoot]
|
|
24
|
+
capabilities: list[str]
|
|
25
|
+
metadata: dict[str, Any] = Field(default_factory=dict)
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## FileOperator Mapping
|
|
29
|
+
|
|
30
|
+
`RelayFileOperator` maps SDK file operations to `file.*` methods:
|
|
31
|
+
|
|
32
|
+
| SDK behavior | Relay method |
|
|
33
|
+
| ---------------- | ------------- |
|
|
34
|
+
| read text/bytes | `file.read` |
|
|
35
|
+
| write text/bytes | `file.write` |
|
|
36
|
+
| list directory | `file.list` |
|
|
37
|
+
| stat path | `file.stat` |
|
|
38
|
+
| create directory | `file.mkdir` |
|
|
39
|
+
| delete path | `file.delete` |
|
|
40
|
+
| search content | `file.search` |
|
|
41
|
+
|
|
42
|
+
Paths should be virtualized. The model and runtime see `/workspace/main/README.md`; the relay client maps it to an approved local root.
|
|
43
|
+
|
|
44
|
+
Request example:
|
|
45
|
+
|
|
46
|
+
```json
|
|
47
|
+
{
|
|
48
|
+
"method": "file.read",
|
|
49
|
+
"params": {
|
|
50
|
+
"root_id": "main",
|
|
51
|
+
"path": "README.md",
|
|
52
|
+
"encoding": "utf-8"
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Shell Mapping
|
|
58
|
+
|
|
59
|
+
`RelayShell` maps SDK shell execution to `shell.*` methods:
|
|
60
|
+
|
|
61
|
+
| SDK behavior | Relay method |
|
|
62
|
+
| --------------- | -------------- |
|
|
63
|
+
| start command | `shell.start` |
|
|
64
|
+
| send stdin | `shell.input` |
|
|
65
|
+
| resize terminal | `shell.resize` |
|
|
66
|
+
| send signal | `shell.signal` |
|
|
67
|
+
| cancel command | `shell.cancel` |
|
|
68
|
+
| inspect command | `shell.status` |
|
|
69
|
+
|
|
70
|
+
Shell output uses stream frames:
|
|
71
|
+
|
|
72
|
+
```json
|
|
73
|
+
{
|
|
74
|
+
"type": "stream",
|
|
75
|
+
"id": "req_shell_1",
|
|
76
|
+
"event": "stdout",
|
|
77
|
+
"data": "pytest started\n"
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
The terminal response carries exit status:
|
|
82
|
+
|
|
83
|
+
```json
|
|
84
|
+
{
|
|
85
|
+
"type": "response",
|
|
86
|
+
"id": "req_shell_1",
|
|
87
|
+
"result": {
|
|
88
|
+
"exit_code": 0,
|
|
89
|
+
"duration_ms": 18233
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## Resource Mapping
|
|
95
|
+
|
|
96
|
+
Relay resources represent long-lived provider-side objects:
|
|
97
|
+
|
|
98
|
+
- browser sessions.
|
|
99
|
+
- computer sessions.
|
|
100
|
+
- database connections.
|
|
101
|
+
- local app automation handles.
|
|
102
|
+
- external service sessions.
|
|
103
|
+
|
|
104
|
+
Method mapping:
|
|
105
|
+
|
|
106
|
+
```text
|
|
107
|
+
resource.list
|
|
108
|
+
resource.get
|
|
109
|
+
resource.create
|
|
110
|
+
resource.dispose
|
|
111
|
+
resource.export_state
|
|
112
|
+
resource.restore_state
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Resource state should integrate with SDK resumable resources when possible.
|
|
116
|
+
|
|
117
|
+
## Tool Mapping
|
|
118
|
+
|
|
119
|
+
Relay custom tools are described by JSON Schema and exposed as SDK tools.
|
|
120
|
+
|
|
121
|
+
Tool descriptor:
|
|
122
|
+
|
|
123
|
+
```json
|
|
124
|
+
{
|
|
125
|
+
"name": "local_open_in_editor",
|
|
126
|
+
"title": "Open File in Local Editor",
|
|
127
|
+
"description": "Open a workspace file in the user's configured editor.",
|
|
128
|
+
"input_schema": {
|
|
129
|
+
"type": "object",
|
|
130
|
+
"properties": {
|
|
131
|
+
"path": { "type": "string" },
|
|
132
|
+
"line": { "type": "integer" }
|
|
133
|
+
},
|
|
134
|
+
"required": ["path"]
|
|
135
|
+
},
|
|
136
|
+
"capability": "tools",
|
|
137
|
+
"risk": "low",
|
|
138
|
+
"approval_policy": "ask_once_per_run"
|
|
139
|
+
}
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
Runtime mapping:
|
|
143
|
+
|
|
144
|
+
1. Relay client registers tool descriptors.
|
|
145
|
+
2. Runtime constructs a `RelayToolset` from accepted descriptors.
|
|
146
|
+
3. Model calls generated SDK tool.
|
|
147
|
+
4. Runtime sends `tool.call` over relay.
|
|
148
|
+
5. Relay client executes the local tool.
|
|
149
|
+
6. Runtime records trace and returns model-facing result.
|
|
150
|
+
|
|
151
|
+
## Computer Mapping
|
|
152
|
+
|
|
153
|
+
Computer use can be represented as either:
|
|
154
|
+
|
|
155
|
+
- a specialized `RelayComputerProvider` used by a `ComputerUseToolset`.
|
|
156
|
+
- custom tools registered under the `tools` capability.
|
|
157
|
+
|
|
158
|
+
The specialized provider is preferred for product-grade computer use because it needs standard snapshot, action, artifact, pause, takeover, and policy semantics.
|
|
159
|
+
|
|
160
|
+
Method mapping:
|
|
161
|
+
|
|
162
|
+
```text
|
|
163
|
+
computer.status
|
|
164
|
+
computer.see
|
|
165
|
+
computer.act
|
|
166
|
+
computer.pause
|
|
167
|
+
computer.resume
|
|
168
|
+
computer.takeover
|
|
169
|
+
computer.release
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
## Binding to Agent Runs
|
|
173
|
+
|
|
174
|
+
Each relay request should include runtime context when available:
|
|
175
|
+
|
|
176
|
+
```json
|
|
177
|
+
{
|
|
178
|
+
"context": {
|
|
179
|
+
"session_id": "session_123",
|
|
180
|
+
"run_id": "run_456",
|
|
181
|
+
"tool_call_id": "call_789",
|
|
182
|
+
"workspace_id": "workspace_abc"
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
This lets providers upload artifacts, render user-facing prompts, and attach local audit logs to runtime objects.
|
|
188
|
+
|
|
189
|
+
## Lifecycle
|
|
190
|
+
|
|
191
|
+
```mermaid
|
|
192
|
+
sequenceDiagram
|
|
193
|
+
participant Runtime as Runtime
|
|
194
|
+
participant Server as Relay Server
|
|
195
|
+
participant Client as Relay Client
|
|
196
|
+
|
|
197
|
+
Client->>Server: connect + hello
|
|
198
|
+
Server->>Runtime: provider registered
|
|
199
|
+
Runtime->>Server: create RelayEnvironment for session
|
|
200
|
+
Runtime->>Server: request file/shell/tool/computer
|
|
201
|
+
Server->>Client: relay request
|
|
202
|
+
Client-->>Server: response / stream
|
|
203
|
+
Server-->>Runtime: SDK result
|
|
204
|
+
Runtime->>Server: dispose run resources
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
## Reconnect
|
|
208
|
+
|
|
209
|
+
Relay clients can reconnect with the same `client_id`. Server behavior:
|
|
210
|
+
|
|
211
|
+
- mark capabilities unavailable when disconnected.
|
|
212
|
+
- fail pending requests with `relay_disconnected`.
|
|
213
|
+
- accept a fresh `hello` after reconnect.
|
|
214
|
+
- recreate environments against the new connection when session policy permits it.
|
|
215
|
+
|
|
216
|
+
Future protocol versions can add resumable request IDs and provider-side durable sessions.
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
# 04. Security and Policy
|
|
2
|
+
|
|
3
|
+
## Goal
|
|
4
|
+
|
|
5
|
+
YA Environment Relay gives an agent runtime access to external execution environments. The protocol must make every capability explicit, scoped, revocable, and traceable.
|
|
6
|
+
|
|
7
|
+
## Trust Layers
|
|
8
|
+
|
|
9
|
+
```mermaid
|
|
10
|
+
flowchart TB
|
|
11
|
+
RuntimePolicy[Runtime Policy] --> RelayGrant[Relay Grant]
|
|
12
|
+
RelayGrant --> ProviderPolicy[Provider Local Policy]
|
|
13
|
+
ProviderPolicy --> Capability[Capability Execution]
|
|
14
|
+
|
|
15
|
+
RuntimePolicy --> HITL[Runtime HITL]
|
|
16
|
+
ProviderPolicy --> LocalPrompt[Provider User Prompt]
|
|
17
|
+
ProviderPolicy --> LocalBlock[Local Block]
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Runtime policy controls model-facing access. Provider policy controls local execution. Both can require approvals or block actions.
|
|
21
|
+
|
|
22
|
+
## Authentication
|
|
23
|
+
|
|
24
|
+
Relay connections should authenticate with a scoped token:
|
|
25
|
+
|
|
26
|
+
```http
|
|
27
|
+
Authorization: Bearer <relay-token>
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Token scope should include:
|
|
31
|
+
|
|
32
|
+
- client identity.
|
|
33
|
+
- allowed runtime or connection.
|
|
34
|
+
- workspace or Space identity.
|
|
35
|
+
- capability grants.
|
|
36
|
+
- expiration.
|
|
37
|
+
- revocation ID.
|
|
38
|
+
|
|
39
|
+
## Authorization Grant
|
|
40
|
+
|
|
41
|
+
Grant shape:
|
|
42
|
+
|
|
43
|
+
```ts
|
|
44
|
+
type RelayGrant = {
|
|
45
|
+
grant_id: string;
|
|
46
|
+
client_id: string;
|
|
47
|
+
runtime_id: string;
|
|
48
|
+
scope_id?: string;
|
|
49
|
+
capabilities: RelayCapabilityGrant[];
|
|
50
|
+
expires_at?: string;
|
|
51
|
+
created_at: string;
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
type RelayCapabilityGrant = {
|
|
55
|
+
capability: "fileops" | "shell" | "tools" | "resources" | "artifacts" | "computer";
|
|
56
|
+
enabled: boolean;
|
|
57
|
+
policy_id?: string;
|
|
58
|
+
roots?: RelayRootGrant[];
|
|
59
|
+
};
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
File roots should be individually granted:
|
|
63
|
+
|
|
64
|
+
```ts
|
|
65
|
+
type RelayRootGrant = {
|
|
66
|
+
root_id: string;
|
|
67
|
+
virtual_path: string;
|
|
68
|
+
mode: "ro" | "rw";
|
|
69
|
+
};
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Capability Acceptance
|
|
73
|
+
|
|
74
|
+
The relay server should accept only capabilities allowed by the active grant. The `hello` frame advertises provider capabilities. The server returns accepted capabilities in `relay.accepted`.
|
|
75
|
+
|
|
76
|
+
A provider may advertise `computer`; the server can accept only `fileops` and `tools` based on policy.
|
|
77
|
+
|
|
78
|
+
## Path Safety
|
|
79
|
+
|
|
80
|
+
Relay file operations use virtual paths and root IDs. Providers must enforce root boundaries after path normalization.
|
|
81
|
+
|
|
82
|
+
Rules:
|
|
83
|
+
|
|
84
|
+
- normalize paths before access.
|
|
85
|
+
- resolve symlinks according to root policy.
|
|
86
|
+
- reject traversal outside roots.
|
|
87
|
+
- preserve read-only grants.
|
|
88
|
+
- include root ID and virtual path in audit logs.
|
|
89
|
+
|
|
90
|
+
## Shell Safety
|
|
91
|
+
|
|
92
|
+
Shell grants should include:
|
|
93
|
+
|
|
94
|
+
- allowed roots and cwd.
|
|
95
|
+
- environment variable allowlist.
|
|
96
|
+
- network policy metadata.
|
|
97
|
+
- command approval policy.
|
|
98
|
+
- max runtime.
|
|
99
|
+
- streaming output limits.
|
|
100
|
+
|
|
101
|
+
Shell execution should use provider-local sandboxing when available.
|
|
102
|
+
|
|
103
|
+
## Tool Safety
|
|
104
|
+
|
|
105
|
+
Custom tools should declare risk and approval policy:
|
|
106
|
+
|
|
107
|
+
```ts
|
|
108
|
+
type RelayToolPolicy = {
|
|
109
|
+
risk: "low" | "medium" | "high" | "critical";
|
|
110
|
+
approval_policy: "allow" | "ask_once" | "ask_once_per_run" | "always_ask" | "block";
|
|
111
|
+
};
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
Runtime profiles can override provider suggestions with stricter rules.
|
|
115
|
+
|
|
116
|
+
## Computer Safety
|
|
117
|
+
|
|
118
|
+
Computer use should use additional local controls:
|
|
119
|
+
|
|
120
|
+
- explicit user enablement.
|
|
121
|
+
- visible active state.
|
|
122
|
+
- pause, takeover, release, stop.
|
|
123
|
+
- app allow/deny lists.
|
|
124
|
+
- screenshot retention policy.
|
|
125
|
+
- artifact upload policy.
|
|
126
|
+
- sensitive surface detection.
|
|
127
|
+
|
|
128
|
+
The provider should check local control state before each computer action.
|
|
129
|
+
|
|
130
|
+
## Artifact Safety
|
|
131
|
+
|
|
132
|
+
Artifact uploads should be tied to a run or approved workspace scope.
|
|
133
|
+
|
|
134
|
+
Artifact policy dimensions:
|
|
135
|
+
|
|
136
|
+
- allowed MIME types.
|
|
137
|
+
- max size.
|
|
138
|
+
- retention days.
|
|
139
|
+
- redaction required.
|
|
140
|
+
- upload approval for sensitive classes.
|
|
141
|
+
- remote runtime upload consent.
|
|
142
|
+
|
|
143
|
+
## Audit
|
|
144
|
+
|
|
145
|
+
Every relay request should be auditable:
|
|
146
|
+
|
|
147
|
+
```ts
|
|
148
|
+
type RelayAuditEntry = {
|
|
149
|
+
id: string;
|
|
150
|
+
connection_id: string;
|
|
151
|
+
client_id: string;
|
|
152
|
+
method: string;
|
|
153
|
+
session_id?: string;
|
|
154
|
+
run_id?: string;
|
|
155
|
+
tool_call_id?: string;
|
|
156
|
+
capability: string;
|
|
157
|
+
policy_decision: "allowed" | "approved" | "blocked";
|
|
158
|
+
started_at: string;
|
|
159
|
+
completed_at?: string;
|
|
160
|
+
status: "succeeded" | "failed" | "cancelled";
|
|
161
|
+
};
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
Runtime and provider can both keep audit logs. Runtime audit links to run trace. Provider audit supports local diagnostics and user trust review.
|
|
165
|
+
|
|
166
|
+
## Revocation
|
|
167
|
+
|
|
168
|
+
Revocation should close active sockets and fail pending requests. Provider-side revocation should stop new execution immediately. Runtime-side revocation should remove the relay provider from capability discovery.
|
|
169
|
+
|
|
170
|
+
Common revocation triggers:
|
|
171
|
+
|
|
172
|
+
- user disables relay for a Space.
|
|
173
|
+
- token expires.
|
|
174
|
+
- provider loses required permissions.
|
|
175
|
+
- remote runtime identity changes.
|
|
176
|
+
- policy version changes.
|
|
177
|
+
- user emergency stop.
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
# 05. Implementation Plan
|
|
2
|
+
|
|
3
|
+
## Phase 1: Spec and Models
|
|
4
|
+
|
|
5
|
+
Deliverables:
|
|
6
|
+
|
|
7
|
+
- spec folder.
|
|
8
|
+
- Python protocol models.
|
|
9
|
+
- TypeScript protocol model references for product clients.
|
|
10
|
+
- frame validation fixtures.
|
|
11
|
+
- method namespace constants.
|
|
12
|
+
|
|
13
|
+
Suggested Python package layout:
|
|
14
|
+
|
|
15
|
+
```text
|
|
16
|
+
packages/ya-environment-relay/
|
|
17
|
+
pyproject.toml
|
|
18
|
+
ya_environment_relay/
|
|
19
|
+
__init__.py
|
|
20
|
+
protocol.py
|
|
21
|
+
errors.py
|
|
22
|
+
capabilities.py
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Phase 2: In-Process Mock Transport
|
|
26
|
+
|
|
27
|
+
Build an in-process transport before WebSocket integration.
|
|
28
|
+
|
|
29
|
+
Deliverables:
|
|
30
|
+
|
|
31
|
+
- mock relay server.
|
|
32
|
+
- mock relay client.
|
|
33
|
+
- request/response roundtrip.
|
|
34
|
+
- stream and cancel tests.
|
|
35
|
+
- fake fileops provider.
|
|
36
|
+
- fake custom tool provider.
|
|
37
|
+
|
|
38
|
+
This validates Environment mapping without product-specific networking.
|
|
39
|
+
|
|
40
|
+
## Phase 3: SDK Environment Integration
|
|
41
|
+
|
|
42
|
+
Deliverables:
|
|
43
|
+
|
|
44
|
+
- `RelayEnvironment`.
|
|
45
|
+
- `RelayFileOperator`.
|
|
46
|
+
- `RelayShell`.
|
|
47
|
+
- `RelayToolset`.
|
|
48
|
+
- resource registry draft.
|
|
49
|
+
|
|
50
|
+
Tests:
|
|
51
|
+
|
|
52
|
+
- file read/list/write against fake provider.
|
|
53
|
+
- shell streaming result.
|
|
54
|
+
- generated tool call through `tool.call`.
|
|
55
|
+
- cancellation behavior.
|
|
56
|
+
|
|
57
|
+
## Phase 4: WebSocket Transport
|
|
58
|
+
|
|
59
|
+
Deliverables:
|
|
60
|
+
|
|
61
|
+
- relay server transport.
|
|
62
|
+
- relay client transport.
|
|
63
|
+
- heartbeat.
|
|
64
|
+
- reconnect state.
|
|
65
|
+
- request timeout handling.
|
|
66
|
+
- connection registry.
|
|
67
|
+
|
|
68
|
+
The server transport can first live in Claw, then move common pieces into `ya-environment-relay` after the API stabilizes.
|
|
69
|
+
|
|
70
|
+
## Phase 5: Claw Integration
|
|
71
|
+
|
|
72
|
+
Deliverables:
|
|
73
|
+
|
|
74
|
+
- Claw relay connection endpoint.
|
|
75
|
+
- relay provider registry.
|
|
76
|
+
- `RelayWorkspaceProvider`.
|
|
77
|
+
- session workspace binding support.
|
|
78
|
+
- run trace projections for relay calls.
|
|
79
|
+
- artifact reserve/upload/complete endpoints or adapters.
|
|
80
|
+
|
|
81
|
+
## Phase 6: Desktop Integration
|
|
82
|
+
|
|
83
|
+
Deliverables:
|
|
84
|
+
|
|
85
|
+
- Desktop relay client.
|
|
86
|
+
- Space-level relay grants.
|
|
87
|
+
- local fileops provider.
|
|
88
|
+
- local shell provider.
|
|
89
|
+
- custom tool registration.
|
|
90
|
+
- relay diagnostics UI.
|
|
91
|
+
|
|
92
|
+
## Phase 7: Computer Use Capability
|
|
93
|
+
|
|
94
|
+
Deliverables:
|
|
95
|
+
|
|
96
|
+
- `RelayComputerProvider`.
|
|
97
|
+
- `computer.status`.
|
|
98
|
+
- `computer.see`.
|
|
99
|
+
- `computer.act`.
|
|
100
|
+
- artifact upload for screenshots and UI trees.
|
|
101
|
+
- Desktop Host Computer Bridge integration.
|
|
102
|
+
|
|
103
|
+
## Test Matrix
|
|
104
|
+
|
|
105
|
+
| Area | Test |
|
|
106
|
+
| ----------------- | ---------------------------------------------------- |
|
|
107
|
+
| protocol | frame parse/serialize fixtures |
|
|
108
|
+
| request lifecycle | success, error, timeout, cancel |
|
|
109
|
+
| streaming | stdout/stderr/progress ordering |
|
|
110
|
+
| fileops | path normalization and root boundary |
|
|
111
|
+
| shell | output stream and signal handling |
|
|
112
|
+
| tools | JSON Schema descriptor to SDK tool |
|
|
113
|
+
| artifacts | reserve/upload/complete failure modes |
|
|
114
|
+
| reconnect | pending request failure and provider re-registration |
|
|
115
|
+
| security | grant filtering and capability acceptance |
|
|
116
|
+
|
|
117
|
+
## MVP Cut
|
|
118
|
+
|
|
119
|
+
Recommended first production slice:
|
|
120
|
+
|
|
121
|
+
1. `ya-environment-relay.v1` protocol models.
|
|
122
|
+
2. Claw WebSocket endpoint.
|
|
123
|
+
3. Desktop relay client.
|
|
124
|
+
4. file read/list/stat.
|
|
125
|
+
5. shell start with stream and cancel.
|
|
126
|
+
6. custom tool list/call.
|
|
127
|
+
7. artifact reserve/complete.
|
|
128
|
+
|
|
129
|
+
Computer use becomes the first high-value specialized capability after the base relay environment is proven.
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# YA Environment Relay Spec
|
|
2
|
+
|
|
3
|
+
YA Environment Relay is a provider-neutral protocol for connecting agent runtimes to external execution environments. It is designed to build on top of `ya-agent-sdk` Environment abstractions and expose remote or local capabilities as file operators, shells, resources, and toolsets.
|
|
4
|
+
|
|
5
|
+
YA Environment Relay is a general protocol. YA Desktop is one important relay client, but the protocol should also support headless relay agents, server-side workers, browser sandboxes, VM sandboxes, and custom tool hosts.
|
|
6
|
+
|
|
7
|
+
## Goals
|
|
8
|
+
|
|
9
|
+
- Let an agent runtime call capabilities that live outside the runtime process.
|
|
10
|
+
- Represent remote capabilities as SDK Environment components.
|
|
11
|
+
- Support file operations, shell execution, custom tools, resources, artifacts, and computer use.
|
|
12
|
+
- Use one bidirectional transport for request/response, streaming, cancellation, and provider events.
|
|
13
|
+
- Keep tool schemas compatible with JSON Schema and model tool calling.
|
|
14
|
+
- Preserve runtime-owned tracing, approvals, and artifact persistence.
|
|
15
|
+
|
|
16
|
+
## Package Direction
|
|
17
|
+
|
|
18
|
+
Initial work is spec-only. Future implementation can become a workspace package:
|
|
19
|
+
|
|
20
|
+
```text
|
|
21
|
+
packages/ya-environment-relay/
|
|
22
|
+
spec/
|
|
23
|
+
pyproject.toml
|
|
24
|
+
ya_environment_relay/
|
|
25
|
+
protocol.py
|
|
26
|
+
client.py
|
|
27
|
+
server.py
|
|
28
|
+
environment.py
|
|
29
|
+
providers/
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
The first Python implementation should integrate with `ya-agent-sdk` and expose:
|
|
33
|
+
|
|
34
|
+
- `RelayEnvironment`
|
|
35
|
+
- `RelayFileOperator`
|
|
36
|
+
- `RelayShell`
|
|
37
|
+
- `RelayToolset`
|
|
38
|
+
- `RelayResourceRegistry`
|
|
39
|
+
- protocol models for `ya-environment-relay.v1`
|
|
40
|
+
|
|
41
|
+
## Section Map
|
|
42
|
+
|
|
43
|
+
| Section | Document | Topic |
|
|
44
|
+
| ------- | ------------------------------------------------------ | ---------------------------------------------------------------------- |
|
|
45
|
+
| 01 | [01-overview.md](01-overview.md) | goals, parties, capability model, relationship to SDK and Claw |
|
|
46
|
+
| 02 | [02-protocol.md](02-protocol.md) | WebSocket frames, request/response, streaming, cancellation, errors |
|
|
47
|
+
| 03 | [03-environment.md](03-environment.md) | SDK Environment mapping, file operator, shell, resources, custom tools |
|
|
48
|
+
| 04 | [04-security-and-policy.md](04-security-and-policy.md) | authentication, grants, policy, approvals, artifact safety |
|
|
49
|
+
| 05 | [05-implementation-plan.md](05-implementation-plan.md) | MVP phases and package layout |
|
|
50
|
+
|
|
51
|
+
## Relationship to Products
|
|
52
|
+
|
|
53
|
+
- `ya-agent-sdk` provides the Environment concepts that YA Environment Relay implements remotely.
|
|
54
|
+
- `ya-claw` can host a relay server and route agent tool calls to connected providers.
|
|
55
|
+
- `ya-desktop` can act as a relay client for local files, shell, computer use, and custom tools.
|
|
56
|
+
- Future services can implement relay clients for sandboxes, browsers, VMs, and specialized tools.
|