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:
@@ -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",
|
||||||
|
|||||||
Reference in New Issue
Block a user