Release 0.9.0: native gocoon provider + withdraw/unstake fix + reset#23
Merged
Conversation
…fecycle - Replace the cocoon LLM provider with gocoon (pure-Go COCOON client, native OpenAI tool-calling); delete the XML tool-injection shim (src/cocoon/). - src/gocoon/: installer (download v0.2.0 + SHA-256 + cache), supervisor (spawn gocoon-runner + health + watchdog), lifecycle (init/waitFunded/ topup/withdrawAll) with a shared ProgressSink. - CLI: teleton gocoon init|topup|withdraw|status. - WebUI: /api/gocoon/* routes + Gocoon panel in Config. - Auto-start: provider=gocoon installs + supervises the runner on start.
Swap the XML tool-injection cocoon shim for gocoon, a pure-Go COCOON client exposing a native OpenAI-compatible API. Adds a turnkey TON channel lifecycle: download and verify release binaries, supervise the runner, init/fund/topup/withdraw, with auto-start when provider is gocoon. Exposes it via the `teleton gocoon` CLI and a dedicated Gocoon WebUI page. Pins gocoon v0.2.0; default model Qwen/Qwen3-32B.
pi-ai always sends stream:true and only parses Server-Sent Events, but the gocoon runner returns a single JSON document, so streaming clients parsed zero chunks and saw an empty response with zero tokens. Start a local proxy (when provider is gocoon) that forwards to the runner and frames its JSON reply as SSE, leaving gocoon itself unchanged. pi-ai points at the proxy instead of the runner.
codex was in the backend registry but missing from the hardcoded frontend provider list, so it never appeared in the WebUI. Add it, and treat it as keyless in provider-meta (it authenticates via the Codex CLI ~/.codex/auth.json, no API key to paste) so the switch flow shows no key field.
gocoon webui withdraw matches myduckai-agent: a Stop agent control, destination validation, type-"withdraw" confirm, and live progress polling, over the same withdrawAll the CLI uses. Unstake fix: withdrawAll located the channel via the owner wallet instead of the fund wallet (findClientSC(fundAddress)). The owner wallet has no on-chain history, so the channel was never found, the close was skipped, and only the liquid balance was withdrawn while the staked TON stayed locked. It now closes the channel and waits for the refund before draining, so the stake comes back. Wallet reset: teleton gocoon reset (CLI), POST /gocoon/reset, and a Reset wallet button delete the local wallet + config so the next setup creates a fresh owner/node wallet. Guarded: refuses while the runner is up, or while funds or a non-closed channel with stake remain. channelInfoOnChain checks the channel state (not the contract account status, which stays active after a cooperative close). --force overrides the fund/channel checks. Also a knip dead-code pass (events/bus, memory/agent/sessions, telegram/callbacks, SearchInput, a11y, assorted dead exports) and a webui cleanup (Dashboard, styles, AllowLists).
Drop the non-existent scripts/ entry from package.json files.
0.9.0 dropped 'cocoon' from the provider enum. Existing 0.8.6 configs with agent.provider: cocoon now migrate to 'gocoon' (carrying a custom cocoon.port) instead of failing config validation, mirroring the claude-code -> anthropic shim. Adds a loader test for the migration.
The create-release job rendered ghcr.io/${{ github.repository }} (mixed
case) in the public install snippet, which the Docker CLI rejects. Use a
lowercased step output, matching the actual image push.
- findClientSC throws a typed ChannelNotFoundError only for a genuine no-channel case; transient tonapi/HTTP errors propagate so withdrawAll ABORTS instead of draining the liquid wallet while the stake stays locked and reporting success. - withdrawAll decides liveness from the channel state (channelInfoOnChain stateName/stake), not the account status, so a re-run on an already-closed channel skips the close and sweeps the balance idempotently instead of re-closing and timing out. - waitForRefund returns a boolean; on a slow cooperative refund the withdraw no longer hard-fails (misleading 'lost') but reports the refund pending (~12h unilateral fallback) and leaves funds for a re-run. - resetWallet refuses when the channel state can't be verified (transient error) rather than risk deleting keys to a live stake. - gocoon wallet withdraw gets a generous --timeout for slow finality.
A runner error (non-2xx, a {error} envelope, or a non-JSON body) was
reframed into an empty 200 SSE stream that the OpenAI SDK parses as a
successful zero-token reply, hiding failures (no workers / channel out of
balance) and letting the agent retry silently. Now non-2xx is forwarded
with its status and error envelopes/parse failures become SSE error
events the SDK throws on. Adds completionToSse tests.
The version sentinel only checked a version string, so an out-of-band swap/corruption of gocoon/gocoon-runner went undetected. The sentinel now records each binary's sha256 and ensureGocoonBinaries re-hashes before reuse, re-downloading on mismatch. Legacy string sentinels re-verify once.
`gocoon status` printed the owner wallet (no on-chain history, not the deposit address) labelled 'COCOON wallet' — the same owner/fund confusion behind the unstake bug; it now shows the fund address. The WebUI top-up control is disabled while the runner is stopped (top-up needs a live runner).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Release 0.9.0.
Highlights
gocoonprovider replacescocoon(breaking): OpenAI-compatible pure-Go COCOON client with a turnkey TON payment-channel lifecycle (auto-install + integrity-verify the runner, supervise it, set up / top-up / withdraw from the CLIteleton gocoonor the WebUI Gocoon page). Nativetools/tool_callsreplace the removed XML shim.cocoon,events/bus,memory/agent/sessions,telegram/callbacks, webSearchInput,lib/a11y).Migration (breaking)
Set
agent.provider: gocoonand rename thecocoon:config block togocoon:(gocoon.port, default10000). Legacycocoonconfigs are auto-migrated on load.Fund-safety fixes
Release hygiene
npm audit fixin-range on root + web (root 8 vulns -> 1 low dev-only; web 4 -> 0). Major bumps (React 19, react-router 7, TS 6, etc.) deferred.npm ciin sync.[0.9.0].The tag
v0.9.0(pushed after merge) triggers npm + Docker + GitHub Release publishing.