conversation_api/execution/
context.rs1use serde::{Deserialize, Serialize};
4
5use crate::execution::{
6 ClientId, ConversationSurface, OperationId, RunId, ScopeId, TenantId, ThreadId, UserId,
7};
8
9#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
11#[serde(deny_unknown_fields)]
12pub struct Scope {
13 pub tenant_id: Option<TenantId>,
15 pub scope_id: ScopeId,
17}
18
19#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
21#[serde(deny_unknown_fields)]
22pub struct Actor {
23 pub principal: crate::ClientPrincipal,
25 pub credential_id: Option<String>,
27 pub client_id: Option<ClientId>,
29}
30
31impl Actor {
32 #[must_use]
33 pub fn user(user_id: impl Into<UserId>, client_id: Option<ClientId>) -> Self {
34 Self {
35 principal: crate::ClientPrincipal::User {
36 user_id: user_id.into().as_str().to_owned(),
37 },
38 credential_id: None,
39 client_id,
40 }
41 }
42
43 pub fn user_id(&self) -> Option<&str> {
44 self.principal.user_id()
45 }
46
47 pub fn valid_for(&self, scope: &Scope, surface: &ConversationSurface) -> bool {
49 if self
50 .client_id
51 .as_ref()
52 .is_some_and(|id| !valid_id(id.as_str()))
53 || self
54 .credential_id
55 .as_deref()
56 .is_some_and(|id| !valid_id(id))
57 {
58 return false;
59 }
60 match &self.principal {
61 crate::ClientPrincipal::User { user_id } => {
62 valid_id(user_id)
63 && !surface.is_space_clients()
64 && surface.user_id().is_none_or(|owner| owner == user_id)
65 }
66 crate::ClientPrincipal::Space { .. } => {
67 self.client_id.is_some()
68 && self.credential_id.is_some()
69 && self.principal.validate_for(
70 scope.tenant_id.as_ref().map_or("", |id| id.as_str()),
71 scope.scope_id.as_str(),
72 )
73 && surface.is_space_clients()
74 }
75 }
76 }
77}
78
79fn valid_id(value: &str) -> bool {
80 !value.is_empty() && value.trim() == value && !value.chars().any(char::is_control)
81}
82
83#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
85#[serde(deny_unknown_fields)]
86pub struct InvocationContext {
87 pub scope: Scope,
89 pub actor: Actor,
91 pub surface_id: ConversationSurface,
93 pub thread_id: ThreadId,
95 pub run_id: RunId,
97 pub operation_id: OperationId,
99 pub deadline_unix_ms: Option<u64>,
101 pub traceparent: Option<String>,
103}