Commit graph

728 commits

Author SHA1 Message Date
CREDO23
66103c68f6 refactor(agents): colocate main-agent-only tools (scrape_webpage, update_memory)
These two tools were "shared-by-folder, not shared-by-use": the only live
consumer of shared/tools/{scrape_webpage,update_memory} was the main agent
(the research/memory subagents carry their own local copies; web_search,
by contrast, is genuinely shared with anonymous_chat and stays put).

Move both into main_agent/tools/ (their sole owner). The shared BUILTIN_TOOLS
catalog still lists them for action_log/revert + /agent/tools, now via
deferred-import factories (_build_scrape_webpage_tool, _build_update_memory_tool)
mirroring the create_automation precedent to avoid a multi_agent_chat import
cycle. Removed the now-dead re-exports from shared/tools/__init__.py.

Verified: full unit suite green (2431 passed, 1 skipped).
2026-06-04 19:10:48 +02:00
CREDO23
482aefc32a refactor(agents): SRP main-agent tool registry, decoupled from BUILTIN_TOOLS
The main agent only exposes 4 SurfSense tools (web_search, scrape_webpage,
update_memory, create_automation) and delegates connectors/MCP/deliverables
to subagents. Yet it built those 4 by importing and iterating the 900-line,
connector-laden shared BUILTIN_TOOLS via build_tools_async.

Introduce app/agents/multi_agent_chat/main_agent/tools/registry.py owning
just those 4 factories, and switch runtime/factory.py to build_main_agent_tools.
Binding order is preserved (scrape_webpage, web_search, create_automation,
update_memory) to match prior behavior exactly.

shared/tools/registry.py BUILTIN_TOOLS is intentionally unchanged: it remains
the app-wide tool *metadata* catalog used by action_log (revert/dedup
resolvers for subagent-executed connector tools) and the /agent/tools
listing endpoint.

Verified: full unit suite green (2431 passed, 1 skipped); import-all guard ok.
2026-06-04 19:01:44 +02:00
CREDO23
add9e14694 refactor(agents): colocate middleware into vertical slices
Eliminate the top-level multi_agent_chat/middleware/ package so each slice
owns its middleware (vertical-slice colocation):

- middleware/shared/   -> shared/middleware/        (cross-slice middleware)
- middleware/subagent/ -> subagents/shared/middleware/ (subagent stack)
- main_agent/middleware/ already colocated in Slice A

The moved shared/ subtree is internally consistent (all relative imports
stay within it), so only external absolute refs were rewritten. The
subagent stack's ..shared.* relatives were promoted to absolute paths to
the new shared/middleware/ location.

multi_agent_chat/ root is now: main_agent/, shared/, subagents/.
Verified: 2430 unit tests pass, 1 skipped (baseline unchanged).
2026-06-04 18:13:47 +02:00
CREDO23
9c845d562e refactor(agents): colocate main-agent middleware under main_agent/ slice
Vertical-slice colocation: all main-agent code should live under
main_agent/ instead of being split across a parallel middleware/main_agent
tree. Move multi_agent_chat/middleware/main_agent/ -> main_agent/middleware/
and its assembler middleware/stack.py -> main_agent/middleware/stack.py, so
the main-agent slice is self-contained (graph, runtime, system_prompt, tools,
middleware).

Genuinely cross-slice middleware (middleware/shared/, middleware/subagent/)
stays under multi_agent_chat/middleware/ for a later slice; the moved builders
now reference it via absolute imports.

Pure move + import rewrite (git-tracked renames). Verified: full unit suite
green (2430 passed, 1 skipped), including test_import_all and the
checkpointed-subagent middleware suite.
2026-06-04 18:03:49 +02:00
CREDO23
1acde6a470 test(agents): cover live filesystem middleware, retire dead twin
The single-agent-era filesystem middleware (app/agents/shared/middleware/
filesystem.py, ~2000 lines) was never instantiated in production, yet three
unit suites validated it — an illusory guardrail while the live decomposed
middleware (multi_agent_chat/middleware/shared/filesystem) was unguarded.

Close the gap before reorganizing the agents module:
- Add 14 integration tests driving live B's tools in desktop mode (real
  on-disk effects) and cloud mode (in-state staging, namespace policy).
- Port all high-value dead-twin assertions onto the live path: cloud rm/rmdir
  staging + guard rails, KBPostgresBackend delete-view filter, mode-scoped
  system prompt, cwd/relative/namespace resolution, multi-root mount
  normalization.
- Delete dead twin filesystem.py, drop its __init__ re-export, and retire its
  3 dead-twin tests.

Verified: test_import_all + middleware unit + FS integration all green.
2026-06-04 17:46:49 +02:00
CREDO23
8faa03889d docs(agents): refresh comments that referenced the deleted single-agent stack (bucket B6)
After deleting app/agents/new_chat/, several shared-kernel comments still cited
new_chat paths/cycles. Update the two lazy-import comments in middleware to state
the real reason (tools.registry <-> shared.middleware cycle), and repoint dangling
``new_chat/tools/hitl.py`` / ``chat_deepagent`` doc references to their shared
locations. Comment-only; suite unaffected.
2026-06-04 13:47:10 +02:00
CREDO23
14bbea0854 refactor(agents): delete single-agent stack + new_chat shim package (bucket B3/B4)
With multi-agent the only live factory (B1), the single-agent stack is dead.
Remove app/agents/new_chat/ entirely: chat_deepagent.py, subagents/, and all
re-export shims (errors/context/llm_config/permissions/tools/middleware/...) that
existed only to serve frozen single-agent code. Live code already imports the
shared kernel (app.agents.shared.*) directly.

Tests: delete single-agent-only suites (test_resolve_prompt_model_name,
test_specialized_subagents) and the chat_deepagent source-shape contract assertion;
repoint test_scoped_model_fallback to the shared middleware path. Suite green
(2710 passed).
2026-06-04 13:40:44 +02:00
CREDO23
64d2ad6451 refactor(agents): promote anonymous_agent to its own anonymous_chat/ package (slice 8)
The anonymous / free-chat agent is a distinct live agent (not part of the
single-agent stack and not shared infrastructure), so it gets its own top-level
package app/agents/anonymous_chat/ (sibling to multi_agent_chat). Moved
new_chat/anonymous_agent.py -> anonymous_chat/agent.py with a package __init__
re-exporting create_anonymous_chat_agent + build_anonymous_system_prompt.

Repointed its only new_chat import (the context shim) to app.agents.shared.context
and updated the single importer (anonymous_chat_routes). The test_import_all
guard auto-discovers the new package via pkgutil.walk_packages, so it is covered.
2026-06-04 13:25:23 +02:00
CREDO23
a019f18d1c refactor(agents): move connector_searchable_types, agent_cache, system_prompt + prompts to app/agents/shared (slice 7b)
Three live shared leaves discovered while taking stock after slice 7 (all are
consumed by the multi-agent stack and/or live routes, not single-agent-only):

- connector_searchable_types -> shared + shim (multi-agent factory uses it)
- agent_cache -> shared + shim (multi-agent runtime/agent_cache uses it)
- system_prompt + prompts/ (42 .md fragments) -> shared together + shim.
  Repointed composer's _PROMPTS_PACKAGE to app.agents.shared.prompts so
  importlib.resources fragment loading keeps working; system_prompt's relative
  ".prompts.composer" import is preserved by moving both as a unit.

Each keeps a re-export shim for the frozen chat_deepagent. After this slice,
new_chat/ holds only the frozen single-agent stack (chat_deepagent, subagents/,
__init__) plus shims.
2026-06-04 13:21:45 +02:00
CREDO23
13a96851ef refactor(agents): move skills/, plugins/, plugin_loader to app/agents/shared (slice 7)
- skills/ (builtin SKILL.md assets) has zero Python importers; it is read by
  filesystem path only. Moved the dir and restored
  skills_backends._default_builtin_root() to the clean
  parent.parent / "skills" / "builtin" form (undoing the transient path from 5c).
- plugin_loader.py -> shared (frozen chat_deepagent uses it -> re-export shim).
- plugins/ package -> shared (year_substituter rewired to shared.plugin_loader;
  docstring entry-point example updated to the shared dotted path). No shim
  needed (only a test imported it). Plugin discovery is via importlib entry
  points (group "surfsense.plugins"), not dotted-path import, and nothing is
  registered in pyproject, so the move does not affect runtime discovery.
2026-06-04 13:16:22 +02:00
CREDO23
aab95b9130 refactor(agents): move tools package to app/agents/shared (slice 6)
Relocate the entire new_chat/tools/ package (62 files incl. registry, hitl, MCP
cluster, and all connector subpackages: gmail/slack/discord/teams/drive/etc.)
to the shared kernel. The package turned out to be a clean cohesive cluster:
its only references to non-tools new_chat modules were comments, and its
middleware deps were already flipped to shared in slice 5c.

Flip 33 live importers (multi-agent, flows, routes, services, anonymous_agent,
tests). Re-export shims remain for the frozen single-agent stack: a package
__init__ mirroring the public surface (new_chat.__init__ imports it) plus
invalid_tool + registry submodule shims (chat_deepagent imports those).

Resolves slice 5c's two transient back-edges: shared/middleware/action_log
(TYPE_CHECKING ToolDefinition) and tool_call_repair (local INVALID_TOOL_NAME)
now point at app.agents.shared.tools.
2026-06-04 13:11:56 +02:00
CREDO23
a7fde2a48e refactor(agents): move filesystem_backends to app/agents/shared (slice 5d)
Completes slice 5. filesystem_backends was deferred from 3b because it depends
on middleware.{kb_postgres_backend,multi_root_local_folder_backend}; those moved
to shared in 5c, so it now relocates cleanly. Flip the 2 non-frozen importers
(multi-agent factory + test); a re-export shim remains for the frozen
chat_deepagent (build_backend_resolver).
2026-06-04 13:03:15 +02:00
CREDO23
227983a104 refactor(agents): move middleware package to app/agents/shared (slice 5c)
Relocate the entire new_chat/middleware/ package to the shared kernel as one
cohesive unit (it is live shared infrastructure: the multi-agent stack wraps
nearly every middleware via multi_agent_chat/middleware/main_agent/*, and
anonymous_agent consumes it too). Flip 69 live importers across both the
package-path and submodule-path forms.

Shims left for the frozen single-agent stack: a package __init__ re-export plus
submodule shims for permission, skills_backends, and scoped_model_fallback
(the three imported via submodule path by chat_deepagent/subagents).

Cycle break: importing shared.middleware previously reached back into
new_chat.tools at module load, which dragged in new_chat.__init__ ->
chat_deepagent -> the middleware shim -> half-initialized shared.middleware.
Made action_log's ToolDefinition import TYPE_CHECKING-only and
tool_call_repair's INVALID_TOOL_NAME import function-local. These tools-package
back-edges fully resolve in slice 6.

Asset note: skills_backends._default_builtin_root now walks to
app/agents/new_chat/skills/builtin (the skills/ tree migrates in slice 7).
2026-06-04 13:00:41 +02:00
CREDO23
6f488d9564 refactor(agents): move checkpointer + mention_resolver to app/agents/shared (slice 5b)
Two independent leaf modules (no intra-new_chat deps, no frozen importer),
consumed only by flows/routes/tests. Flipped 8 importers across both the
dotted-path and module-style (from app.agents.new_chat import mention_resolver)
forms. No shims needed.
2026-06-04 12:52:54 +02:00
CREDO23
dcdf8f776b refactor(agents): move utils + document_xml to app/agents/shared (slice 5a)
Two pure leaf modules with no intra-new_chat deps and no frozen importer.
Moving them now (before the middleware package) pre-empts two shared->new_chat
back-edges that the middleware move would otherwise create
(knowledge_search->utils, kb_postgres_backend->document_xml).
2026-06-04 12:50:38 +02:00
CREDO23
946f8a8c5d refactor(agents): move llm_config + prompt_caching to app/agents/shared (slice 4b)
Relocate the mutually-dependent LLM config layer and the LiteLLM prompt-caching
helper to the shared kernel as one unit, rewiring their internal cross-reference
to the shared paths. Flip 21 non-frozen importers. Re-export shims remain at
new_chat/{llm_config,prompt_caching}.py for the frozen single-agent stack
(chat_deepagent); they will be removed when that stack is retired.
2026-06-04 12:41:52 +02:00
CREDO23
8fca2753aa refactor(agents): move permissions to app/agents/shared (slice 4a)
Relocate the permission evaluator (wildcard matcher + rule evaluation) to the
shared kernel and flip 43 non-frozen importers. A re-export shim remains at
new_chat/permissions.py for the frozen single-agent stack (chat_deepagent and
subagents/{config,providers/linear,providers/slack}); it will be removed when
that stack is retired.
2026-06-04 12:38:30 +02:00
CREDO23
3efe51e6ec refactor(agents): move filesystem_state, path_resolver, sandbox to app/agents/shared (slice 3b)
Relocate three leaf filesystem-cluster modules to the shared kernel and flip
all 38 importers. No re-export shims needed (no frozen single-agent importer).
This also resolves the pre-existing shared->new_chat back-edge from
shared/receipt_command.py onto filesystem_state.

filesystem_backends is intentionally deferred to slice 5: it depends on
new_chat middleware (kb_postgres_backend, multi_root_local_folder_backend)
that have not yet moved, so relocating it now would create a shared->new_chat edge.
2026-06-04 12:34:28 +02:00
CREDO23
1b536b8aee refactor(agents): move filesystem_selection to app/agents/shared (slice 3a)
Promote the filesystem mode contracts (FilesystemMode, FilesystemSelection,
ClientPlatform, LocalFilesystemMount) out of `new_chat` into the cross-agent
`app/agents/shared` kernel.

Pure leaf consumed across the whole multi-agent filesystem middleware/tool tree,
the chat flows/monolith, routes and tests. git mv (content unchanged) + flipped
all ~48 importers. A re-export shim remains at new_chat/filesystem_selection.py
only for the not-yet-retired single-agent (chat_deepagent).

Also updated the stream parity test's annotation normalizer to strip the new
app.agents.shared.filesystem_selection. prefix (the dataclasses' __module__
changed with the move), keeping monolith<->flows signature parity intact.

Behavior-preserving: only import paths change. 1326 tests green.
2026-06-04 12:28:20 +02:00
CREDO23
a975754e7d refactor(agents): move feature flags to app/agents/shared/feature_flags (slice 2b)
Promote the agent feature-flag resolver (AgentFeatureFlags / get_flags) out of
`new_chat` into the cross-agent `app/agents/shared` kernel.

feature_flags is a pure leaf consumed across the multi-agent middleware stack,
the chat routes, and tests. Moved it via git mv (content unchanged) and flipped
all 37 importers to app.agents.shared.feature_flags. A thin re-export shim
remains at new_chat/feature_flags.py only for the not-yet-retired single-agent
(chat_deepagent); it goes away with the single-agent deletion.

Behavior-preserving: only import paths change. 1243 tests green.
2026-06-04 12:23:12 +02:00
CREDO23
28b13ed25b refactor(agents): move context schema + state reducers to app/agents/shared (slice 2)
Continue promoting the shared agent toolkit out of `new_chat` into the
cross-agent `app/agents/shared` kernel.

- state_reducers.py: clean move (no single-agent importer); all 7 importers
  flipped to app.agents.shared.state_reducers.
- context.py: moved to app.agents.shared.context; flipped the multi-agent,
  app, automations, chat-flows and monolith importers. A thin re-export shim
  remains at new_chat/context.py because the not-yet-retired single-agent
  (chat_deepagent) and the new_chat package __init__ still import it; the shim
  goes away with the single-agent deletion.
- Updated the stream parity test's annotation normalizer to strip the new
  app.agents.shared.context. prefix (SurfSenseContextSchema.__module__ changed
  with the move), keeping monolith<->flows signature parity intact.

Behavior-preserving: definitions unchanged; only import paths move. 1219 tests green.
2026-06-04 12:19:22 +02:00
CREDO23
0354f73f29 refactor(agents): move error taxonomy to app/agents/shared/errors (slice 1)
First slice of promoting the shared agent toolkit out of the misnamed
`new_chat` package into the cross-agent `app/agents/shared` kernel.

`errors.py` is a leaf module (no intra-package deps) consumed by the
multi-agent chat, the chat streaming flows/monolith, and tests — i.e. it is
shared infrastructure, not single-agent code. Moved it verbatim to
`app.agents.shared.errors` and flipped all 12 importers. No re-export shim
remains since zero importers needed it.

Behavior-preserving: identical class/enum definitions; only the import path
changes. 1208 agent + chat-task tests green.
2026-06-04 12:13:55 +02:00
CREDO23
a4010a357f refactor: extract shared connector->searchable-type mapping out of chat_deepagent
The multi-agent factory reached into the single-agent factory module
(chat_deepagent) for `_map_connectors_to_searchable_types`. Move this
agent-agnostic helper (and its two lookup tables) into a dedicated
`connector_searchable_types` module and point both factories at it.

Behavior-preserving: the function body is unchanged; only its home and
visibility (now public `map_connectors_to_searchable_types`) change. This
removes the cross-dependency on the dying single-agent module so it can be
retired later without breaking the multi-agent path.
2026-06-04 12:05:17 +02:00
CREDO23
0b006badb0 chore: remove dead agent code (vision autocomplete, linear tools, provider hints) 2026-06-04 11:44:23 +02:00
CREDO23
cb44063081 fix: repair pre-existing agent_task, gateway, and skills tests 2026-06-04 10:25:06 +02:00
CREDO23
b6710ae9af refactor(jira): remove dead legacy indexing and write tools (mcp-only now) 2026-06-02 16:38:00 +02:00
DESKTOP-RTLN3BA\$punk
0f2e3c7655 refactor: anonymous/free chat experience
- Enhanced lambda function formatting in `_after_commit` for better clarity.
- Simplified generator expression in `_match_condition` for improved readability.
- Streamlined function signature in `_eligible` for consistency.
- Updated imports and refactored anonymous chat routes to use a new agent creation method.
- Added a new function `_load_anon_document` to handle document loading from Redis.
- Improved UI components by replacing legacy structures with modern alternatives, including alerts and separators.
- Refactored quota-related components to utilize new alert structures for better user feedback.
- Cleaned up unused variables and optimized component states for performance.
2026-05-31 15:58:21 -07:00
DESKTOP-RTLN3BA\$punk
9d1a01eb0c refactor(automations): streamline model eligibility handling in automation creation
- Removed the eligibility gate for model selection in the automation creation process, allowing users to choose models directly in the builder.
- Updated the `AutomationBuilderForm` to incorporate model selection logic, ensuring that selected models are validated and preserved during automation creation and editing.
- Simplified the `AutomationsContent` and `AutomationNewContent` components by eliminating unnecessary eligibility checks and alerts.
- Enhanced the user experience by integrating model selection directly into the automation approval process, ensuring that only billable models are used.
- Refactored related tests to cover new model selection behavior and ensure proper validation of user-selected models.
2026-05-29 20:27:40 -07:00
DESKTOP-RTLN3BA\$punk
409fec94c3 feat(automations): implement model eligibility checks for automation creation
- Added model eligibility checks to ensure automations can only use billable models (premium or BYOK).
- Introduced new API endpoint to report model eligibility status for search spaces.
- Updated frontend components to display eligibility alerts and disable creation options when models are not billable.
- Enhanced automation creation forms to reflect model eligibility, preventing users from submitting invalid configurations.
- Implemented server-side logic to capture and preserve model preferences across automation edits, ensuring consistent behavior during execution.
2026-05-29 03:13:46 -07:00
DESKTOP-RTLN3BA\$punk
40ca9e6ed2 refactor: remove search_surfsense_docs tool and related references
- Deleted the `search_surfsense_docs` tool and its associated files, streamlining the agent's toolset.
- Updated various components and prompts to remove references to the now-removed tool, ensuring consistency across the codebase.
- Adjusted documentation to direct users to the SurfSense documentation link for product-related queries instead.
2026-05-28 22:35:14 -07:00
DESKTOP-RTLN3BA\$punk
94e834134f chore: linting 2026-05-28 19:21:29 -07:00
Rohan Verma
4dda02c06c
Merge pull request #1443 from CREDO23/feature-automations
[Feat] Automation V1 — Scheduled Agent Tasks, Created via Chat (HITL) or JSON
2026-05-28 12:41:41 -07:00
CREDO23
91962ba879 fix automation run inputs, hitl routing, and detail UI polish 2026-05-28 02:48:47 +02:00
CREDO23
2e572d7818 feat(web): create_automation HITL approval card in chat
Closes the create loop in chat: the agent describes user intent → the
drafter sub-LLM produces an AutomationCreate JSON → this card surfaces
a structured preview → approve persists; reject cancels. Edits flow
through chat refinement (re-call with a refined intent), not in-card,
so the card stays simple and the multi-turn checkpointer carries the
context.

Tool UI (components/tool-ui/automation/):
- create-automation.tsx — entry dispatcher + ApprovalCard chrome
  (pending/processing/complete/rejected via useHitlPhase) + SavedCard
  (links to the detail page) + InvalidCard (lists drafter validation
  issues) + ErrorCard (verbatim message). Rejection result is hidden
  because the approval card itself shows the rejected phase inline.
- automation-draft-preview.tsx — structured preview body: name +
  description + goal, triggers (humanised cron + tz + static-input
  keys), plan steps (step_id → action), and a collapsible raw JSON
  for power users.

Wiring:
- components/tool-ui/index.ts — re-export.
- features/chat-messages/timeline/tool-registry/registry.ts —
  register create_automation → CreateAutomationToolUI (dynamic import,
  same pattern as other connector tools).
- contracts/enums/toolIcons.tsx — Workflow icon + "Create automation"
  display name so fallback chrome (and timeline headers) are honest.

Shared util:
- lib/automations/describe-cron.ts — lifted from the route slice's
  lib/ folder since both the dashboard slice and the new approval card
  now render schedule descriptions. Slice imports updated; the now-
  empty slice lib/ folder is gone.

Backend prompt fragments:
- main_agent/system_prompt/.../create_automation/description.md and
  the tool's docstring no longer promise in-card edits. They make the
  refinement path explicit: if the user wants changes after seeing the
  draft, they reply in chat and the agent calls the tool again with a
  refined intent.

v1 deliberately excludes:
- In-card edit form / right-side edit panel — defer until we see real
  demand. The chat refinement loop covers the common case.
- approve_always / persistent allow rules — automations are a single
  artifact, not a repeated mutation, so the "trust this kind of call"
  affordance doesn't apply.
2026-05-28 01:32:04 +02:00
CREDO23
2b7d91aa03 feat(automations): add create_automation HITL tool (NL → draft → approve → save)
Single tool exposed to the main agent. The main agent passes a natural-language
`intent`; a focused drafter sub-LLM turns it into a full AutomationCreate JSON;
that JSON is surfaced via request_approval (action_type "automation_create") so
the user can edit/approve it on a frontend card; on approval the tool persists
via AutomationService. Three phases, one tool call.

Scope split:
- main agent sees only `intent: str` (no schema knowledge leaks into the calling
  graph) — prompt fragments scoped accordingly.
- drafter sub-LLM owns the schema + few-shot intent→JSON examples — lives in
  the generating graph's prompt (tools/automation/prompt.py).

Files:
- main_agent/tools/automation/{create.py, prompt.py, __init__.py}: new tool
  + drafter system prompt with two few-shot intent→JSON examples.
- system_prompt/prompts/tools/create_automation/{description.md, example.md}:
  intent-only guidance for the main agent.
- main_agent/tools/index.py: add create_automation to the main-agent allowlist.
- new_chat/tools/registry.py: deferred-import factory to break the
  multi_agent_chat ↔ registry cycle; one ToolDefinition entry.
2026-05-28 00:12:02 +02:00
DESKTOP-RTLN3BA\$punk
9d6e9b7e2d feat: enhance task management and timeout configurations in multi-agent chat
- Added new environment variables for controlling task execution limits, including `SURFSENSE_SUBAGENT_INVOKE_TIMEOUT_SECONDS`, `SURFSENSE_TASK_BATCH_CONCURRENCY`, and `SURFSENSE_TASK_BATCH_MAX_SIZE`.
- Updated documentation to reflect new batch processing capabilities for `task` calls, allowing for concurrent execution of multiple subagent tasks.
- Improved error handling and receipt generation for deliverables, ensuring consistent feedback on task status.
- Refactored middleware to incorporate search space ID for better task management.
2026-05-27 14:58:10 -07:00
Anish Sarkar
a41b16b73e feat(web): enhance chat context and mention handling with connector support 2026-05-26 21:11:53 +05:30
Rohan Verma
69388fc710
Merge pull request #1429 from CREDO23/fix-desktop-redirects
[Fixes] Packaged desktop: connector redirect + linux launcher icon
2026-05-23 15:51:59 -07:00
Anish Sarkar
98e3950dc8 Merge remote-tracking branch 'upstream/dev' into feat/opentelemetry 2026-05-23 03:21:08 +05:30
CREDO23
d97b2830c5 fix: resolve desktop KB prompt self-contradiction on chunk_ids
The citations fix (cacb27e0) added a "Chunk citations in your prose"
section to system_prompt_desktop.md telling the KB subagent to always
leave `evidence.chunk_ids` null and emit no `[citation:...]` markers in
desktop mode, but left the pre-existing line declaring that
`chunk_ids` apply to `<priority_documents>` hits. The two rules
contradicted each other; the model picked one per turn.

Strike the stale conditional clause and point at the dedicated section
as the single source of truth. Matches the parallel line in
system_prompt_cloud.md and the already-consistent
system_prompt_readonly_desktop.md.
2026-05-22 17:24:57 +02:00
Anish Sarkar
dc893281ba feat(chat): add model retry and stream lifecycle events 2026-05-22 17:48:43 +05:30
Anish Sarkar
8bca29fe0d feat(agents): track subagent invocation telemetry 2026-05-22 13:48:57 +05:30
DESKTOP-RTLN3BA\$punk
cacb27e007 fix: citations in agent responses 2026-05-21 14:41:32 -07:00
Anish Sarkar
53691f9c51 feat(agents): track permission and compaction events 2026-05-21 23:02:54 +05:30
Anish Sarkar
ea3d0a6463 feat(agents): emit metrics for model and tool calls 2026-05-21 23:02:36 +05:30
CREDO23
49da7a57df Merge remote-tracking branch 'upstream/dev' into improvement-agent-speed
Resolves: surfsense_backend/app/agents/new_chat/middleware/memory_injection.py
- Took both imports: upstream moved MEMORY_HARD_LIMIT/SOFT_LIMIT to
  app.services.memory; kept our perf-logger import for timing.

Pulls in upstream changes:
- Memory document feature (services/memory refactor, removal of
  app.agents.new_chat.memory_extraction and background extraction in
  stream_new_chat — agent now drives memory via update_memory tool).
- BACKEND_URL env refactor across web tool-ui/editor/chat/dashboard/lib.
- GitHub Actions backend test workflow + pre-commit biome bump.
- Token-display polish in MessageInfoDropdown; save_memory no-update
  sentinel.

Verified: 1723 unit tests pass, ruff clean. No semantic regression in
stream_new_chat (their memory-extraction deletion and our preflight
removal touch different functions).
2026-05-20 21:23:48 +02:00
CREDO23
d5ee8cc4cd Merge remote-tracking branch 'upstream/dev' into improvement-agent-speed 2026-05-20 19:22:49 +02:00
CREDO23
704d1bf18f refactor(mcp): per-connector cache refresh on lifecycle events
Collapse the invalidate + warmup pair into a single
refresh_mcp_tools_cache_for_connector(connector_id, search_space_id)
helper and scope live discovery to the one connector that changed
instead of the whole search space.

- new mcp_tool.discover_single_mcp_connector: load one connector,
  refresh OAuth if needed, force live MCP discovery so its cached_tools
  row is rewritten; returned wrappers are discarded since the in-process
  LRU is rebuilt lazily on the next user query
- mcp_tools_cache.refresh_mcp_tools_cache_for_connector: synchronously
  evicts the per-space LRU (LRU keys cannot scope finer) and schedules
  the per-connector prefetch via loop.create_task
- routes (OAuth callback, MCP POST, MCP PUT) collapse their two
  back-to-back calls into a single refresh call; DELETE handlers keep
  using bare invalidate_mcp_tools_cache (nothing to prefetch)

No new automated tests: the new functions are I/O glue (DB + network)
where mocked unit tests would test implementation rather than behavior.
The existing 9 unit tests for the cached_tools data shape are unchanged.
2026-05-20 17:43:27 +02:00
CREDO23
c0aa4261ac perf(mcp): persist list_tools discovery in connector.config.cached_tools
Skip the ~1-3s MCP initialize + list_tools handshake on every cache miss
by reading tool definitions from the connector row we already load. Lazy
populate on first miss, self-heal on corrupt cache, zero schema migration.
2026-05-20 16:11:07 +02:00
CREDO23
db8bffab38 perf(prompt-cache): enable Azure prompt_cache_key routing hint
Splits the OpenAI-family gate into per-param predicates so AZURE and
AZURE_OPENAI configs now receive prompt_cache_key for backend routing
affinity (Microsoft auto-caches GPT-4o+ deployments at >=1024 tokens;
the key clusters same-prefix requests on the same GPU pool and raises
hit rate on turn 2+). prompt_cache_retention stays opted out for Azure
because litellm 1.83.14's Azure transformer would drop it silently;
revisit when Azure's supported params list is updated.
2026-05-20 11:58:15 +02:00