fix: change api contract to return ResourceNotFoundException (#375)
This commit is contained in:
parent
a78dfc24af
commit
7cc39d2b56
|
|
@ -389,6 +389,9 @@ describe('Peer', () => {
|
|||
describe('POST /peers/:id/card', () => {
|
||||
test('card returns string array or null', async () => {
|
||||
const peer = await client.peer('card-peer')
|
||||
const session = await client.session('card-session')
|
||||
await session.addPeers([peer.id])
|
||||
await session.addMessages([peer.message('hello')])
|
||||
|
||||
const card = await peer.card()
|
||||
|
||||
|
|
@ -399,6 +402,9 @@ describe('Peer', () => {
|
|||
test('card with target peer', async () => {
|
||||
const observer = await client.peer('card-observer')
|
||||
const observed = await client.peer('card-observed')
|
||||
const session = await client.session('card-target-session')
|
||||
await session.addPeers([observer.id, observed.id])
|
||||
await session.addMessages([observer.message('hello'), observed.message('hi')])
|
||||
|
||||
const card = await observer.card(observed)
|
||||
|
||||
|
|
@ -408,6 +414,10 @@ describe('Peer', () => {
|
|||
|
||||
test('card with target ID string', async () => {
|
||||
const peer = await client.peer('card-string-peer')
|
||||
const target = await client.peer('some-target-id')
|
||||
const session = await client.session('card-string-session')
|
||||
await session.addPeers([peer.id, target.id])
|
||||
await session.addMessages([peer.message('hello'), target.message('hi')])
|
||||
|
||||
const card = await peer.card('some-target-id')
|
||||
|
||||
|
|
@ -479,6 +489,9 @@ describe('Peer', () => {
|
|||
describe('POST /peers/:id/context', () => {
|
||||
test('context returns representation and card', async () => {
|
||||
const peer = await client.peer('context-peer')
|
||||
const session = await client.session('context-session')
|
||||
await session.addPeers([peer.id])
|
||||
await session.addMessages([peer.message('hello')])
|
||||
|
||||
const context = await peer.context()
|
||||
|
||||
|
|
@ -492,6 +505,9 @@ describe('Peer', () => {
|
|||
test('context with target peer', async () => {
|
||||
const observer = await client.peer('context-observer')
|
||||
const observed = await client.peer('context-observed')
|
||||
const session = await client.session('context-target-session')
|
||||
await session.addPeers([observer.id, observed.id])
|
||||
await session.addMessages([observer.message('hello'), observed.message('hi')])
|
||||
|
||||
const context = await observer.context({ target: observed })
|
||||
|
||||
|
|
@ -501,6 +517,9 @@ describe('Peer', () => {
|
|||
|
||||
test('context with options', async () => {
|
||||
const peer = await client.peer('context-options-peer')
|
||||
const session = await client.session('context-options-session')
|
||||
await session.addPeers([peer.id])
|
||||
await session.addMessages([peer.message('hello')])
|
||||
|
||||
const context = await peer.context({
|
||||
searchQuery: 'interests',
|
||||
|
|
|
|||
|
|
@ -3,12 +3,12 @@ from __future__ import annotations
|
|||
import logging
|
||||
from typing import cast
|
||||
|
||||
from sqlalchemy import select, update
|
||||
from sqlalchemy import update
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from src import models, schemas
|
||||
from src.cache.client import cache
|
||||
from src.crud.peer import get_or_create_peers, peer_cache_key
|
||||
from src.crud.peer import get_or_create_peers, get_peer, peer_cache_key
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
|
@ -32,15 +32,12 @@ async def get_peer_card(
|
|||
observer: Peer name of the observer
|
||||
|
||||
Returns:
|
||||
The peer's card text if present, otherwise None (also None if peer not found).
|
||||
The peer's card text if present, otherwise None.
|
||||
|
||||
Raises:
|
||||
ResourceNotFoundException: If the peer does not exist.
|
||||
"""
|
||||
peer = await db.scalar(
|
||||
select(models.Peer)
|
||||
.where(models.Peer.workspace_name == workspace_name)
|
||||
.where(models.Peer.name == observer)
|
||||
)
|
||||
if peer is None:
|
||||
return None
|
||||
peer = await get_peer(db, workspace_name, schemas.PeerCreate(name=observer))
|
||||
return cast(
|
||||
list[str] | None,
|
||||
peer.internal_metadata.get(
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ using the DialecticAgent.
|
|||
import logging
|
||||
from collections.abc import AsyncIterator
|
||||
|
||||
from src import crud
|
||||
from src import crud, schemas
|
||||
from src.config import ReasoningLevel
|
||||
from src.dependencies import tracked_db
|
||||
from src.dialectic.core import DialecticAgent
|
||||
|
|
@ -40,6 +40,11 @@ async def agentic_chat(
|
|||
The synthesized answer string
|
||||
"""
|
||||
async with tracked_db("dialectic.agentic_chat") as db:
|
||||
# Validate that the peers exist before proceeding
|
||||
await crud.get_peer(db, workspace_name, schemas.PeerCreate(name=observer))
|
||||
if observer != observed:
|
||||
await crud.get_peer(db, workspace_name, schemas.PeerCreate(name=observed))
|
||||
|
||||
# Resolve configuration to check if peer cards should be used
|
||||
session = None
|
||||
if session_name:
|
||||
|
|
@ -101,6 +106,11 @@ async def agentic_chat_stream(
|
|||
Chunks of the response text as they are generated
|
||||
"""
|
||||
async with tracked_db("dialectic.agentic_chat_stream") as db:
|
||||
# Validate that the peers exist before proceeding
|
||||
await crud.get_peer(db, workspace_name, schemas.PeerCreate(name=observer))
|
||||
if observer != observed:
|
||||
await crud.get_peer(db, workspace_name, schemas.PeerCreate(name=observed))
|
||||
|
||||
# Resolve configuration to check if peer cards should be used
|
||||
session = None
|
||||
if session_name:
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ from typing import Any
|
|||
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from src import crud
|
||||
from src import crud, schemas
|
||||
from src.config import settings
|
||||
from src.schemas import ResolvedConfiguration
|
||||
from src.telemetry import prometheus_metrics
|
||||
|
|
@ -142,6 +142,11 @@ class BaseSpecialist(ABC):
|
|||
task_name = f"dreamer_{self.name}_{run_id}"
|
||||
start_time = time.perf_counter()
|
||||
|
||||
# Validate that the peers exist before proceeding
|
||||
await crud.get_peer(db, workspace_name, schemas.PeerCreate(name=observer))
|
||||
if observer != observed:
|
||||
await crud.get_peer(db, workspace_name, schemas.PeerCreate(name=observed))
|
||||
|
||||
# Determine if peer card tools should be included
|
||||
peer_card_enabled = configuration is None or configuration.peer_card.create
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ from sqlalchemy.ext.asyncio import AsyncSession
|
|||
|
||||
from src import models
|
||||
from src.crud.peer_card import construct_peer_card_label, get_peer_card, set_peer_card
|
||||
from src.exceptions import ResourceNotFoundException
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
|
|
@ -50,33 +51,33 @@ async def test_peer_card_get_set_roundtrip(
|
|||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_get_peer_card_missing_peer_returns_none(
|
||||
async def test_get_peer_card_missing_peer_raises(
|
||||
db_session: AsyncSession, sample_data: tuple[models.Workspace, models.Peer]
|
||||
):
|
||||
"""Getting a peer card for a non-existent peer should return None while creating the peer."""
|
||||
"""Getting a peer card for a non-existent peer should raise ResourceNotFoundException."""
|
||||
workspace, _existing_peer = sample_data
|
||||
result = await get_peer_card(
|
||||
db_session,
|
||||
workspace.name,
|
||||
observer="missing-peer",
|
||||
observed="missing-peer",
|
||||
)
|
||||
assert result is None
|
||||
with pytest.raises(ResourceNotFoundException):
|
||||
await get_peer_card(
|
||||
db_session,
|
||||
workspace.name,
|
||||
observer="missing-peer",
|
||||
observed="missing-peer",
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_get_peer_card_missing_workspace_returns_none(
|
||||
async def test_get_peer_card_missing_workspace_raises(
|
||||
db_session: AsyncSession, sample_data: tuple[models.Workspace, models.Peer]
|
||||
):
|
||||
"""Getting a peer card for a non-existent workspace should return None."""
|
||||
"""Getting a peer card for a non-existent workspace should raise ResourceNotFoundException."""
|
||||
_workspace, peer = sample_data
|
||||
result = await get_peer_card(
|
||||
db_session,
|
||||
"missing-workspace",
|
||||
observer=peer.name,
|
||||
observed=peer.name,
|
||||
)
|
||||
assert result is None
|
||||
with pytest.raises(ResourceNotFoundException):
|
||||
await get_peer_card(
|
||||
db_session,
|
||||
"missing-workspace",
|
||||
observer=peer.name,
|
||||
observed=peer.name,
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
|
|
|
|||
|
|
@ -113,6 +113,10 @@ def test_peer_card_operations(honcho_test_client: Honcho):
|
|||
peer = honcho_test_client.peer(id="card-test-peer")
|
||||
target = honcho_test_client.peer(id="card-test-target")
|
||||
|
||||
# Create the peers on the server by adding a message
|
||||
session = honcho_test_client.session(id="card-test-session")
|
||||
session.add_messages([peer.message("hello"), target.message("hi")])
|
||||
|
||||
# Initially card should be None
|
||||
card = peer.get_card()
|
||||
assert card is None
|
||||
|
|
|
|||
|
|
@ -159,12 +159,20 @@ async def test_peer_card_with_empty_target(client_fixture: tuple[Honcho, str]):
|
|||
|
||||
if client_type == "async":
|
||||
peer = await honcho_client.aio.peer(id="test-card-validation-peer")
|
||||
session = await honcho_client.aio.session(id="test-card-validation-session")
|
||||
|
||||
# Create the peer on the server by adding a message
|
||||
await session.aio.add_messages([peer.message("hello")])
|
||||
|
||||
# Empty target is treated as no target (same as None)
|
||||
result = await peer.aio.get_card(target="")
|
||||
assert result is None or isinstance(result, list)
|
||||
else:
|
||||
peer = honcho_client.peer(id="test-card-validation-peer")
|
||||
session = honcho_client.session(id="test-card-validation-session")
|
||||
|
||||
# Create the peer on the server by adding a message
|
||||
session.add_messages([peer.message("hello")])
|
||||
|
||||
# Empty target is treated as no target (same as None)
|
||||
result = peer.get_card(target="")
|
||||
|
|
|
|||
Loading…
Reference in New Issue