bridge_common/repo/
abilities.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
// Copyright 2024 StarfleetAI
// SPDX-License-Identifier: Apache-2.0

use anyhow::Context;
use chrono::Utc;
use serde_json::json;
use sqlx::{query, query_as, Executor, Postgres};

use crate::{
    clients::openai::Function,
    types::{abilities::Ability, Result},
};

pub struct CreateParams {
    pub name: String,
    pub description: String,
    pub code: String,
    pub parameters_json: Function,
}

pub struct UpdateParams {
    pub id: i32,
    pub name: String,
    pub description: String,
    pub code: String,
    pub parameters_json: Function,
}

/// List abilities for agent.
///
/// # Errors
///
/// Returns error if there was a problem while accessing database.
pub async fn list_for_agent<'a, E>(
    executor: E,
    company_id: i32,
    agent_id: i32,
) -> Result<Vec<Ability>>
where
    E: Executor<'a, Database = Postgres>,
{
    Ok(query_as!(
        Ability,
        r#"
        SELECT abilities.*
        FROM abilities
        INNER JOIN agent_abilities ON abilities.id = agent_abilities.ability_id
        WHERE abilities.company_id = $1 AND agent_abilities.agent_id = $2
        "#,
        company_id,
        agent_id
    )
    .fetch_all(executor)
    .await?)
}

/// List all abilities.
///
/// # Errors
///
/// Returns error if there was a problem while accessing database.
pub async fn list<'a, E>(executor: E, company_id: i32) -> Result<Vec<Ability>>
where
    E: Executor<'a, Database = Postgres>,
{
    Ok(query_as!(
        Ability,
        "SELECT * FROM abilities WHERE company_id = $1 ORDER BY id DESC",
        company_id
    )
    .fetch_all(executor)
    .await?)
}

/// Create ability.
///
/// # Errors
///
/// Returns error if there was a problem while creating ability.
pub async fn create<'a, E>(executor: E, company_id: i32, params: CreateParams) -> Result<Ability>
where
    E: Executor<'a, Database = Postgres>,
{
    Ok(query_as!(
        Ability,
        r#"
        INSERT INTO abilities (company_id, name, description, code, parameters_json, created_at, updated_at)
        VALUES ($1, $2, $3, $4, $5, $6, $6)
        RETURNING *
        "#,
        company_id,
        params.name,
        params.description,
        params.code,
        json!(params.parameters_json),
        Utc::now()
    )
        .fetch_one(executor)
        .await?)
}

/// Update ability.
///
/// # Errors
///
/// Returns error if there was a problem while accessing database.
pub async fn update<'a, E>(executor: E, company_id: i32, params: UpdateParams) -> Result<Ability>
where
    E: Executor<'a, Database = Postgres>,
{
    Ok(query_as!(
        Ability,
        r#"
        UPDATE abilities
        SET name = $3, description = $4, code = $5, parameters_json = $6, updated_at = $7
        WHERE company_id = $1 AND id = $2
        RETURNING *
        "#,
        company_id,
        params.id,
        params.name,
        params.description,
        params.code,
        json!(params.parameters_json),
        Utc::now()
    )
    .fetch_one(executor)
    .await?)
}

/// Delete ability.
///
/// # Errors
///
/// Returns error if there was a problem while deleting ability.
pub async fn delete<'a, E>(executor: E, company_id: i32, id: i32) -> Result<()>
where
    E: Executor<'a, Database = Postgres>,
{
    query!(
        "DELETE FROM abilities WHERE company_id = $1 AND id = $2",
        company_id,
        id
    )
    .execute(executor)
    .await
    .with_context(|| "Failed to delete ability")?;

    Ok(())
}