Skip to main content

sim_lib_openai_server/
capabilities.rs

1use sim_kernel::{CapabilityName, Cx, Result};
2
3/// Capability id `openai-gateway.serve` for serving the OpenAI gateway.
4pub const OPENAI_GATEWAY_SERVE_CAPABILITY: &str = "openai-gateway.serve";
5/// Capability id `openai-gateway.admin` for gateway administration.
6pub const OPENAI_GATEWAY_ADMIN_CAPABILITY: &str = "openai-gateway.admin";
7/// Capability id `openai-gateway.plan` for local plan execution.
8pub const OPENAI_GATEWAY_PLAN_CAPABILITY: &str = "openai-gateway.plan";
9/// Capability id `openai-gateway.plan.remote` for remote plan execution.
10pub const OPENAI_GATEWAY_PLAN_REMOTE_CAPABILITY: &str = "openai-gateway.plan.remote";
11/// Capability id `openai-gateway.federate` for federating to peer gateways.
12pub const OPENAI_GATEWAY_FEDERATE_CAPABILITY: &str = "openai-gateway.federate";
13/// Capability id `openai-gateway.tools` for invoking gateway tools.
14pub const OPENAI_GATEWAY_TOOLS_CAPABILITY: &str = "openai-gateway.tools";
15/// Capability id `ai-runner-cache` for using the AI runner plan cache.
16pub const AI_RUNNER_CACHE_CAPABILITY: &str = "ai-runner-cache";
17/// Capability id `net/http` for outbound HTTP access.
18pub const NETWORK_CAPABILITY: &str = "net/http";
19/// Capability id `webhook-serve` for serving inbound webhook requests.
20pub const WEBHOOK_SERVE_CAPABILITY: &str = "webhook-serve";
21
22/// Returns the [`OPENAI_GATEWAY_SERVE_CAPABILITY`] as a [`CapabilityName`].
23pub fn openai_gateway_serve_capability() -> CapabilityName {
24    CapabilityName::new(OPENAI_GATEWAY_SERVE_CAPABILITY)
25}
26
27/// Returns the [`OPENAI_GATEWAY_ADMIN_CAPABILITY`] as a [`CapabilityName`].
28pub fn openai_gateway_admin_capability() -> CapabilityName {
29    CapabilityName::new(OPENAI_GATEWAY_ADMIN_CAPABILITY)
30}
31
32/// Returns the [`OPENAI_GATEWAY_PLAN_CAPABILITY`] as a [`CapabilityName`].
33pub fn openai_gateway_plan_capability() -> CapabilityName {
34    CapabilityName::new(OPENAI_GATEWAY_PLAN_CAPABILITY)
35}
36
37/// Returns the [`OPENAI_GATEWAY_PLAN_REMOTE_CAPABILITY`] as a [`CapabilityName`].
38pub fn openai_gateway_plan_remote_capability() -> CapabilityName {
39    CapabilityName::new(OPENAI_GATEWAY_PLAN_REMOTE_CAPABILITY)
40}
41
42/// Returns the [`OPENAI_GATEWAY_FEDERATE_CAPABILITY`] as a [`CapabilityName`].
43pub fn openai_gateway_federate_capability() -> CapabilityName {
44    CapabilityName::new(OPENAI_GATEWAY_FEDERATE_CAPABILITY)
45}
46
47/// Returns the [`OPENAI_GATEWAY_TOOLS_CAPABILITY`] as a [`CapabilityName`].
48pub fn openai_gateway_tools_capability() -> CapabilityName {
49    CapabilityName::new(OPENAI_GATEWAY_TOOLS_CAPABILITY)
50}
51
52/// Returns the [`AI_RUNNER_CACHE_CAPABILITY`] as a [`CapabilityName`].
53pub fn ai_runner_cache_capability() -> CapabilityName {
54    CapabilityName::new(AI_RUNNER_CACHE_CAPABILITY)
55}
56
57/// Returns the [`NETWORK_CAPABILITY`] as a [`CapabilityName`].
58pub fn network_capability() -> CapabilityName {
59    CapabilityName::new(NETWORK_CAPABILITY)
60}
61
62/// Returns the [`WEBHOOK_SERVE_CAPABILITY`] as a [`CapabilityName`].
63pub fn webhook_serve_capability() -> CapabilityName {
64    CapabilityName::new(WEBHOOK_SERVE_CAPABILITY)
65}
66
67/// Returns the capability set required to serve the OpenAI gateway: serve,
68/// net/http, and webhook-serve.
69pub fn openai_gateway_serve_capabilities() -> Vec<CapabilityName> {
70    vec![
71        openai_gateway_serve_capability(),
72        network_capability(),
73        webhook_serve_capability(),
74    ]
75}
76
77/// Requires the capabilities needed to serve the OpenAI gateway.
78pub fn require_openai_gateway_serve_capabilities(cx: &Cx) -> Result<()> {
79    cx.require(&openai_gateway_serve_capability())?;
80    require_with_aliases(cx, network_capability(), net_http_aliases())?;
81    cx.require(&webhook_serve_capability())
82}
83
84fn net_http_aliases() -> &'static [&'static str] {
85    &["net.http", "net-connect", "network"]
86}
87
88fn require_with_aliases(
89    cx: &Cx,
90    canonical: CapabilityName,
91    aliases: &'static [&'static str],
92) -> Result<()> {
93    if cx.capabilities().contains(&canonical)
94        || aliases
95            .iter()
96            .any(|alias| cx.capabilities().contains(&CapabilityName::new(*alias)))
97    {
98        Ok(())
99    } else {
100        Err(sim_kernel::Error::CapabilityDenied {
101            capability: canonical,
102        })
103    }
104}