|
|
@@ -3,6 +3,7 @@ from typing import cast
|
|
|
|
|
|
from sqlalchemy.orm import Session
|
|
|
|
|
|
+from core_events import EventPublishContract, EventServiceClient, EventServiceClientError
|
|
|
from core_domain import (
|
|
|
AgentSkillRefContract,
|
|
|
AgentToolRefContract,
|
|
|
@@ -47,6 +48,7 @@ class AgentApplicationService:
|
|
|
memory_client: MemoryClient | None = None,
|
|
|
tool_client: ToolServiceClient | None = None,
|
|
|
skill_client: SkillServiceClient | None = None,
|
|
|
+ event_client: EventServiceClient | None = None,
|
|
|
) -> None:
|
|
|
self.agent_repository = agent_repository
|
|
|
self.agent_version_repository = agent_version_repository
|
|
|
@@ -55,6 +57,7 @@ class AgentApplicationService:
|
|
|
self.memory_client = memory_client
|
|
|
self.tool_client = tool_client
|
|
|
self.skill_client = skill_client
|
|
|
+ self.event_client = event_client
|
|
|
|
|
|
def create_agent(self, payload: AgentCreateRequest) -> AgentDefinition:
|
|
|
return self.agent_repository.create(
|
|
|
@@ -115,7 +118,7 @@ class AgentApplicationService:
|
|
|
if agent_version is None:
|
|
|
raise ValueError("published agent version not found")
|
|
|
|
|
|
- return self.agent_run_repository.create(
|
|
|
+ agent_run = self.agent_run_repository.create(
|
|
|
tenant_id=payload.tenant_id,
|
|
|
agent_id=payload.agent_id,
|
|
|
agent_version_id=agent_version.id,
|
|
|
@@ -123,6 +126,12 @@ class AgentApplicationService:
|
|
|
input_text=payload.input_text,
|
|
|
input_json=payload.input_json,
|
|
|
)
|
|
|
+ self._publish_event(
|
|
|
+ event_type="agent.run.created",
|
|
|
+ agent_run=agent_run,
|
|
|
+ payload_json={"agent_run_id": agent_run.id, "status": agent_run.status},
|
|
|
+ )
|
|
|
+ return agent_run
|
|
|
|
|
|
def list_agent_runs(
|
|
|
self,
|
|
|
@@ -207,7 +216,7 @@ class AgentApplicationService:
|
|
|
selected_skills=selected_skills,
|
|
|
),
|
|
|
)
|
|
|
- return self.agent_run_repository.update_status(
|
|
|
+ completed_run = self.agent_run_repository.update_status(
|
|
|
agent_run_id=agent_run.id,
|
|
|
status="completed",
|
|
|
worker_key=payload.worker_key,
|
|
|
@@ -229,6 +238,17 @@ class AgentApplicationService:
|
|
|
**memory_metadata,
|
|
|
},
|
|
|
)
|
|
|
+ if completed_run is not None:
|
|
|
+ self._publish_event(
|
|
|
+ event_type="agent.run.completed",
|
|
|
+ agent_run=completed_run,
|
|
|
+ payload_json={
|
|
|
+ "agent_run_id": completed_run.id,
|
|
|
+ "dry_run": True,
|
|
|
+ "status": completed_run.status,
|
|
|
+ },
|
|
|
+ )
|
|
|
+ return completed_run
|
|
|
|
|
|
tool_invocations = self._invoke_selected_tools(
|
|
|
agent_run=agent_run,
|
|
|
@@ -271,7 +291,10 @@ class AgentApplicationService:
|
|
|
agent_version.model_config_json,
|
|
|
"temperature",
|
|
|
),
|
|
|
- max_tokens=self._read_optional_int(agent_version.model_config_json, "max_tokens"),
|
|
|
+ max_tokens=self._read_optional_int(
|
|
|
+ agent_version.model_config_json,
|
|
|
+ "max_tokens",
|
|
|
+ ),
|
|
|
messages=messages,
|
|
|
metadata_json={
|
|
|
"tenant_id": agent_run.tenant_id,
|
|
|
@@ -295,7 +318,7 @@ class AgentApplicationService:
|
|
|
agent_version=agent_version,
|
|
|
output_text=response.content,
|
|
|
)
|
|
|
- return self.agent_run_repository.update_status(
|
|
|
+ completed_run = self.agent_run_repository.update_status(
|
|
|
agent_run_id=agent_run.id,
|
|
|
status="completed",
|
|
|
worker_key=payload.worker_key,
|
|
|
@@ -313,6 +336,45 @@ class AgentApplicationService:
|
|
|
**memory_write_metadata,
|
|
|
},
|
|
|
)
|
|
|
+ if completed_run is not None:
|
|
|
+ self._publish_event(
|
|
|
+ event_type="agent.run.completed",
|
|
|
+ agent_run=completed_run,
|
|
|
+ payload_json={
|
|
|
+ "agent_run_id": completed_run.id,
|
|
|
+ "dry_run": False,
|
|
|
+ "status": completed_run.status,
|
|
|
+ },
|
|
|
+ )
|
|
|
+ return completed_run
|
|
|
+
|
|
|
+ def _publish_event(
|
|
|
+ self,
|
|
|
+ *,
|
|
|
+ event_type: str,
|
|
|
+ agent_run: AgentRun,
|
|
|
+ payload_json: dict[str, JSONValue],
|
|
|
+ ) -> None:
|
|
|
+ if self.event_client is None:
|
|
|
+ return
|
|
|
+ try:
|
|
|
+ self.event_client.publish_event(
|
|
|
+ EventPublishContract(
|
|
|
+ tenant_id=agent_run.tenant_id,
|
|
|
+ event_type=event_type,
|
|
|
+ source_service="agent-service",
|
|
|
+ aggregate_type="agent_run",
|
|
|
+ aggregate_id=agent_run.id,
|
|
|
+ correlation_id=agent_run.session_id,
|
|
|
+ payload_json={
|
|
|
+ **payload_json,
|
|
|
+ "agent_id": agent_run.agent_id,
|
|
|
+ "agent_version_id": agent_run.agent_version_id,
|
|
|
+ },
|
|
|
+ )
|
|
|
+ )
|
|
|
+ except EventServiceClientError:
|
|
|
+ return
|
|
|
|
|
|
def execute_next_claimed_agent_run(
|
|
|
self,
|
|
|
@@ -372,7 +434,9 @@ class AgentApplicationService:
|
|
|
ChatMessageContract(role="system", content=agent_version.system_prompt),
|
|
|
]
|
|
|
if agent_version.goal:
|
|
|
- messages.append(ChatMessageContract(role="system", content=f"Goal: {agent_version.goal}"))
|
|
|
+ messages.append(
|
|
|
+ ChatMessageContract(role="system", content=f"Goal: {agent_version.goal}")
|
|
|
+ )
|
|
|
if memory_results:
|
|
|
messages.append(
|
|
|
ChatMessageContract(
|
|
|
@@ -891,4 +955,8 @@ def build_agent_application_service(
|
|
|
base_url=settings.skill_service_url,
|
|
|
timeout_seconds=settings.skill_service_timeout_seconds,
|
|
|
),
|
|
|
+ event_client=EventServiceClient(
|
|
|
+ base_url=settings.event_service_url,
|
|
|
+ timeout_seconds=settings.event_service_timeout_seconds,
|
|
|
+ ),
|
|
|
)
|