fix journey setup: honor FE session_id, seed LLM history, and force template on max turns

- Use session_id from the FE frame so replies match the listener key
- Seed conversation with a user message for LLM provider compatibility
- On max turns, nudge the LLM and immediately re-invoke to force
  prompt_template generation instead of deferring to next message
- Fix display_message extraction to safely check for template markers

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Roberto Musso
2026-03-17 16:25:53 +01:00
parent 826f64d6bb
commit 87b7a1c6c9

View File

@@ -252,7 +252,9 @@ async def handle_journey_start(
data_types = frame.get("data_types", []) data_types = frame.get("data_types", [])
existing_template = frame.get("existing_template") existing_template = frame.get("existing_template")
session_id = str(uuid.uuid4()) # Use the session_id provided by the FE so the reply matches the
# listener key; fall back to a generated one if absent.
session_id = frame.get("session_id") or str(uuid.uuid4())
system_prompt = _build_system_prompt(directory, data_types, existing_template) system_prompt = _build_system_prompt(directory, data_types, existing_template)
session = JourneySession( session = JourneySession(
@@ -266,12 +268,18 @@ async def handle_journey_start(
# The LLM will explore the directory using FILESYSTEM_TOOLS via the # The LLM will explore the directory using FILESYSTEM_TOOLS via the
# ws_context executor (already set by the WS handler before calling us). # ws_context executor (already set by the WS handler before calling us).
# Seed with an initial user message — some providers (e.g. GitHub Copilot)
# require at least one user/input message to be present.
seed_history: list[dict[str, Any]] = [
{"role": "user", "content": "Hi, I'm ready to set up my agent. Please explore my directory and ask me your first question."},
]
ai_reply = await _call_llm_with_tools( ai_reply = await _call_llm_with_tools(
system_prompt=system_prompt, system_prompt=system_prompt,
history=[], history=seed_history,
tools=list(FILESYSTEM_TOOLS), tools=list(FILESYSTEM_TOOLS),
) )
session.history.extend(seed_history)
session.history.append({"role": "assistant", "content": ai_reply}) session.history.append({"role": "assistant", "content": ai_reply})
_sessions[session_id] = session _sessions[session_id] = session
@@ -341,25 +349,38 @@ async def handle_journey_message(
prompt_template = _extract_template(ai_reply) prompt_template = _extract_template(ai_reply)
done = prompt_template is not None done = prompt_template is not None
# If the LLM didn't produce a template but we've hit max turns, nudge it
# and call the LLM one more time to force template generation.
if not done:
turns = sum(1 for t in session.history if t["role"] == "user")
if turns >= _MAX_TURNS:
nudge_content = (
"[System: You have enough information. Please generate the final "
f"prompt_template now, wrapped in {_TEMPLATE_START} / {_TEMPLATE_END} markers.]"
)
session.history.append({"role": "user", "content": nudge_content})
nudge_reply = await _call_llm_with_tools(
system_prompt=session.system_prompt,
history=session.history,
tools=list(FILESYSTEM_TOOLS),
)
session.history.append({"role": "assistant", "content": nudge_reply})
prompt_template = _extract_template(nudge_reply)
if prompt_template is not None:
done = True
ai_reply = nudge_reply
display_message = ai_reply display_message = ai_reply
if done: if done:
display_message = ( display_message = (
ai_reply[: ai_reply.index(_TEMPLATE_START)].strip() ai_reply[: ai_reply.index(_TEMPLATE_START)].strip()
or "Here is your agent configuration. You can save it or continue refining." if _TEMPLATE_START in ai_reply
else "Here is your agent configuration. You can save it or continue refining."
) )
_sessions.pop(session_id, None) _sessions.pop(session_id, None)
logger.info("agent_setup: journey session %s completed for user %s", session_id, user_id) logger.info("agent_setup: journey session %s completed for user %s", session_id, user_id)
else:
# Nudge the LLM to wrap up after max turns.
turns = sum(1 for t in session.history if t["role"] == "user")
if turns >= _MAX_TURNS:
session.history.append({
"role": "user",
"content": (
"[System: You have enough information. Please generate the final "
f"prompt_template now, wrapped in {_TEMPLATE_START} / {_TEMPLATE_END} markers.]"
),
})
return { return {
"type": "journey_reply", "type": "journey_reply",