interloper-api 0.110.2__tar.gz → 0.112.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {interloper_api-0.110.2 → interloper_api-0.112.0}/PKG-INFO +1 -1
- {interloper_api-0.110.2 → interloper_api-0.112.0}/pyproject.toml +1 -1
- {interloper_api-0.110.2 → interloper_api-0.112.0}/pyproject.toml.orig +1 -1
- {interloper_api-0.110.2 → interloper_api-0.112.0}/src/interloper_api/routes/agent.py +28 -1
- {interloper_api-0.110.2 → interloper_api-0.112.0}/README.md +0 -0
- {interloper_api-0.110.2 → interloper_api-0.112.0}/src/interloper_api/__init__.py +0 -0
- {interloper_api-0.110.2 → interloper_api-0.112.0}/src/interloper_api/app.py +0 -0
- {interloper_api-0.110.2 → interloper_api-0.112.0}/src/interloper_api/dependencies/__init__.py +0 -0
- {interloper_api-0.110.2 → interloper_api-0.112.0}/src/interloper_api/dependencies/auth.py +0 -0
- {interloper_api-0.110.2 → interloper_api-0.112.0}/src/interloper_api/dependencies/rbac.py +0 -0
- {interloper_api-0.110.2 → interloper_api-0.112.0}/src/interloper_api/dependencies/state.py +0 -0
- {interloper_api-0.110.2 → interloper_api-0.112.0}/src/interloper_api/notifications/__init__.py +0 -0
- {interloper_api-0.110.2 → interloper_api-0.112.0}/src/interloper_api/notifications/base.py +0 -0
- {interloper_api-0.110.2 → interloper_api-0.112.0}/src/interloper_api/notifications/invitations.py +0 -0
- {interloper_api-0.110.2 → interloper_api-0.112.0}/src/interloper_api/notifications/super_admins.py +0 -0
- {interloper_api-0.110.2 → interloper_api-0.112.0}/src/interloper_api/routes/__init__.py +0 -0
- {interloper_api-0.110.2 → interloper_api-0.112.0}/src/interloper_api/routes/admin.py +0 -0
- {interloper_api-0.110.2 → interloper_api-0.112.0}/src/interloper_api/routes/auth.py +0 -0
- {interloper_api-0.110.2 → interloper_api-0.112.0}/src/interloper_api/routes/backfills.py +0 -0
- {interloper_api-0.110.2 → interloper_api-0.112.0}/src/interloper_api/routes/catalog.py +0 -0
- {interloper_api-0.110.2 → interloper_api-0.112.0}/src/interloper_api/routes/components.py +0 -0
- {interloper_api-0.110.2 → interloper_api-0.112.0}/src/interloper_api/routes/executions.py +0 -0
- {interloper_api-0.110.2 → interloper_api-0.112.0}/src/interloper_api/routes/health.py +0 -0
- {interloper_api-0.110.2 → interloper_api-0.112.0}/src/interloper_api/routes/oauth.py +0 -0
- {interloper_api-0.110.2 → interloper_api-0.112.0}/src/interloper_api/routes/organisations.py +0 -0
- {interloper_api-0.110.2 → interloper_api-0.112.0}/src/interloper_api/routes/overview.py +0 -0
- {interloper_api-0.110.2 → interloper_api-0.112.0}/src/interloper_api/routes/relations.py +0 -0
- {interloper_api-0.110.2 → interloper_api-0.112.0}/src/interloper_api/routes/runs.py +0 -0
- {interloper_api-0.110.2 → interloper_api-0.112.0}/src/interloper_api/routes/tokens.py +0 -0
- {interloper_api-0.110.2 → interloper_api-0.112.0}/src/interloper_api/routes/websocket.py +0 -0
- {interloper_api-0.110.2 → interloper_api-0.112.0}/src/interloper_api/utils/__init__.py +0 -0
- {interloper_api-0.110.2 → interloper_api-0.112.0}/src/interloper_api/utils/time.py +0 -0
|
@@ -20,12 +20,13 @@ from typing import Annotated, Any
|
|
|
20
20
|
from uuid import UUID
|
|
21
21
|
|
|
22
22
|
from fastapi import APIRouter, Query, Request, Response
|
|
23
|
+
from interloper.telemetry import meter
|
|
23
24
|
from interloper_agent import TURN_LIMITS, summary_of
|
|
24
25
|
from interloper_db import Page, PageQuery
|
|
25
26
|
from interloper_db.models import Conversation
|
|
26
27
|
from interloper_toolkit import ToolkitContext
|
|
27
28
|
from pydantic import BaseModel
|
|
28
|
-
from pydantic_ai import DeferredToolResults
|
|
29
|
+
from pydantic_ai import Agent, DeferredToolResults
|
|
29
30
|
from pydantic_ai.agent import AgentRunResult
|
|
30
31
|
from pydantic_ai.messages import (
|
|
31
32
|
ModelMessage,
|
|
@@ -49,6 +50,12 @@ router = APIRouter(prefix="/agent", tags=["agent"])
|
|
|
49
50
|
SDK_VERSION = 7
|
|
50
51
|
"""The AI SDK major version the app speaks; tool approvals need at least 6."""
|
|
51
52
|
|
|
53
|
+
_turns = meter().create_counter("interloper.agent.turns", unit="{turn}", description="Agent turns, by outcome")
|
|
54
|
+
_tokens = meter().create_counter("interloper.agent.tokens", unit="{token}", description="Tokens agent turns spent")
|
|
55
|
+
_requests = meter().create_histogram(
|
|
56
|
+
"interloper.agent.requests", unit="{request}", description="Model requests one agent turn took"
|
|
57
|
+
)
|
|
58
|
+
|
|
52
59
|
|
|
53
60
|
class LoggedEventStream(VercelAIEventStream[ToolkitContext, Any]):
|
|
54
61
|
"""The Vercel event stream, with a run's failure in the server log too.
|
|
@@ -68,6 +75,7 @@ class LoggedEventStream(VercelAIEventStream[ToolkitContext, Any]):
|
|
|
68
75
|
The protocol's error chunks.
|
|
69
76
|
"""
|
|
70
77
|
logger.error("Agent turn failed: %s", error, exc_info=error)
|
|
78
|
+
_turns.add(1, {"status": "failed"})
|
|
71
79
|
async for chunk in super().on_error(error):
|
|
72
80
|
yield chunk
|
|
73
81
|
|
|
@@ -327,6 +335,11 @@ async def chat(
|
|
|
327
335
|
usage.output_tokens,
|
|
328
336
|
len(messages),
|
|
329
337
|
)
|
|
338
|
+
model = _model_name(agent)
|
|
339
|
+
_turns.add(1, {"status": "completed", "model": model})
|
|
340
|
+
_tokens.add(usage.input_tokens, {"kind": "input", "model": model})
|
|
341
|
+
_tokens.add(usage.output_tokens, {"kind": "output", "model": model})
|
|
342
|
+
_requests.record(usage.requests, {"model": model})
|
|
330
343
|
|
|
331
344
|
history = ModelMessagesTypeAdapter.validate_python(conversation.messages)
|
|
332
345
|
return await ConversationAdapter.dispatch_request(
|
|
@@ -342,6 +355,20 @@ async def chat(
|
|
|
342
355
|
)
|
|
343
356
|
|
|
344
357
|
|
|
358
|
+
def _model_name(agent: Agent[ToolkitContext, Any]) -> str:
|
|
359
|
+
"""The model an agent answers with, as a metric attribute.
|
|
360
|
+
|
|
361
|
+
Args:
|
|
362
|
+
agent: The assistant; its model is the ``provider:model`` string it
|
|
363
|
+
was built with until the first turn resolves it.
|
|
364
|
+
|
|
365
|
+
Returns:
|
|
366
|
+
The model's name.
|
|
367
|
+
"""
|
|
368
|
+
model = agent.model
|
|
369
|
+
return model if isinstance(model, str) else getattr(model, "model_name", str(model))
|
|
370
|
+
|
|
371
|
+
|
|
345
372
|
def _fold_turns(messages: list[UIMessage]) -> list[UIMessage]:
|
|
346
373
|
"""Merge each turn's assistant messages into one, as the stream builds them.
|
|
347
374
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{interloper_api-0.110.2 → interloper_api-0.112.0}/src/interloper_api/dependencies/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{interloper_api-0.110.2 → interloper_api-0.112.0}/src/interloper_api/notifications/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{interloper_api-0.110.2 → interloper_api-0.112.0}/src/interloper_api/notifications/invitations.py
RENAMED
|
File without changes
|
{interloper_api-0.110.2 → interloper_api-0.112.0}/src/interloper_api/notifications/super_admins.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{interloper_api-0.110.2 → interloper_api-0.112.0}/src/interloper_api/routes/organisations.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|