Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,49 @@ All notable changes to Wirebot are documented in this file.

## [Unreleased]

## [0.4.0] - 2026-10-11

### Added

- Default-on Auto effort & speed: reassess every message against the full active
conversation using a subscription-backed GPT-6.1 Sol / Low / Fast classifier.
Research and debugging use Ultra at Standard speed; ordinary tasks use High or
Extra high, simple questions Low or Medium. Explicit speed requests use the fastest
tier available to the selected model and account. Local routing handles classifier
failures. Web and in-chat settings can switch back to manual mode.

### Changed

- Slack `/wirebot config` always opens the native settings buttons, including Auto
effort & speed, even when the browser app is available. `/wirebot web` remains
the browser entry point. In-chat Codex saves now refresh the loaded runtime settings.
- Updated the bundled Codex CLI from 0.159.0 to 0.162.1 and regenerated the app-server
protocol bindings, including support for the new partial-answer message phase.
- Model and speed pickers use the current Codex catalog, including GPT-6.1 Sol and
Ultrafast where available to the account. The web speed selector now shows Standard
correctly when no tier is configured. In-chat settings show speed names and reset
unsupported speed and reasoning choices when switching models, matching the web app.
- Slack mentions refresh the complete thread context, including intervening human
discussion. DMs no longer replay messages from before the latest `new` reset.
- New Codex threads explicitly retain legacy rollout history while the bundled CLI's
paginated history endpoints are unimplemented.

### Fixed

- Auto routing cancellation covers history and classifier startup, including late
responses; streamed classifier answers are retained when completion omits items.
- Auto speed stays local to the turn. Manual and scheduled turns restore default
effort, and continued model-specific threads use their actual model capabilities.
- Slack preserves message order during history retrieval; local fallback uses only
the latest request and recognizes negated speed requests and Russian questions.
- Toggling Auto preserves conflict detection for an unsaved web settings draft.
- Delayed Auto toggle responses preserve newly saved settings. Slack follow-ups
retain queued acknowledgements, attachment captions cannot bypass their queue,
and historical skill mentions no longer activate skills on later requests.
- Current voice transcripts remain separate from Slack history for routing and
skill selection. Ineligible classifiers skip history loading, and metadata lookup
failures no longer block otherwise runnable turns.

## [0.3.6] - 2026-09-29

### Changed
Expand Down
39 changes: 35 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -189,9 +189,9 @@ Telegram's hosted Bot API only allows bots to download files up to 20 MB and upl

## Slack connector

Wirebot can additionally bridge Codex into Slack over [Socket Mode](https://docs.slack.dev/apis/events-api/using-socket-mode) — no public URL required. Direct messages stream progress like the Telegram private chat; in channels the bot answers mentions in threads, with each thread acting as its own Codex conversation. Approvals arrive as buttons, files flow in both directions, and commands are available as `/wirebot <subcommand>` (Slack reserves bare `/new`-style messages for its own slash-command system). `@Wirebot new` in a thread, or `new` in the bot DM, restarts that conversation's Codex task and replays the messages before the restart into the next turn as plain-text context. Scheduled runs created from Slack notify back into the originating channel or thread.
Wirebot can additionally bridge Codex into Slack over [Socket Mode](https://docs.slack.dev/apis/events-api/using-socket-mode) — no public URL required. Direct messages stream progress like the Telegram private chat; in channels the bot answers mentions in threads, with each thread acting as its own Codex conversation. Approvals arrive as buttons, files flow in both directions, and commands are available as `/wirebot <subcommand>` (Slack reserves bare `/new`-style messages for its own slash-command system). `@Wirebot new` in a thread, or `new` in the bot DM, restarts that conversation's Codex task. Channel threads retain their full Slack history as context; DMs start fresh after `new`. Scheduled runs created from Slack notify back into the originating channel or thread.

Set `SLACK_BOT_TOKEN`, `SLACK_APP_TOKEN`, and `SLACK_ALLOWED_USER_IDS` together to enable it. [docs/slack.md](docs/slack.md) walks through creating the Slack app from a pasteable manifest, collecting both tokens, and first steps. Admins can open the full web app using `/wirebot config` or `/wirebot web` in a bot DM. No Telegram account is needed.
Set `SLACK_BOT_TOKEN`, `SLACK_APP_TOKEN`, and `SLACK_ALLOWED_USER_IDS` together to enable it. [docs/slack.md](docs/slack.md) walks through creating the Slack app from a pasteable manifest, collecting both tokens, and first steps. Admins can open native settings using `/wirebot config`, or the full web app using `/wirebot web`, in a bot DM. No Telegram account is needed.

## Discord connector

Expand Down Expand Up @@ -230,7 +230,7 @@ Wirebot's design rule is to use Codex's native app-server behavior instead of bu

Open `https://your-wirebot-origin/app` in a normal browser. Settings, Skills, and Schedules have bookmarkable URLs at `/app/settings`, `/app/skills`, and `/app/schedules`, and so do their detail pages: `/app/settings/model`, `/app/settings/access`, `/app/settings/features`, `/app/settings/environment`, `/app/settings/remote`, `/app/skills/<name>`, `/app/schedules/<id>`, and `/app/schedules/new`; `/` and the existing `/miniapp` URL work too. Wide browsers (900px and up) use a left rail that lists the Settings pages with their current values and shows usage limits, and open Skills and Schedules as a list beside the detail. Phones use bottom navigation on the three tab roots; sub-pages drop the tab bar in favor of a back link and a single bottom action, so a Save button never stacks on the tab bar. Browser colors follow the system light/dark preference, independently of Telegram. Mobile layouts support safe areas, dynamic viewport height, readable form controls, and pinch zoom.

For browser sign-in, send `/wirebot web` (or `/wirebot config`) in a private Slack or Discord bot chat; Telegram users can send `/web`. The bot replies with a private, one-use link that expires in 5 minutes. Open it in your preferred browser. Requesting a new link invalidates your previous unused link. After signing in, ordinary URLs work for 12 hours, including across reloads and new tabs. **Sign out** revokes that browser session; restarting Wirebot invalidates all links and sessions.
For browser sign-in, send `/wirebot web` in a private Slack or Discord bot chat; Telegram users can send `/web`. The bot replies with a private, one-use link that expires in 5 minutes. Open it in your preferred browser. Requesting a new link invalidates your previous unused link. After signing in, ordinary URLs work for 12 hours, including across reloads and new tabs. **Sign out** revokes that browser session; restarting Wirebot invalidates all links and sessions. In Slack, `/wirebot config` always opens the native menu buttons, including Auto effort & speed, model, manual effort, and the available speed tiers. Button changes save immediately and apply to the next Codex turn. Discord also accepts `/wirebot config` for browser sign-in when the web app is available.

Browser access follows the connector's bot-admin policy, not Slack workspace or Discord server roles: `SLACK_ADMIN_USER_IDS` and `DISCORD_ADMIN_USER_IDS` restrict access when configured, and otherwise every authorized user is an admin. All Telegram allowlisted users are admins. The server rechecks authorization when issuing links, exchanging them, and using a session (Slack workspace membership uses its existing 10-minute cache). Link secrets live in URL fragments, are removed from the address bar on load, and are exchanged for Secure, HttpOnly, SameSite cookies. Serve the public app over HTTPS and keep login links private. Browser auth uses no Telegram SDK, localStorage, or third-party authentication service.

Expand All @@ -247,9 +247,40 @@ The Settings tab opens as a summary: usage limits, the Codex configuration pages

Choices come from the running app-server and active configuration layers instead of a handwritten catalog. Codex itself is the validator: a save is a version-checked `config/batchWrite`, so all changes either pass Codex validation and land together or leave `config.toml` untouched. The app-server runs with `--strict-config`, so unknown configuration keys fail loudly.

In **Settings → Model**, choose an available model (including GPT-6.1 Sol, GPT-6 Astra,
GPT-6 Sol, and GPT-6 Luna). **Auto effort & speed** is on by default and reassesses
each message using the full current Codex conversation, including previous turns.
Slack mentions also include the entire Slack thread, including intervening human messages.
In DMs, `new` starts a fresh context; messages before it are not replayed.

| Request | Auto effort | Auto speed |
|---|---|---|
| Simple facts, translations | Low | Standard |
| Ordinary questions | Medium | Standard |
| Average tasks / complex work | High / Extra high | Standard |
| Deep research / debugging | Ultra (or the model's highest supported level) | Standard |
| Explicit request to work quickly | Appropriate to the task | Ultrafast, then Fast, then Standard, according to availability |

Routing uses a separate, ephemeral **GPT-6.1 Sol / Low / Fast** turn through the
existing Codex subscription sign-in, with host capabilities, tools, and MCP servers disabled.
It consumes subscription usage. If the classifier is unavailable, times out, or fails,
Wirebot uses local routing; a simple “continue” can reuse the last decision. The selected
answering model stays unchanged. Scheduled runs keep their configured settings.
Wirebot does not call the [Decisions API](https://developers.openai.com/api/docs/guides/decisions),
which documents separate Platform API-key authentication and billing.

Turn Auto off for manual reasoning and **Speed** controls. The toggle saves immediately
and is also available in Slack/Discord in-chat settings; choosing a manual effort or speed
there disables Auto. Fast and Ultrafast appear when Codex
advertises them for that model and account; availability follows your plan and workspace
settings. See [Codex speed modes](https://developers.openai.com/codex/speed) for usage
and access details. **Ultra** reasoning and **Ultrafast** speed are separate controls.
Switching models preserves compatible choices and resets unsupported reasoning or speed
options to their defaults. The Slack and Discord in-chat settings follow the same rules.

Wirebot keeps the running Codex process synchronized using the [app-server mechanisms designed for this purpose](https://learn.chatgpt.com/docs/app-server#api-overview):

- Mini App saves hot-reload the effective user configuration and carry supported model, approval, and reasoning choices into the next turn.
- Mini App saves hot-reload the effective user configuration and carry supported model, speed, approval, and reasoning choices into the next turn.
- External edits to config files are applied on demand: send `/reload` or press **Apply changes** in the Mini App to run the same reconciliation. An invalid edit leaves the last healthy runtime active and shows a degraded status.
- Skills use Codex's built-in watcher plus a forced `skills/list` refresh. Explicit `$skill-name` mentions are sent as native skill inputs.
- MCP definitions use `config/mcpServer/reload`. Codex queues refreshed MCP state for loaded threads, so it becomes active on their next turn.
Expand Down
2 changes: 1 addition & 1 deletion codex.version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.159.0
0.162.1
60 changes: 60 additions & 0 deletions docs/auto-mode.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# Auto effort and speed

Auto mode reclassifies every foreground user turn from the full active Codex
history and the latest request. Slack channel messages also include the complete
Slack thread; local fallback rules use only the latest message. DMs use the active
Codex thread and start fresh after `new`.

The classifier uses the user's Codex ChatGPT subscription with GPT-6.1 Sol, Low
effort and Fast when advertised by the model catalog. It has a separate ephemeral
thread, empty workspace, no tools or MCP servers, and a 20-second deadline covering
configuration, history and startup as well as inference. Cancellation releases
pending waits and cleans up late thread/turn startup responses. API-key accounts
and classifier failures use local rules without launching an additional billed
API request.

The answering model is unchanged. Supported effort and speed come from its live
catalog entry, including the effective model of a resumed model-specific schedule.
Auto uses `serviceTierForTurn` so its speed choice does not become a saved thread
preference. Manual turns and scheduled runs explicitly restore the effective
model's default effort when the configured effort is unset.
If model metadata cannot be read, Wirebot logs the lookup failure and keeps the
loaded settings so otherwise runnable foreground and scheduled turns can continue.

## Codex 0.162.1 protocol evidence

The compatibility behavior below was checked with the pinned **Codex 0.162.1**
app-server on 2026-10-11, using a fresh temporary Codex home and a loopback Responses
fixture with `requires_openai_auth = false`. Inference was simulated locally;
no vendor API key, subscription inference, external model endpoint or account
entitlement was involved. These observations verify app-server transport and
settings semantics, not live model availability.

Three sequential `turn/start` calls on the same thread produced these provider
request settings:

| Sent model / effort / persistent tier / per-turn tier | Provider model | Provider effort | Provider tier |
| --- | --- | --- | --- |
| `gpt-6-luna` / `max` / `priority` / omitted | `gpt-6-luna` | `max` | `priority` |
| `null` / `null` / `null` / `default` | `gpt-6-luna` | `max` | omitted (Standard) |
| `null` / `medium` / `default` / omitted | `gpt-6-luna` | `medium` | omitted (Standard) |

Thus null model and effort preserve the loaded settings, while explicit effort
restores the requested value. Both the persistent `default` value and the
documented per-turn `default` value were accepted. Auto uses the latter to avoid
changing persistent speed.

All three startup responses had empty `turn.items`. Successful completion
notifications carried the final agent message with `itemsView: "summary"`.
The classifier accepts this normal path and also retains `item/completed` text
for completions without answer items. It does not assume completion items are
always empty.

The pinned upstream implementation provides the corresponding contracts:

- [Turn processing and persistent overrides](https://github.com/openai/codex/blob/rust-v0.162.1/codex-rs/app-server/src/request_processors/turn_processor.rs): nullable effort maps to an optional override; null does not clear it.
- [Completion notifications](https://github.com/openai/codex/blob/rust-v0.162.1/codex-rs/app-server/src/bespoke_event_handling.rs): the last agent message becomes a summary item when available; otherwise the item list is empty.

Regression tests cover both completion shapes, cancellation during every startup
stage, late cleanup, default-effort restoration for manual/scheduled turns,
effective-model selection, full history and latest-message fallback routing.
39 changes: 20 additions & 19 deletions docs/slack.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ What works in Slack:
answers in a thread. Every message addressed to the bot needs a mention —
including follow-ups in the same thread — so human discussion around it
stays untouched. Each thread is its own Codex conversation with persistent
context. When first mentioned inside an existing thread, the bot reads the
earlier thread messages (up to 100, newest-biased) as context, so it
understands the discussion it was called into.
context. On every mention inside an existing thread, the bot reads all
earlier thread messages, including intervening human discussion. Auto mode
uses this context and the active Codex conversation to reassess effort and speed.
- Approvals: when Codex asks for confirmation, the question arrives as Slack
buttons.
- Scheduled runs: results are delivered to the channel or thread that created
Expand Down Expand Up @@ -119,10 +119,15 @@ Open it to the whole workspace only if that is acceptable.
Optionally, `SLACK_ADMIN_USER_IDS` (comma-separated member IDs) restricts
instance-wide commands — `/wirebot config`, `login`, `logout`, `reload`, and
`restart`, plus browser sign-in with `web` — to the listed users. Unset, every authorized user may
run them. `/wirebot config` opens the web app through a private sign-in link.
Set `PUBLIC_URL` to an HTTPS origin or use the automatic quick tunnel. Without
either, `/wirebot config` keeps the compact in-chat settings picker. Browser
sessions last 12 hours and retain the Slack user identity for schedule ownership.
run them. In a bot DM, `/wirebot config` always opens Slack menu buttons:
**Auto effort & speed**, **Model**, **Reasoning effort**, **Speed**, and access settings.
Auto has **On/Off** buttons; manual effort or speed selections switch Auto off.
Model and speed choices follow the account's live Codex catalog, including Ultrafast
where available. Changes save immediately and apply to the next Codex turn.

Use `/wirebot web` for the browser app through a private sign-in link. Set
`PUBLIC_URL` to an HTTPS origin or use the automatic quick tunnel. Browser sessions
last 12 hours and retain the Slack user identity for schedule ownership.

## 4. Configure Wirebot

Expand Down Expand Up @@ -157,12 +162,11 @@ variables set, Wirebot runs Slack-only with the same web app. Restart Wirebot an
`continue`) only work as `/wirebot …` in the bot DM; in a channel each thread
is its own conversation, so run them inside the thread as a mention
(`@Wirebot /stop`).
- **Restart with the thread carried over**: `@Wirebot new` inside a thread (or
plain `new` in the bot DM) starts a fresh Codex task for that conversation.
Your next message there carries the thread's messages from before the
restart — or, in the DM, the recent messages — as plain-text context (newest
8,000 characters), so Codex knows the discussion without the previous task's
memory. `@Wirebot /new` and `/wirebot new` behave the same way.
- **Restart**: `@Wirebot new` inside a thread (or plain `new` in the bot DM)
starts a fresh Codex task. Channel threads still provide their full Slack
discussion as context on the next mention. In DMs, messages before `new`
are excluded, including from Auto routing. `@Wirebot /new` and `/wirebot new`
behave the same way.
- **Sign-in**: if Codex is not signed in yet, `/wirebot login` in the bot DM
returns the ChatGPT device-code link, exactly like `/login` on Telegram.

Expand All @@ -171,12 +175,9 @@ variables set, Wirebot runs Slack-only with the same web app. Restart Wirebot an
- **Authorization**: messages, commands, and button clicks from users outside
`SLACK_ALLOWED_USER_IDS` are ignored (and logged). Scheduled runs re-check
the owner against the allowlist before every unattended execution.
- **Thread context after a restart**: the "already read this thread" memory
is in-process, so the first mention after a Wirebot restart re-reads the
thread history. The Codex conversation itself is persisted and continues.
- **Pending `new` carry-over**: the "replay the conversation on the next
message" note set by `new` is in-process too; if Wirebot restarts in between,
the next message starts the fresh task without the replayed context.
- **Context after a process restart**: the active Codex conversation is persisted
and continues; Slack thread context is refreshed on every mention. A DM `new`
reset remains effective across restarts.
- **Attachments**: inbound files are downloaded through Slack's private file
URLs with the bot token (never sent to third-party hosts); generated files
are uploaded back with `files.uploadV2`. Slack voice clips are transcribed
Expand Down
Loading
Loading