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
// SPDX-License-Identifier: Apache-2.0
// Copyright (C) 2025 Michael Dippery <michael@monkey-robot.com>
//! Interfaces for AI provider API client implementations.
//!
//! These traits define the general behavior expected of all clients for
//! AI services. Generally they are implemented in individual provider
//! packages, such as [cogito-openai], so only service provider implementors
//! need worry about the nitty-gritty of this module.
//!
//! [cogito-openai]: https://docs.rs/cogito-openai
use crateAiModel;
pub use HttpError as AiError;
/// A client for an AI service's API.
///
/// API clients for specific AI services should adopt this trait to provide
/// a common interface for interacting with all AI services in a uniform manner.
/// A request to an AI service's API.
///
/// Different AI services may offer different options when making API requests,
/// and different [`AiClient`] implementations may offer different capabilities.
/// `AIRequest` offers a uniform way to make requests to AI services that
/// may differ slightly in behavior. If a service does not offer a particular
/// feature, then its `AIRequest` implementations can do nothing for calls
/// to the accompanying methods.
///
/// # Examples
///
/// This trait follows a "builder" pattern where elements of the request
/// are built up over time.
///
/// Assuming you have enum called `Model` that specifies available AI models
/// for your service, and a `ConcreteAPIRequest` struct that implements
/// `AIRequest`, you would create an API request like this:
///
/// ```
/// # use cogito::AiModel;
/// # use cogito::client::AiRequest;
/// #
/// # #[derive(Clone, Copy, Debug, Default)]
/// # pub enum Model {
/// # #[default]
/// # AIModel,
/// # }
/// #
/// # impl AiModel for Model {
/// # fn flagship() -> Self {
/// # Model::AIModel
/// # }
/// #
/// # fn best() -> Self {
/// # Model::AIModel
/// # }
/// #
/// # fn fastest() -> Self {
/// # Model::AIModel
/// # }
/// #
/// # fn cheapest() -> Self {
/// # Model::AIModel
/// # }
/// # }
/// #
/// # #[derive(Default)]
/// # pub struct ConcreteApiRequest;
/// #
/// # impl AiRequest for ConcreteApiRequest {
/// # type Model = Model;
/// # fn model(self, model: Self::Model) -> Self { self }
/// # fn instructions(self, instructions: impl Into<String>) -> Self { self }
/// # fn input(self, input: impl Into<String>) -> Self { self }
/// # }
/// #
/// let request = ConcreteApiRequest::default()
/// .model(Model::AIModel)
/// .instructions("Be really snarky.")
/// .input("How do I make an API request?");
/// ```
/// A response from an AI service's API.
/// An API result that includes the response if successful or an error
/// if unsuccessful.
pub type AiResult<T> = ;