Commit graph

693 commits

Author SHA1 Message Date
CREDO23
8bdfd00a15 Merge upstream/dev 2026-06-05 19:18:12 +02:00
CREDO23
0081b627e9 refactor(agents): move kb_persistence middleware into main_agent (owner)
The KB-persistence impl lived in shared/middleware/ but no subagent uses it --
consumers are the main_agent builder and the boundary event loop. Colocate with
its owner using the folder-per-middleware shape; __init__ re-exports the public
surface. Tests that reached module internals now alias the .middleware submodule.

  main_agent/middleware/kb_persistence.py -> kb_persistence/builder.py
  shared/middleware/kb_persistence.py     -> kb_persistence/middleware.py
2026-06-05 14:11:55 +02:00
CREDO23
a7a642fedc refactor(agents): move busy_mutex middleware into main_agent (owner)
The busy-mutex impl (BusyMutexMiddleware + cancel/turn-lifecycle primitives)
lived in shared/middleware/ but no subagent uses it -- consumers are the
main_agent builder and the boundary (turn lifecycle). Colocate with its owner
using the folder-per-middleware shape; __init__ re-exports the public surface so
boundary import sites only change package path:

  main_agent/middleware/busy_mutex.py    -> busy_mutex/builder.py
  shared/middleware/busy_mutex.py        -> busy_mutex/middleware.py
2026-06-05 14:08:45 +02:00
CREDO23
f2a61bc0ef refactor(agents): consolidate chat runtime infra under chat/runtime
Move the lower-level runtime/infra modules out of multi_agent_chat/shared/
(they were never used by subagents, so they failed the shared-by-all-siblings
rule) and unify them with the already-relocated checkpointer:

  agents/runtime/                      -> agents/chat/runtime/
  mac/shared/errors.py                 -> chat/runtime/errors.py
  mac/shared/llm_config.py             -> chat/runtime/llm_config.py
  mac/shared/prompt_caching.py         -> chat/runtime/prompt_caching.py
  mac/shared/mention_resolver.py       -> chat/runtime/mention_resolver.py
  mac/shared/path_resolver.py          -> chat/runtime/path_resolver.py

These sit below the agent packages: the boundary + agent factory + shared
middleware depend on them, and they import no agent code (acyclic).
2026-06-05 13:19:24 +02:00
CREDO23
7d866a2279 refactor(agents): sink sandbox.py into filesystem subsystem
shared/sandbox.py was used only by the filesystem middleware/tools (and the
boundary) -- never by main_agent or subagents as shared code. Move it next to
its only agent-side consumer:

  multi_agent_chat/shared/sandbox.py
  -> multi_agent_chat/shared/middleware/filesystem/sandbox.py
2026-06-05 13:15:57 +02:00
CREDO23
24b62a63b4 refactor(agents): introduce chat/ category; dissolve top-level agents/shared
Recursive shared-folder rule: a shared/ must be shared by ALL siblings at its
level. The kernel (context, compaction, retry_after, web_search) was shared by
only 2 of the agents -- anonymous_chat + multi_agent_chat -- never by podcaster
or video_presentation. Those 2 are the "chat" category, so their shared code
belongs in that category's shared/, not the top-level one.

  app/agents/anonymous_chat/   -> app/agents/chat/anonymous_chat/
  app/agents/multi_agent_chat/ -> app/agents/chat/multi_agent_chat/
  app/agents/shared/           -> app/agents/chat/shared/   (anon<->mac kernel)

Top-level app/agents/shared/ is gone: nothing was shared across all three
categories (chat / podcaster / video_presentation).

~289 import sites rewritten (app.agents.{anonymous_chat,multi_agent_chat,shared}
-> app.agents.chat.*); all moves are git renames (history preserved).
app/agents/ now: chat/, podcaster/, video_presentation/, runtime/.
2026-06-05 12:54:02 +02:00
CREDO23
b7ea829371 refactor(agents): relocate boundary-only infra out of shared/
Neither module is imported by any sibling agent package, so neither belongs in
the cross-agent shared kernel:

- checkpointer.py -> app/agents/runtime/checkpointer.py
  LangGraph Postgres checkpoint saver. It's cross-agent *runtime infra* wired by
  the boundary (app lifespan + anonymous_chat & multi_agent_chat flows), not
  agent code. New app/agents/runtime/ layer holds boundary-wired agent infra.

- shared/system_prompt.py + shared/prompts/ -> app/prompts/
  The legacy single-agent prompt composer. The live agents don't use it
  (main_agent has its own system_prompt/ builder; anonymous_chat builds inline);
  its only consumer is new_llm_config_routes for displaying default instructions.
  Moved to the existing non-agent prompt domain:
    system_prompt.py        -> app/prompts/default_system_instructions.py
    prompts/                 -> app/prompts/system_prompt_composer/

app/agents/shared/ now contains only genuinely cross-agent code: context,
middleware/{compaction,retry_after,dedup_tool_calls}, tools/.

NOTE: get_default_system_instructions() (LLM-config UI) composes from the legacy
library, which differs from what the live agents actually run -- pre-existing
latent staleness, not changed here.
2026-06-05 12:36:44 +02:00
CREDO23
82c5dc5b02 refactor(agents): move mac-only modules out of the cross-agent shared kernel
app/agents/shared/ is a sibling of anonymous_chat/podcaster/multi_agent_chat/
video_presentation, so it should only hold code shared across 2+ of those
agents. In practice podcaster and video_presentation import nothing from it,
and anonymous_chat needs only context + compaction + retry_after + web_search.
Everything else was multi_agent_chat-only (the boundary just passes through).

Move the multi_agent_chat-only cluster into multi_agent_chat/shared/ (files
moved verbatim via git rename; ~116 import sites rewritten):

  errors, feature_flags, filesystem_selection, path_resolver, prompt_caching,
  sandbox, llm_config, mention_resolver
  middleware/busy_mutex, middleware/kb_persistence

busy_mutex/llm_config/mention_resolver are boundary-only but import the moved
modules, so they were folded in to avoid a backwards shared -> multi_agent_chat
dependency. main_agent builders now import the impls directly; the shared
middleware barrel keeps only the genuinely-shared compaction + retry_after.

Also delete the dead leftover shared/plugins and shared/skills dirs (live
copies already live under main_agent/).

Remaining in app/agents/shared/: context, system_prompt(+prompts), checkpointer,
middleware/{compaction,retry_after,dedup_tool_calls}, tools/. checkpointer and
system_prompt are boundary-only infra pending a dedicated home decision.
2026-06-05 12:30:15 +02:00
CREDO23
f615d6b530 refactor(agents): relocate remaining MAC-only kernel (permissions, deliverable_wait)
permissions.py (authorization Rule/Ruleset model) is consumed across all
MAC subagents + the permissions middleware, with a single external
consumer (user_tool_allowlist service) -> move to
multi_agent_chat/shared/permissions.py and repoint all 42 sites.

deliverable_wait.py (wait_for_deliverable) is used only by the podcast and
video_presentation deliverable tools -> colocate into
subagents/builtins/deliverables/.

No behavior change; import-all + permission/allowlist/deliverable unit
tests stay green.
2026-06-05 10:58:49 +02:00
CREDO23
714c5ffea9 refactor(agents): group tool-outcome receipts into multi_agent_chat/shared/receipts/
receipt.py (Receipt model + make_receipt) and receipt_command.py
(with_receipt Command helper) are a tight pair used only by MAC subagent
tools, the graph state, and the kb_persistence middleware -- no external
code imports them (the streaming tool_end handler only references them in a
docstring). Move both into a dedicated receipts/ package
(receipts/receipt.py + receipts/command.py) and repoint importers.

No behavior change; import-all + receipt/deliverable unit tests stay green.
2026-06-05 10:56:37 +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
5b45f78a16 refactor(chat): delete legacy stream_new_chat monolith (cutover complete)
The flows orchestrators (new_chat/resume_chat) are now the sole live path
after the byte-for-byte differential proof, so the monolith and its
monolith-vs-flows parity scaffolding are removed.

- Repoint the last live importer (anonymous_chat_routes) to
  streaming.agent.event_loop.stream_agent_events + shared.stream_result.StreamResult
  (drop-in; the keyword-only fallback-commit params default to inert for anon).
- Repoint e2e launcher patch targets to flows.shared.llm_bundle.
- Repoint helper unit tests (chunk_parts, thinking-step ids, tool-input
  streaming) to their flows homes to preserve coverage.
- Delete the monolith, the contract test, and the parity tests
  (parallel_refactor, stage_1, stage_2, orchestrator_frame) whose sole
  purpose was comparing against the now-removed monolith.

Full suite green (2622 passed, 1 skipped); the two excluded live-app dirs
(document_upload, composio) have a pre-existing, env-gated registration 404
unrelated to this change.
2026-06-04 14:35:45 +02:00
CREDO23
724bbd6deb refactor(agents): hardwire multi-agent as the only chat factory (bucket B1)
Make create_multi_agent_chat_deep_agent the unconditional agent factory in
all three streaming entry points (stream_new_chat monolith + new_chat/resume
flow orchestrators). Drop the MULTI_AGENT_CHAT_ENABLED branch and the now-unused
create_surfsense_deep_agent / _app_config imports. The single-agent
implementation (chat_deepagent.py, subagents/) is left in place; it is deleted
in a later phase. Suite green (2758 passed).
2026-06-04 13:35:38 +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
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
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
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
44abf56d6c fix: restore connector mentions, free-tier fallback, orphan-row guard in new chat flow 2026-06-04 10:25:06 +02:00
Anish Sarkar
e4d7b01b09 refactor(backend): Update references from document summary LLM to agent LLM across multiple files 2026-06-04 01:50:44 +05:30
Anish Sarkar
f3866b9e7e feat(backend): Use deterministic content in connector ingestion 2026-06-04 00:51:38 +05:30
Anish Sarkar
81fa219b30 feat(backend): Remove LLM summaries from document indexing 2026-06-04 00:50:19 +05:30
Anish Sarkar
e68b3f9532 feat(chat): fix support for mentioned connectors in new chat input state and runtime context, enhancing query rendering and context management 2026-06-03 22:51:55 +05:30
CREDO23
9dab07f775 refactor: point notification callers at notifications module 2026-06-03 18:04:47 +02:00
CREDO23
b6710ae9af refactor(jira): remove dead legacy indexing and write tools (mcp-only now) 2026-06-02 16:38:00 +02:00
CREDO23
f9e2c22d45 feat(documents): purge stored blobs on document deletion 2026-06-02 16:10:50 +02:00
Anish Sarkar
e3de7c4667 Merge remote-tracking branch 'upstream/dev' into feat/whatsapp-gateway-integration 2026-06-02 00:29:32 +05:30
Anish Sarkar
e85710dd7b feat(gateway): include Discord in gateway maintenance 2026-06-01 20:59:41 +05:30
Anish Sarkar
b5cc19843c feat(gateway): include Slack in gateway maintenance 2026-06-01 12:37:16 +05:30
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
Anish Sarkar
185759de1f feat(gateway): register multi-platform gateway routes 2026-05-29 10:20:43 +05:30
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
Anish Sarkar
2a41a157f7 refactor(gateway): model external chat surfaces over canonical chats 2026-05-28 04:39:54 +05:30
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
a428f6c05f feat(gateway): schedule gateway maintenance tasks 2026-05-27 23:40:47 +05:30
Anish Sarkar
dbf235cbda feat(web): enhance composer suggestion skeleton, improve document mention picker loading states & improved LLM prompt block for connector mentions 2026-05-27 00:43:50 +05:30
Anish Sarkar
2d134439ec feat(web): enhance mention handling to support connectors and improve document key management 2026-05-26 21:52:04 +05:30
Anish Sarkar
a41b16b73e feat(web): enhance chat context and mention handling with connector support 2026-05-26 21:11:53 +05:30
CREDO23
cf0085575c refactor(chat): add streaming/flows/resume_chat/orchestrator + flows public API
Slim composition root for the resume-chat streaming flow. Mirrors the
new_chat orchestrator but specialized for resumed turns:

* no fresh user turn, no title generation, no image-capability gate
* persists a fresh assistant shell for the resumed turn
* applies build_resume_routing to dispatch user decisions to the
  correct paused subagent before invoking the agent
* shares the same stream_loop + flow-local _recover closure for in-
  stream provider rate-limit recovery

Also lands flows/__init__.py, which becomes the public chat-flow API:

    from app.tasks.chat.streaming.flows import stream_new_chat, stream_resume_chat

Existing wiring (routes, contract test) still imports from the legacy
app.tasks.chat.stream_new_chat module. Cutover is the next phase.
2026-05-25 21:50:09 +02:00
CREDO23
885d4acda9 refactor(chat): add streaming/flows/resume_chat/ per-concern leaf modules
Three focused modules used by the upcoming resume-chat orchestrator:

* runtime_context: build_resume_chat_runtime_context assembles the
  SurfSenseContextSchema for a resume turn (handles empty mention
  lists, since resume requests do not carry fresh @-mentions).
* assistant_shell: persist_resume_assistant_shell writes a fresh
  assistant row for the resumed turn so the post-stream finalize
  has a target.
* resume_routing: build_resume_routing collects the pending
  interrupts across paused subagents and slices the flat list of
  ResumeDecision[] into the correct (thread, subagent) buckets so
  LangGraph routes each decision back to the right paused tool call.

Add-only; no orchestrator yet (next commit).
2026-05-25 21:50:03 +02:00
CREDO23
b2a0888588 refactor(chat): add streaming/flows/new_chat/orchestrator.stream_new_chat
Slim composition root for the new-chat streaming flow. Sequences:

1. validate inputs and load the LLM bundle (negative id => YAML)
2. open the OTEL chat_request span; set agent_mode tag
3. spawn the four pre-stream DB writes (set-ai-responding, persist
   user turn, persist assistant shell, first-assistant probe)
4. reserve premium quota (with free-fallback retry on denial)
5. build connector + checkpointer + agent + input_state
6. emit first frames (message-start, step-start, initial thinking step)
7. spawn the background title generator
8. run the shared stream_loop with a flow-local _recover closure that
   reroutes to the next auto-pin config on provider 429s
9. finalize: emit terminal title/token frames, shielded assistant
   finalize, release-or-finalize premium quota, close session, GC,
   record OTEL outcome

Public entry-point flows/new_chat/__init__ re-exports stream_new_chat.

Existing wiring (routes, tests) still imports the legacy function from
app.tasks.chat.stream_new_chat. Cutover is a later commit.
2026-05-25 21:49:55 +02:00
CREDO23
927009745e refactor(chat): add streaming/flows/new_chat/ per-concern leaf modules
Seven focused modules that the upcoming new_chat orchestrator
composes:

* auto_pin: resolve_initial_auto_pin selects the initial config (with
  vision-capable filtering and error classification).
* llm_capability: check_image_input_capability blocks routing an
  image-bearing turn to a known text-only model.
* runtime_context: build_new_chat_runtime_context assembles the
  SurfSenseContextSchema for a new-chat turn.
* persistence_spawn: spawn_set_ai_responding_bg, spawn_persist_user_task,
  spawn_persist_assistant_shell_task, and await_persist_task background
  the four pre-stream DB writes so they overlap with agent build.
* initial_thinking_step: build_initial_thinking_step +
  iter_initial_thinking_step_frame produce the very first thinking-1 SSE
  step ("Understanding your request" / "Analyzing referenced content").
* title_gen: spawn_title_task + maybe_emit_title_update +
  await_pending_title_update background the thread-title generator and
  interleave its update into the stream when ready.
* input_state: build_new_chat_input_state assembles the LangGraph
  input_state (history bootstrap, mentions resolution, context blocks,
  human-message construction). The heavy one.

Add-only; no orchestrator yet (next commit).
2026-05-25 21:49:45 +02:00
CREDO23
21bddc73a7 refactor(chat): add streaming/flows/shared/assistant_finalize.py
Extracts finalize_assistant_message: the post-stream server-side write
of the final assistant message (with content parts + token usage)
guarded by asyncio.shield + shielded_async_session so a client
disconnect cannot abort the persist.

Add-only; legacy stream_new_chat.py keeps its inline finalize block
until cutover.
2026-05-25 21:49:31 +02:00
CREDO23
b54b803dc9 refactor(chat): add streaming/flows/shared/ rate-limit recovery + stream loop
Two cooperating modules that wrap stream_agent_events with in-stream
recovery from provider 429s:

* rate_limit_recovery: can_recover_provider_rate_limit truth-table
  guard, reroute_to_next_auto_pin (selects the next eligible auto-pin
  config and reloads the LLM bundle), log_rate_limit_recovered.
* stream_loop: run_stream_loop drives stream_agent_events in a
  while-True loop, delegating recovery to a flow-supplied RecoverFn
  callback so new_chat and resume_chat can share the same loop while
  keeping their own nonlocal state.

Add-only; not yet wired into any orchestrator.
2026-05-25 21:49:27 +02:00
CREDO23
2c3edb7c84 refactor(chat): add streaming/flows/shared/terminal_error.py
Extracts handle_terminal_exception: the shared except-branch behavior for
the chat orchestrators. Classifies the raised exception, logs the
structured chat_stream error event, and emits the terminal-error SSE
frame + done sentinel via the streaming service.

Add-only; nothing imports it yet.
2026-05-25 21:49:18 +02:00
CREDO23
40300d300a refactor(chat): add streaming/flows/shared/premium_quota.py
Centralizes the premium-credits lifecycle for chat turns:

* needs_premium_quota: gate check (premium user + non-fallback config).
* PremiumReservation: dataclass capturing reservation state + token totals.
* reserve_premium / finalize_premium / release_premium: idempotent
  reservation, commit, and rollback used by the orchestrators.

Add-only; legacy stream_new_chat.py keeps its inline quota handling
until cutover.
2026-05-25 21:49:14 +02:00
CREDO23
e9a98ecafb refactor(chat): add streaming/flows/shared/ base helpers
Six small, single-purpose modules shared by the upcoming new_chat and
resume_chat orchestrators:

* llm_bundle: dispatches negative config_id to the YAML loader and
  non-negative config_id to the DB loader, returning (llm, AgentConfig).
* pre_stream_setup: builds the connector service, resolves the
  Firecrawl API key, and returns the chat checkpointer.
* first_frames: iter_initial_frames + iter_final_frames emit the canonical
  message-start / step-start / idle / finish / done SSE envelope.
* finalize_emit: iter_token_usage_frame emits the per-turn usage frame
  from a TokenAccumulator summary.
* finally_cleanup: close_session_and_clear_ai_responding and run_gc_pass
  centralize the finally-block bookkeeping.
* span: open_chat_request_span / set_agent_mode / close_chat_request_span /
  record_outcome_attrs wrap the OpenTelemetry chat_request span.

Add-only; these are not yet wired into stream_new_chat.py.
2026-05-25 21:49:09 +02:00