mirror of
https://github.com/infiniflow/ragflow.git
synced 2026-08-05 15:20:30 +08:00
@@ -26,6 +26,30 @@ def _snip(text: str, limit: int = 160) -> str:
|
||||
return text if len(text) <= limit else text[: limit - 3] + "..."
|
||||
|
||||
|
||||
def _discovered_entity(tools) -> str | None:
|
||||
"""Pick a salient discovered name from the gathered evidence.
|
||||
|
||||
Prefers an explicit entity/keyword tag on a chunk, falling back to a source
|
||||
document name. Used only to gate ``graph_explore`` eligibility (its context
|
||||
check needs ``context.last_entity``), so a coarse signal is enough.
|
||||
"""
|
||||
chunks = (getattr(tools, "kbinfos", {}) or {}).get("chunks", []) or []
|
||||
for c in chunks:
|
||||
for key in ("entities_kwd", "important_kwd"):
|
||||
val = c.get(key)
|
||||
if isinstance(val, list) and val:
|
||||
first = str(val[0]).strip()
|
||||
if first:
|
||||
return first
|
||||
if isinstance(val, str) and val.strip():
|
||||
return val.strip().split()[0]
|
||||
for c in chunks:
|
||||
name = str(c.get("docnm_kwd") or "").strip()
|
||||
if name:
|
||||
return name
|
||||
return None
|
||||
|
||||
|
||||
async def agentic_research(state: dict, tools) -> dict:
|
||||
"""Two-level loop for high/ultra modes."""
|
||||
question = state.get("question", "")
|
||||
@@ -93,6 +117,10 @@ async def agentic_research(state: dict, tools) -> dict:
|
||||
)
|
||||
_LOG.info('[Agentic research] Found a new angle worth researching: "%s"', dc)
|
||||
|
||||
# ── Step A.5: note a discovered entity so graph_explore becomes eligible
|
||||
# in the next round (its context gate requires context.last_entity). ──
|
||||
ctx.note_entity(_discovered_entity(tools))
|
||||
|
||||
# ── Step B: Sufficiency Check ──
|
||||
all_chunks = {i: c for i, c in enumerate(tools.kbinfos.get("chunks", []))}
|
||||
agent_results_list = [c.agent_result for c in ctx.claims if c.agent_result]
|
||||
|
||||
@@ -153,6 +153,16 @@ class OrchestratorContext:
|
||||
def last_entity(self) -> str | None:
|
||||
return self._last_entity
|
||||
|
||||
def note_entity(self, name: str | None) -> None:
|
||||
"""Record the most recently discovered entity/document name.
|
||||
|
||||
Gates ``graph_explore`` in ``tool_fits_context``: the tool is only
|
||||
offered once research has surfaced something to expand from. Ignores
|
||||
empty values so a fruitless round can't clear a prior discovery.
|
||||
"""
|
||||
if isinstance(name, str) and name.strip():
|
||||
self._last_entity = name.strip()
|
||||
|
||||
@property
|
||||
def current_claim(self) -> str | None:
|
||||
unverified = [c for c in self.claims if not c.is_verified]
|
||||
|
||||
@@ -1999,7 +1999,7 @@ class LiteLLMBase(ABC):
|
||||
content = json.dumps(result, ensure_ascii=False)
|
||||
else:
|
||||
content = str(result)
|
||||
hist.append({"role": "tool", "tool_call_id": tc.id, "content": content})
|
||||
hist.append({"role": "tool", "tool_call_id": tc.id, "content": content.replace("</think>", "")})
|
||||
return hist
|
||||
|
||||
def bind_tools(self, toolcall_session=None, tools=None):
|
||||
|
||||
Reference in New Issue
Block a user