mirror of
https://github.com/tiennm99/serena.git
synced 2026-10-11 12:29:04 +00:00
Merge pull request #1827 from oraios/memory-cleanup
This commit is contained in:
14 files changed
+181
-238
No files matched your search
@@ -1,32 +0,0 @@
|
||||
# Conventions
|
||||
|
||||
## Style (project-instructed)
|
||||
- Idiomatic, object-oriented design. Non-trivial interfaces use **explicitly typed abstractions** (strategy pattern etc.) rather than bare functions/callbacks.
|
||||
- Avoid low-level data structures where an OO abstraction fits. For simple data containers use **dataclasses**, not dicts/tuples.
|
||||
- Structure function bodies into **functional blocks separated by blank lines**, each prefixed with a short elliptical phrase (lowercase, no leading capital) describing the block's purpose.
|
||||
- **Docstrings: reStructuredText.** Param/return/raises use `:param x:`, `:return:`, `:raises X:`.
|
||||
- Parameter / method / class descriptions begin with a precise elliptical phrase defining *what* the thing is; details in subsequent sentences.
|
||||
|
||||
## Formatting / lint (ruff)
|
||||
- Line length 140, double quotes, target `py311`.
|
||||
- Many "annoying" rules are disabled — see `[tool.ruff.lint] ignore` in `pyproject.toml` before adding workarounds (e.g. `Optional[T]` is preferred over `T | None`, `Union` is allowed, relative imports forbidden, `% string formatting` allowed).
|
||||
- `ruff format` runs on `src scripts test`; same set for `ruff check`.
|
||||
- mccabe complexity cap: 20.
|
||||
|
||||
## Typing (ty)
|
||||
- Type checker is **ty** (Astral), configured under `[tool.ty]` in `pyproject.toml`.
|
||||
|
||||
## Tests
|
||||
- Language-server tests are pytest-marker-gated (one marker per language; see `pyproject.toml` `[tool.pytest.ini_options].markers`). Default `poe test` runs unmarked tests + whatever `PYTEST_MARKERS` selects.
|
||||
- Snapshot tests use **syrupy** with custom `--snapshot-patch-pycharm-diff` plugin (auto-added via `addopts`).
|
||||
|
||||
## Tool descriptions (LLM-facing)
|
||||
- To change how a tool is described to the model, edit the Tool class's `apply()` **docstring** (in
|
||||
`src/serena/tools/*.py`) — `make_mcp_tool` parses the docstring body + `:param:` lines into the MCP tool
|
||||
description/schema. Do NOT use `tool_description_overrides` in context ymls (e.g. `claude-code.yml`); the
|
||||
docstring is the single source of truth and overrides drift. Keep `:param:` lines accurate.
|
||||
|
||||
## Memories
|
||||
- Follow `mem:memory_maintenance` for any new/updated memory in `.serena/memories/`.
|
||||
- Durable knowledge goes in memories/docs (not the assistant's auto-memory); see the monorepo top-level
|
||||
`CLAUDE.md` for the cross-repo conventions (no benchmark-tuning of agent-facing strings, etc.).
|
||||
@@ -0,0 +1,48 @@
|
||||
# Software Design
|
||||
|
||||
IMPORTANT: You use an idiomatic, object-oriented style (Java-esque principles, Pythonic syntax and constructs).
|
||||
|
||||
* You keep each concern in exactly one home.
|
||||
A mechanism whose parts are only correct in combination is implemented as a single component/class, and its parts are private to it;
|
||||
expose a minimal public surface. Java-like encapsulation: If helper functions and constants are only used by one abstraction,
|
||||
make them internal to the respective class.
|
||||
* You enforce invariants through structure and visibility; interfaces should not permit states the design forbids.
|
||||
* For any non-trivial interfaces, you use interfaces that expect explicitly typed abstractions
|
||||
rather than mere functions (i.e. use the strategy pattern, for example).
|
||||
You avoid the use of low-level data structures in all cases where an object-oriented abstraction would be more appropriate.
|
||||
For simple data storage, you use dataclasses instead of dictionaries or tuples.
|
||||
|
||||
# Testing
|
||||
|
||||
The key principle is to test *only* externally observable behavior and guarantees, never implementation structure.
|
||||
* Litmus test: a behaviour-preserving refactoring must not break any test. A test that could break is wrong and must not be written.
|
||||
* When functionality is removed, you delete its tests. You never add tests asserting the *absence* of something;
|
||||
absence of an implementation detail is not a behaviour, and such tests only freeze the current implementation and burden maintenance.
|
||||
* Fewer, behaviour-anchored tests are preferred; a missing test is better than an implementation-coupled one.
|
||||
|
||||
Language-server tests are pytest-marker-gated (one marker per language; see `pyproject.toml` `[tool.pytest.ini_options].markers`). Default `poe test` runs unmarked tests + whatever `PYTEST_MARKERS` selects.
|
||||
Snapshot tests use syrupy.
|
||||
|
||||
# Docstrings & Comments
|
||||
|
||||
* You consistently use reStructuredText.
|
||||
* You structure function implementations into functional blocks that are separated by blank lines.
|
||||
Atop each functional block, you write an elliptical phrase (starting with lower-case letter) that describes the purpose of the
|
||||
block in a concise manner.
|
||||
* When describing parameters, methods/functions and classes, you use a precise style, where the initial (elliptical) phrase
|
||||
clearly defines *what* it is. Any details then follow in subsequent sentences.
|
||||
* Each piece of information appears exactly once, at the element that owns it: callers do not
|
||||
explain callees' internals, and callees do not describe their callers.
|
||||
|
||||
# Pull requests
|
||||
|
||||
Read `mem:creating_pull_requests` when asked to participate in the creation of a pull request.
|
||||
|
||||
# Memories
|
||||
|
||||
- Follow `mem:memory_maintenance` for any new/updated memory in `.serena/memories/`.
|
||||
- Durable project knowledge goes into memories or docs/
|
||||
|
||||
# Dev Tools
|
||||
|
||||
Read `mem:task_completion` for tools to call upon task completion.
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
- Core principle: progressive discovery through references, building a graph of memories.
|
||||
- Initially, agents are provided with the list of all memories (names only).
|
||||
- Agents should read `mem:core` as the top-level entry point (graph root).
|
||||
- Agents should read `mem:critical_info` as the top-level entry point (graph root).
|
||||
This memory should contain references to other memories covering major project domains.
|
||||
The referenced memories shall, in turn, shall contain references to even more specific memories, and so on.
|
||||
The depth of the graph shall depend on the project complexity.
|
||||
|
||||
@@ -18,12 +18,10 @@ Serena is an MCP-based "IDE for coding agents": semantic code retrieval/editing/
|
||||
- `test/serena/`, `test/solidlsp/<lang>/` — pytest suites; per-language tests gated by pytest markers
|
||||
- `test/resources/repos/<lang>/` — fixture projects used by language-server tests
|
||||
- `scripts/` — utilities (prompt regen, tool overview, profiling, agno agent)
|
||||
- `docs/` — Jupyter Book sources; build via poe `doc-build`
|
||||
- `docs/` — Jupyter Book sources; build via `poe doc-build`
|
||||
|
||||
## Project-wide invariants
|
||||
|
||||
- Package name (PyPI): `serena-agent`; import root: `serena`. Wheel includes `serena`, `interprompt`, `solidlsp`.
|
||||
- Package name (PyPI): `serena-agent`; Wheel includes `serena`, `interprompt`, `solidlsp`.
|
||||
- Python: `>=3.11, <3.15`. Dependencies are exact-pinned in `pyproject.toml` (uvx installs from git, lockfile ignored — pin exactly).
|
||||
- Entry points: `serena` → `serena.cli:top_level`; `serena-hooks` → `serena.hooks:hook_commands`.
|
||||
- Per-project state lives under `<project>/.serena/` (config + `memories/` as `.md` files).
|
||||
- See `mem:tech_stack`, `mem:suggested_commands`, `mem:conventions`, `mem:task_completion`.
|
||||
@@ -1,113 +0,0 @@
|
||||
# Serena Repository Structure
|
||||
|
||||
## Overview
|
||||
Serena is a multi-language code assistant that combines two main components:
|
||||
1. **Serena Core** - The main agent framework with tools and MCP server
|
||||
2. **SolidLSP** - A unified Language Server Protocol wrapper for multiple programming languages
|
||||
|
||||
## Top-Level Structure
|
||||
|
||||
```
|
||||
serena/
|
||||
├── src/ # Main source code
|
||||
│ ├── serena/ # Serena agent framework
|
||||
│ ├── solidlsp/ # LSP wrapper library
|
||||
│ └── interprompt/ # Multi-language prompt templates
|
||||
├── test/ # Test suites
|
||||
│ ├── serena/ # Serena agent tests
|
||||
│ ├── solidlsp/ # Language server tests
|
||||
│ └── resources/repos/ # Test repositories for each language
|
||||
├── scripts/ # Build and utility scripts
|
||||
├── resources/ # Static resources and configurations
|
||||
├── pyproject.toml # Python project configuration
|
||||
├── README.md # Project documentation
|
||||
└── CHANGELOG.md # Version history
|
||||
```
|
||||
|
||||
## Source Code Organization
|
||||
|
||||
### Serena Core (`src/serena/`)
|
||||
- **`agent.py`** - Main SerenaAgent class that orchestrates everything
|
||||
- **`tools/`** - MCP tools for file operations, symbols, memory, etc.
|
||||
- `file_tools.py` - File system operations (read, write, search)
|
||||
- `symbol_tools.py` - Symbol-based code operations (find, edit)
|
||||
- `memory_tools.py` - Knowledge persistence and retrieval
|
||||
- `config_tools.py` - Project and mode management
|
||||
- `workflow_tools.py` - Onboarding and meta-operations
|
||||
- **`config/`** - Configuration management
|
||||
- `serena_config.py` - Main configuration classes
|
||||
- `context_mode.py` - Context and mode definitions
|
||||
- **`util/`** - Utility modules
|
||||
- **`mcp.py`** - MCP server implementation
|
||||
- **`cli.py`** - Command-line interface
|
||||
|
||||
### SolidLSP (`src/solidlsp/`)
|
||||
- **`ls.py`** - Main SolidLanguageServer class
|
||||
- **`language_servers/`** - Language-specific implementations
|
||||
- `csharp_language_server.py` - C# (Microsoft.CodeAnalysis.LanguageServer)
|
||||
- `python_server.py` - Python (Pyright)
|
||||
- `typescript_language_server.py` - TypeScript
|
||||
- `rust_analyzer.py` - Rust
|
||||
- `gopls.py` - Go
|
||||
- And many more...
|
||||
- **`ls_config.py`** - Language server configuration
|
||||
- **`ls_types.py`** - LSP type definitions
|
||||
- **`ls_utils.py`** - Utilities for working with LSP data
|
||||
|
||||
### Interprompt (`src/interprompt/`)
|
||||
- Multi-language prompt template system
|
||||
- Jinja2-based templating with language fallbacks
|
||||
|
||||
## Test Structure
|
||||
|
||||
### Language Server Tests (`test/solidlsp/`)
|
||||
Each language has its own test directory:
|
||||
```
|
||||
test/solidlsp/
|
||||
├── csharp/
|
||||
│ └── test_csharp_basic.py
|
||||
├── python/
|
||||
│ └── test_python_basic.py
|
||||
├── typescript/
|
||||
│ └── test_typescript_basic.py
|
||||
└── ...
|
||||
```
|
||||
|
||||
### Test Resources (`test/resources/repos/`)
|
||||
Contains minimal test projects for each language:
|
||||
```
|
||||
test/resources/repos/
|
||||
├── csharp/test_repo/
|
||||
│ ├── serena.sln
|
||||
│ ├── TestProject.csproj
|
||||
│ ├── Program.cs
|
||||
│ └── Models/Person.cs
|
||||
├── python/test_repo/
|
||||
├── typescript/test_repo/
|
||||
└── ...
|
||||
```
|
||||
|
||||
### Test Infrastructure
|
||||
- **`test/conftest.py`** - Shared test fixtures and utilities
|
||||
- **`create_ls()`** function - Creates language server instances for testing
|
||||
- **`language_server` fixture** - Parametrized fixture for multi-language tests
|
||||
|
||||
## Key Configuration Files
|
||||
|
||||
- **`pyproject.toml`** - Python dependencies, build config, and tool settings
|
||||
- **`.serena/`** directories - Project-specific Serena configuration and memories
|
||||
- **`CLAUDE.md`** - Instructions for AI assistants working on the project
|
||||
|
||||
## Dependencies Management
|
||||
|
||||
The project uses modern Python tooling:
|
||||
- **uv** for fast dependency resolution and virtual environments
|
||||
- **pytest** for testing with language-specific markers (`@pytest.mark.csharp`)
|
||||
- **ruff** for linting and formatting
|
||||
- **ty** (Astral) for type checking
|
||||
|
||||
## Build and Development
|
||||
|
||||
- **Docker support** - Full containerized development environment
|
||||
- **GitHub Actions** - CI/CD with language server testing
|
||||
- **Development scripts** in `scripts/` directory
|
||||
@@ -1,24 +0,0 @@
|
||||
# Suggested Commands
|
||||
|
||||
Run via `uv run poe <task>` (or `poe <task>` inside the activated venv). Poe executor is `simple`, so plain `poe` works without uv re-resolving.
|
||||
|
||||
## Dev loop
|
||||
- `poe test` — pytest on `test/` (per-language tests are marker-gated; pass `-m <marker>` to enable).
|
||||
- `poe lint` — ruff format-check + ruff check (no fixes).
|
||||
- `poe format` — ruff `--fix` then `ruff format` (mutates files).
|
||||
- `poe type-check` — ty on `src/serena`, `src/solidlsp`, and `test/` (test pass relaxes pytest/mock-noisy rules via `[[tool.ty.overrides]]`).
|
||||
- Single test file: `uv run pytest test/path/to/test_x.py -vv`. Language-gated: add `-m python` etc.
|
||||
|
||||
## Docs
|
||||
- `poe doc-build` — clean + autogen + sphinx (uses `rm -rf`; needs a unix-like shell, e.g. Git Bash on Windows).
|
||||
|
||||
## Entrypoints
|
||||
- `uv run serena ...` — main CLI (`serena.cli:top_level`).
|
||||
- `uv run serena-hooks ...` — hook helpers.
|
||||
- `python scripts/gen_prompt_factory.py` — regenerate `src/serena/generated/generated_prompt_factory.py` after editing prompt templates.
|
||||
|
||||
## Windows shell notes (PowerShell 7+ is the project shell)
|
||||
- Use `Remove-Item -Recurse -Force <path>` instead of `rm -rf` (the `doc-clean` poe task uses unix `rm -rf` and requires bash).
|
||||
- Env vars: `$env:NAME = 'value'` (not `export`).
|
||||
- Path separator in `pyproject.toml` poe tasks uses forward slashes; PowerShell accepts them in arguments.
|
||||
- `git`, `uv`, `poe`, `pytest` behave identically to unix.
|
||||
@@ -8,4 +8,4 @@ After any code change in `src/` or `test/`, run:
|
||||
|
||||
If prompt templates changed: `uv run python scripts/gen_prompt_factory.py` (regenerates `src/serena/generated/generated_prompt_factory.py`; use `uv run poe format` and commit the result).
|
||||
|
||||
If memories were edited/renamed/split: run `uv run serena memories check` from the project root to find broken `mem:` references.
|
||||
If memories were edited/renamed/split: run `uv run --no-sync serena memories check` from the project root to find broken `mem:` references.
|
||||
@@ -1,10 +0,0 @@
|
||||
# Tech Stack
|
||||
|
||||
- Language: Python 3.11–3.14 (`requires-python = ">=3.11, <3.15"`).
|
||||
- Package/dep manager: **uv** (uv.lock present). Exact version pins in `pyproject.toml` because `uvx` installs from git and ignores the lockfile.
|
||||
- Build backend: `hatchling`. Packages: `src/serena`, `src/interprompt`, `src/solidlsp`.
|
||||
- Task runner: **poethepoet** (`poe <task>`). Poe executor is `simple` (does NOT shell out via uv) — avoids env recreation while MCP server is running.
|
||||
- Key runtime deps: `mcp`, `flask` (dashboard), `pydantic`, `pygls` + `lsprotocol` (LSP), `anthropic`, `jinja2`, `ruamel.yaml`, `pywebview`/`pystray` (GUI), `pythonnet` (Windows only).
|
||||
- Dev deps: `ruff` (lint+format), `ty` (Astral type checker; replaced mypy), `pytest` (+ `pytest-xdist`, `pytest-timeout`, `syrupy` snapshots), `sphinx`/`jupyter-book` for docs.
|
||||
- Optional extras: `agno` (Agno agent integration), `google` (gemini).
|
||||
- LSP client core lives under `src/solidlsp/`; one subdir per supported language server under `language_servers/`.
|
||||
+4
-34
@@ -68,41 +68,11 @@ excluded_tools: []
|
||||
# Find the list of tools here: https://oraios.github.io/serena/01-about/035_tools.html
|
||||
included_optional_tools: []
|
||||
|
||||
# initial prompt for the project. It will always be given to the LLM upon activating the project
|
||||
# (contrary to the memories, which are loaded on demand).
|
||||
# initial prompt for the project, which will be provided to the LLM upon project activation
|
||||
# (or within Serena's initial instructions if the project is activated at startup).
|
||||
## See: https://oraios.github.io/serena/02-usage/050_configuration.html#prompt-templates
|
||||
initial_prompt: |
|
||||
IMPORTANT: You use an idiomatic, object-oriented style (Java-esque principles, Pythonic syntax and constructs).
|
||||
|
||||
Design:
|
||||
* You keep each concern in exactly one home.
|
||||
A mechanism whose parts are only correct in combination is implemented as a single component/class, and its parts are private to it;
|
||||
expose a minimal public surface. Java-like encapsulation: If helper functions and constants are only used by one abstraction,
|
||||
make them internal to the respective class.
|
||||
* You enforce invariants through structure and visibility; interfaces should not permit states the design forbids.
|
||||
* For any non-trivial interfaces, you use interfaces that expect explicitly typed abstractions
|
||||
rather than mere functions (i.e. use the strategy pattern, for example).
|
||||
You avoid the use of low-level data structures in all cases where an object-oriented abstraction would be more appropriate.
|
||||
For simple data storage, you use dataclasses instead of dictionaries or tuples.
|
||||
|
||||
Testing:
|
||||
The key principle is to test *only* externally observable behavior and guarantees, never implementation structure.
|
||||
* Litmus test: a behaviour-preserving refactoring must not break any test. A test that could break is wrong and must not be written.
|
||||
* When functionality is removed, you delete its tests. You never add tests asserting the *absence* of something;
|
||||
absence of an implementation detail is not a behaviour, and such tests only freeze the current implementation and burden maintenance.
|
||||
* Fewer, behaviour-anchored tests are preferred; a missing test is better than an implementation-coupled one.
|
||||
|
||||
Docstrings & Comments:
|
||||
* You consistently use reStructuredText.
|
||||
* You structure function implementations into functional blocks that are separated by blank lines.
|
||||
Atop each functional block, you write an elliptical phrase (starting with lower-case letter) that describes the purpose of the
|
||||
block in a concise manner.
|
||||
* When describing parameters, methods/functions and classes, you use a precise style, where the initial (elliptical) phrase
|
||||
clearly defines *what* it is. Any details then follow in subsequent sentences.
|
||||
* Each piece of information appears exactly once, at the element that owns it: callers do not
|
||||
explain callees' internals, and callees do not describe their callers.
|
||||
|
||||
Pull requests:
|
||||
Read `mem:creating_pull_requests` when asked to participate in the creation of a pull request.
|
||||
{{ embed_memory("critical_info") }}
|
||||
|
||||
# the encoding used by text files in the project
|
||||
# For a list of possible encodings, see https://docs.python.org/3.11/library/codecs.html#standard-encodings
|
||||
|
||||
+3
-1
@@ -16,7 +16,9 @@ Status of the `main` branch. Changes prior to the next official version change w
|
||||
- ProjectServer: Configure trusted hosts (local hosts only) when listening on localhost
|
||||
- SerenaDashboardTrayManager: Configure trusted hosts (local hosts only)
|
||||
- Enclose sub-prompts in XML-like tags to make scopes explicit
|
||||
- Allow initial project prompts and project-specific newly activated modes to use templating
|
||||
- Prompts and prompt templates:
|
||||
- Allow initial project prompts and project-specific newly activated modes to use templating
|
||||
- Support function `embed_memory` in prompt templates to inline a memory's contents
|
||||
|
||||
* CLI:
|
||||
- Fix: `start-mcp-server` help text for `--project-from-cwd` falsely promised a fallback to the CWD, which was
|
||||
|
||||
@@ -155,6 +155,43 @@ You can manage modes using the `mode` command,
|
||||
serena mode edit <mode-name>
|
||||
serena mode delete <mode-name>
|
||||
|
||||
(prompt-templates)=
|
||||
## Prompt Templates
|
||||
|
||||
All prompts that Serena provides to the LLM are [Jinja2](https://jinja.palletsprojects.com/) templates.
|
||||
Templating applies to
|
||||
|
||||
* **Serena's system prompt** (the "Serena Instructions Manual"), which is defined in the prompt template `system_prompt`
|
||||
(see [Custom Prompts](custom-prompts) for how to override it),
|
||||
* **context and mode prompts**, i.e. the `prompt` field in context and mode definition files, and
|
||||
* **the project prompt**, i.e. `initial_prompt` in `project.yml`, which is provided to the LLM upon project activation.
|
||||
|
||||
Templating allows prompts to adapt to the active configuration; for instance, a mode prompt can mention a tool
|
||||
only if that tool is actually available in the current session.
|
||||
|
||||
### Variables and Functions
|
||||
|
||||
The following variables can be used in all of the above templates:
|
||||
|
||||
| Variable | Description |
|
||||
|---------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| `available_tools` | the list of names of the tools that are currently exposed to the LLM. Use it to include content conditionally, e.g. `{% if 'replace_content' in available_tools %}…{% endif %}`. |
|
||||
| `available_markers` | the list of names of the tool markers (tool categories, e.g. `ToolMarkerSymbolicRead`) for which at least one tool is exposed; useful for conditioning on entire groups of tools. |
|
||||
| `tool_names` | a mapping from canonical tool names to effective tool names, which accounts for legacy tool renames as well as for tools being functionally replaced due to the active language backend (e.g. `find_symbol` being replaced by `jet_brains_find_symbol` when the JetBrains backend is active). Prefer `{{ tool_names['find_symbol'] }}` over hard-coded names. |
|
||||
|
||||
Context, mode and project prompts (but not Serena's system prompt) additionally support the following function:
|
||||
|
||||
| Function | Description |
|
||||
|----------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| `embed_memory(name)` | embeds the content of the memory with the given name, wrapped in a tag `<memory name="...">`. Use this to inline knowledge that shall always be provided to the LLM rather than being loaded on demand. If the memory cannot be loaded, an error is logged and nothing is rendered. |
|
||||
|
||||
For example, a project can inline its coding conventions from a memory into the project prompt:
|
||||
|
||||
```yaml
|
||||
initial_prompt: |
|
||||
{{ embed_memory("coding_conventions") }}
|
||||
```
|
||||
|
||||
## Advanced Configuration
|
||||
|
||||
For advanced users, Serena's configuration can be further customized.
|
||||
@@ -1247,6 +1284,7 @@ Supported settings:
|
||||
| `yaml_language_server_version` | `1.19.2` | Override the npm package version Serena installs when `ls_path` is not set. |
|
||||
| `npm_registry` | `null` | Override the npm registry Serena uses for the managed install. |
|
||||
|
||||
(custom-prompts)=
|
||||
### Custom Prompts
|
||||
|
||||
All of Serena's prompts can be fully customized.
|
||||
|
||||
+41
-9
@@ -956,17 +956,36 @@ class SerenaAgent:
|
||||
result[tool_class.get_name_from_cls()] = new_tool_class.get_name_from_cls()
|
||||
return result
|
||||
|
||||
def _format_prompt_tag(self, text: str, tag: str, tag_name_attr: str | None = None) -> str:
|
||||
@staticmethod
|
||||
def _format_prompt_tag(text: str, tag: str, tag_name_attr: str | None = None) -> str:
|
||||
open_tag = f"<{tag}" + (f' name="{tag_name_attr}"' if tag_name_attr is not None else "") + ">"
|
||||
close_tag = f"</{tag}>"
|
||||
return f"{open_tag}\n{text.strip()}\n{close_tag}"
|
||||
|
||||
def _format_prompt(self, prompt_template: str, tag: str | None = None, tag_name_attr: str | None = None) -> str:
|
||||
def _render_prompt(self, prompt_template: str, tag: str | None = None, tag_name_attr: str | None = None) -> str:
|
||||
"""
|
||||
Renders the given prompt template, providing the necessary variables and functions
|
||||
|
||||
:param prompt_template: the template text (jinja2) to render
|
||||
:param tag: if not None, wraps the rendered prompt text in a tag
|
||||
:param tag_name_attr: for the case where tag is not None, specifies the value of the "name" attribute of the tag
|
||||
:return: the rendered prompt
|
||||
"""
|
||||
|
||||
def embed_memory(memory_name: str) -> str:
|
||||
try:
|
||||
memory_manager = self._get_memory_manager()
|
||||
return self._format_prompt_tag(memory_manager.load_memory(memory_name), tag="memory", tag_name_attr=memory_name)
|
||||
except Exception as e:
|
||||
log.error("Tried to embed memory '%s' but failed to load it: %s", memory_name, e)
|
||||
return ""
|
||||
|
||||
template = JinjaTemplate(prompt_template)
|
||||
text = template.render(
|
||||
available_tools=self._exposed_tools.tool_names,
|
||||
available_markers=self._exposed_tools.tool_marker_names,
|
||||
tool_names=self._prompt_tool_names_mapping,
|
||||
embed_memory=embed_memory,
|
||||
)
|
||||
|
||||
if tag is not None:
|
||||
@@ -982,6 +1001,21 @@ class SerenaAgent:
|
||||
"""
|
||||
return self.prompt_factory.create_connection_prompt()
|
||||
|
||||
def _create_global_memory_manager(self) -> MemoryManager:
|
||||
"""
|
||||
:return: a memory manager for global memories only (no project memories)
|
||||
"""
|
||||
return MemoryManager(serena_data_folder=None, read_only_memory_patterns=self.serena_config.read_only_memory_patterns)
|
||||
|
||||
def _get_memory_manager(self) -> MemoryManager:
|
||||
"""
|
||||
:return: the memory manager for the active project (if any) or a global memory manager if no project is active
|
||||
"""
|
||||
if self._active_project is not None:
|
||||
return self._active_project.memory_manager
|
||||
else:
|
||||
return self._create_global_memory_manager()
|
||||
|
||||
def create_system_prompt(self, session_id: str = "global") -> str:
|
||||
"""
|
||||
Returns the 'Serena Instructions Manual', i.e. Serena's system prompt.
|
||||
@@ -991,9 +1025,7 @@ class SerenaAgent:
|
||||
"""
|
||||
available_tools = self._active_tools
|
||||
available_markers = available_tools.tool_marker_names
|
||||
global_memories = MemoryManager(
|
||||
serena_data_folder=None, read_only_memory_patterns=self.serena_config.read_only_memory_patterns
|
||||
).list_global_memories()
|
||||
global_memories = self._create_global_memory_manager().list_global_memories()
|
||||
global_memories_str = dict_string(global_memories.to_dict()) if len(global_memories) > 0 else ""
|
||||
log.info("Generating system prompt with available_tools=(see active tools), available_markers=%s", available_markers)
|
||||
|
||||
@@ -1007,8 +1039,8 @@ class SerenaAgent:
|
||||
self._project_prompt_status.mark_mode_prompts_as_provided(session_id)
|
||||
|
||||
system_prompt = self.prompt_factory.create_system_prompt(
|
||||
context_system_prompt=self._format_prompt(self._context.prompt, tag="context"),
|
||||
mode_system_prompts=[self._format_prompt(mode.prompt, tag="mode", tag_name_attr=mode.name) for mode in relevant_modes],
|
||||
context_system_prompt=self._render_prompt(self._context.prompt, tag="context"),
|
||||
mode_system_prompts=[self._render_prompt(mode.prompt, tag="mode", tag_name_attr=mode.name) for mode in relevant_modes],
|
||||
available_tools=available_tools.tool_names,
|
||||
available_markers=available_markers,
|
||||
global_memories_list=global_memories_str,
|
||||
@@ -1065,12 +1097,12 @@ class SerenaAgent:
|
||||
modes_with_prompts = self._project_prompt_status.get_modes_with_prompts_to_be_provided_for_project_activation(session_id)
|
||||
if modes_with_prompts:
|
||||
for mode in modes_with_prompts:
|
||||
msg += self._format_prompt(mode.prompt, tag="mode", tag_name_attr=mode.name) + "\n"
|
||||
msg += self._render_prompt(mode.prompt, tag="mode", tag_name_attr=mode.name) + "\n"
|
||||
self._project_prompt_status.mark_mode_prompts_as_provided(session_id)
|
||||
|
||||
# add project-specific prompt
|
||||
if proj.project_config.initial_prompt:
|
||||
msg += "\n" + self._format_prompt(proj.project_config.initial_prompt, tag="project-instructions")
|
||||
msg += "\n" + self._render_prompt(proj.project_config.initial_prompt, tag="project-instructions")
|
||||
|
||||
self._project_prompt_status.mark_project_activation_message_as_provided(session_id)
|
||||
|
||||
|
||||
@@ -1,11 +1,28 @@
|
||||
# See Serena's documentation for more details on concept of contexts.
|
||||
description: Description of the context, not used in the code.
|
||||
prompt: Prompt that will form part of the system prompt/initial instructions for agents started in this context.
|
||||
# See Serena's documentation for more details on concept of contexts:
|
||||
# https://oraios.github.io/serena/02-usage/050_configuration.html#contexts
|
||||
description: Description of the context (meta-information only)
|
||||
|
||||
# define a prompt which will be included in the system prompt when agents are started in this context.
|
||||
# See: https://oraios.github.io/serena/02-usage/050_configuration.html#prompt-templates
|
||||
prompt: |
|
||||
This prompt will form part of the system prompt/initial instructions for agents started in this context.
|
||||
Add as much content as needed.
|
||||
Leave it undefined if no prompt is needed, i.e.
|
||||
prompt: null
|
||||
|
||||
# tools to be excluded in this context.
|
||||
# Find the list of tools here: https://oraios.github.io/serena/01-about/035_tools.html
|
||||
excluded_tools: []
|
||||
|
||||
# several tools are excluded by default and have to be explicitly included by the user
|
||||
# included tools that would otherwise be excluded (particularly optional tools that are disabled by default).
|
||||
# Find the list of tools here: https://oraios.github.io/serena/01-about/035_tools.html
|
||||
included_optional_tools: []
|
||||
|
||||
# fixed set of tools to use as the base tool set (if non-empty), replacing Serena's default set of tools.
|
||||
# This cannot be combined with non-empty excluded_tools or included_optional_tools.
|
||||
# Find the list of tools here: https://oraios.github.io/serena/01-about/035_tools.html
|
||||
fixed_tools: []
|
||||
|
||||
# mapping of tool names to an override of their descriptions (the default description is the docstring of the Tool's apply method).
|
||||
# Sometimes, tool descriptions are too long (e.g., for ChatGPT), or users may want to override them for another reason.
|
||||
tool_description_overrides: {}
|
||||
|
||||
@@ -1,8 +1,25 @@
|
||||
# See Serena's documentation for more details on concept of modes.
|
||||
# See Serena's documentation for more details on concept of modes:
|
||||
# https://oraios.github.io/serena/02-usage/050_configuration.html#modes
|
||||
description: Description of the mode (meta-information only)
|
||||
|
||||
# define a prompt which will be included in the system prompt when this mode is activated
|
||||
# (or will be provided in the project activation message if the mode is activated dynamically).
|
||||
# See: https://oraios.github.io/serena/02-usage/050_configuration.html#prompt-templates
|
||||
prompt: |
|
||||
Provide a prompt that will form part of the instructions sent to the model when this mode is activated.
|
||||
# tools that are to be excluded by this mode
|
||||
This prompt will form part of the system prompt/initial instructions for agents started in this context.
|
||||
Add as much content as needed.
|
||||
Leave it undefined if no prompt is needed, i.e.
|
||||
prompt: null
|
||||
|
||||
# tools to be excluded in this context.
|
||||
# Find the list of tools here: https://oraios.github.io/serena/01-about/035_tools.html
|
||||
excluded_tools: []
|
||||
# several tools are excluded by default and have to be explicitly included by the user
|
||||
included_optional_tools: []
|
||||
|
||||
# included tools that would otherwise be excluded (particularly optional tools that are disabled by default).
|
||||
# Find the list of tools here: https://oraios.github.io/serena/01-about/035_tools.html
|
||||
included_optional_tools: []
|
||||
|
||||
# fixed set of tools to use as the base tool set (if non-empty), replacing Serena's default set of tools.
|
||||
# This cannot be combined with non-empty excluded_tools or included_optional_tools.
|
||||
# Find the list of tools here: https://oraios.github.io/serena/01-about/035_tools.html
|
||||
fixed_tools: []
|
||||
Reference in new issue
Block a user