feat(local-agent-v2): step 4 — journey produces structured AgentConfig JSON
Replace freeform prompt_template output with validated AgentConfig JSON: - agent_setup.py: new system prompt (journey_system_v2), AGENT_CONFIG_START/END markers, _extract_agent_config() with Pydantic validation, updated handlers returning agent_config key; import AgentConfig from schemas - tests/test_journey_v2.py: 6 unit tests + 5 parametrized LLM eval cases following test_agent_runner_v2.py pattern; _run_journey uses set_client_executor/clear_client_executor mirroring device_ws - tests/fixtures/journey_v2/: cases.yaml + email_action.html + email_info.html - tests/conftest.py: add --journey-dir CLI option; remove S3/plugin fixtures (cleanup from microservices migration, already present in working tree) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -6,26 +6,21 @@ a per-test session, and a FastAPI ``TestClient`` wired to use it.
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import os
|
||||
import time
|
||||
import uuid
|
||||
from collections.abc import AsyncGenerator, Generator
|
||||
from unittest.mock import patch
|
||||
|
||||
import boto3
|
||||
import pytest
|
||||
import pytest_asyncio
|
||||
from fastapi.testclient import TestClient
|
||||
from jose import jwt
|
||||
from moto import mock_aws
|
||||
from sqlalchemy import StaticPool, event
|
||||
from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker, create_async_engine
|
||||
|
||||
from app.config.settings import settings
|
||||
from app.db import Base, get_session
|
||||
from app.main import app
|
||||
from app.models import Plugin, Subscription, User
|
||||
from app.models import Subscription, User
|
||||
|
||||
# ── Fixed test user IDs (one per tier) ───────────────────────────────
|
||||
|
||||
@@ -109,79 +104,6 @@ def client(db_session: AsyncSession) -> Generator[TestClient, None, None]: # n
|
||||
app.dependency_overrides.pop(get_session, None)
|
||||
|
||||
|
||||
# ── Seed data helpers ────────────────────────────────────────────────
|
||||
|
||||
_SEED_PLUGINS = [
|
||||
Plugin(
|
||||
id="plugin-github-sync",
|
||||
name="GitHub Sync",
|
||||
description="Sync tasks with GitHub Issues and pull requests.",
|
||||
version="1.0.0",
|
||||
author_name="Adiuva",
|
||||
category="productivity",
|
||||
price_cents=0,
|
||||
permissions=json.dumps(["read:tasks", "write:tasks"]),
|
||||
status="approved",
|
||||
s3_package_key="plugins/plugin-github-sync/1.0.0/package.zip",
|
||||
install_count=0,
|
||||
avg_rating=0.0,
|
||||
),
|
||||
Plugin(
|
||||
id="plugin-slack-notify",
|
||||
name="Slack Notifier",
|
||||
description="Post task and timeline updates to Slack channels.",
|
||||
version="1.2.0",
|
||||
author_name="Adiuva",
|
||||
category="communication",
|
||||
price_cents=499,
|
||||
permissions=json.dumps(["read:tasks", "read:timelines"]),
|
||||
status="approved",
|
||||
s3_package_key="plugins/plugin-slack-notify/1.2.0/package.zip",
|
||||
install_count=0,
|
||||
avg_rating=0.0,
|
||||
),
|
||||
Plugin(
|
||||
id="plugin-time-tracker",
|
||||
name="Time Tracker",
|
||||
description="Track time spent on tasks with automatic reporting.",
|
||||
version="0.9.1",
|
||||
author_name="Third Party",
|
||||
category="productivity",
|
||||
price_cents=999,
|
||||
permissions=json.dumps(["read:tasks", "write:tasks"]),
|
||||
status="approved",
|
||||
s3_package_key="plugins/plugin-time-tracker/0.9.1/package.zip",
|
||||
install_count=0,
|
||||
avg_rating=0.0,
|
||||
),
|
||||
]
|
||||
|
||||
|
||||
@pytest_asyncio.fixture
|
||||
async def seed_plugins(db_session: AsyncSession) -> list[Plugin]:
|
||||
"""Insert the 3 default approved plugins and return them."""
|
||||
plugins = []
|
||||
for template in _SEED_PLUGINS:
|
||||
p = Plugin(
|
||||
id=template.id,
|
||||
name=template.name,
|
||||
description=template.description,
|
||||
version=template.version,
|
||||
author_name=template.author_name,
|
||||
category=template.category,
|
||||
price_cents=template.price_cents,
|
||||
permissions=template.permissions,
|
||||
status=template.status,
|
||||
s3_package_key=template.s3_package_key,
|
||||
install_count=template.install_count,
|
||||
avg_rating=template.avg_rating,
|
||||
)
|
||||
db_session.add(p)
|
||||
plugins.append(p)
|
||||
await db_session.commit()
|
||||
return plugins
|
||||
|
||||
|
||||
# ── JWT helpers ──────────────────────────────────────────────────────
|
||||
|
||||
|
||||
@@ -212,29 +134,6 @@ def auth_header(tier: str = "power", user_id: str | None = None) -> dict[str, st
|
||||
return {"Authorization": f"Bearer {make_jwt(tier, user_id)}"}
|
||||
|
||||
|
||||
# ── S3 mock fixture ──────────────────────────────────────────────────
|
||||
|
||||
S3_TEST_BUCKET = "test-bucket"
|
||||
S3_TEST_REGION = "us-east-1"
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def s3_bucket():
|
||||
"""Create a mocked S3 bucket via moto and patch BlobStore settings."""
|
||||
with mock_aws():
|
||||
os.environ.setdefault("AWS_ACCESS_KEY_ID", "testing")
|
||||
os.environ.setdefault("AWS_SECRET_ACCESS_KEY", "testing")
|
||||
os.environ.setdefault("AWS_DEFAULT_REGION", S3_TEST_REGION)
|
||||
client = boto3.client("s3", region_name=S3_TEST_REGION)
|
||||
client.create_bucket(Bucket=S3_TEST_BUCKET)
|
||||
with patch("app.storage.blob_store.settings") as mock_settings:
|
||||
mock_settings.S3_BUCKET = S3_TEST_BUCKET
|
||||
mock_settings.S3_REGION = S3_TEST_REGION
|
||||
mock_settings.AWS_ACCESS_KEY_ID = "testing"
|
||||
mock_settings.AWS_SECRET_ACCESS_KEY = "testing"
|
||||
yield S3_TEST_BUCKET
|
||||
|
||||
|
||||
# ── CLI options ───────────────────────────────────────────────────────
|
||||
|
||||
def pytest_addoption(parser):
|
||||
@@ -243,3 +142,13 @@ def pytest_addoption(parser):
|
||||
default=None,
|
||||
help="Override fixture folder for preprocessor tests (must contain cases.yaml + data/)",
|
||||
)
|
||||
parser.addoption(
|
||||
"--runner-dir",
|
||||
default=None,
|
||||
help="Override fixture folder for agent_runner_v2 eval tests (must contain cases.yaml + data/)",
|
||||
)
|
||||
parser.addoption(
|
||||
"--journey-dir",
|
||||
default=None,
|
||||
help="Override fixture folder for journey_v2 eval tests (must contain cases.yaml + data/)",
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user