Skip to content

v0.6.8: mothership tool loop#3733

Merged
Sg312 merged 29 commits intomainfrom
staging
Mar 24, 2026
Merged

v0.6.8: mothership tool loop#3733
Sg312 merged 29 commits intomainfrom
staging

Conversation

@icecrasher321
Copy link
Collaborator

@icecrasher321 icecrasher321 commented Mar 24, 2026

Summary

fix(auth): hide Turnstile widget container to prevent layout gap (#3706)
improvement(mothership): copilot, files, compaction, tools, persistence, duplication constraints (#3682)
fix(mothership): workflow name constraints (#3710)
fix(mothership): minor followups (abort fix, diff engine fix) (#3709)
fix(mothership): fix edit hashing (#3711)
fix(kb): store filename with .txt extension for connector documents; fix stuck-doc retry race conditions and parsing edge cases (#3707)
chore: optimize all the images (#3713)
feat(sidebar): add right-click context menu to settings nav item (#3715)
chore: client and server components (#3716)
improvement(mothership): add file patch tool (#3712)
fix(mothership): fix build error (#3717)
fix(auth): use absolute positioning for Turnstile container (#3718)
fix(login): move password reset success message inside the form (#3719)
improvement(settings): add searchable member selector in integrations and secrets (#3721)
fix(tables): use overflow-clip on header text to allow horizontal scrolling (#3722)
feat(slack): add conversations.create and conversations.invite tools; integrate into Slack block; update outputs/docs (#3720)
fix(copilot): allow loop-in-loop workflow edits (#3723)
fix(autolayout): coalesce edits for same request diffs (#3724)
improvement(settings): add “View Invoices” button; add error alert on billing portal failure (#3726)
fix(oauth): decode ID token instead of calling Graph API for Microsoft providers; improve error handling (#3727)
feat(quiver): add QuiverAI integration for SVG generation and vectorization (#3728)
fix(mothership): tool call loop fixes; subagent, streaming, hydration, and execution improvements (#3729)
fix(quiver): build fail (#3730)
fix(mothership): tool durability (#3731)
fix(ppt): dependency injection (#3732)
fix(mothership): abort streamlining (#3734)
fix(mothership): async resume and tool result ordering (#3735)

waleedlatif1 and others added 26 commits March 21, 2026 13:23
The invisible Turnstile iframe was taking up space between the
password field and submit button. Wrapped in a hidden div.
…ce, duplication constraints (#3682)

* Improve

* Hide is hosted

* Remove hardcoded

* fix

* Fixes

* v0

* Fix bugs

* Restore settings

* Handle compaction event type

* Add keepalive

* File streaming

* Error tags

* Abort defense

* Edit hashes

* DB backed tools

* Fixes

* progress on autolayout improvements

* Abort fixes

* vertical insertion improvement

* Consolidate file attachments

* Fix lint

* Manage agent result card fix

* Remove hardcoded ff

* Fix file streaming

* Fix persisted writing file tab

* Fix lint

* Fix streaming file flash

* Always set url to /file on file view

* Edit perms for tables

* Fix file edit perms

* remove inline tool call json dump

* Enforce name uniqueness (#3679)

* Enforce name uniqueness

* Use established pattern for error handling

* Fix lint

* Fix lint

* Add kb name uniqueness to db

* Fix lint

* Handle name getting taken before restore

* Enforce duplicate file name

* Fix lint

---------

Co-authored-by: Theodore Li <theo@sim.ai>

* fix temp file creation

* fix types

* Streaming fixes

* type xml tag structures + return invalid id linter errors back to LLM

* Add image gen and viz tools

* Tags

* Workflow tags

* Fix lint

* Fix subagent abort

* Fix subagent persistence

* Fix subagent aborts

* Nuke db migs

* Re add db migrations

* Fix lint

---------

Co-authored-by: Theodore Li <teddy@zenobiapay.com>
Co-authored-by: Vikhyath Mondreti <vikhyath@simstudio.ai>
Co-authored-by: Theodore Li <theodoreqili@gmail.com>
Co-authored-by: Theodore Li <theo@sim.ai>
* fix(mothership): abort fix

* diff engine fix
…3707)

* fix(kb): store filename with .txt extension for connector documents

Connector documents (e.g. Fireflies transcripts) have titles without
file extensions. The DB stored the raw title as filename, but the
processing pipeline extracts file extension from filename to determine
the parser. On retry/reprocess, this caused "Unsupported file type"
errors with the document title treated as the extension.

Now stores processingFilename (which includes .txt) instead of the
raw title, consistent with what was actually uploaded to storage.

* fix(kb): guard stuck document retry against filenames without extension

Existing DB rows may have connector document filenames stored without
a .txt extension (raw meeting titles). The stuck-doc retry path reads
filename from DB and passes it to parseHttpFile, which extracts the
extension via split('.'). When there's no dot, the entire title
becomes the "extension", causing "Unsupported file type" errors.

Falls back to 'document.txt' when the stored filename has no extension.

* fix(kb): fix race condition in stuck document retry during sync

The stuck document retry at the end of each sync was querying for all
documents with processingStatus 'pending' or 'failed'. This included
documents added in the CURRENT sync that were still processing
asynchronously, causing duplicate concurrent processing attempts.

The race between the original (correct) processing and the retry
(which reads the raw title from DB as filename) produced
nondeterministic failures — some documents would succeed while
others would fail with "Unsupported file type: <meeting title>".

Fixes:
- Filter stuck doc query by uploadedAt < syncStartedAt to exclude
  documents from the current sync
- Pass mimeType through to parseHttpFile so text/plain content can
  be decoded directly without requiring a file extension in the
  filename (matches parseDataURI which already handles this)
- Restore filename as extDoc.title in DB (the display name, not
  the processing filename)

* fix(kb): fix race condition in stuck document retry during sync

The stuck document retry at the end of each sync was querying for all
documents with processingStatus 'pending' or 'failed'. This included
documents added in the CURRENT sync that were still processing
asynchronously, causing duplicate concurrent processing attempts.

The race between the original (correct) processing and the retry
(which reads the raw title from DB as filename) produced
nondeterministic failures — some documents would succeed while
others would fail with "Unsupported file type: <meeting title>".

Fixes:
- Filter stuck doc query by uploadedAt < syncStartedAt to exclude
  documents from the current sync
- Pass mimeType through to parseHttpFile and use existing
  getExtensionFromMimeType utility as fallback when filename has
  no extension (e.g. Fireflies meeting titles)
- Apply same mimeType fallback in parseDataURI for consistency

* lint

* fix(kb): handle empty extension edge case in parseDataURI

When filename ends with a dot (e.g. "file."), split('.').pop() returns
an empty string. Fall through to mimeType-based extension lookup
instead of passing empty string to parseBuffer.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat(sidebar): add right-click context menu to settings nav item

* fix(sidebar): revert settings active highlight

* fix(sidebar): allow modifier-key clicks to open in new tab, make InfisicalIcon black

* update icons
* v0

* Fix ppt load

* Fixes

* Fixes

* Fix lint

* Fix wid

* Download image

* Update tools

* Fix lint

* Fix error msg

* Tool fixes

* Reenable subagent stream

* Subagent stream

* Fix edit workflow hydration

* Throw func execute error on error

* Sandbox PPTX generation in subprocess with vm.createContext

AI-generated PptxGenJS code was executed via new Function() in both
the server (full Node.js access) and browser (XSS risk). Replace with
a dedicated Node.js subprocess (pptx-worker.cjs) that runs user code
inside vm.createContext with a null-prototype sandbox — no access to
process, require, Buffer, or any Node.js globals. Process-level
isolation ensures a vm escape cannot reach the main process or DB.

File access is brokered via IPC so the subprocess never touches the
database directly, mirroring the isolated-vm worker pattern. Compilation
happens lazily at serve time (compilePptxIfNeeded) rather than on write,
matching industry practice for source-stored PPTX pipelines.

- Add pptx-worker.cjs: sandboxed subprocess worker
- Add pptx-vm.ts: orchestration, IPC bridge, file brokering
- Add /api/workspaces/[id]/pptx/preview: REST-correct preview endpoint
- Update serve route: compile pptxgenjs source to binary on demand
- Update workspace-file.ts: remove unsafe new Function(), store source only
- Update next.config.ts: include pptxgenjs in outputFileTracingIncludes
- Update trigger.config.ts: add pptx-worker.cjs and pptxgenjs to build

* upgrade deps, file viewer

* Fix auth bypass, SSRF, and wrong size limit comment

- Add 'patch' to workspace_file WRITE_ACTIONS — patch operation was
  missing, letting read-only users modify file content
- Add download_to_workspace_file to WRITE_ACTIONS with '*' wildcard —
  tool was completely ungated, letting read-only users write workspace files
- Update isActionAllowed to handle '*' (always-write tools) and undefined
  action (tools with no operation/action field)
- Block private/internal URLs in download_to_workspace_file to prevent
  SSRF against RFC 1918 ranges, loopback, and cloud metadata endpoints
- Fix file-reader.ts image size limit comment and error message (was 20MB,
  actual constant is 5MB)

* Fix Buffer not assignable to BodyInit in preview route

Wrap Buffer in Uint8Array for NextResponse body — Buffer is not
directly assignable to BodyInit in strict TypeScript mode.

* Fix SSRF bypass, IPv6 coverage, download size cap, and missing deps

- Validate post-redirect URL to block SSRF via open redirectors
- Expand IPv6 private range blocking: fe80::/10, fc00::/7, ::ffff: mapped
- Add 50 MB download cap (Content-Length pre-check + post-buffer check)
- Add refetchOnWindowFocus: 'always' to useWorkspaceFileBinary
- Add workspaceId to PptxPreview useEffect dependency array

* Replace hand-rolled SSRF guard with secureFetchWithValidation

The previous implementation hand-rolled private-IP detection with regex,
missing edge cases (octal IPs, hex IPs, full IPv6 coverage). The codebase
already has secureFetchWithValidation which uses ipaddr.js, handles DNS
rebinding via IP pinning, validates each redirect target, and enforces a
streaming size cap — removing the need for isPrivateUrl, isPrivateIPv4,
the manual pre/post-redirect checks, and the Content-Length + post-buffer
size checks.

* Fix streaming preview cache ordering and patch ambiguity

- PptxPreview: move streaming content check before cache check so live
  AI-generated previews are never blocked by a warm cache from a prior
  file view
- workspace_file patch: reject edits where the search string matches
  more than one location, preventing silent wrong-location patches
- workspace_file patch: remove redundant Record<string, unknown> cast;
  args is already Zod-validated with the correct field types

* Fix subprocess env leak, unbounded preview spawning, and dead code

- pptx-vm: pass minimal env to worker subprocess so it cannot inherit
  DB URLs, API keys, or other secrets from the Next.js process on a
  vm.createContext escape
- PptxPreview: add AbortController so in-flight preview fetch is
  cancelled when the effect re-runs (e.g. next SSE update), preventing
  unbounded concurrent subprocesses; add 500ms debounce on streaming
  renders to reduce subprocess churn during rapid AI generation
- file-reader: remove dead code — the `if (!isReadableType)` guard on
  line 110 was always true (all readable types returned earlier at
  line 76), making the subsequent `return null` unreachable

* Wire abort signal through to subprocess and correct security comment

- generatePptxFromCode now accepts an optional AbortSignal; when the
  signal fires (e.g. client disconnects mid-stream), done() is called
  which clears timers and kills the subprocess immediately rather than
  waiting for the 60s timeout
- preview route passes req.signal so client-side AbortController.abort()
  (from the streaming debounce cleanup) propagates all the way to the
  worker process
- Correct misleading comment in pptx-worker.cjs and pptx-vm.ts:
  vm.createContext is NOT a sandbox when non-primitives are in scope;
  the real security boundary is the subprocess + minimal env

* Remove implementation-specific comments from pptx worker files

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Fix pre-aborted signal, pptx-worker tracing, and binary fetch cache

* Lazy worker path resolution, code size cap, unused param prefix

* Add cache-busting timestamp to binary file fetch

* Fix PPTX cache key stability and attribute-order-independent dimension parsing

* ran lint

---------

Co-authored-by: waleed <walif6@gmail.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
h-0 w-0 overflow-hidden was clipping the iframe, preventing
Turnstile from executing. absolute takes it out of flow without
clipping, fixing both the layout gap and the captcha failure.
Was rendered above the form between the header and email field.
Now shows above the submit button alongside other form messages.
…3720)

* feat(slack): add conversations.create and conversations.invite tools

* fix(slack): address PR review comments on conversation tools

* feat(slack): wire create/invite conversation tools into Slack block

* lint

* fix(slack): rename channel output to channelInfo to avoid type collision

The block outputs already declare `channel` as type string (channel ID from
send operation). Rename the object output to `channelInfo` to match the
pattern used by get_channel_info and avoid [object Object] rendering.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs(slack): update output key in docs to match channelInfo rename

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(docs): fix lint errors in auto-generated docs files

Sort imports in icon-mapping.ts and add trailing newline to meta.json.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* lint

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* Allow loop-in-loop workflow edits

* Fix lint

* Fix orphaned loop-in-loop if parent id not found

---------

Co-authored-by: Theodore Li <theo@sim.ai>
* fix(autolayout): edits coalesced for same request diffs

* address comments

* address edge signature gen

* perf improvement
…ng details (#3726)

* improvement(settings): add View Invoices button to subscription billing details

* lint

* fix(settings): add user-facing error alert on billing portal failure
…t providers (#3727)

* fix(oauth): decode ID token instead of calling Graph API for Microsoft providers

* fix(oauth): fix type error in getMicrosoftUserInfoFromIdToken parameter

* fix(oauth): address review comments - try-catch JSON.parse, fix email fallback order, guard undefined email

* style(oauth): format email fallback chain to single line
…zation (#3728)

* feat(quiver): add QuiverAI integration for SVG generation and vectorization

* fix(quiver): address review feedback — n>1 data loss, error handling, import consistency

* fix(quiver): add files array to image-to-svg response, remove camelCase param leaks
* v0

* Fix ppt load

* Fixes

* Fixes

* Fix lint

* Fix wid

* Download image

* Update tools

* Fix lint

* Fix error msg

* Tool fixes

* Reenable subagent stream

* Subagent stream

* Fix edit workflow hydration

* Throw func execute error on error

* Rewrite

* Remove promptForToolApproval flag, fix workflow terminal logs

* Fixes

* Fix buffer

* Fix

* Fix claimed by

* Cleanup v1

* Tool call loop

* Fixes

* Fixes

* Fix subaget aborts

* Fix diff

* Add delegating state to subagents

* Fix build

* Fix sandbox

* Fix lint

---------

Co-authored-by: Waleed <walif6@gmail.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Lakee Sivaraya <71339072+lakeesiv@users.noreply.github.com>
Co-authored-by: Vikhyath Mondreti <vikhyath@simstudio.ai>
Co-authored-by: Vikhyath Mondreti <vikhyathvikku@gmail.com>
Co-authored-by: Theodore Li <teddy@zenobiapay.com>
* Fix test

* Fix schema

* Fix test

* Fix

* Fix
* Durability

* Go check

* Fix

* add pptxgen setup to dockerfile

* Update tools

* Fix

* Fix aborts and gen viz

---------

Co-authored-by: Vikhyath Mondreti <vikhyath@simstudio.ai>
@vercel
Copy link

vercel bot commented Mar 24, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
docs Skipped Skipped Mar 24, 2026 10:47am

Request Review

@cursor
Copy link

cursor bot commented Mar 24, 2026

PR Summary

High Risk
High risk because it changes copilot chat persistence/streaming and tool-confirmation durability, plus adds dynamic PPTX compilation in the file-serving path, which impacts core UX and security/performance of file delivery.

Overview
Copilot/mothership chat streaming is made more durable and long-running. Chat routes now default to claude-opus-4-6, increase maxDuration/timeouts to 1 hour, add executionId/runId propagation, and persist both user and assistant messages (including tool call/content block metadata) into copilotChats.messages during/after streaming.

Tool confirmation is migrated from Redis-based signaling to durable storage + pub/sub. /api/copilot/confirm now validates tool call ownership via async-run records, writes terminal/non-terminal states via completeAsyncToolCall/upsertAsyncToolCall, and then publishes a confirmation event; tests were rewritten accordingly. Stream replay (/api/copilot/chat/stream) now handles client aborts and stops on cancelled status (with a new unit test).

Files UX adds PPTX rendering/preview and on-the-fly PPTX compilation. File serving (/api/files/serve) can compile non-zip .pptx payloads from stored PptxGenJS source (with a small in-memory cache and raw=1 escape hatch), and the workspace file viewer gains image preview plus PPTX slide rendering (client-side) with a new authenticated compile-preview endpoint.

Integrations/docs updates. Adds a new Quiver integration (icons, mappings, integrations.json, and docs with new quiver_* tools) and extends Slack docs/metadata for conversations.create and conversations.invite. Also adds 409 conflict responses for KB/table/file restore/create/update flows via typed *ConflictErrors, tweaks React Query mutation retry behavior, and removes unnecessary 'use client' directives in several components.

Written by Cursor Bugbot for commit 8eb45e3. Configure here.

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Fix All in Cursor

Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

* Fixes

* Address bugbot

* Fixes

* Fix

* Fixes

* Fix lint

* Fixes

* Fixes

* Truncate log
* fix(mothership):  async resume and tool result ordering

* ensure tool call terminal state

* address comments
@Sg312 Sg312 merged commit c78c870 into main Mar 24, 2026
26 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants