Commit Graph

2117 Commits

Author SHA1 Message Date
Vyctor H. Brzezowski 82efd1f0ee fix: generate session and thread titles in sentence case (#123389)
Generated titles came back in Title Case because none of the title prompts stated a capitalization style; asked for a "title" with no case rule, models default to Title Case and nothing downstream corrects it. The tool-call purpose titles already ask for sentence case, so session titles, Discord auto-thread titles, and Telegram DM topic labels were the outliers.

Sets sentence case in each title prompt rather than post-processing: the titles follow the user's language, and sentence-case rules are language-specific, so a mechanical normalizer would mangle German nouns and proper nouns like OpenClaw or GitHub.
2026-08-15 01:38:41 -03:00
Peter Steinberger fc5265d685 improve: tighten newest regression ownership (#123606)
* test: tighten newest regression ownership

* test(ui): stabilize request-driven e2e waits

* fix(ci): stabilize lifecycle-bound test observations

* test(ci): pin current Telegram job cap

* test(ui): wait for terminal selection owner

* test(mac): use shared unread wait policy
2026-08-14 08:08:45 -07:00
Dallin Romney 83d53044a4 fix(channels): route commentary through one progress owner (#121009)
* fix(slack): keep commentary progress on draft lane

* fix(channels): route commentary through one progress owner

Keep non-verbose commentary in Slack and Discord draft lanes while preserving one durable commentary payload when verbose progress makes those drafts yield. Freeze that owner decision for the turn so session changes apply on the next turn.

Co-authored-by: Dallin Romney <dallinromney@gmail.com>

Punchcard-Session: amber-workshop-workshop-36

* fix(channels): refresh queued commentary owner

Recompute the frozen draft-versus-durable commentary owner for every queued follow-up turn and carry that decision into final payload projection.

Punchcard-Session: amber-workshop-workshop-36

* fix(channels): clarify commentary owner opt-in

* fix(channels): preserve queued draft preambles

* fix(channels): require explicit queued progress ownership

* refactor(channels): record commentary progress owner

* fix(telegram): tolerate unscoped queued updates

* test(discord): use canonical draft fixture after rebase

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-08-14 22:15:53 +08:00
Josh Avant 97a53a9b35 feat: audit admitted channel participant identity (#122863)
* feat: audit admitted channel participant identity

* fix: preserve Telegram identity through thread recovery

* fix: signal held gateway process groups

* fix: keep audit evidence passive in collect routing

* fix: validate copied channel participant evidence

* fix: bind channel participant evidence to host ingress

* fix: honor Telegram proof credential roles

* fix: restart held Telegram proof through gateway

* fix: repair channel identity CI regressions

* test(matrix): bind thread routing owner

* fix: preserve direct DM SDK compatibility

* fix: bind channel provenance at host runtime

* test(feishu): provide channel context builder

* fix: defer record-bound channel runtime resolution

* fix: keep channel admission evidence core-private

* fix(audit): bind channel admission to plugin lifecycle

* fix(audit): bind ingress provenance to final context

* refactor(audit): split admission scope keys

* test(queue): cover combined metadata carriers

* refactor(audit): keep lifecycle helpers private

* fix(queue): preserve combined turn authority

* test(channels): provide ingress context builders

* test(channels): align integrated CI fixtures

* test(clickclack): resolve model-loop ingress

* docs: preserve channel participant evidence invariant
2026-08-14 08:57:01 -05:00
Peter Lee ed08d1352b fix(telegram): reject webhook and health route collisions (#119268)
Reject reserved /healthz webhook configurations before registration, preventing silent Telegram update loss. Warn through Doctor and document recovery.

Co-authored-by: Peter Lee <22994703+xialonglee@users.noreply.github.com>
Co-authored-by: Ayaan Zaidi <hi@obviy.us>
2026-08-14 12:37:31 +00:00
iridescentWen 94cdb6c46e fix(telegram): preserve batched reply and quote context (#121907)
Preserve reply and selected-quote metadata from later Telegram debounce and fragment-batch messages while keeping reply-chain recovery bounded.

Co-authored-by: iridescentWen <whatmakesbetter@outlook.com>
Co-authored-by: Ayaan Zaidi <hi@obviy.us>
2026-08-14 17:27:11 +05:30
Ayaan Zaidi 72a8b9b5b4 fix(telegram): retry abandoned durable ingress updates (#123528)
Treat pre-adoption Telegram turn abandonment as retryable so durable ingress releases the claim instead of tombstoning an unprocessed update.
2026-08-14 10:55:37 +00:00
Ayaan Zaidi e826501fdb fix(telegram): resolve native command names from the loaded registry only (#123607)
Telegram native-command registration resolved provider names through the bundled channel-plugin fallback, which jiti-transpiles the entire plugin plus core graph from source when no registry entry is loaded (~190s silent CPU) — tripping the 300s no-output CI watchdog on the two Telegram test files that register at module scope. Telegram defines no resolveNativeCommandName hook, so the load resolved nothing. Thread the existing includeBundledChannelFallback option through the spec-listing helpers and use loaded-registry-only lookups in the Telegram plugin, matching the Discord sibling. Runtime names are byte-identical; both files drop from 200s to ~5s.
2026-08-14 10:47:20 +00:00
Vatsal Garg d8a1ebbb49 fix(approvals): prevent cross-channel exec approval leak (#122517)
Reject unbound foreign-channel fallback at shared approval-account selection while preserving recorded bindings and explicit forwarding targets. Cover Telegram and Matrix routing contracts.

Co-authored-by: vatsalgargg <vatsalg80@gmail.com>
Co-authored-by: Ayaan Zaidi <hi@obviy.us>
2026-08-14 13:11:03 +05:30
Ayaan Zaidi 0d584aabfb fix(telegram): preserve bare URL query separators (#123230)
Preserve raw query separators in Telegram rich-message bare URLs by leaving parser-generated links to Telegram entity detection. Authored Markdown links remain typed, while file references remain code-formatted.

Co-authored-by: Ayaan Zaidi <hi@obviy.us>
2026-08-14 02:19:53 +00:00
Ayaan Zaidi f70d5b8ba5 fix(reasoning-tags): prevent internal reflections in replies (#123196)
Treat <internal> blocks as private reasoning in the shared parser and remove Telegram raw-reasoning fallbacks. This keeps model reflections out of user-visible replies while preserving surrounding answer text.

Closes #122623

Co-authored-by: Ayaan Zaidi <hi@obviy.us>
Co-authored-by: WangYan <wang.yan29@xydigit.com>
2026-08-13 20:36:48 +05:30
Peter Steinberger c3d843eb24 test: remove residual duplicate assertions (#123134)
* test: remove residual duplicate assertions

* test: repair stale routing and capability fixtures

* fix(cli): bound one-shot stream drain exit
2026-08-13 04:41:37 -07:00
Peter Steinberger ccc1920068 improve(telegram): cut cold channel setup import latency (#122955)
* perf(telegram): keep setup entry on light graph

* fix(plugin-sdk): complete private UI hint boundaries
2026-08-13 01:55:47 -07:00
Peter Steinberger 683d37a35f test(telegram): align ingress fixtures with Bot API (#123059) 2026-08-13 00:58:17 -07:00
Peter Steinberger dbe4ce9f33 fix(telegram): prevent multi-agent cache ownership startup failures (#123029)
* fix(telegram): scope runtime caches by account owner

* test(telegram): type partial owner runtime stub

* refactor(telegram): remove obsolete default owner seam

* fix(telegram): tolerate partial durable updates

* test(telegram): request raw progress detail explicitly
2026-08-13 00:33:38 -07:00
Peter Steinberger 3f4f57a021 test(extensions): scope remaining multi-agent fixtures to explicit owners (#123021)
Class provenance: #114388 made multi-agent ownership explicit; prior partial sweeps #122883 and #122978 repaired Codex, Copilot, ClickClack, and policy fixtures.

Per-file changes:
- extensions/telegram/src/bot.create-telegram-bot.test.ts: declare startup owners for the four reload fixtures and add the default Telegram binding for the topic override case while preserving dynamic account/topic routing assertions.
2026-08-12 23:14:34 -07:00
Vincent Koc dabf55727b fix(ci): prevent channel add command test timeout (#122879)
* test(channels): isolate add env setup contracts

* test(channels): cover adapter env setup
2026-08-12 19:24:31 -07:00
Peter Steinberger c2d8b3be4d fix(telegram): prevent multi-agent startup migration false positives (#122877)
* fix(telegram): resolve legacy state owners explicitly

* docs(changelog): note Telegram migration ownership fix

* Revert "docs(changelog): note Telegram migration ownership fix"

This reverts commit e02962eb4b2e2475854adf8c2a2915bcfd1cf65a.
2026-08-12 18:13:45 -07:00
Peter Steinberger 2e86f7cc95 fix(telegram): preserve pre-dispatch send custody (#122741) 2026-08-12 10:47:08 -07:00
Peter Steinberger 99d662473c fix(channels): fail-fast headless channel setup with plugin-declared env contracts (#122530)
* fix(channels): validate headless channel setup

* docs(channels): document headless provisioning

* fix(channels): repair setup metadata typing

* chore(channels): regenerate official channel catalog for env metadata

* fix(slack): keep mode-conditional env contract plugin-owned

Static --use-env declaration keeps only the unconditional SLACK_BOT_TOKEN;
socket-vs-HTTP conditional requirements (app token, signing secret) stay in
Slack's own setup validation so HTTP mode no longer demands an irrelevant
SLACK_APP_TOKEN.

* chore(sdk): regenerate api baselines and catalog after rebase

* fix(slack): align manifest env declaration with runtime contract

* chore(sdk): regenerate api baselines after rebase

* chore(sdk): regenerate api baselines after rebase

* chore(sdk): regenerate api baselines after rebase
2026-08-12 17:12:15 +00:00
Peter Steinberger c23d66e3b5 refactor: consolidate coercion ownership (#122692)
* refactor: consolidate coercion ownership

* test: align shard check with weighted planning

* chore: refresh plugin SDK API baseline
2026-08-12 09:25:28 -07:00
Peter Steinberger b080dd1e76 refactor: consolidate coercion contracts (#122458)
* refactor: consolidate coercion contracts

Centralize exact string, record, numeric, date, Boolean, argument, and structured-error coercions while preserving call-site semantics.

Migrate canonical-name collisions and deprecated internal SDK bypasses, deleting 55 net production/tooling lines. Expand declaration ownership enforcement to 101 allowed helpers and add a narrow export-completeness audit.

* fix: preserve standalone script coercions

Keep copied Control UI tooling self-contained and retain the trusted release harness module-relative source seam when the harness runs against an old target cwd.
2026-08-11 23:26:37 -07:00
Peter Steinberger cb52ded58d refactor(telegram): split native commands by executor (#122419)
* refactor(telegram): split native commands by executor

* refactor(telegram): deduplicate DM-thread target session

* chore(lint): ratchet max-lines baseline after telegram commands split

* test(telegram): fix native command split checks
2026-08-11 21:45:17 -07:00
joshavant d4f8553a0c fix: retry debounced ingress failures before adoption 2026-08-11 22:27:11 -05:00
Peter Steinberger b350f76484 fix(channels): preserve failed agent run reactions (#122009) 2026-08-11 15:26:44 -07:00
Mariano edb7a1692e fix(telegram): expose live location updates to hooks (#122185)
* fix(telegram): expose live location updates to hooks

* test(telegram): keep location coverage focused

* fix(telegram): emit stopped live locations

* test(plugin-sdk): refresh location hook contracts

* docs(changelog): note Telegram live location hooks

* fix(telegram): complete live-location observer path

---------

Co-authored-by: mbelinky <mbelinky@users.noreply.github.com>
2026-08-11 23:26:23 +02:00
Ayaan Zaidi d2825c70a5 refactor(telegram): consolidate bot handlers into named modules (#122174)
The bot-handlers family was 22 files behind a 22-line fan-out: six files holding one callback switch, four holding one inbound pipeline, every interface a derived ReturnType, processMessage taking 8 positional args, and its params type declared inside bot-native-commands.ts. Three named coordinators (inbound pipeline, callback router, event bindings) now sit behind the same registerTelegramHandlers entry with hand-written leaf contracts; the factory graph, 16 slice/barrel files, and the type shim are deleted. Behavior-neutral: bot.test.ts and the ingress e2e byte-identical to main (SHA-256-pinned) and green; +185 production LOC accepted as the written-contract tradeoff.

Co-authored-by: Ayaan Zaidi <hi@obviy.us>
2026-08-11 18:18:16 +00:00
Peter Steinberger 86bc5aa726 test(plugins): remove stale test plumbing (#122175) 2026-08-11 11:01:05 -07:00
Peter Steinberger cad77fb39c refactor: consolidate remaining coercion helpers (#122020) 2026-08-11 10:22:01 -07:00
Ayaan Zaidi 1bfd12674c test(telegram): provision keyed store in ingress coalescing fixture
The command-menu locale ledger reads state.openKeyedStore during
hydration; the fixture's partial runtime stub lacked it, so the
degrade warning broke both claim-watchdog cancellation tests on main.
Provision it like the dispatch harness does. Surfaced by #122091's
follow-up work; suite runs locally only (see #122029 decision).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-11 19:01:16 +02:00
Ayaan Zaidi e31a6e29ff refactor(telegram): merge dispatch controllers into one turn module (#122091)
The four Telegram dispatch controllers were partitions of one closure: ~75 factory parameter slots, 7 post-construction back-edge setters, a shared mutable state bag, and load-bearing construction order. One turn record now carries the once-resolved config and all state; the four files remain as implementation with a hand-written leaf type contract (four state-slice types). Rides along: dead generation fence deleted (constant-0 from birth), queuedFinal ||= fix with regression (suppressed exec-approval turns no longer trigger a spurious fallback), collapse resolver/mutator split. Dispatch tests and harness byte-identical to main; live E2E lifecycle proof on the PR.

Co-authored-by: Ayaan Zaidi <hi@obviy.us>
2026-08-11 15:45:42 +00:00
Peter Steinberger 2cf725191c refactor(telegram): centralize text delivery (#117327)
Centralize Telegram text delivery: page planning and reply-target progression move into telegram-text-delivery.ts, shared by the durable send, edit, and streaming-final paths; bot/reply-threading.ts and per-path split/page logic are deleted. Formatted-to-plain recovery routes through withTelegramPlainFallback everywhere. Restores the projection-cursor invalidation contract on terminal multi-page failures (with regression). Net -321 production LOC. Live E2E on the PR: formatted entity path, plain-fallback recovery, and 2-page chaining.

Co-authored-by: Peter Steinberger <steipete@gmail.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-11 14:37:54 +00:00
Ayaan Zaidi 1dde25cb20 test(telegram): expect status-only default command progress preview
#121600 (4c951398ef) made default command progress status-only — raw
command text stays out of chat previews. This assertion still expected
the pre-#121600 preview with the raw command line; bisect-confirmed
first-bad at 4c951398ef. Pre-existing failure surfaced by the
dispatch-suite CI gap (#122029). Dispatch suite now 247/247.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-11 14:40:20 +02:00
Ayaan Zaidi 56d62e6f23 test(telegram): expect canonical channel-prefixed durable delivery target
resolveDeliveryTarget (src/channels/turn/durable-delivery.ts:57) reads
OriginatingTo/To — channel-prefixed refs — as its own fallback chain, so
telegram:-100555 is the contract shape for the durable 'to', not the
bare chat id this assertion expected. Pre-existing failure surfaced by
the dispatch-suite CI gap (#122029).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-11 14:40:20 +02:00
Ayaan Zaidi a6ab4b7d54 test(telegram): align dispatch custody assertions with final-update options
#121908 (210aca6de3) added the onPlatformSendDispatch options bag to
final draft-stream updates and updated draft-failures-progress.test.ts,
but missed 19 sibling assertion sites across 6 dispatch test files.
Those files do not currently execute in any CI lane, so main's local
dispatch suite has been red since. Two remaining failures
(context-recovery session-target prefix, draft-failures-progress
preview shape) predate #121908 and are tracked separately.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-11 14:21:06 +02:00
Peter Steinberger 02e8470bb8 refactor: burn SDK export collision debt (#121888)
* refactor: burn SDK export collision debt

* chore: regenerate collision debt baselines

* fix: update durable delivery core import

* fix: remove stale channel metadata type import

* fix: preserve config write SDK parameter type

* fix: preserve chat metadata SDK return type

* chore: refresh plugin SDK API baseline

* test: update plugin enable mock import

* fix: remove duplicate status helper re-export

* fix: preserve strict QA runtime availability errors
2026-08-11 05:06:11 -07:00
Ayaan Zaidi 79016b415a refactor(telegram): unify formatted-to-plain send degradation in one orchestrator (#121990)
The Telegram send-funnel parity invariant (durable and streaming funnels must degrade formatted sends identically) was prose-enforced and had drifted: draft previews and message edits only degraded on HTML-parse 400s, not empty-content 400s. One orchestrator (withTelegramPlainFallback) now owns classification, guard, logging, and plain-chunk planning for all 11 call sites; withTelegramHtmlParseFallback and buildTelegramPlainFallbackPlan are deleted. Net -29 production LOC. Behavior change: previews/edits recover empty-content 400s as plain text; degrade logs unify to `degrade=plain-fallback:<trigger>`.

Co-authored-by: Ayaan Zaidi <hi@obviy.us>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-11 10:29:26 +00:00
Ayaan Zaidi 73d4c07bd5 fix(delivery): record ambiguous final loss as durable notice debt (#121833)
A final reply whose platform send was accepted but whose response was lost
previously ended in silence. Custody that stays unknown after a claimed send
now records durable pendingDeliveryNotice debt; the next same-route turn
delivers one "could not confirm delivery" notice and acknowledges it into the
transcript. Restart recovery completes ambiguous sessions with the same debt
instead of a fire-and-forget notice; the debt survives reset and rollover, and
suppressed notice sends retain it instead of faking delivery. Permanent typed
no-send rejections settle as terminal suppression (no replay, no false
notice); retryable ones restore prepared custody for safe replay. Google Chat
media-only rejections use the typed no-send contract; Telegram native-command
replies join pending-final custody.

Fixes #80362

Co-authored-by: Ayaan Zaidi <hi@obviy.us>
2026-08-11 09:25:04 +00:00
Peter Steinberger e0b195690b fix(telegram): preserve finalized preview on late media failure (#121903)
* fix(telegram): preserve finalized preview on late media failure

* test(telegram): assert final preview delivery custody
2026-08-11 01:37:48 -07:00
Ayaan Zaidi 210aca6de3 fix(gateway): prevent restart replay after final delivery (#121908)
Re-lands the reverted #121507 on the current custody contracts. The reply dispatcher now owns direct-send pending-final custody: claim before provider I/O, terminal settlement for delivered/suppressed/failed outcomes, proven no-send stays replayable, ambiguous evidence fails closed — so Gateway restarts can no longer duplicate an already-accepted final reply.

Proof: ClawSweeper local review clean, exact-head ci-gate green, live Telegram E2E (one turn, one final, no duplicates).

Co-authored-by: Ayaan Zaidi <hi@obviy.us>
2026-08-11 13:09:59 +05:30
Peter Steinberger fa03d9b913 refactor: consolidate coercion helpers (#121366)
* refactor: consolidate coercion helpers

* fix: remove duplicate coercion imports

* fix: preserve serialized coercion guard

* chore: ratchet coercion helper carve-outs

* fix(test): keep gauntlet subprocess startup lean

* fix: preserve imported session timestamp semantics

* fix: preserve catalog timestamp string semantics

* chore: align plugin SDK surface ratchet

* fix: preserve trajectory and SDK string contracts

* fix(test): preserve QA record assertion semantics

* fix: complete standalone record guard rename

* refactor(cron): use canonical string coercion

* fix(acpx): preserve Pi timestamp parsing

* test(channels): adapt custody test harnesses

* test(telegram): classify media harness as test support

* test(acpx): split timestamp contract coverage

* test(channels): support generated custody contracts

* chore: ban the full coercion helper name set

Extends the declaration guard to all eleven consolidated helper names and
renames the cron schedule-identity readNumber wrapper to readScheduleInteger
so the banned generic name cannot regrow.

* fix(scripts): repair release-validation guard drift and lint cause

Restores the renamed isJsonRecord guard in assertTrustedWorkflowHarness after
main added isRecord call sites in parallel, and attaches the caught YAML error
as the thrown error cause (preserve-caught-error was red on main).

* fix: preserve Claude timestamp string semantics

* fix: preserve persisted timestamp string semantics

* fix: preserve date-first timestamp contracts

* fix(openai): harden delegation failure formatting

* chore: close coercion helper guard gaps

* test(openai): model non-error delegation rejection

* chore: refresh plugin SDK API contract

* fix(tasks): use canonical string field reader

* fix(ai): use canonical provider error field coercion

* fix(browser): migrate native bootstrap coercion

* docs(plugin-sdk): clarify text record export compatibility

* fix(gateway): normalize approval execution identity

* test(outbound): isolate message action poll harness
2026-08-11 00:02:18 -07:00
Peter Steinberger d6f70a96cb fix(plugins): native commands execute the selected plugin (#121544)
* fix(plugins): preserve selected command identity

* test(telegram): use scoped command registries

* test(telegram): isolate command runtime fixtures

* test(telegram): warm native command runtime

* refactor(plugins): keep command metadata private

* fix(plugins): accept synchronous command handlers

* fix(plugins): scope command drain bypass to live execution

* test(telegram): use scoped command registry fixtures

* test(telegram): isolate native menu runtime fixtures

* test(telegram): isolate login session store

* test(telegram): surface login flow failures

* test(telegram): preload native login module

* test(telegram): scope native command registries

* fix(plugins): complete command dispatch contracts

* fix(plugins): break command dispatch import cycles

* fix(plugins): stabilize command dispatch contracts

* fix(channels): keep plugin dispatch options internal

* fix(plugins): keep command dispatch carrier opaque

* test(channels): align delivery adapter fixtures

* test(delivery): align custody ownership coverage

* test(delivery): align latest queue reconciliation

* test(channels): drop obsolete delivery wrappers

* fix(plugins): rebind channel reload starts

* fix(plugins): scope command catalog reloads

* fix(ci): align current runtime contracts

* chore(plugin-sdk): refresh API baseline
2026-08-10 19:30:47 -07:00
Peter Steinberger c39abcecda fix(security): report DM isolation from effective routing (#121741)
* fix(security): audit effective DM session ownership

Resolve admitted DM principals through canonical route, account, identity-link, and channel-owned session policy before reporting shared-session risk. Doctor now renders the structured channel security owner instead of duplicating the global-only default-account heuristic.\n\nCloses #121711

* chore(plugin-sdk): refresh API contract baseline

* fix(telegram): preserve direct peer SDK export

* fix(telegram): preserve direct peer resolver signature

* fix(ci): use supported DM audit grouping

* fix(protocol): refresh approval reviewer Swift models
2026-08-10 15:34:37 -07:00
Ayaan Zaidi 9935ca3b30 fix(approvals): bind native requests to channel accounts (#121673)
Native approval delivery and resolution now stay bound to the originating or explicitly targeted channel account. Unbound requests fail closed across multiple eligible accounts; trusted reviewer-less SDK callers remain compatible.

Co-authored-by: Ayaan Zaidi <hi@obviy.us>
2026-08-11 01:42:41 +05:30
Ayaan Zaidi 4c951398ef fix(messages): keep runtime details out of chat alerts (#121600)
Keep raw commands, paths, and provider errors out of ordinary chat while preserving explicit raw diagnostics and structured admin history.

Default command progress is status-only; `/verbose full` and `commandText: "raw"` retain diagnostic detail.

Co-authored-by: Ayaan Zaidi <hi@obviy.us>
2026-08-10 21:37:48 +05:30
Peter Steinberger 3b3c540896 refactor: remove dead branches and test-only helpers (#121345)
* refactor: remove dead branches and test-only helpers

* fix: preserve codex cleanup error causes

* fix: preserve gateway error code compatibility

* chore: update plugin sdk api baseline

* docs: fix live cache runner path
2026-08-10 06:47:43 -07:00
Peter Steinberger 0d4e9f3ede fix(codex): report harness context window; compact context popover (#121491)
* fix(codex): report harness context window as session contextTokens

Codex app-server reports model_context_window per turn. Carry it through the projector into the run result meta so session rows show the real window instead of the catalog's standard-tier input cap (272k vs 1M for gpt-5.6 models).

* improve(ui): compact chat context popover

Inline stat rows replace boxed tiles; zero-value cost rows and the whole cost section when empty are omitted; provider/model provenance lines are removed because the footer already shows the model; and the popover is narrowed to 300px.

* refactor(codex): split attempt-result assembly out of event projector

* fix(codex): seed attempt context window from startup binding

App-server v2 turn/started omits the core model_context_window, so thread/tokenUsage/updated is the only live carrier. Seed usage-less attempts from the retained startup binding rollout/session window so session metadata cannot regress to the catalog fallback.

* fix(codex): prefer native startup context window

Persisted session contextTokens has no source provenance and may contain the catalog fallback. Keep the minimum window for the conservative rotation fuse, but seed the projector from the native rollout when it is available.

* chore(plugin-sdk): regenerate api baseline (new format)

* revert(gateway): "prevent restart replay after final delivery" (broke 5 CI jobs)
2026-08-10 05:52:19 -07:00
Ayaan Zaidi 1f75018600 fix(gateway): prevent restart replay after final delivery
Record channel delivery custody before recipient-visible sends so restart recovery cannot duplicate accepted finals.

Ambiguous legacy markers now fail closed with a visible interruption instead of blind replay.

Co-authored-by: Ayaan Zaidi <hi@obviy.us>
2026-08-10 16:42:14 +05:30
Peter Steinberger b8f861364c fix(telegram): preserve unsent media while deduplicating streamed replies (#121141)
* fix(telegram): preserve unsent media while deduplicating streamed replies

## What Problem This Solves
A Telegram final reply could resend an attachment already delivered in a streamed block when the legacy mediaUrl still referenced that sent attachment while another mediaUrls item remained. Conversely, unsent legacy-only attachments must not be discarded.

## Why This Change Was Made
The Telegram media-deduplication owner now clears mediaUrl only when its normalized attachment was actually sent, preserving independently unsent legacy attachments and preventing downstream outbound planning from restoring delivered media.

## User Impact
Telegram replies retain every unsent attachment exactly once and no longer duplicate already streamed images in mixed final-message payloads.

## Context
Seven zero-dependency scenarios passed against the actual media owner and outbound planner, including mixed legacy/vector attachments, whitespace normalization, visible-send handling, and remaining-media preservation. The exact frozen campaign baseline passed 844 tests. Existing oxfmt formatting and staged whitespace checks passed; focused Vitest CI remains pending.

* refactor(telegram): inline legacy media dedup check
2026-08-09 22:57:21 -07:00
Ayaan Zaidi 9c3241f19f fix(telegram): honor disabled topic command policy
Use the canonical topic → group → account → default policy for native commands. Disabled scopes now stop before routing and dispatch; sender-specific authorization remains explicit.

Co-authored-by: Ayaan Zaidi <hi@obviy.us>
Co-authored-by: JuniperTheDev <juniperthedev@users.noreply.github.com>
2026-08-10 10:27:44 +05:30