mirror of
https://github.com/tiennm99/DocsGPT.git
synced 2026-10-13 12:14:00 +00:00
Hold resumed turns and public-link visitors to the right wiki rules
A paused turn is found by the agent owner's id, so anyone holding one of the owner's agent keys could resume the owner's own chat with its saved wiki edit rights. A resume now counts as an API or widget caller when either the saved state or the resuming request is one, cuts the wiki tool to wiki_view unless the wiki allows outside edits, and gives the tool executor the same flags. A request that names an agent, by key or id, may only resume that agent's turn; otherwise the claim is released and the request refused. Public-link visitors run as themselves and reach only wikis they may edit, so the wiki switch no longer applies to them. Instead every wiki write in a public-link run waits for the visitor's approval, so the agent owner's prompt or sources can't steer an edit to the visitor's wiki unasked.
This commit is contained in:
1 parent
91e70d2f0c
commit
051452c438
10 files changed
+405
-64
No files matched your search
@@ -887,10 +887,10 @@ class _PauseThenAnswerAgent:
|
||||
yield {"answer": self.ANSWER_TEXT}
|
||||
|
||||
|
||||
def _seed_agent(conn, user_id: str, key: str) -> None:
|
||||
def _seed_agent(conn, user_id: str, key: str) -> str:
|
||||
from docsgpt.storage.db.repositories.agents import AgentsRepository
|
||||
|
||||
AgentsRepository(conn).create(user_id, "Weather Agent", "published", key=key)
|
||||
return str(AgentsRepository(conn).create(user_id, "Weather Agent", "published", key=key)["id"])
|
||||
|
||||
|
||||
@contextmanager
|
||||
@@ -898,12 +898,14 @@ def _wire_v1_route_db(engine, monkeypatch):
|
||||
"""Full route-level DB wiring for the ``/v1/chat/completions`` blueprint.
|
||||
|
||||
Extends ``_wire_db`` (conversation/continuation/base services) with the v1
|
||||
routes module's own ``db_readonly`` (used by ``_lookup_agent``) and a fake
|
||||
routes module's own ``db_readonly`` (used by ``_lookup_agent``), the
|
||||
stream processor's (the resume looks up the key's agent), and a fake
|
||||
title-gen ``LLMCreator`` on the base module, so a real two-POST round-trip
|
||||
runs entirely against the ephemeral Postgres with no live LLM/provider.
|
||||
"""
|
||||
from docsgpt.api.v1 import routes as v1_routes_mod
|
||||
from docsgpt.api.answer.routes import base as base_mod
|
||||
from docsgpt.api.answer.services import stream_processor as sp_mod
|
||||
|
||||
@contextmanager
|
||||
def _readonly():
|
||||
@@ -915,6 +917,7 @@ def _wire_v1_route_db(engine, monkeypatch):
|
||||
|
||||
with _wire_db(engine, monkeypatch):
|
||||
monkeypatch.setattr(v1_routes_mod, "db_readonly", _readonly)
|
||||
monkeypatch.setattr(sp_mod, "db_readonly", _readonly)
|
||||
monkeypatch.setattr(
|
||||
base_mod.LLMCreator,
|
||||
"create_llm",
|
||||
@@ -993,14 +996,17 @@ class TestV1ToolRoundTripEndToEnd:
|
||||
api_key = f"key-{uuid.uuid4().hex[:8]}"
|
||||
with pg_engine.begin() as conn:
|
||||
_seed_user(conn, user_id)
|
||||
_seed_agent(conn, user_id, api_key)
|
||||
agent_id = _seed_agent(conn, user_id, api_key)
|
||||
|
||||
app = self._build_app()
|
||||
|
||||
# ``build_agent`` is the only mock — a fresh pausing/answering agent
|
||||
# per call. The route's ``build_continuation_from_messages`` calls this
|
||||
# internally on POST #2, so the rebuild itself still runs for real.
|
||||
# It binds the agent as ``_configure_agent`` would, so the paused turn
|
||||
# is saved under the agent the key resumes.
|
||||
def _fake_build_agent(self, question): # noqa: ARG001
|
||||
self.agent_id = agent_id
|
||||
return _PauseThenAnswerAgent(
|
||||
TestV1ToolRoundTripEndToEnd.PENDING
|
||||
)
|
||||
|
||||
Reference in new issue
Block a user