optio-opencode 0.1.0__py3-none-any.whl
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.
- optio_opencode/__init__.py +38 -0
- optio_opencode/host_actions.py +432 -0
- optio_opencode/prompt.py +153 -0
- optio_opencode/session.py +552 -0
- optio_opencode/snapshots.py +101 -0
- optio_opencode/types.py +55 -0
- optio_opencode-0.1.0.dist-info/METADATA +84 -0
- optio_opencode-0.1.0.dist-info/RECORD +10 -0
- optio_opencode-0.1.0.dist-info/WHEEL +5 -0
- optio_opencode-0.1.0.dist-info/top_level.txt +1 -0
optio_opencode/types.py
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"""Public data types for optio-opencode consumers.
|
|
2
|
+
|
|
3
|
+
The generic ``DeliverableCallback`` / ``HookCallback`` types and
|
|
4
|
+
``SSHConfig`` are owned by ``optio-host`` (since they describe the
|
|
5
|
+
log/deliverables protocol and SSH config in general). This module
|
|
6
|
+
re-exports them so existing ``from optio_opencode.types import ...``
|
|
7
|
+
imports keep working unchanged.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from dataclasses import dataclass, field
|
|
11
|
+
from typing import Any, Callable
|
|
12
|
+
|
|
13
|
+
from optio_host.protocol.session import DeliverableCallback, HookCallback
|
|
14
|
+
from optio_host.types import SSHConfig
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
__all__ = ["DeliverableCallback", "HookCallback", "SSHConfig", "OpencodeTaskConfig"]
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
@dataclass
|
|
21
|
+
class OpencodeTaskConfig:
|
|
22
|
+
"""Configuration for one optio-opencode task instance."""
|
|
23
|
+
consumer_instructions: str
|
|
24
|
+
opencode_config: dict[str, Any] = field(default_factory=dict)
|
|
25
|
+
ssh: SSHConfig | None = None
|
|
26
|
+
on_deliverable: DeliverableCallback | None = None
|
|
27
|
+
install_if_missing: bool = True
|
|
28
|
+
# Absolute path on the host where the opencode binary is/should be
|
|
29
|
+
# installed. ``None`` (default) → ``~/.local/bin`` (user home resolved
|
|
30
|
+
# at task start). The same directory is used for installation, for
|
|
31
|
+
# smart-install's PATH lookup, and for the post-"ok" ``command -v``
|
|
32
|
+
# resolution, so an explicit override stays consistent across all
|
|
33
|
+
# three. Must be an absolute path when set.
|
|
34
|
+
opencode_install_dir: str | None = None
|
|
35
|
+
workdir_exclude: list[str] | None = None
|
|
36
|
+
supports_resume: bool = True
|
|
37
|
+
before_execute: HookCallback | None = None
|
|
38
|
+
after_execute: HookCallback | None = None
|
|
39
|
+
# Optional pair of synchronous bytes->bytes transforms wrapping the
|
|
40
|
+
# opencode session JSON blob at GridFS write/read. When both are set,
|
|
41
|
+
# the snapshot session blob is encrypted at rest. When both are None
|
|
42
|
+
# (default), plaintext is used (backward-compatible). Setting only one
|
|
43
|
+
# raises a config error: asymmetric usage is always a mistake.
|
|
44
|
+
session_blob_encrypt: Callable[[bytes], bytes] | None = None
|
|
45
|
+
session_blob_decrypt: Callable[[bytes], bytes] | None = None
|
|
46
|
+
|
|
47
|
+
def __post_init__(self) -> None:
|
|
48
|
+
e = self.session_blob_encrypt is not None
|
|
49
|
+
d = self.session_blob_decrypt is not None
|
|
50
|
+
if e != d:
|
|
51
|
+
raise ValueError(
|
|
52
|
+
"OpencodeTaskConfig: session_blob_encrypt and "
|
|
53
|
+
"session_blob_decrypt must be set together (both callables) "
|
|
54
|
+
"or both left as None; one without the other is a config error."
|
|
55
|
+
)
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: optio-opencode
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Run opencode web as an optio task; local subprocess or remote via SSH.
|
|
5
|
+
Author-email: Kristof Csillag <kristof.csillag@deai-labs.com>
|
|
6
|
+
License-Expression: Apache-2.0
|
|
7
|
+
Project-URL: Homepage, https://github.com/deai-network/optio
|
|
8
|
+
Project-URL: Repository, https://github.com/deai-network/optio
|
|
9
|
+
Project-URL: Issues, https://github.com/deai-network/optio/issues
|
|
10
|
+
Classifier: Development Status :: 4 - Beta
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
15
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
16
|
+
Classifier: Operating System :: MacOS
|
|
17
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
18
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
19
|
+
Classifier: Topic :: Software Development :: Code Generators
|
|
20
|
+
Classifier: Framework :: AsyncIO
|
|
21
|
+
Requires-Python: >=3.11
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
Requires-Dist: optio-core<0.2,>=0.1
|
|
24
|
+
Requires-Dist: optio-host<0.2,>=0.1
|
|
25
|
+
Requires-Dist: asyncssh>=2.14
|
|
26
|
+
Provides-Extra: dev
|
|
27
|
+
Requires-Dist: pytest>=8.0; extra == "dev"
|
|
28
|
+
Requires-Dist: pytest-asyncio>=0.23; extra == "dev"
|
|
29
|
+
|
|
30
|
+
# optio-opencode
|
|
31
|
+
|
|
32
|
+
Run [opencode web](https://github.com/opencode-ai/opencode) as an [optio](https://github.com/deai-network/optio) task — local subprocess or remote over SSH — with opencode's UI reachable through optio's UI components.
|
|
33
|
+
|
|
34
|
+
## What it does
|
|
35
|
+
|
|
36
|
+
Given an `OpencodeTaskConfig` (workdir contents, prompt, deliverable callback), `optio-opencode`:
|
|
37
|
+
|
|
38
|
+
1. Provisions a fresh workdir on the chosen host (local or remote).
|
|
39
|
+
2. Writes `AGENTS.md` (base prompt + your instructions) and `opencode.json` (your config) into it.
|
|
40
|
+
3. Installs the opencode binary if missing (remote mode only).
|
|
41
|
+
4. Launches `opencode web` with a random auth password.
|
|
42
|
+
5. Registers the opencode UI as a widget that optio's UI components can embed via the widget proxy — SSH tunnel hidden from optio-api.
|
|
43
|
+
6. Tails a log file the LLM writes to and translates structured lines into optio events:
|
|
44
|
+
- `STATUS: …` → `ctx.report_progress(percent, message)`
|
|
45
|
+
- `DELIVERABLE: <path>` → fetches the file, invokes your `on_deliverable` callback
|
|
46
|
+
- `DONE [summary]` → clean completion
|
|
47
|
+
- `ERROR [message]` → failure
|
|
48
|
+
7. Cleans up workdir and SSH connection on teardown.
|
|
49
|
+
|
|
50
|
+
The same `OpencodeTaskConfig` works for local and remote modes; only `SSHConfig` differs.
|
|
51
|
+
|
|
52
|
+
## When to use it
|
|
53
|
+
|
|
54
|
+
You want an opencode-driven assistant session as a managed optio task — surfaced through optio's UI, with progress reporting and file deliverables — without writing the host management, log parsing, or widget plumbing yourself.
|
|
55
|
+
|
|
56
|
+
## Installation
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
pip install optio-opencode
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Python 3.11+. Depends on `optio-core`, `optio-host`, and `asyncssh`.
|
|
63
|
+
|
|
64
|
+
## Minimal example
|
|
65
|
+
|
|
66
|
+
```python
|
|
67
|
+
from optio_opencode import create_opencode_task, OpencodeTaskConfig
|
|
68
|
+
from optio_host import SSHConfig
|
|
69
|
+
|
|
70
|
+
config = OpencodeTaskConfig(
|
|
71
|
+
workdir_files={"AGENTS.md": "Do the thing.", "opencode.json": "{...}"},
|
|
72
|
+
on_deliverable=lambda ctx, path, text: print(f"got {path}: {len(text)} bytes"),
|
|
73
|
+
ssh=SSHConfig(host="worker-1", user="optio", key_path="~/.ssh/id_optio"),
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
task = create_opencode_task(config)
|
|
77
|
+
# Schedule / run via optio-core as usual.
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Set `ssh=None` for local subprocess mode.
|
|
81
|
+
|
|
82
|
+
## License
|
|
83
|
+
|
|
84
|
+
Apache-2.0.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
optio_opencode/__init__.py,sha256=o9iKS_N-sTNR8rliw7teae1-yfYyZXz5QWyPnlCplMc,1040
|
|
2
|
+
optio_opencode/host_actions.py,sha256=NO6iGf-b_GIzinqtcDKeC3EtQFjEMnP17aL6euZlMk8,17331
|
|
3
|
+
optio_opencode/prompt.py,sha256=8L1QSdyu92wNiQOHtFdxR6aR0336CBTYzLaWzjwCiZw,6122
|
|
4
|
+
optio_opencode/session.py,sha256=oySS6pgCH6oOVjquwlrn6Kg4CPD30C3jwuMngB3X5WM,22394
|
|
5
|
+
optio_opencode/snapshots.py,sha256=wKX4OpCMYe-M9-LNZYVBxlaDtw9s15eZhR3c2mxreXw,3285
|
|
6
|
+
optio_opencode/types.py,sha256=Cs46PA6Mv1NraNObd_avWAx5xd8LMQ2elwkL2FpG-aE,2491
|
|
7
|
+
optio_opencode-0.1.0.dist-info/METADATA,sha256=DXDzoM32H1DH59GomwmxnanOsasMjvU_pIRd14ChKp8,3444
|
|
8
|
+
optio_opencode-0.1.0.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
|
|
9
|
+
optio_opencode-0.1.0.dist-info/top_level.txt,sha256=1jAPllx4JDiN8gzJtbS206_8fTFSwitP9dv1WkxyiYM,15
|
|
10
|
+
optio_opencode-0.1.0.dist-info/RECORD,,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
optio_opencode
|