Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion cogsol/core/migrations.py
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ def diff_states(
)
else:
# Cognitive API entities (agents)
for entity in ["retrieval_tools", "tools", "lessons", "faqs", "fixed_responses", "agents"]:
for entity in ["retrieval_tools", "tools", "agents", "lessons", "faqs", "fixed_responses"]:
operations.extend(
_diff_bucket(
entity,
Expand Down
5 changes: 4 additions & 1 deletion cogsol/management/commands/makemigrations.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@
from pathlib import Path
from typing import Any

from cogsol import __version__
try:
from cogsol import __version__
except ImportError:
__version__ = "unknown"
from cogsol.core import migrations as migutils
from cogsol.core.loader import collect_content_definitions, collect_definitions
from cogsol.management.base import BaseCommand
Expand Down
35 changes: 18 additions & 17 deletions cogsol/management/commands/startproject.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,23 +33,24 @@ def main():

TOOLS_PY = """\
from cogsol.tools import BaseTool, tool_params
#
# class ExampleTool(BaseTool):
# description = "Demo tool that echoes the provided text."
#
# @tool_params(
# text={"description": "Text to echo", "type": "string", "required": True},
# count={"description": "Times to repeat", "type": "integer", "required": False},
# )
# def run(self, chat=None, data=None, secrets=None, log=None, text: str = "", count: int = 1):
# \"\"\"
# text: Text to echo back.
# count: Times to repeat the text.
# \"\"\"
# message = " ".join([text] * max(1, int(count)))
# # chat/data/secrets/log are available per platform docs
# response = message
# return response


class ExampleTool(BaseTool):
description = "Demo tool that echoes the provided text."

@tool_params(
text={"description": "Text to echo", "type": "string", "required": True},
count={"description": "Times to repeat", "type": "integer", "required": False},
)
def run(self, chat=None, data=None, secrets=None, log=None, text: str = "", count: int = 1):
\"\"\"
text: Text to echo back.
count: Times to repeat the text.
\"\"\"
message = " ".join([text] * max(1, int(count)))
# chat/data/secrets/log are available per platform docs
response = message
return response
"""

SEARCHES_PY = """\
Expand Down
108 changes: 107 additions & 1 deletion tests/test_agents.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,13 @@
from cogsol.agents import BaseAgent, genconfigs, optimizations
from cogsol.core.loader import collect_definitions
from cogsol.core.migrations import diff_states, empty_state
from cogsol.db.migrations import AlterField, CreateRetrievalTool
from cogsol.db.migrations import (
AlterField,
CreateAgent,
CreateLesson,
CreateRetrievalTool,
CreateTool,
)


class TestBaseAgent:
Expand Down Expand Up @@ -141,6 +147,106 @@ def test_faq_change_creates_faq_alter(self):
assert agent_faq_ops == []


class TestOperationOrdering:
"""Tests for correct dependency ordering of migration operations."""

def test_agent_created_before_lessons(self):
"""CreateAgent should appear before CreateLesson in migration operations."""
with tempfile.TemporaryDirectory() as tmpdir:
project_path = Path(tmpdir)
agents_path = project_path / "agents"
agent_pkg = agents_path / "assistant"
agent_pkg.mkdir(parents=True)

(agents_path / "__init__.py").write_text("", encoding="utf-8")
(agents_path / "tools.py").write_text("", encoding="utf-8")
(agent_pkg / "__init__.py").write_text("", encoding="utf-8")
(agent_pkg / "agent.py").write_text(
"""
from cogsol.agents import BaseAgent


class GreetingLesson:
name = "Greeting"
content = "Always greet the user."


class AssistantAgent(BaseAgent):
system_prompt = "You are a helpful assistant."
lessons = [GreetingLesson()]

class Meta:
name = "AssistantAgent"
chat_name = "Assistant"
""",
encoding="utf-8",
)

defs = collect_definitions(project_path, "agents")
ops = diff_states(empty_state(), defs, app="agents")

create_agent_indices = [i for i, op in enumerate(ops) if isinstance(op, CreateAgent)]
create_lesson_indices = [i for i, op in enumerate(ops) if isinstance(op, CreateLesson)]

assert create_agent_indices, "Expected at least one CreateAgent operation"
assert create_lesson_indices, "Expected at least one CreateLesson operation"
assert max(create_agent_indices) < min(
create_lesson_indices
), "CreateAgent operations must come before CreateLesson operations"

def test_tools_created_before_agents(self):
"""CreateTool should appear before CreateAgent in migration operations."""
with tempfile.TemporaryDirectory() as tmpdir:
project_path = Path(tmpdir)
agents_path = project_path / "agents"
agent_pkg = agents_path / "assistant"
agent_pkg.mkdir(parents=True)

(agents_path / "__init__.py").write_text("", encoding="utf-8")
(agents_path / "tools.py").write_text(
"""
from cogsol.tools import BaseTool


class MyTool(BaseTool):
name = "my_tool"
description = "A test tool."
parameters = []

def run(self, **kwargs):
return "ok"
""",
encoding="utf-8",
)
(agent_pkg / "__init__.py").write_text("", encoding="utf-8")
(agent_pkg / "agent.py").write_text(
"""
from cogsol.agents import BaseAgent


class AssistantAgent(BaseAgent):
system_prompt = "You are a helpful assistant."

class Meta:
name = "AssistantAgent"
chat_name = "Assistant"
""",
encoding="utf-8",
)

defs = collect_definitions(project_path, "agents")
ops = diff_states(empty_state(), defs, app="agents")

create_tool_indices = [i for i, op in enumerate(ops) if isinstance(op, CreateTool)]
create_agent_indices = [i for i, op in enumerate(ops) if isinstance(op, CreateAgent)]

assert create_tool_indices, "Expected at least one CreateTool operation"
assert create_agent_indices, "Expected at least one CreateAgent operation"
assert max(create_tool_indices) < min(
create_agent_indices
), "CreateTool operations must come before CreateAgent operations"


class TestRetrievalTools:
"""Tests for retrieval tool definitions."""

Expand Down