diff --git a/app/api/routes/agent_setup.py b/app/api/routes/agent_setup.py index 9479732..d5bae95 100644 --- a/app/api/routes/agent_setup.py +++ b/app/api/routes/agent_setup.py @@ -252,7 +252,9 @@ async def handle_journey_start( data_types = frame.get("data_types", []) 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) session = JourneySession( @@ -266,12 +268,18 @@ async def handle_journey_start( # The LLM will explore the directory using FILESYSTEM_TOOLS via the # 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( system_prompt=system_prompt, - history=[], + history=seed_history, tools=list(FILESYSTEM_TOOLS), ) + session.history.extend(seed_history) session.history.append({"role": "assistant", "content": ai_reply}) _sessions[session_id] = session @@ -341,25 +349,38 @@ async def handle_journey_message( prompt_template = _extract_template(ai_reply) 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 if done: display_message = ( 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) 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 { "type": "journey_reply",