Add Stellar Styles system prompt and wire into agent#3
Conversation
Reviewer's GuideWires a new, file-based Stellar Styles system prompt into the voice agent, updates the default greeting to match the new persona, and adds a unit test to verify the prompt is loaded and applied to the Assistant. Sequence diagram for agent session using Stellar prompt and default openingsequenceDiagram
actor Caller
participant AgentSession as agent_session
participant Assistant
participant Session
Caller->>AgentSession: start_call()
AgentSession->>Assistant: create Assistant()
Assistant->>Assistant: use STELLAR_SYSTEM_PROMPT as instructions
AgentSession->>Session: create Session(Assistant)
AgentSession->>Session: generate_reply(DEFAULT_OPENING)
Session-->>Caller: spoken Stellar greeting
Class diagram for Assistant using Stellar system promptclassDiagram
class Agent {
+__init__(instructions)
}
class Assistant {
+__init__()
}
class Prompts {
<<module>>
+STELLAR_SYSTEM_PROMPT: str
+DEFAULT_OPENING: str
}
Assistant --|> Agent
Assistant ..> Prompts: uses
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Hey - I've found 2 issues, and left some high level feedback:
- Reading the prompt file at import time with
PROMPT_PATH.read_text(...)will raise at module import if the file is missing or the path changes; consider adding error handling or usingimportlib.resourcesso the module can still import cleanly in misconfigured environments. - Using
DEFAULT_OPENINGas theinstructionsargument insession.generate_replymay override or conflict with the system persona for that turn; consider sending the opening as the content of the first assistant message (or as a separate parameter) while keepingSTELLAR_SYSTEM_PROMPTas the persistent system instructions.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- Reading the prompt file at import time with `PROMPT_PATH.read_text(...)` will raise at module import if the file is missing or the path changes; consider adding error handling or using `importlib.resources` so the module can still import cleanly in misconfigured environments.
- Using `DEFAULT_OPENING` as the `instructions` argument in `session.generate_reply` may override or conflict with the system persona for that turn; consider sending the opening as the content of the first assistant message (or as a separate parameter) while keeping `STELLAR_SYSTEM_PROMPT` as the persistent system instructions.
## Individual Comments
### Comment 1
<location> `tests/test_agent.py:18-23` </location>
<code_context>
return inference.LLM(model="openai/gpt-4.1-mini")
+def test_stellar_prompt_loaded() -> None:
+ assistant = Assistant()
+
+ assert "Stellar Styles and More" in STELLAR_SYSTEM_PROMPT
+ assert hasattr(assistant, "instructions")
+ assert "Stellar Styles and More" in assistant.instructions
+
+
</code_context>
<issue_to_address>
**suggestion (testing):** Strengthen the test by asserting the Assistant’s `instructions` exactly matches `STELLAR_SYSTEM_PROMPT`.
The current checks only verify that both `STELLAR_SYSTEM_PROMPT` and `assistant.instructions` contain the substring "Stellar Styles and More", so the test would still pass if a different or truncated prompt included that phrase. To better verify the wiring, assert direct equality instead:
```python
def test_stellar_prompt_loaded() -> None:
assistant = Assistant()
assert "Stellar Styles and More" in STELLAR_SYSTEM_PROMPT # still validates the brand anchor
assert hasattr(assistant, "instructions")
assert assistant.instructions == STELLAR_SYSTEM_PROMPT
```
This ensures the assistant uses the full prompt loaded from disk.
</issue_to_address>
### Comment 2
<location> `tests/test_agent.py:26-27` </location>
<code_context>
+ assert "Stellar Styles and More" in assistant.instructions
+
+
@pytest.mark.asyncio
async def test_offers_assistance() -> None:
"""Evaluation of the agent's friendly nature."""
</code_context>
<issue_to_address>
**suggestion (testing):** Add a test that explicitly verifies the `DEFAULT_OPENING` greeting is used when a session starts.
The current tests still only validate that the assistant is generally friendly/helpful and that `DEFAULT_OPENING` exists, but not that it’s actually used when a session starts.
Please add (or extend) a test that:
1. Starts an `agent_session` (or your intended public entry point) with a test `JobContext` and stubbed LLM, and
2. Asserts that the first call to `generate_reply` receives `DEFAULT_OPENING` (or that the assistant’s first reply contains the expected greeting text).
This will confirm the new runtime behavior described in the PR, not just the constant definition.
Suggested implementation:
```python
@pytest.mark.asyncio
async def test_offers_assistance(agent_session, job_context, stub_llm) -> None:
"""Evaluation of the agent's friendly nature and opening greeting behavior."""
# Start a new assistant session with a test JobContext and stubbed LLM
session = agent_session(job_context=job_context, llm=stub_llm)
# The first reply in a fresh session should use the DEFAULT_OPENING greeting
first_reply = await session.generate_reply()
# Depending on your agent API, `first_reply` may be a string or an object with `.content`
content = getattr(first_reply, "content", first_reply)
assert DEFAULT_OPENING in content
```
To fully integrate this change, you may need to:
1. Ensure `agent_session`, `job_context`, and `stub_llm` fixtures exist and are imported/defined consistently with the rest of your test suite. If your existing public entry point is named differently (e.g. `create_agent_session` or `AgentSession(...)`), update the call site and parameters accordingly.
2. Import `DEFAULT_OPENING` at the top of `tests/test_agent.py` if it is not already imported, e.g.:
`from your_agent_module import DEFAULT_OPENING`
3. If your agent's first reply is returned via a different method (e.g. `await session.next()` or `await session.step()`), or the reply object exposes text under a different attribute (e.g. `.text` instead of `.content`), adjust the `generate_reply()` call and the `content` extraction line to match the actual API.
4. If you prefer to keep `test_offers_assistance` focused only on friendliness, you can instead:
- Restore its original signature/body, and
- Add a separate test `test_session_uses_default_opening_greeting(...)` immediately below it with the same body as in the replacement block above.
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
| def test_stellar_prompt_loaded() -> None: | ||
| assistant = Assistant() | ||
|
|
||
| assert "Stellar Styles and More" in STELLAR_SYSTEM_PROMPT | ||
| assert hasattr(assistant, "instructions") | ||
| assert "Stellar Styles and More" in assistant.instructions |
There was a problem hiding this comment.
suggestion (testing): Strengthen the test by asserting the Assistant’s instructions exactly matches STELLAR_SYSTEM_PROMPT.
The current checks only verify that both STELLAR_SYSTEM_PROMPT and assistant.instructions contain the substring "Stellar Styles and More", so the test would still pass if a different or truncated prompt included that phrase. To better verify the wiring, assert direct equality instead:
def test_stellar_prompt_loaded() -> None:
assistant = Assistant()
assert "Stellar Styles and More" in STELLAR_SYSTEM_PROMPT # still validates the brand anchor
assert hasattr(assistant, "instructions")
assert assistant.instructions == STELLAR_SYSTEM_PROMPTThis ensures the assistant uses the full prompt loaded from disk.
| @pytest.mark.asyncio | ||
| async def test_offers_assistance() -> None: |
There was a problem hiding this comment.
suggestion (testing): Add a test that explicitly verifies the DEFAULT_OPENING greeting is used when a session starts.
The current tests still only validate that the assistant is generally friendly/helpful and that DEFAULT_OPENING exists, but not that it’s actually used when a session starts.
Please add (or extend) a test that:
- Starts an
agent_session(or your intended public entry point) with a testJobContextand stubbed LLM, and - Asserts that the first call to
generate_replyreceivesDEFAULT_OPENING(or that the assistant’s first reply contains the expected greeting text).
This will confirm the new runtime behavior described in the PR, not just the constant definition.
Suggested implementation:
@pytest.mark.asyncio
async def test_offers_assistance(agent_session, job_context, stub_llm) -> None:
"""Evaluation of the agent's friendly nature and opening greeting behavior."""
# Start a new assistant session with a test JobContext and stubbed LLM
session = agent_session(job_context=job_context, llm=stub_llm)
# The first reply in a fresh session should use the DEFAULT_OPENING greeting
first_reply = await session.generate_reply()
# Depending on your agent API, `first_reply` may be a string or an object with `.content`
content = getattr(first_reply, "content", first_reply)
assert DEFAULT_OPENING in contentTo fully integrate this change, you may need to:
- Ensure
agent_session,job_context, andstub_llmfixtures exist and are imported/defined consistently with the rest of your test suite. If your existing public entry point is named differently (e.g.create_agent_sessionorAgentSession(...)), update the call site and parameters accordingly. - Import
DEFAULT_OPENINGat the top oftests/test_agent.pyif it is not already imported, e.g.:
from your_agent_module import DEFAULT_OPENING - If your agent's first reply is returned via a different method (e.g.
await session.next()orawait session.step()), or the reply object exposes text under a different attribute (e.g..textinstead of.content), adjust thegenerate_reply()call and thecontentextraction line to match the actual API. - If you prefer to keep
test_offers_assistancefocused only on friendliness, you can instead:- Restore its original signature/body, and
- Add a separate test
test_session_uses_default_opening_greeting(...)immediately below it with the same body as in the replacement block above.
There was a problem hiding this comment.
Pull request overview
This PR adds a comprehensive "Stellar Styles and More" brand persona to the voice agent by introducing a system prompt file and wiring it into the agent's initialization. The changes replace the generic assistant instructions with a detailed, brand-specific prompt that defines the agent's voice, behavior, and guidelines.
Changes:
- Added a new system prompt file defining the Stellar Styles agent persona with voice guidelines, allowed/disallowed behaviors, and default responses
- Modified agent initialization to load and use the Stellar system prompt instead of generic instructions
- Added a DEFAULT_OPENING constant and applied it to the initial greeting generation
- Added a unit test to verify the prompt is loaded correctly
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| src/prompts/stellar_styles_system_prompt.txt | New system prompt file defining the Stellar Styles brand voice, behavior rules, and default opening/closing messages |
| src/agent.py | Loads the Stellar system prompt at startup and uses it in the Assistant class; adds DEFAULT_OPENING constant for initial greeting |
| tests/test_agent.py | Adds test to verify the Stellar prompt is loaded into both the module-level constant and the Assistant instance |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| PROMPT_PATH = ( | ||
| Path(__file__).resolve().parent / "prompts" / "stellar_styles_system_prompt.txt" | ||
| ) | ||
| STELLAR_SYSTEM_PROMPT = PROMPT_PATH.read_text(encoding="utf-8").strip() |
There was a problem hiding this comment.
The prompt file loading lacks error handling. If the prompt file is missing, moved, or has read permission issues, the application will crash at module import time with an unclear error. Consider adding a try-except block that provides a clear error message or falls back to a default prompt, similar to how other configuration loading is typically handled.
| await session.generate_reply( | ||
| instructions="Greet the caller and offer your assistance." | ||
| instructions=DEFAULT_OPENING | ||
| ) |
There was a problem hiding this comment.
The DEFAULT_OPENING is passed as the instructions parameter to session.generate_reply(). Based on the parameter name "instructions" and the previous usage pattern ("Greet the caller and offer your assistance."), this parameter appears to expect a directive/instruction to the agent, not the actual text to say. The current implementation passes the literal greeting text which may not produce the intended behavior. Consider using a directive like "Greet the user with the default opening" or verify the API behavior to ensure this produces the expected output.
| assert hasattr(assistant, "instructions") | ||
| assert "Stellar Styles and More" in assistant.instructions |
There was a problem hiding this comment.
The test uses hasattr(assistant, "instructions") to check for the attribute's existence, but this doesn't verify that the attribute is actually set by the parent class constructor. If the Agent parent class doesn't have an instructions attribute, this test will fail even though the prompt was loaded correctly. Consider accessing the attribute directly (which will raise AttributeError if missing) or verify the Agent API to ensure instructions is the correct attribute name.
Motivation
Description
src/prompts/stellar_styles_system_prompt.txtcontaining the full Stellar system/developer prompt (voice, allowed/not allowed rules, default opening/closing, etc.).src/agent.pyasSTELLAR_SYSTEM_PROMPTand pass it into the agent constructor so the agent uses the Stellar persona for instructions.DEFAULT_OPENINGinsrc/agent.pyand use it insession.generate_reply(...)to ensure the default greeting matches the spec.tests/test_agent.py::test_stellar_prompt_loadedthat asserts the Stellar prompt is present inSTELLAR_SYSTEM_PROMPTand on theAssistantinstance.Testing
uv run ruff formatanduv run ruff check, but both failed in this environment due to a lockfile platform mismatch error.uv run pytest, but it failed in this environment for the same lockfile platform mismatch error so the new test could not be executed here.test_stellar_prompt_loadedwas added totests/test_agent.pyand will pass in a compatible environment whereuvand the lockfile conditions are met.Codex Task
Summary by Sourcery
Integrate a new Stellar Styles and More system prompt into the voice agent and ensure it is used for greetings and instructions at runtime.
New Features:
Tests: