refactor(test): remove mock LLM providers from Robot Framework integration tests #704

Closed
freemo wants to merge 2 commits from refactor/m3-remove-mock-llm-integration into master
7 changed files with 108 additions and 99 deletions
+8
View File
@@ -580,6 +580,13 @@ def integration_tests(session: nox.Session):
pabot_args, robot_args = _split_pabot_args(session.posargs)
parallel_args = _pabot_parallel_args(pabot_args)
# Skip tests that require real LLM API keys when the keys are not
# available (e.g. CI environments without secrets configured).
llm_exclude_args: list[str] = []
if not os.environ.get("ANTHROPIC_API_KEY"):
session.log("ANTHROPIC_API_KEY not set excluding llm-required tests")
llm_exclude_args.extend(["--exclude", "llm-required"])
session.run(
"pabot",
*parallel_args,
@@ -604,6 +611,7 @@ def integration_tests(session: nox.Session):
"code_blocks",
"--exclude",
"wip",
*llm_exclude_args,
"--listener",
"robot/tdd_expected_fail_listener.py",
*robot_args,
+11 -4
View File
@@ -25,12 +25,13 @@ Context Analysis Agent Module Can Be Imported
Context Analysis Agent Can Be Instantiated With Default Parameters
[Documentation] Create ContextAnalysisAgent with defaults
[Tags] llm-required
${script}= Catenate SEPARATOR=\n
... import sys
... sys.path.insert(0, '${SRC_DIR}')
... from cleveragents.agents.context_analysis import ContextAnalysisAgent
... from langchain_community.llms import FakeListLLM
... agent = ContextAnalysisAgent(llm=FakeListLLM(responses=['test']*3))
... from langchain_anthropic import ChatAnthropic
... agent = ContextAnalysisAgent(llm=ChatAnthropic(model='claude-3-haiku-20240307'))
... assert agent is not None
... assert agent.chunk_size == 2000
... assert agent.chunk_overlap == 200
@@ -42,12 +43,13 @@ Context Analysis Agent Can Be Instantiated With Default Parameters
Context Analysis Agent Can Be Instantiated With Custom Chunk Settings
[Documentation] Create ContextAnalysisAgent with custom chunk_size and overlap
[Tags] llm-required
${script}= Catenate SEPARATOR=\n
... import sys
... sys.path.insert(0, '${SRC_DIR}')
... from cleveragents.agents.context_analysis import ContextAnalysisAgent
... from langchain_community.llms import FakeListLLM
... agent = ContextAnalysisAgent(llm=FakeListLLM(responses=['test']*3), chunk_size=1000, chunk_overlap=100)
... from langchain_anthropic import ChatAnthropic
... agent = ContextAnalysisAgent(llm=ChatAnthropic(model='claude-3-haiku-20240307'), chunk_size=1000, chunk_overlap=100)
... assert agent.chunk_size == 1000
... assert agent.chunk_overlap == 100
... print('Chunk size: ' + str(agent.chunk_size) + ', overlap: ' + str(agent.chunk_overlap))
@@ -58,6 +60,7 @@ Context Analysis Agent Can Be Instantiated With Custom Chunk Settings
Context Analysis Agent Workflow Contains Expected Nodes
[Documentation] Verify all workflow nodes are present using helper script
[Tags] llm-required
${result}= Run Process ${PYTHON} ${HELPER} nodes
Log ${result.stdout}
Log ${result.stderr}
@@ -81,6 +84,7 @@ LangGraph Graphs Package Exports Context Analysis Agent
Context Analysis Agent Can Load Files
[Documentation] Test file loading functionality using helper script
[Tags] llm-required
${result}= Run Process ${PYTHON} ${HELPER} load_files
Log ${result.stdout}
Log ${result.stderr}
@@ -90,6 +94,7 @@ Context Analysis Agent Can Load Files
Context Analysis Agent Handles Missing Files
[Documentation] Test error handling for missing files using helper script
[Tags] llm-required
${result}= Run Process ${PYTHON} ${HELPER} missing_file
Log ${result.stdout}
Log ${result.stderr}
@@ -99,6 +104,7 @@ Context Analysis Agent Handles Missing Files
Context Analysis Agent Invoke Returns Complete Result
[Documentation] Test complete workflow execution via invoke using helper script
[Tags] llm-required
${result}= Run Process ${PYTHON} ${HELPER} invoke
Log ${result.stdout}
Log ${result.stderr}
@@ -108,6 +114,7 @@ Context Analysis Agent Invoke Returns Complete Result
Context Analysis Agent Streaming Produces Updates
[Documentation] Test streaming workflow execution using helper script
[Tags] llm-required
${result}= Run Process ${PYTHON} ${HELPER} streaming
Log ${result.stdout}
Log ${result.stderr}
+10 -7
View File
@@ -112,6 +112,7 @@ Unit Of Work Transaction Rollback
Service Layer Uses Repositories
[Documentation] Test that services properly use repositories
[Tags] llm-required
Create Temporary Project Directory
Initialize Project With Service service-project
${project}= Get Current Project From Service
@@ -127,6 +128,7 @@ Service Layer Uses Repositories
End To End Database Workflow
[Documentation] Test complete workflow using database
[Tags] llm-required
Create Temporary Project Directory
# Run the complete workflow in one script
@@ -138,14 +140,14 @@ End To End Database Workflow
... from cleveragents.application.services.context_service import ContextService
... from cleveragents.infrastructure.database.unit_of_work import UnitOfWork
... from cleveragents.config.settings import Settings
... from features.mocks.mock_ai_provider import MockAIProvider
... from cleveragents.providers.registry import get_provider_registry
... from pathlib import Path
... os.environ["CLEVERAGENTS_TESTING_USE_MOCK_AI"] = "true"
... settings = Settings()
... uow = UnitOfWork('sqlite:///${TEMP_DIR}/test.db')
... mock_ai = MockAIProvider()
... registry = get_provider_registry(settings)
... ai_provider = registry.create_ai_provider(provider_type='anthropic', model_id='claude-3-haiku-20240307')
... project_service = ProjectService(settings, uow)
... plan_service = PlanService(settings, uow, mock_ai)
... plan_service = PlanService(settings, uow, ai_provider)
... plan_service.actor_service.ensure_default_mock_actor(force=True)
... context_service = ContextService(settings, uow)
... # Initialize project
@@ -548,14 +550,15 @@ Create Plan With Service
... from cleveragents.application.services.project_service import ProjectService
... from cleveragents.infrastructure.database.unit_of_work import UnitOfWork
... from cleveragents.config.settings import Settings
... from features.mocks.mock_ai_provider import MockAIProvider
... from cleveragents.providers.registry import get_provider_registry
... import os
... os.chdir('${TEMP_DIR}')
... settings = Settings()
... uow = UnitOfWork('sqlite:///${TEMP_DIR}/test.db')
... mock_ai = MockAIProvider()
... registry = get_provider_registry(settings)
... ai_provider = registry.create_ai_provider(provider_type='anthropic', model_id='claude-3-haiku-20240307')
... project_service = ProjectService(settings, uow)
... plan_service = PlanService(settings, uow, mock_ai)
... plan_service = PlanService(settings, uow, ai_provider)
... project = project_service.get_current_project()
... plan = plan_service.create_plan(project, '${prompt}')
... print('Plan created')
+11 -46
View File
@@ -15,7 +15,7 @@ from typing import Any
src_dir = Path(__file__).parent.parent / "src"
sys.path.insert(0, str(src_dir))
from langchain_community.llms import FakeListLLM # noqa: E402
from langchain_anthropic import ChatAnthropic # noqa: E402
from cleveragents.agents.context_analysis import ( # noqa: E402
ContextAnalysisAgent,
@@ -23,18 +23,15 @@ from cleveragents.agents.context_analysis import ( # noqa: E402
)
def _create_llm() -> ChatAnthropic:
"""Create a real ChatAnthropic LLM instance for integration tests."""
return ChatAnthropic(model="claude-3-haiku-20240307")
def test_nodes() -> None:
"""Test that the workflow graph contains all expected nodes."""
try:
agent = ContextAnalysisAgent(
llm=FakeListLLM(
responses=[
"Dependencies: ['os']",
"Relevance: High",
"Summary: test",
]
)
)
agent = ContextAnalysisAgent(llm=_create_llm())
# Get the nodes from the graph
graph = agent.graph
@@ -66,15 +63,7 @@ def test_nodes() -> None:
def test_load_files() -> None:
"""Test file loading functionality."""
try:
agent = ContextAnalysisAgent(
llm=FakeListLLM(
responses=[
"Dependencies: ['os']",
"Relevance: High",
"Summary: test",
]
)
)
agent = ContextAnalysisAgent(llm=_create_llm())
# Create a temporary test file
with tempfile.NamedTemporaryFile(mode="w", suffix=".py", delete=False) as f:
@@ -117,15 +106,7 @@ def test_load_files() -> None:
def test_missing_file() -> None:
"""Test error handling for missing files."""
try:
agent = ContextAnalysisAgent(
llm=FakeListLLM(
responses=[
"Dependencies: ['os']",
"Relevance: High",
"Summary: test",
]
)
)
agent = ContextAnalysisAgent(llm=_create_llm())
# Create state with non-existent file
state: ContextAnalysisState = {
@@ -163,15 +144,7 @@ def test_missing_file() -> None:
def test_invoke() -> None:
"""Test complete workflow execution via invoke."""
try:
agent = ContextAnalysisAgent(
llm=FakeListLLM(
responses=[
"Dependencies: ['os']",
"Relevance: High",
"Summary: test",
]
)
)
agent = ContextAnalysisAgent(llm=_create_llm())
# Create a temporary test file
with tempfile.NamedTemporaryFile(mode="w", suffix=".py", delete=False) as f:
@@ -237,15 +210,7 @@ def test_invoke() -> None:
def test_streaming() -> None:
"""Test streaming workflow execution."""
try:
agent = ContextAnalysisAgent(
llm=FakeListLLM(
responses=[
"Dependencies: ['os']",
"Relevance: High",
"Summary: test",
]
)
)
agent = ContextAnalysisAgent(llm=_create_llm())
# Create a temporary test file
with tempfile.NamedTemporaryFile(mode="w", suffix=".py", delete=False) as f:
+3 -2
View File
@@ -12,7 +12,7 @@ SRC_DIR = PROJECT_ROOT / "src"
if str(SRC_DIR) not in sys.path:
sys.path.insert(0, str(SRC_DIR))
from langchain_community.llms import FakeListLLM # noqa: E402
from langchain_anthropic import ChatAnthropic # noqa: E402
from cleveragents.agents.plan_generation import PlanGenerationGraph # noqa: E402
from cleveragents.domain.models.core import Context # noqa: E402
@@ -21,7 +21,8 @@ from cleveragents.domain.models.core import Context # noqa: E402
def run_context_summary() -> None:
"""Generate plan context metadata to validate Robot tests."""
graph = PlanGenerationGraph(llm=FakeListLLM(responses=["test response"] * 3))
llm = ChatAnthropic(model="claude-3-haiku-20240307")
graph = PlanGenerationGraph(llm=llm)
with tempfile.NamedTemporaryFile(delete=False, suffix=".py") as tmp:
tmp.write(b"def main():\n return True\n")
tmp_path = Path(tmp.name)
+55 -36
View File
@@ -25,12 +25,13 @@ Plan Generation Graph Module Can Be Imported
Plan Generation Graph Can Be Instantiated With Default Parameters
[Documentation] Create PlanGenerationGraph with defaults
[Tags] llm-required
${script}= Catenate SEPARATOR=\n
... import sys
... sys.path.insert(0, '${SRC_DIR}')
... from cleveragents.agents.plan_generation import PlanGenerationGraph
... from langchain_community.llms import FakeListLLM
... graph = PlanGenerationGraph(llm=FakeListLLM(responses=['test']*3))
... from langchain_anthropic import ChatAnthropic
... graph = PlanGenerationGraph(llm=ChatAnthropic(model='claude-3-haiku-20240307'))
... assert graph is not None
... assert graph.max_retries == 3
... assert graph.llm is not None
@@ -41,12 +42,13 @@ Plan Generation Graph Can Be Instantiated With Default Parameters
Plan Generation Graph Can Be Instantiated With Custom Max Retries
[Documentation] Create PlanGenerationGraph with custom max_retries
[Tags] llm-required
${script}= Catenate SEPARATOR=\n
... import sys
... sys.path.insert(0, '${SRC_DIR}')
... from cleveragents.agents.plan_generation import PlanGenerationGraph
... from langchain_community.llms import FakeListLLM
... graph = PlanGenerationGraph(llm=FakeListLLM(responses=['test']*3), max_retries=5)
... from langchain_anthropic import ChatAnthropic
... graph = PlanGenerationGraph(llm=ChatAnthropic(model='claude-3-haiku-20240307'), max_retries=5)
... assert graph.max_retries == 5
... print('Max retries: ' + str(graph.max_retries))
${result}= Run Process ${PYTHON} -c ${script} shell=True
@@ -55,12 +57,13 @@ Plan Generation Graph Can Be Instantiated With Custom Max Retries
Plan Generation Graph Creates Prompt Templates
[Documentation] Verify prompt templates are created
[Tags] llm-required
${script}= Catenate SEPARATOR=\n
... import sys
... sys.path.insert(0, '${SRC_DIR}')
... from cleveragents.agents.plan_generation import PlanGenerationGraph
... from langchain_community.llms import FakeListLLM
... graph = PlanGenerationGraph(llm=FakeListLLM(responses=['test']*3))
... from langchain_anthropic import ChatAnthropic
... graph = PlanGenerationGraph(llm=ChatAnthropic(model='claude-3-haiku-20240307'))
... assert hasattr(graph, 'analyze_prompt')
... assert hasattr(graph, 'generate_prompt')
... assert hasattr(graph, 'validate_prompt')
@@ -73,12 +76,13 @@ Plan Generation Graph Creates Prompt Templates
Plan Generation Graph Builds Workflow With Correct Nodes
[Documentation] Verify workflow graph has correct nodes
[Tags] llm-required
${script}= Catenate SEPARATOR=\n
... import sys
... sys.path.insert(0, '${SRC_DIR}')
... from cleveragents.agents.plan_generation import PlanGenerationGraph
... from langchain_community.llms import FakeListLLM
... graph = PlanGenerationGraph(llm=FakeListLLM(responses=['test']*3))
... from langchain_anthropic import ChatAnthropic
... graph = PlanGenerationGraph(llm=ChatAnthropic(model='claude-3-haiku-20240307'))
... nodes = graph.graph.nodes
... assert 'load_context' in nodes
... assert 'analyze_requirements' in nodes
@@ -109,12 +113,13 @@ LangGraph Graphs Package Exports Workflow Classes
Format Context Summary With No Files Returns Appropriate Message
[Documentation] Test _format_context_summary with empty list
[Tags] llm-required
${script}= Catenate SEPARATOR=\n
... import sys
... sys.path.insert(0, '${SRC_DIR}')
... from cleveragents.agents.plan_generation import PlanGenerationGraph
... from langchain_community.llms import FakeListLLM
... graph = PlanGenerationGraph(llm=FakeListLLM(responses=['test']*3))
... from langchain_anthropic import ChatAnthropic
... graph = PlanGenerationGraph(llm=ChatAnthropic(model='claude-3-haiku-20240307'))
... summary = graph._format_context_summary([])
... assert summary == 'No context files provided'
... print('Empty context handled correctly')
@@ -124,13 +129,14 @@ Format Context Summary With No Files Returns Appropriate Message
Format Context Summary With Multiple Files
[Documentation] Test _format_context_summary with multiple Context objects
[Tags] llm-required
${script}= Catenate SEPARATOR=\n
... import sys
... sys.path.insert(0, '${SRC_DIR}')
... from cleveragents.agents.plan_generation import PlanGenerationGraph
... from langchain_community.llms import FakeListLLM
... from langchain_anthropic import ChatAnthropic
... from cleveragents.domain.models.core import Context
... graph = PlanGenerationGraph(llm=FakeListLLM(responses=['test']*3))
... graph = PlanGenerationGraph(llm=ChatAnthropic(model='claude-3-haiku-20240307'))
... contexts = [
... Context(plan_id=1, path='file1.py', content='# File 1 content'),
... Context(plan_id=1, path='file2.py', content='# File 2 content'),
@@ -146,13 +152,14 @@ Format Context Summary With Multiple Files
Format Context Summary Limits To Five Files
[Documentation] Test that _format_context_summary limits to first 5 files
[Tags] llm-required
${script}= Catenate SEPARATOR=\n
... import sys
... sys.path.insert(0, '${SRC_DIR}')
... from cleveragents.agents.plan_generation import PlanGenerationGraph
... from langchain_community.llms import FakeListLLM
... from langchain_anthropic import ChatAnthropic
... from cleveragents.domain.models.core import Context
... graph = PlanGenerationGraph(llm=FakeListLLM(responses=['test']*3))
... graph = PlanGenerationGraph(llm=ChatAnthropic(model='claude-3-haiku-20240307'))
... contexts = [Context(plan_id=1, path=f'file{i}.py', content='content') for i in range(8)]
... summary = graph._format_context_summary(contexts)
... assert 'file0.py' in summary
@@ -165,13 +172,14 @@ Format Context Summary Limits To Five Files
Load Context Node Initializes State
[Documentation] Test _load_context node execution
[Tags] llm-required
${script}= Catenate SEPARATOR=\n
... import sys
... sys.path.insert(0, '${SRC_DIR}')
... from cleveragents.agents.plan_generation import PlanGenerationGraph
... from langchain_community.llms import FakeListLLM
... from langchain_anthropic import ChatAnthropic
... from cleveragents.domain.models.core import Project, Plan
... graph = PlanGenerationGraph(llm=FakeListLLM(responses=['test']*3))
... graph = PlanGenerationGraph(llm=ChatAnthropic(model='claude-3-haiku-20240307'))
... state = {'project': None, 'plan': None, 'contexts': []}
... result = graph._load_context(state)
... assert result['retry_count'] == 0
@@ -187,6 +195,7 @@ Load Context Node Initializes State
Load Context Node Generates Summary With Sample Contexts
[Documentation] Ensure context analysis metadata is populated
[Tags] llm-required
${result}= Run Process ${PYTHON} ${CURDIR}/helper_plan_generation.py
Should Contain ${result.stdout} Context analysis summary ready
Should Be Equal As Integers ${result.rc} 0
@@ -194,12 +203,13 @@ Load Context Node Generates Summary With Sample Contexts
Should Retry Returns Retry When Validation Fails And Retries Available
[Documentation] Test _should_retry returns "retry" appropriately
[Tags] llm-required
${script}= Catenate SEPARATOR=\n
... import sys
... sys.path.insert(0, '${SRC_DIR}')
... from cleveragents.agents.plan_generation import PlanGenerationGraph
... from langchain_community.llms import FakeListLLM
... graph = PlanGenerationGraph(llm=FakeListLLM(responses=['test']*3), max_retries=3)
... from langchain_anthropic import ChatAnthropic
... graph = PlanGenerationGraph(llm=ChatAnthropic(model='claude-3-haiku-20240307'), max_retries=3)
... state = {
... 'validation_result': {'status': 'FAIL'},
... 'retry_count': 0
@@ -214,12 +224,13 @@ Should Retry Returns Retry When Validation Fails And Retries Available
Should Retry Returns End When Validation Passes
[Documentation] Test _should_retry returns "end" when validation succeeds
[Tags] llm-required
${script}= Catenate SEPARATOR=\n
... import sys
... sys.path.insert(0, '${SRC_DIR}')
... from cleveragents.agents.plan_generation import PlanGenerationGraph
... from langchain_community.llms import FakeListLLM
... graph = PlanGenerationGraph(llm=FakeListLLM(responses=['test']*3), max_retries=3)
... from langchain_anthropic import ChatAnthropic
... graph = PlanGenerationGraph(llm=ChatAnthropic(model='claude-3-haiku-20240307'), max_retries=3)
... state = {
... 'validation_result': {'status': 'PASS'},
... 'retry_count': 0
@@ -233,12 +244,13 @@ Should Retry Returns End When Validation Passes
Should Retry Returns End When Max Retries Reached
[Documentation] Test _should_retry returns "end" when max retries reached
[Tags] llm-required
${script}= Catenate SEPARATOR=\n
... import sys
... sys.path.insert(0, '${SRC_DIR}')
... from cleveragents.agents.plan_generation import PlanGenerationGraph
... from langchain_community.llms import FakeListLLM
... graph = PlanGenerationGraph(llm=FakeListLLM(responses=['test']*3), max_retries=3)
... from langchain_anthropic import ChatAnthropic
... graph = PlanGenerationGraph(llm=ChatAnthropic(model='claude-3-haiku-20240307'), max_retries=3)
... state = {
... 'validation_result': {'status': 'FAIL'},
... 'retry_count': 3
@@ -277,12 +289,13 @@ Plan Generation State TypedDict Has Correct Structure
Validate Node Fails When No Changes Provided
[Documentation] Test _validate with no changes
[Tags] llm-required
${script}= Catenate SEPARATOR=\n
... import sys
... sys.path.insert(0, '${SRC_DIR}')
... from cleveragents.agents.plan_generation import PlanGenerationGraph
... from langchain_community.llms import FakeListLLM
... graph = PlanGenerationGraph(llm=FakeListLLM(responses=['test']*3))
... from langchain_anthropic import ChatAnthropic
... graph = PlanGenerationGraph(llm=ChatAnthropic(model='claude-3-haiku-20240307'))
... state = {'generated_changes': []}
... result = graph._validate(state)
... assert result['validation_result']['status'] == 'FAIL'
@@ -294,12 +307,13 @@ Validate Node Fails When No Changes Provided
Generate Plan Handles Missing Requirements
[Documentation] Test _generate_plan with no requirements
[Tags] llm-required
${script}= Catenate SEPARATOR=\n
... import sys
... sys.path.insert(0, '${SRC_DIR}')
... from cleveragents.agents.plan_generation import PlanGenerationGraph
... from langchain_community.llms import FakeListLLM
... graph = PlanGenerationGraph(llm=FakeListLLM(responses=['test']*3))
... from langchain_anthropic import ChatAnthropic
... graph = PlanGenerationGraph(llm=ChatAnthropic(model='claude-3-haiku-20240307'))
... state = {'analyzed_requirements': {}}
... result = graph._generate_plan(state)
... assert result['generated_changes'] == []
@@ -311,14 +325,15 @@ Generate Plan Handles Missing Requirements
Generate Plan Infers Test File Name From Prompt
[Documentation] Test file name inference for test-related prompts
[Tags] llm-required
${script}= Catenate SEPARATOR=\n
... import sys
... from pathlib import Path
... sys.path.insert(0, '${SRC_DIR}')
... from cleveragents.agents.plan_generation import PlanGenerationGraph
... from langchain_community.llms import FakeListLLM
... from langchain_anthropic import ChatAnthropic
... from cleveragents.domain.models.core import Project, Plan
... graph = PlanGenerationGraph(llm=FakeListLLM(responses=['test']*3))
... graph = PlanGenerationGraph(llm=ChatAnthropic(model='claude-3-haiku-20240307'))
... state = {
... 'project': Project(id=1, name='test', path=Path('/tmp/test_project')),
... 'plan': Plan(id=1, project_id=1, name='Unit Test Plan', prompt='Create unit tests'),
@@ -340,14 +355,15 @@ Generate Plan Infers Test File Name From Prompt
Generate Plan Infers Error Handler File Name From Prompt
[Documentation] Test file name inference for error/exception prompts
[Tags] llm-required
${script}= Catenate SEPARATOR=\n
... import sys
... from pathlib import Path
... sys.path.insert(0, '${SRC_DIR}')
... from cleveragents.agents.plan_generation import PlanGenerationGraph
... from langchain_community.llms import FakeListLLM
... from langchain_anthropic import ChatAnthropic
... from cleveragents.domain.models.core import Project, Plan
... graph = PlanGenerationGraph(llm=FakeListLLM(responses=['test']*3))
... graph = PlanGenerationGraph(llm=ChatAnthropic(model='claude-3-haiku-20240307'))
... state = {
... 'project': Project(id=1, name='test', path=Path('/tmp/test_project')),
... 'plan': Plan(id=1, project_id=1, name='Error Handling Plan', prompt='Add error handling'),
@@ -368,14 +384,15 @@ Generate Plan Infers Error Handler File Name From Prompt
Workflow Invoke Method Returns Complete State
[Documentation] Test that invoke() returns complete workflow state
[Tags] llm-required
${script}= Catenate SEPARATOR=\n
... import sys
... from pathlib import Path
... sys.path.insert(0, '${SRC_DIR}')
... from cleveragents.agents.plan_generation import PlanGenerationGraph
... from langchain_community.llms import FakeListLLM
... from langchain_anthropic import ChatAnthropic
... from cleveragents.domain.models.core import Project, Plan, Context
... graph = PlanGenerationGraph(llm=FakeListLLM(responses=['test']*3))
... graph = PlanGenerationGraph(llm=ChatAnthropic(model='claude-3-haiku-20240307'))
... project = Project(id=1, name='test_project', path=Path('/tmp/test_project'))
... plan = Plan(id=1, project_id=1, name='Logging Plan', prompt='Add logging')
... contexts = [Context(plan_id=plan.id, path='app.py', content='def main(): pass')]
@@ -398,14 +415,15 @@ Workflow Invoke Method Returns Complete State
Workflow Stream Method Yields Events
[Documentation] Test that stream() yields workflow events
[Tags] llm-required
${script}= Catenate SEPARATOR=\n
... import sys
... from pathlib import Path
... sys.path.insert(0, '${SRC_DIR}')
... from cleveragents.agents.plan_generation import PlanGenerationGraph
... from langchain_community.llms import FakeListLLM
... from langchain_anthropic import ChatAnthropic
... from cleveragents.domain.models.core import Project, Plan, Context
... graph = PlanGenerationGraph(llm=FakeListLLM(responses=['test']*3))
... graph = PlanGenerationGraph(llm=ChatAnthropic(model='claude-3-haiku-20240307'))
... project = Project(id=1, name='test_project', path=Path('/tmp/test_project'))
... plan = Plan(id=1, project_id=1, name='Feature Plan', prompt='Add feature')
... contexts = [Context(plan_id=plan.id, path='app.py', content='# app')]
@@ -420,13 +438,14 @@ Workflow Stream Method Yields Events
Graph Has Checkpointer For State Persistence
[Documentation] Verify checkpointer is configured
[Tags] llm-required
${script}= Catenate SEPARATOR=\n
... import sys
... sys.path.insert(0, '${SRC_DIR}')
... from cleveragents.agents.plan_generation import PlanGenerationGraph
... from langchain_community.llms import FakeListLLM
... from langchain_anthropic import ChatAnthropic
... from langgraph.checkpoint.memory import MemorySaver
... graph = PlanGenerationGraph(llm=FakeListLLM(responses=['test']*3))
... graph = PlanGenerationGraph(llm=ChatAnthropic(model='claude-3-haiku-20240307'))
... assert graph.checkpointer is not None
... assert isinstance(graph.checkpointer, MemorySaver)
... assert graph.app is not None
@@ -406,10 +406,16 @@ class PlanService:
model_name = model_value or provider_name
provider_instance_mutable = cast(Any, provider_instance)
if hasattr(provider_instance_mutable, "name"):
provider_instance_mutable.name = provider_name
if hasattr(provider_instance_mutable, "model_id"):
provider_instance_mutable.model_id = model_name
try:
if hasattr(provider_instance_mutable, "name"):
provider_instance_mutable.name = provider_name
except AttributeError:
pass # Read-only property on real provider implementations
try:
if hasattr(provider_instance_mutable, "model_id"):
provider_instance_mutable.model_id = model_name
except AttributeError:
pass # Read-only property on real provider implementations
selection_metadata = self._provider_selection_metadata(
actor=actor,