refactor: reduce invocation helper arguments

This commit is contained in:
a.tolmachev
2026-03-30 09:40:11 +03:00
parent e4d2f6adc9
commit 0cec8cc826
2 changed files with 103 additions and 91 deletions
+66 -62
View File
@@ -317,6 +317,21 @@ pub struct OperationAgentRefView {
pub display_name: String, pub display_name: String,
} }
struct InvocationRecordRequest<'a> {
workspace_id: &'a WorkspaceId,
agent_id: Option<&'a AgentId>,
operation: &'a RegistryOperation,
source: InvocationSource,
level: InvocationLevel,
status: InvocationStatus,
message: String,
status_code: Option<u16>,
error_kind: Option<String>,
duration_ms: u64,
request_preview: Value,
response_preview: Value,
}
#[derive(Clone, Debug, Serialize)] #[derive(Clone, Debug, Serialize)]
pub struct OperationSummaryView { pub struct OperationSummaryView {
pub id: String, pub id: String,
@@ -1110,20 +1125,20 @@ impl AdminService {
match build_request_preview(&record.snapshot.input_mapping, &payload.input) { match build_request_preview(&record.snapshot.input_mapping, &payload.input) {
Ok(preview) => preview, Ok(preview) => preview,
Err(error) => { Err(error) => {
self.record_invocation( self.record_invocation(InvocationRecordRequest {
workspace_id, workspace_id,
None, agent_id: None,
&record.snapshot, operation: &record.snapshot,
InvocationSource::AdminTestRun, source: InvocationSource::AdminTestRun,
InvocationLevel::Error, level: InvocationLevel::Error,
InvocationStatus::Error, status: InvocationStatus::Error,
"mapping preview failed".to_owned(), message: "mapping preview failed".to_owned(),
None, status_code: None,
Some("mapping".to_owned()), error_kind: Some("mapping".to_owned()),
0, duration_ms: 0,
Value::Null, request_preview: Value::Null,
Value::Null, response_preview: Value::Null,
) })
.await?; .await?;
return Ok(TestRunResult { return Ok(TestRunResult {
ok: false, ok: false,
@@ -1141,20 +1156,20 @@ impl AdminService {
Ok(output) => { Ok(output) => {
let duration_ms = let duration_ms =
u64::try_from(started_at.elapsed().as_millis()).unwrap_or(u64::MAX); u64::try_from(started_at.elapsed().as_millis()).unwrap_or(u64::MAX);
self.record_invocation( self.record_invocation(InvocationRecordRequest {
workspace_id, workspace_id,
None, agent_id: None,
&record.snapshot, operation: &record.snapshot,
InvocationSource::AdminTestRun, source: InvocationSource::AdminTestRun,
InvocationLevel::Info, level: InvocationLevel::Info,
InvocationStatus::Ok, status: InvocationStatus::Ok,
"admin test run completed".to_owned(), message: "admin test run completed".to_owned(),
None, status_code: None,
None, error_kind: None,
duration_ms, duration_ms,
request_preview.clone(), request_preview: request_preview.clone(),
output.clone(), response_preview: output.clone(),
) })
.await?; .await?;
Ok(TestRunResult { Ok(TestRunResult {
ok: true, ok: true,
@@ -1166,20 +1181,20 @@ impl AdminService {
Err(error) => { Err(error) => {
let duration_ms = let duration_ms =
u64::try_from(started_at.elapsed().as_millis()).unwrap_or(u64::MAX); u64::try_from(started_at.elapsed().as_millis()).unwrap_or(u64::MAX);
self.record_invocation( self.record_invocation(InvocationRecordRequest {
workspace_id, workspace_id,
None, agent_id: None,
&record.snapshot, operation: &record.snapshot,
InvocationSource::AdminTestRun, source: InvocationSource::AdminTestRun,
InvocationLevel::Error, level: InvocationLevel::Error,
InvocationStatus::Error, status: InvocationStatus::Error,
error.to_string(), message: error.to_string(),
None, status_code: None,
Some(runtime_error_code(&error).to_owned()), error_kind: Some(runtime_error_code(&error).to_owned()),
duration_ms, duration_ms,
request_preview.clone(), request_preview: request_preview.clone(),
Value::Null, response_preview: Value::Null,
) })
.await?; .await?;
Ok(TestRunResult { Ok(TestRunResult {
ok: false, ok: false,
@@ -1996,35 +2011,24 @@ impl AdminService {
async fn record_invocation( async fn record_invocation(
&self, &self,
workspace_id: &WorkspaceId, request: InvocationRecordRequest<'_>,
agent_id: Option<&AgentId>,
operation: &RegistryOperation,
source: InvocationSource,
level: InvocationLevel,
status: InvocationStatus,
message: String,
status_code: Option<u16>,
error_kind: Option<String>,
duration_ms: u64,
request_preview: Value,
response_preview: Value,
) -> Result<(), ApiError> { ) -> Result<(), ApiError> {
let log = InvocationLog { let log = InvocationLog {
id: InvocationLogId::new(new_prefixed_id("log")), id: InvocationLogId::new(new_prefixed_id("log")),
workspace_id: workspace_id.clone(), workspace_id: request.workspace_id.clone(),
agent_id: agent_id.cloned(), agent_id: request.agent_id.cloned(),
operation_id: operation.id.clone(), operation_id: request.operation.id.clone(),
source, source: request.source,
level, level: request.level,
status, status: request.status,
tool_name: operation.name.clone(), tool_name: request.operation.name.clone(),
message, message: request.message,
request_id: None, request_id: None,
status_code, status_code: request.status_code,
duration_ms, duration_ms: request.duration_ms,
error_kind, error_kind: request.error_kind,
request_preview, request_preview: request.request_preview,
response_preview, response_preview: request.response_preview,
created_at: now_string()?, created_at: now_string()?,
}; };
+37 -29
View File
@@ -244,14 +244,16 @@ async fn mcp_post(
let _ = persist_invocation( let _ = persist_invocation(
&state, &state,
&tool, &tool,
InvocationStatus::Ok, InvocationRecord {
InvocationLevel::Info, status: InvocationStatus::Ok,
"agent tool call completed", level: InvocationLevel::Info,
None, message: "agent tool call completed",
None, status_code: None,
started_at.elapsed(), error_kind: None,
request_preview, duration: started_at.elapsed(),
output.clone(), request_preview,
response_preview: output.clone(),
},
) )
.await; .await;
jsonrpc_result( jsonrpc_result(
@@ -275,14 +277,16 @@ async fn mcp_post(
let _ = persist_invocation( let _ = persist_invocation(
&state, &state,
&tool, &tool,
InvocationStatus::Error, InvocationRecord {
InvocationLevel::Error, status: InvocationStatus::Error,
&error.to_string(), level: InvocationLevel::Error,
None, message: &error.to_string(),
Some(runtime_error_code(&error)), status_code: None,
started_at.elapsed(), error_kind: Some(runtime_error_code(&error)),
request_preview, duration: started_at.elapsed(),
Value::Null, request_preview,
response_preview: Value::Null,
},
) )
.await; .await;
json_response( json_response(
@@ -550,38 +554,42 @@ fn build_request_preview(
} }
} }
async fn persist_invocation( struct InvocationRecord<'a> {
state: &Arc<AppState>,
tool: &PublishedAgentTool,
status: InvocationStatus, status: InvocationStatus,
level: InvocationLevel, level: InvocationLevel,
message: &str, message: &'a str,
status_code: Option<u16>, status_code: Option<u16>,
error_kind: Option<&str>, error_kind: Option<&'a str>,
duration: Duration, duration: Duration,
request_preview: Value, request_preview: Value,
response_preview: Value, response_preview: Value,
}
async fn persist_invocation(
state: &Arc<AppState>,
tool: &PublishedAgentTool,
record: InvocationRecord<'_>,
) -> Result<(), crank_registry::RegistryError> { ) -> Result<(), crank_registry::RegistryError> {
let created_at = OffsetDateTime::now_utc() let created_at = OffsetDateTime::now_utc()
.format(&Rfc3339) .format(&Rfc3339)
.unwrap_or_else(|_| "1970-01-01T00:00:00Z".to_owned()); .unwrap_or_else(|_| "1970-01-01T00:00:00Z".to_owned());
let duration_ms = u64::try_from(duration.as_millis()).unwrap_or(u64::MAX); let duration_ms = u64::try_from(record.duration.as_millis()).unwrap_or(u64::MAX);
let log = InvocationLog { let log = InvocationLog {
id: InvocationLogId::new(format!("log_{}", uuid::Uuid::now_v7().simple())), id: InvocationLogId::new(format!("log_{}", uuid::Uuid::now_v7().simple())),
workspace_id: tool.workspace_id.clone(), workspace_id: tool.workspace_id.clone(),
agent_id: Some(tool.agent_id.clone()), agent_id: Some(tool.agent_id.clone()),
operation_id: tool.operation.id.clone(), operation_id: tool.operation.id.clone(),
source: InvocationSource::AgentToolCall, source: InvocationSource::AgentToolCall,
level, level: record.level,
status, status: record.status,
tool_name: tool.tool_name.clone(), tool_name: tool.tool_name.clone(),
message: message.to_owned(), message: record.message.to_owned(),
request_id: None, request_id: None,
status_code, status_code: record.status_code,
duration_ms, duration_ms,
error_kind: error_kind.map(ToOwned::to_owned), error_kind: record.error_kind.map(ToOwned::to_owned),
request_preview, request_preview: record.request_preview,
response_preview, response_preview: record.response_preview,
created_at, created_at,
}; };