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.
@@ -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,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (82.0.1)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1 @@
1
+ optio_opencode