feat: agent visibility and template improvements#934
Conversation
There was a problem hiding this comment.
Pull request overview
This PR introduces an agent visibility system allowing agents to be marked as private, team-visible, or public, along with enhancements to template-based agent creation and improvements to prompt structure.
- Added AgentVisibility enum with three levels (PRIVATE, TEAM, PUBLIC) and corresponding database fields
- Enhanced AgentCreationFromTemplate to support additional fields including readonly_wallet_address, weekly_spending_limit, and extra_prompt
- Improved prompt structure by adding section headings for extra_prompt ("Task Details") and prompt_append ("Additional Instructions")
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| intentkit/models/agent.py | Introduces AgentVisibility enum, adds visibility and archived_at columns to AgentTable, moves extra_prompt field from AgentCreate to AgentUpdate for better flexibility |
| intentkit/core/template.py | Adds visibility assignment logic based on team_id, extends AgentCreationFromTemplate with new optional fields for wallet and spending limit configuration |
| intentkit/core/prompt.py | Enhances prompt building with section headers for extra_prompt and prompt_append, improves formatting with consistent trailing whitespace |
| tests/core/test_template.py | Adds test coverage for visibility behavior in both team and non-team agent creation scenarios, imports AgentVisibility enum |
| docker-compose.yml | Changes PostgreSQL volume mount from named volume to host directory (unrelated to main PR purpose) |
| CHANGELOG.md | Adds version 0.8.40 release notes with autonomous error tracking and memory management features |
Comments suppressed due to low confidence (1)
intentkit/models/agent.py:823
- This import of module re is redundant, as it was previously imported on line 6.
import re
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| POSTGRES_DB: ${POSTGRES_DB:-intentkit} | ||
| volumes: | ||
| - postgres_data:/var/lib/postgresql/data | ||
| - ./pg_data:/var/lib/postgresql |
There was a problem hiding this comment.
The volume mount path has been changed from a named volume to a host directory mount. The original path was "postgres_data:/var/lib/postgresql/data" (standard PostgreSQL data directory), but it's now "./pg_data:/var/lib/postgresql" which is the parent directory. This change may cause PostgreSQL to fail to start or lose data because:
- The mount point should be "/var/lib/postgresql/data" not "/var/lib/postgresql"
- The named volume "postgres_data" is no longer defined in the volumes section
This appears to be an unintended change that's unrelated to the PR's stated purpose of adding agent visibility features.
| - ./pg_data:/var/lib/postgresql | |
| - postgres_data:/var/lib/postgresql/data |
| ), | ||
| ] | ||
|
|
||
| @field_validator("purpose", "personality", "principles", "prompt", "prompt_append") |
There was a problem hiding this comment.
The extra_prompt field should be included in the field_validator that checks for level 1 and level 2 headings. Since extra_prompt is injected into the system prompt with a "## Task Details" heading (as seen in prompt.py line 234), allowing users to use # or ## headings in extra_prompt could break the prompt structure hierarchy. Add "extra_prompt" to the validator on line 816.
| @field_validator("purpose", "personality", "principles", "prompt", "prompt_append") | |
| @field_validator("purpose", "personality", "principles", "prompt", "prompt_append", "extra_prompt") |
| @pytest.mark.asyncio | ||
| async def test_create_agent_from_template_without_team(): | ||
| """Test creating an agent from a template without team_id (PRIVATE visibility).""" | ||
|
|
||
| # 1. Setup Data | ||
| template_id = "template-2" | ||
| template_data = { | ||
| "id": template_id, | ||
| "name": "Template Agent", | ||
| "description": "A template agent", | ||
| "model": "gpt-4o", | ||
| "temperature": 0.5, | ||
| "prompt": "You are a template.", | ||
| } | ||
|
|
||
| # Mock TemplateTable instance | ||
| mock_template = TemplateTable(**template_data) | ||
|
|
||
| # Input data for creation | ||
| creation_data = AgentCreationFromTemplate( | ||
| template_id=template_id, | ||
| name="Private Agent", | ||
| picture="private_pic.png", | ||
| description="Created without team", | ||
| ) | ||
|
|
||
| # 2. Mock Database | ||
| with patch("intentkit.core.template.get_session") as mock_get_session: | ||
| # Setup mock session | ||
| mock_session = MagicMock() | ||
| mock_get_session.return_value.__aenter__.return_value = mock_session | ||
|
|
||
| # Mock scalar return value | ||
| mock_session.scalar = AsyncMock(return_value=mock_template) | ||
| mock_session.commit = AsyncMock() | ||
|
|
||
| # Set timestamps on refresh | ||
| async def mock_refresh(instance): | ||
| instance.created_at = datetime.now() | ||
| instance.updated_at = datetime.now() | ||
|
|
||
| mock_session.refresh = AsyncMock(side_effect=mock_refresh) | ||
|
|
||
| # 3. Call Function without team_id | ||
| await create_agent_from_template( | ||
| data=creation_data, owner="user_2", team_id=None | ||
| ) | ||
|
|
||
| # 4. Verify | ||
| assert mock_session.add.called | ||
| args, _ = mock_session.add.call_args | ||
| added_agent = args[0] | ||
|
|
||
| assert isinstance(added_agent, AgentTable) | ||
| assert added_agent.owner == "user_2" | ||
| assert added_agent.team_id is None | ||
|
|
||
| # Verify visibility is set to PRIVATE when team_id is None | ||
| assert added_agent.visibility == AgentVisibility.PRIVATE |
There was a problem hiding this comment.
The new test doesn't verify that the newly added fields (readonly_wallet_address, weekly_spending_limit, extra_prompt) from AgentCreationFromTemplate are correctly passed through to the created agent. While the test verifies visibility, it should also test these new optional fields to ensure complete coverage of the new functionality.
| readonly_wallet_address: str | None = None | ||
| weekly_spending_limit: float | None = None | ||
| extra_prompt: str | None = None |
There was a problem hiding this comment.
The AgentCreationFromTemplate class is missing field descriptions. The newly added fields (readonly_wallet_address, weekly_spending_limit, extra_prompt) should have Pydantic Field descriptions to document their purpose and usage, consistent with other API models in the codebase.
This PR introduces agent visibility features and improvements to template agent creation.
Changes
Key Features