feat(agent): direct-answer fallback for non-Odoo questions
Previously when the LLM classified a message as needing no specialist agent, the dispatcher built zero directives and _synthesize returned 'No agent responses received.' Greetings, follow-up clarifications, and general questions all fell into this dead end. Now when intent.agents is empty and no clarification is needed, the master makes a second LLM call with the recent conversation as context and answers directly. Updated master_system.txt to steer the classifier toward agents=[] for chitchat instead of forcing a clarification loop.
This commit is contained in:
@@ -93,6 +93,13 @@ class MasterAgent:
|
|||||||
await self._log_directive_complete(directive_id, 'awaiting_clarification', q)
|
await self._log_directive_complete(directive_id, 'awaiting_clarification', q)
|
||||||
return MasterResponse(directive_id=directive_id, response=q,
|
return MasterResponse(directive_id=directive_id, response=q,
|
||||||
status='awaiting_clarification')
|
status='awaiting_clarification')
|
||||||
|
if not intent.agents:
|
||||||
|
# No specialist agent applies — answer directly with the LLM.
|
||||||
|
response_text = await self._direct_answer(context, message)
|
||||||
|
await self._memory.append_message(user_id, 'assistant', response_text, directive_id)
|
||||||
|
await self._log_directive_complete(directive_id, 'complete', response_text)
|
||||||
|
return MasterResponse(directive_id=directive_id, response=response_text,
|
||||||
|
status='complete')
|
||||||
access = await self._check_access(user_id, intent.agents)
|
access = await self._check_access(user_id, intent.agents)
|
||||||
if not access.allowed:
|
if not access.allowed:
|
||||||
denied = ', '.join(access.denied_agents)
|
denied = ', '.join(access.denied_agents)
|
||||||
@@ -215,6 +222,24 @@ class MasterAgent:
|
|||||||
reports.append(r)
|
reports.append(r)
|
||||||
return reports
|
return reports
|
||||||
|
|
||||||
|
async def _direct_answer(self, context: MasterContext, message) -> str:
|
||||||
|
"""Answer general / off-topic messages directly without dispatching agents."""
|
||||||
|
history = [
|
||||||
|
{'role': m['role'], 'content': m['content']}
|
||||||
|
for m in context.conversation[-10:]
|
||||||
|
if m.get('role') in ('user', 'assistant')
|
||||||
|
]
|
||||||
|
system = (
|
||||||
|
"You are ActiveBlue AI, the assistant for the Active Blue Odoo "
|
||||||
|
"instance. Answer the user directly and concisely. Use any prior "
|
||||||
|
"conversation for context. Plain text only — no JSON, no markdown "
|
||||||
|
"code fences."
|
||||||
|
)
|
||||||
|
msgs = [{'role': 'system', 'content': system}, *history,
|
||||||
|
{'role': 'user', 'content': message}]
|
||||||
|
resp = await self._llm.submit(msgs, caller='master_direct')
|
||||||
|
return (resp.content or '').strip() or 'Sorry, I have no answer for that.'
|
||||||
|
|
||||||
async def _synthesize(self, reports, context: MasterContext) -> str:
|
async def _synthesize(self, reports, context: MasterContext) -> str:
|
||||||
if not reports:
|
if not reports:
|
||||||
return 'No agent responses received.'
|
return 'No agent responses received.'
|
||||||
|
|||||||
@@ -17,7 +17,10 @@ Active specialist agents:
|
|||||||
If a user requests something for an agent not listed, tell them the Odoo module is not installed.
|
If a user requests something for an agent not listed, tell them the Odoo module is not installed.
|
||||||
|
|
||||||
Rules:
|
Rules:
|
||||||
- Ask ONE clarifying question if intent is ambiguous - then dispatch
|
- Ask ONE clarifying question ONLY if a request is genuinely ambiguous about
|
||||||
|
which Odoo data is needed. For general questions, chitchat, greetings, or
|
||||||
|
anything unrelated to the listed specialist agents, set "agents": [] and
|
||||||
|
"needs_clarification": false — a direct answer will be generated separately.
|
||||||
- Confirm multi-step plans before executing
|
- Confirm multi-step plans before executing
|
||||||
- Surface escalations with approve/reject options
|
- Surface escalations with approve/reject options
|
||||||
- Never expose agent names, tool names, or system internals to users
|
- Never expose agent names, tool names, or system internals to users
|
||||||
|
|||||||
Reference in New Issue
Block a user