Repository navigation
v0.9.24: computer use and browser fixes, mothership tool deadlines and run cleanup, billing and seo improvements - #9099
Merged
Merged
Conversation
…lish (#9083) Co-authored-by: Sim Pi Agent <pi@sim.ai>
Co-authored-by: Sim Pi Agent <pi@sim.ai>
Models carry observe: {} over from click and type to set_checked,
select_option, click_at, insert_text and drag, and the driver refused those
calls outright, costing a round each time (26 refusals across 650 benchmark
episodes). The observation runs after the action exactly as it does for the
other actions.
…yling (#9079) * docs(changelog): prepare Connect agents to Oracle Database * improvement(changelog): expand release coverage and add link icons * fix(changelog): explain Vanta credential migration * improvement(content): simplify links and align markdown colors
…ts stop stalling commits (#9087) Vacuuming these tables writes WAL, mostly full-page images, faster than the synchronous standbys flush it, so every write commit on the primary waits for a standby until the vacuum ends. A per-table autovacuum cost delay and limit, on each table and its TOAST relation, cap that rate. The ALTERs are catalog-only under SHARE UPDATE EXCLUSIVE: no rewrite, and reads and writes never wait on them, even while one is queued behind a running vacuum. An integration test applies the migration and checks the lock mode, that writes proceed, and that the settings land on both relations.
… declare accepted kinds (#9086) The outbound receiver parsed a poll batch strictly, so one control kind this build did not know threw for the whole batch: nothing in it was answered and the worker waited out each request's timeout. Parse each request alone, answer an unknown kind 501 sim_control_unsupported and a malformed one 400, and keep running its batch-mates. Every poll now declares the kinds this build's generated contract parses, so the worker can stop sending kinds a receiver cannot handle.
* fix(desktop): make computer use act on the app the user sees - Hit-test coordinate input with Accessibility: Notification Center and the Dock keep full-screen click-through windows, so the window-list check rejected every click - Count an AX press that times out while a sheet or modal opens as dispatched - Keep the snapshot when nothing reached the app, in the helper and the service - Type into any focusable element (terminals, combo boxes), send keys to sheets and popovers, accept common key aliases - Complete menu presses that only highlight their item, observe open menus and submenus first, and show menu shortcuts in labels - Fit the model projection under Mothership's computer result budget * test(desktop): computer-use snapshots survive actions that sent nothing * fix(desktop): refuse unverifiable clicks, stop menu completion on cancel, scope press_key - Refuse coordinate input when Accessibility cannot say which app owns the point - Check cancellation before the menu-completion Return - press_key goes to the observed window or a dialog, panel or popover above it, never another document window - Only presses treat an Accessibility timeout as delivered; a value or selection change that times out fails as uncertain * fix(desktop): accept press_key without a window and screenshot shorthand on actions Mirrors the worker contract: press_key may omit windowId (the key goes to the focused observed window, or a dialog above it), and mutations accept includeScreenshot as shorthand for observeAfter.includeScreenshot. * fix(desktop): type the computer-use params omit over the whole input union * fix(desktop): confirm the click window and the highlighted menu item before input - A coordinate click must land in the observed window, or in a sheet, popover, panel or menu above it; another document window of the same app is refused - The menu-completion Return is sent only when the pressed item reports itself highlighted * fix(desktop): refuse input when the receiving window cannot be confirmed Clicks and keys go only to the observed window, or to one of the app's dialogs or floating panels above it. A missing window attribute is allowed only for menus, and an unreadable subrole is refused rather than treated as auxiliary. * fix(desktop): revalidate the editor's window before every keystroke type_text and input_sequence check, before each key, that the editor still sits in an observed window (or a dialog above it) at its observed frame. * fix(desktop): compare the observed window's identity, not only its bounds Each observed windowId keeps its Accessibility window, and click, key and editor checks require that exact window at its observed frame (or a dialog or floating panel), so a second document window with identical bounds is refused. * fix(desktop): refuse input to windows whose identity is ambiguous Window-list entries match their Accessibility windows only by bounds; when two windows share bounds neither gets an identity, so input aimed at either is refused instead of possibly reaching the other. * fix(desktop): read editor focus after activateFirst brings the app forward
…wn 404s (#9088) * improvement(seo): list the v2 API as a catalog item and answer markdown 404s * fix(seo): keep the HTML 404 for clients that refuse Markdown and answer every method
…emoved (#9089) * fix(mothership): stop live runs when their chat, owner or access is removed Deleting a chat, an account or a workspace, or removing someone's access, left the worker's run going: no path issued a Stop, and run control answered the missing chat or owner with a 404/403 the worker can only retry. - Run control answers Stop when the run's chat is deleted, its owner or workspace is gone, or the owner lost access; only a failure to read is an error - Chat delete, copilot chat delete, account deletion, workspace archive, member removal, organization removal, transfer and external-collaborator removal record Stop in their own transaction and push it after commit - Stop delivery is shared with the user's Stop - A takeover never claims a run whose chat was deleted * fix(mothership): deliver removal stops from callers outside page graphs Membership and workspace lifecycle modules sit in page server graphs, so they return the runs they stopped and their callers deliver the Stop. Fixes the organization run-control scope narrowing and shrinks the baselines this change paid down. * fix(mothership): keep stop delivery complete when its rows or marker are gone - Read a stopped run's client workflows and sandbox commands inside the removal's transaction, before a hard delete cascades them away - Abort this process's controller even when the abort marker cannot be written, and keep delivering the rest of the Stop - Account deletion no longer depends on the run-routing lookup - The operator archive repair keeps the delivery out of its script graph - Race test orders admission and deletion with a row-lock barrier; delivery assertions only count the test's own runs * fix(mothership): signal a stopped run before reading its work, and deliver each removal stop once - The user's Stop signals the worker and controller while its workflow and sandbox ownership is still being read - Workspace deletion starts delivering its Stop as soon as the archive commits, before the slower post-archive cleanup - External-collaborator removal delivers the Stop it recorded even when no access was left to remove - Leaving a workspace that also ends the organization membership delivers each run's Stop once * fix(mothership): never answer Stop for a refused delegation or an admin who keeps access - Run control rethrows a refusal of the caller's own delegation (expired mid-request or out of scope) instead of answering Stop; only the chat, owner or access standing answers Stop - Withdrawing a workspace grant stops the user's runs only when no effective access remains, so an organization admin keeps their run * fix(mothership): stop an organization admin's runs when a demotion ends their access Withdrawing a workspace grant and demoting an organization admin both end access only where no effective access remains, so the check runs after either: a role change that drops admin stops the member's runs in the organization's workspaces they can no longer reach, whatever order a directory sync withdraws the grant and the role in. * fix(mothership): keep stopped-run identities out of removal results, check access only where runs live - Organization member removal delivers its stopped runs and strips them from the result it returns to the route and audit - Withdrawing a grant or demoting an admin checks remaining access only in workspaces where the user has a live run, instead of every organization workspace under the mutation lock
…me names (#9090) * fix(mothership): bound every handed tool call by the deadline its frame names * fix(mothership): start nothing for a tool call once its deadline has passed * test(mothership): type the client deadline waiter mock * fix(mothership): report a past-deadline client call as not run only when nothing claimed it * fix(media): submit no fal request for a caller that already gave up * fix(media): flag a refused fal cancellation and stop an aborted inline download
…it (#9091) * fix(billing): re-read the usage gate often once a payer nears its limit The usage gate cached a within-limit admission for five minutes, so a payer who crossed the limit kept running executions and copilot steps for up to that long. On a free plan that is unbilled spend; on a capped plan it bills past the cap. An admission is now held for 10s when the payer or the acting member has less headroom than the larger of $25 and 20% of the limit (every free-plan payer), and for the full five minutes otherwise. The direct-v1 account verdict cache follows the same rule. * test(billing): drive the gate-cache clock with faked timers instead of real waits
…adline left (#9092) * fix(mothership): start no tool call with less than a minute of its deadline left * fix(mothership): refuse a late claim at the database and settle an unclaimed call as not run
…ed sheets (#9093) * fix(desktop): accept coordinate input without a window, one-axis scrolls and targeted keys Mirrors the worker contract. Coordinate clicks, scrolls and drags without a windowId target the window the snapshot selected; scroll deltas default to 0; press_key with an elementId focuses that element first. Each shape was rejected before reaching the app in benchmark runs (about one call per task). * fix(desktop): let input reach sheets attached to the observed window Go to Folder and out-of-process open and save panels are sheets: the app reports them as its focused window, and a panel's contents report no window at all. Input checks now treat a sheet as the window it is attached to, and a click on windowless panel content is allowed only inside the app's focused sheet. * fix(desktop): keep coordinate input on the selected window and confirm targeted focus - Coordinate clicks and scrolls without a windowId use the snapshot's selected window through every input check; element targets keep their own window - press_key with an elementId sends the key only once that element holds focus - The service observes the selected window after a call without one - A scroll needs at least one delta, matching the worker contract * fix(desktop): observe the focused window after an untargeted key
…rovenance withheld (#9094) * fix(billing): answer an in-flight retry at once, and tell Chat what provenance withheld A cost callback retried while an earlier attempt of the same request was still committing (a commit can wait on a synchronous standby while holding the request's ledger lock) waited out lock_timeout on a pooled connection and failed with a 500. The ledger lock is now taken without waiting: a held lock answers 503 BILLING_REQUEST_IN_FLIGHT (Retry-After) at once, and the caller resends later; the monotonic top-up applies the higher cumulative once. Provenance refusals are policy, not faults: each gate admission now reports its refusals as one warning with counts and a bounded sample instead of one error per item, and the table envelope's unknown-row line is a warning. Chat's CLI result now notes how many items of each kind a gate withheld, on stderr, so the model can tell a withheld item from an absent one. Callers outside Chat never classify content and see no change. Also corrects two comments: the worker's callback timeout is 15 s, and no transaction setting bounds a commit waiting on a standby. * test(billing): model the ledger try-lock in the unit tx mock; pass the route context The usage-log unit mock answered every statement with undefined, which the try-lock cannot read; it now answers whether the lock was taken, with a test that a held lock refuses before any read or write. The new route test passes the route context like the typed handler expects, and the refusal reason type stays module-private. * fix(mothership): word the withheld note for every refusal, and describe the rows that read as unknown A gate refuses either the item (unknown provenance) or only the requested view (an excerpt or raw bytes redaction cannot cover), so the note no longer says another read cannot return it. Untracked legacy rows read as exact-empty; only tracked rows with a stale, missing or malformed sidecar read as unknown. * fix(provenance): keep refused ids paired with their cause, name sandbox files by hash, and tell Chat why each item was withheld Refusal reports are grouped by surface, cause and owning record (document, table or chat), each line with top-level surface, cause and refusedCount and the refused ids (up to 200, flagged when truncated), so per-cause queries and id-to-cause pairing survive aggregation. A sandbox file is attributed by a chat-scoped hash of its path rather than the path, which carries the user's file name. A streamed sandbox image declares its view opaque, so its refusal reads as opaque content rather than a missing registry; the use case now requires every caller to declare the view. Gate verdicts carry the refusal reason, and Chat's CLI note says per reason what a read can do next: unknown provenance will not return on a retry, recorded secrets can be read as text for a redacted copy, and provenance that could not be verified may be readable later. Chunk write refusals name their document as the parent. * fix(billing): an in-flight refusal is not a slow ledger transaction The usage ledger's slow-transaction warning fired for every in-flight refusal (stage lock, not succeeded), although nothing waited and the route already logs the refusal once at INFO. It now skips refusals. The span keeps the existing internal_error outcome, since the closed outcome set is generated from the legacy contracts; the response code and the INFO line tell it apart. * fix(provenance): keep this change to the refusal logs and note it introduced Drops the sandbox attribution id, the streamed-image view and the owning-record ids from this change; they belong to the provenance owner's work and fix behavior that predates it. Refusal lines stay one per surface and cause with top-level surface, cause and refusedCount and every refused id as each line names it today, and the note keeps its per-reason wording. * fix(provenance): give every refusal line a refusedCount, and say what tells an in-flight 503 apart A single refusal now carries refusedCount 1 like a grouped one, so summing refusedCount by cause covers both. The route comment now says the span is the same as the retryable settlement 503's and that the body code and the INFO line distinguish them.
…fy competitor pricing, and rebuild the GitHub, Shopify, and Snowflake integration pages (#9098) * improvement(seo): lead comparison pages with a direct answer, re-verify competitor pricing, and rebuild the GitHub, Shopify, and Snowflake integration pages * fix(seo): scope Sim run hosting, fetch PR files in the GitHub example, and drop stale Gumloop free-plan rows * fix(seo): note Gumloop VPC runs are not billed for compute
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
|
* feat(memory): authorize scoped access and durable cleanup * refactor(memory): distinguish scoped note access controls Rename the scoped-note control kind from memory_access to memory_notes_access so it is distinct from graph memory_scope. The HTTP path, delegation audience sim:memory-access, and semantic operation id are unchanged. * chore(audits): exempt Mothership contract copies from the relative-import rule contracts:sync copies these files byte for byte from the worker, whose sibling imports are relative, so they cannot use the app's aliases. Exempt only files in lib/mothership/generated that carry the sync header, and drop their baseline entries. * fix(memory): read-lock note authorization, redact legacy tool calls, skip keyless cleanup Project note checks took the Project lock exclusively while already holding it shared, so overlapping workspace checks could deadlock; they now read under the shared Project lock and the permission-group read lock, as Project Files does. Exports also redact remember calls stored in the legacy top-level toolCalls list. A Sim without COPILOT_API_KEY never reached a worker, so it queues no memory cleanup it could not deliver. * test(memory): use the shared env and outbox mocks for cleanup enqueue
Contributor
[High impact] Billing system changes and API contract updates across multiple services. Desktop deadline enforcement should survive controller loss before this PR merges. FindingsSummaryThis release improves desktop and browser actions, adds tool deadlines and run cleanup, tightens billing checks, and updates stored-content evidence and public content.
|
…t, drop unused contract target (#9100)
…epted knowledge-base file type (#9101)
…ction commits (#9104) * fix(scim): push Stop for runs a directory sync ends, after its transaction commits A directory sync that withdrew a workspace grant or demoted an organization admin recorded Stop for the user's live Chat runs but never pushed it, so the runs ended only on the worker's next run-control read. - Projection deltas carry the runs their withdrawals stopped; withdrawGrant and setOrganizationRole return them instead of dropping them - Group writes and user updates deliver them once their transaction commits; the batched reconcile delivers each batch after it commits, so a rolled-back batch delivers nothing - Member removal, transfer and external-collaborator removal results carry stoppedRuns as a required field, returned from inside the transaction * fix(scim): judge directory stops against the pass's final access - A reconciliation pass that demotes an admin or withdraws a grant while granting the same workspace back no longer stops the run there: access is checked once after every withdrawal and grant - Fix the readonly skipped result that failed type-check - Cover a committed batch delivering when a later batch rolls back, and observe rollback deliveries deterministically
…ce than members (#9109) * fix(slack): refuse binding a Search bot to a different app or workspace than members * fix(slack): check Search app availability on the caller's transaction
…hare, live-doc persist and cleanup edge cases (#9110) * fix(file-search): keep a skipped build published so rendered reads stop requeueing it A skipped publication retired its build and cleared the revision's build id, so a compiled document whose index build skipped never matched its rendered artifact key: every rendered read requeued it, and the worker downloaded, compiled and skipped it again. Skipped builds now stay published with their bound artifact key (and no text), and the artifact-current checks accept a skipped revision. Failed revisions still requeue. * fix(public-shares): answer a shared Project page with a foreign embed as not found renderSimPageDocument throws ProjectPageForeignEmbedError for a Project page that embeds another owner's file. The authenticated artifact read maps it to not_found, but the public content and inline reads let it escape as a 500. Map it the same way at both public render sites. * fix(file-doc): let the workspace document persist take a full snapshot The relay's workspace persist ran behind the proxy with the default 10 MB body cap, so a collaborative state above ~7.5 MiB (12 MiB is allowed) was refused with 413 while the Project persist route took it. Exclude the workspace persist from the proxy matcher and give it the same bypassesProxy body cap, now shared from collab-doc state, and the same off-app-host refusal. * chore(knip): drop the stale ignore for the v2 Project file search contract Its only export is now imported by the v2 route and the OpenAPI spec. * fix(memory): let a rejected key spend memory cleanup attempts A 401 from the worker waited hourly without consuming an attempt, like a missing route, so a permanently revoked self-hosted key kept its cleanup rows pending forever. A 401 still waits an hour but now spends an attempt, so it dead-letters after the default attempts (about ten hours), past a worker rollout. 404, 405 and 501 keep waiting for free. * fix(public-shares): log expected public file share client errors as warnings The public file share routes logged every caught error at ERROR, including classified client failures such as a missing share (404) or a password exchange against a non-password share (400). Log a classified 4xx as a warning and keep ERROR for unclassified failures. * fix(public-shares): import the error logger in the OTP route * test(file-search): skip on a corrupt compiled document the parsers reject
…sues whose summary holds every term (#9111)
…locked owner stop their run (#9114) * fix(mothership): settle a stopped run's call as never run only while nothing started it * fix(mothership): let a blocked owner stop their admitted run
…utes (#9113) * fix(copilot): load workflow chat history through the windowed chat routes * fix(copilot): scope workflow chats without a workspace through their workflow * test(copilot): name each workflow chat fixture's workflow uniquely
…ms of a longer query (#9115) * improvement(search): fall back to summaries holding half the terms of a longer query * fix(search): count Jira half-term summaries by stemmed term, from a wider pool, most terms first * improvement(search): share the half-terms threshold and convert Jira descriptions only when filtered
* docs(library): update byok-multi-model-ai-agent-builder * Pi Babysit: address PR #9116 feedback --------- Co-authored-by: Sim Pi Agent <pi@sim.ai>
* docs(library): update n8n-alternatives * Pi Babysit: address PR #9119 feedback --------- Co-authored-by: Sim Pi Agent <pi@sim.ai>
* docs(library): update langgraph-alternatives * Pi Babysit: address PR #9118 feedback --------- Co-authored-by: Sim Pi Agent <pi@sim.ai>
…-healthcare-legal-procurement (#9117) Co-authored-by: Sim Pi Agent <pi@sim.ai>
… and AX failures (#9112) * fix(desktop): tighten computer use input guards for text, tabs, menus and AX failures * fix(desktop): keep hidden tabs out of the window list and pin typed text to its first editor
…ose holding half of them (#9121) * improvement(search): follow Jira summaries holding every term with those holding half of them * improvement(search): dedupe the Jira summary tiers and the all-terms page in one pass
This branch was previously deployed
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.
Uh oh!
There was an error while loading. Please reload this page.