Skip to content
Merged
52 changes: 52 additions & 0 deletions examples/add_agent_post_example.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import os
import uuid

from cvec import CVec
from cvec.models.agent_post import AgentPostRecommendation, AgentPostTag, Severity


def main() -> None:
# Initialize CVec client
cvec = CVec(
host=os.environ.get("CVEC_HOST", "https://your-subdomain.cvector.dev"),
api_key=os.environ.get("CVEC_API_KEY", "your-api-key"),
)

recommendations = [
AgentPostRecommendation(
content="Critical recommendation",
severity=Severity.CRITICAL,
),
AgentPostRecommendation(
content="Warning recommendation",
severity=Severity.WARNING,
),
AgentPostRecommendation(
content="Info recommendation",
severity=Severity.INFO,
),
]

tags = [
AgentPostTag(
content="urgent",
severity=Severity.CRITICAL,
),
AgentPostTag(
content="monitoring",
severity=Severity.INFO,
),
]

cvec.add_agent_post(
title="Test post",
author="Operational Agent",
image_id=str(uuid.uuid4()), # Replace with actual image UUID uploaded to S3
content="SDK add post test.",
recommendations=recommendations,
tags=tags,
)


if __name__ == "__main__":
main()
30 changes: 30 additions & 0 deletions src/cvec/cvec.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from urllib.parse import urlencode, urljoin
from urllib.request import Request, urlopen

from cvec.models.agent_post import AgentPost, AgentPostRecommendation, AgentPostTag
from cvec.models.eav_column import EAVColumn
from cvec.models.eav_filter import EAVFilter
from cvec.models.eav_table import EAVTable
Expand Down Expand Up @@ -426,6 +427,35 @@ def get_modeling_metrics_data_arrow(
assert isinstance(result, bytes)
return result

def add_agent_post(
self,
title: str,
author: str,
image_id: Optional[str] = None,
content: Optional[str] = None,
recommendations: Optional[List[AgentPostRecommendation]] = None,
tags: Optional[List[AgentPostTag]] = None,
) -> None:
"""
Add an agent post.

Note: If image_id is provided, the image must be uploaded to S3 beforehand.
The image_id should be the UUID used as the filename (without .png extension)
in the S3 bucket at the tenant's path.
"""

post = AgentPost(
title=title,
author=author,
image_id=image_id,
content=content,
recommendations=recommendations,
tags=tags,
)
payload = post.model_dump(mode="json", exclude_none=True)

self._make_request("POST", "/api/agent_posts/add", json_data=payload)

def _login_with_supabase(self, email: str, password: str) -> None:
"""
Login to Supabase and get access/refresh tokens.
Expand Down
10 changes: 10 additions & 0 deletions src/cvec/models/__init__.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,24 @@
from .agent_post import (
AgentPost,
AgentPostRecommendation,
AgentPostTag,
Severity,
)
from .eav_column import EAVColumn
from .eav_filter import EAVFilter
from .eav_table import EAVTable
from .metric import Metric, MetricDataPoint
from .span import Span

__all__ = [
"AgentPost",
"AgentPostRecommendation",
"AgentPostTag",
"EAVColumn",
"EAVFilter",
"EAVTable",
"Metric",
"MetricDataPoint",
"Severity",
"Span",
]
43 changes: 43 additions & 0 deletions src/cvec/models/agent_post.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
from enum import Enum
from typing import List, Optional

from pydantic import BaseModel, Field


class Severity(str, Enum):
"""Severity level for recommendations and tags."""

CRITICAL = "critical"
WARNING = "warning"
INFO = "info"


class AgentPostRecommendation(BaseModel):
"""
Represents a recommendation for creating an agent post.
"""

content: str = Field(..., min_length=1)
severity: Severity


class AgentPostTag(BaseModel):
"""
Represents a tag for creating an agent post.
"""

content: str = Field(..., min_length=1)
severity: Severity


class AgentPost(BaseModel):
"""
Represents an agent post with optional recommendations and tags.
"""

author: str
title: str
content: Optional[str] = None
image_id: Optional[str] = None
recommendations: Optional[List[AgentPostRecommendation]] = None
tags: Optional[List[AgentPostTag]] = None