mirror of
https://github.com/tiennm99/serena.git
synced 2026-10-13 20:15:20 +00:00
Always provide full activation message upon calling activate_project
This is necessary, because some clients (e.g. Claude Desktop) will reuse a single session across chats. Resolves #1384
This commit is contained in:
1 parent
364c08c6e2
commit
f0a3a279b7
3 files changed
+30
-9
No files matched your search
@@ -14,6 +14,8 @@ Status of the `main` branch. Changes prior to the next official version change w
|
||||
`initial_instructions`). Now they are passed directly in the activation message (and excluded from a subsequent `initial_instructions` call).
|
||||
- Fix: Project activation message was provided more than once for case of dynamic project activation followed
|
||||
by `initial_instructions` #1372
|
||||
- Always provide full activation message upon calling `activate_project` (even if project was already active in the same session) #1384
|
||||
This is necessary, because some clients (e.g. Claude Desktop) will reuse a single session across chats.
|
||||
- Security: Forbid `".."` in memory names to disallow accessing files outside dedicated memory directories
|
||||
- Security: Add check for tool being read-only in the project server (previously only checked in `query_project` tool, i.e. client side)
|
||||
- Usage reporting now also includes the name of the Serena context that is used
|
||||
|
||||
+6
-2
@@ -800,9 +800,13 @@ class SerenaAgent:
|
||||
proj = self._active_project
|
||||
assert proj is not None, "A project must be active before calling this."
|
||||
|
||||
# if activation message was already provided in the current session, don't provide it again
|
||||
# Note: The activation message is always returned in full, even if it was already provided in the current session,
|
||||
# because some clients (e.g. Claude Desktop) will use the same session across multiple chats.
|
||||
# So while we don't want the activation message to be additionally included in the system prompt
|
||||
# (initial_instructions), an explicit project activation should always return it.
|
||||
# (The check below deliberately left in place for documentation purposes, preventing a regression)
|
||||
if self._project_prompt_status.is_project_activation_message_already_provided(session_id):
|
||||
return "Project was already activated."
|
||||
pass # no special handling
|
||||
|
||||
# provide basic project information (name, location, languages, encoding)
|
||||
if proj.is_newly_created:
|
||||
|
||||
@@ -728,14 +728,16 @@ class TestPromptProvision:
|
||||
but not on subsequent calls within the same session. #1372
|
||||
"""
|
||||
project_name = "test_repo_python"
|
||||
session1 = "session1"
|
||||
session2 = "session2"
|
||||
|
||||
result1 = self._call_tool(serena_agent, InitialInstructionsTool, session_id="session1")
|
||||
result1 = self._call_tool(serena_agent, InitialInstructionsTool, session_id=session1)
|
||||
self._assert_activation_message(result1, project_name, present=True)
|
||||
|
||||
result2 = self._call_tool(serena_agent, InitialInstructionsTool, session_id="session2")
|
||||
result2 = self._call_tool(serena_agent, InitialInstructionsTool, session_id=session2)
|
||||
self._assert_activation_message(result2, project_name, present=True)
|
||||
|
||||
result3 = self._call_tool(serena_agent, InitialInstructionsTool, session_id="session1")
|
||||
result3 = self._call_tool(serena_agent, InitialInstructionsTool, session_id=session1)
|
||||
self._assert_activation_message(result3, project_name, present=False)
|
||||
|
||||
@pytest.mark.parametrize("serena_agent", [Language.PYTHON], indirect=True)
|
||||
@@ -747,16 +749,18 @@ class TestPromptProvision:
|
||||
"""
|
||||
project_name1 = "test_repo_python"
|
||||
project_name2 = "test_repo_java"
|
||||
session1 = "session1"
|
||||
session2 = "session2"
|
||||
|
||||
# the initial instructions must contain the project activation message for the first project
|
||||
result1 = self._call_tool(serena_agent, InitialInstructionsTool, session_id="session1")
|
||||
result1 = self._call_tool(serena_agent, InitialInstructionsTool, session_id=session1)
|
||||
self._assert_activation_message(result1, project_name1, present=True)
|
||||
|
||||
# now activate another project which dynamically enables a new mode (no-onboarding)
|
||||
reg_project = serena_agent.serena_config.get_registered_project(project_name2)
|
||||
reg_project.project_config.default_modes = ["no-onboarding"]
|
||||
expected_new_mode_message = "The onboarding process is not applied."
|
||||
result2 = self._call_tool(serena_agent, ActivateProjectTool, project=project_name2, session_id="session1")
|
||||
result2 = self._call_tool(serena_agent, ActivateProjectTool, project=project_name2, session_id=session1)
|
||||
|
||||
# the new mode's prompt must be included in the activation message
|
||||
self._assert_activation_message(result2, project_name2, present=True)
|
||||
@@ -765,16 +769,27 @@ class TestPromptProvision:
|
||||
)
|
||||
|
||||
# the mode prompt must not be included in subsequent calls to the initial instructions tool within the same session
|
||||
result3 = self._call_tool(serena_agent, InitialInstructionsTool, session_id="session1")
|
||||
result3 = self._call_tool(serena_agent, InitialInstructionsTool, session_id=session1)
|
||||
assert expected_new_mode_message not in result3, (
|
||||
f"Expected new mode message '{expected_new_mode_message}' to not be included in subsequent calls, but it was found in result:\n{result3}"
|
||||
)
|
||||
|
||||
# the mode prompt must be included in the initial instructions of a new session
|
||||
result4 = self._call_tool(serena_agent, InitialInstructionsTool, session_id="session2")
|
||||
result4 = self._call_tool(serena_agent, InitialInstructionsTool, session_id=session2)
|
||||
assert expected_new_mode_message in result4, (
|
||||
f"Expected new mode message '{expected_new_mode_message}' to be included in new session, but it was not found in result:\n{result4}"
|
||||
)
|
||||
|
||||
# the initial instructions for the new session must also include the activation message for the project
|
||||
self._assert_activation_message(result4, project_name2, present=True)
|
||||
|
||||
@pytest.mark.parametrize("serena_agent", [Language.PYTHON], indirect=True)
|
||||
def test_activate_project_tool_always_returns_activation_message(self, serena_agent: SerenaAgent) -> None:
|
||||
project_name = "test_repo_python"
|
||||
session = "session1"
|
||||
|
||||
result1 = self._call_tool(serena_agent, ActivateProjectTool, project=project_name, session_id=session)
|
||||
self._assert_activation_message(result1, project_name, present=True)
|
||||
|
||||
result2 = self._call_tool(serena_agent, ActivateProjectTool, project=project_name, session_id=session)
|
||||
self._assert_activation_message(result2, project_name, present=True)
|
||||
Reference in new issue
Block a user