SurfSense/docs/proposals/agent
Anish Sarkar c6e2b3b46f refactor(local): move the sidecar supervisor out of electron/
sidecars/ holds what electron/src/main/sidecars/ held, with net.ts, the
session log's Node-only files and check-sidecars.mjs, so the desktop and
the coming headless entry boot from one place (ADR 0072). Renames only:
the electron package runs and typechecks it, and nothing it does changes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-25 22:56:49 +05:30
..
01-which-engine.md docs(agent): fold opencode 2.x into architecture and record its tool policy 2026-10-22 21:15:15 +05:30
02-tools.md docs(agent): fold opencode 2.x into architecture and record its tool policy 2026-10-22 21:15:15 +05:30
04-workflows.md docs(proposals): add agent and chat eval proposals with ADR 0028 2026-09-23 22:19:44 -07:00
05-sources-folder.md docs(agent): fold opencode 2.x into architecture and record its tool policy 2026-10-22 21:15:15 +05:30
README.md refactor(local): move the sidecar supervisor out of electron/ 2026-10-25 22:56:49 +05:30

status code
in-progress
surfsense_local/backend/modules/agent/
surfsense_local/backend/modules/chat/
surfsense_local/backend/modules/documents/
surfsense_local/backend/worker/studio/
surfsense_local/backend/worker/ingestion/
surfsense_local/electron/scripts/
surfsense_local/sidecars/
surfsense_local/frontend/src/features/chat/
surfsense_local/frontend/src/features/agent/

The agent

The selected text model decides how SurfSense works on the user's sources. A model that is tested with opencode drives a bundled opencode over SurfSense's own tools. Every other model runs fixed workflows that SurfSense orchestrates with structured output. Outputs come first: nothing in this proposal edits the user's files.

Today's chat is single-pass grounded chat with no tools (chat), and Studio turns sources into artifacts (studio). The model catalog proposal leaves "an agent loop, where chat hands the model tools" to "a later chat rework with its own proposal". This is that proposal.

Every fact here links to where it was checked: this repo, opencode v1.18.34 (commit aec0b9a), llama.cpp b11050 (the build the app pins), or a named external source, as of 23 Sep 2026, and 1 Oct 2026 for opencode. Anything not yet known is listed under Open questions rather than stated.

Workstreams

Stream File Owns Starts from
Engine choice 01-which-engine.md which engine a selected model gets the capability data the catalogs already carry
Tools 02-tools.md search, read and create-artifact functions both engines call functions that exist today
opencode built: agent packaging, launch, the model endpoint, the backend's client, network lockdown, permissions, working folders, the conversation the tools
Workflows 04-workflows.md Studio's structured output, the formatting pass, the text fallback nothing; can start now
Sources folder 05-sources-folder.md linking a folder on disk as the Sources root nothing; independent

opencode came first, for a model known to call tools (01-which-engine.md), on its own file tools over the sources folder and SurfSense's search and Studio over MCP (02-tools.md): what runs is in agent. Next are the workflows and the linked sources folder, in parallel.

Locked decisions

The file agent proposal changes several of these, and what shipped follows it: since 7 Oct 2026 the user picks Basic (Q&A) or Agentic for each new chat, and every model may pick Agentic unless a technical gate keeps it out (01-which-engine.md); the agent has no shell (ADR 0039); and it edits the user's files only into new copies, never the file itself (agent).

Decision Choice
Engines Two. opencode for a model on a tested list; fixed workflows for every other model.
Who gets opencode Only models on the tested list. The list starts empty. Nanbeige4-3B-Thinking and xLAM-2 are not candidates.
Reading files a model cannot read Docling's extracted text, which ingestion already produces.
Shipping opencode Inside the installer: v1.18.34, of the 1.x line, pinned by version and SHA-256 at build time. What differs in 2.x sits in one backend module.
Installer and network The installer downloads nothing. Anything fetched later is fetched by the running app after egress consent.
opencode and the network None beyond loopback. Its fetches are switched off, its dependencies are shipped, and its proxy variables point at a loopback port nothing listens on. Settings › Network gains nothing.
Models opencode reaches every model, local and remote, through one SurfSense endpoint, so keys and egress checks stay in SurfSense.
Where the agent appears In the chat panel. A thread gets its engine when it is created, from the selected model, and keeps it (01-which-engine.md).
The agent's conversation Kept by opencode, in its database inside SurfSense's data folder. The thread stores the opencode session id (agent).
Model-written code Runs on the user's machine without a sandbox; the agent asks before every shell command, and SurfSense never answers "always" (ADR 0028). A sandbox is later work for licensed users.
Undo Not in this phase. opencode snapshots are off, and the agent writes only inside SurfSense's own output folder.
Sources on disk A linked folder is indexed in place and watched. Git is not the storage.

Out of scope

Editing sources or artifacts, undo, git history, figure and image understanding, a sandbox, output-quality work beyond what 04-workflows.md marks to build, and prompt tuning. The research behind the later items is recorded in the stream files so it is not repeated.

Open questions

Each stream file lists its own. These cut across them:

  • Who maintains the opencode list, and whether its test (01-which-engine.md) runs inside the chat eval.
  • Whether Studio's Office formats should also ask before running model-written code (ADR 0028).