@odla-ai/ai 0.2.0 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +5 -0
- package/dist/{anthropic-JXDXR7O7.js → anthropic-BIGCVQE4.js} +57 -49
- package/dist/anthropic-BIGCVQE4.js.map +1 -0
- package/dist/{chunk-LANGYP65.js → chunk-QFT2DU2X.js} +4 -42
- package/dist/chunk-QFT2DU2X.js.map +1 -0
- package/dist/chunk-U7F6VJCV.js +9 -0
- package/dist/chunk-U7F6VJCV.js.map +1 -0
- package/dist/{google-3TFOFIQO.js → google-QY5B4T5O.js} +38 -29
- package/dist/google-QY5B4T5O.js.map +1 -0
- package/dist/index.cjs +206 -69
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +74 -64
- package/dist/index.d.ts +74 -64
- package/dist/index.js +40 -14
- package/dist/index.js.map +1 -1
- package/dist/{openai-XZRXMKCC.js → openai-PTZPJYTT.js} +40 -32
- package/dist/openai-PTZPJYTT.js.map +1 -0
- package/llms.txt +4 -0
- package/package.json +4 -4
- package/dist/anthropic-JXDXR7O7.js.map +0 -1
- package/dist/chunk-LANGYP65.js.map +0 -1
- package/dist/google-3TFOFIQO.js.map +0 -1
- package/dist/openai-XZRXMKCC.js.map +0 -1
package/dist/index.d.cts
CHANGED
|
@@ -83,6 +83,17 @@ interface OracleMessage {
|
|
|
83
83
|
* multi-modal / tool turns. */
|
|
84
84
|
content: string | OracleContentBlock[];
|
|
85
85
|
}
|
|
86
|
+
|
|
87
|
+
interface OracleUsage {
|
|
88
|
+
inputTokens: number;
|
|
89
|
+
outputTokens: number;
|
|
90
|
+
cacheCreationTokens?: number;
|
|
91
|
+
cacheReadTokens?: number;
|
|
92
|
+
}
|
|
93
|
+
declare function emptyUsage(): OracleUsage;
|
|
94
|
+
/** Accumulate `more` into `into`, in place. Cache fields sum when present. */
|
|
95
|
+
declare function addUsage(into: OracleUsage, more: OracleUsage): void;
|
|
96
|
+
|
|
86
97
|
interface OracleTool {
|
|
87
98
|
name: string;
|
|
88
99
|
description: string;
|
|
@@ -130,15 +141,6 @@ interface OracleRequest {
|
|
|
130
141
|
* portability across providers. */
|
|
131
142
|
providerExtras?: Record<string, unknown>;
|
|
132
143
|
}
|
|
133
|
-
interface OracleUsage {
|
|
134
|
-
inputTokens: number;
|
|
135
|
-
outputTokens: number;
|
|
136
|
-
cacheCreationTokens?: number;
|
|
137
|
-
cacheReadTokens?: number;
|
|
138
|
-
}
|
|
139
|
-
declare function emptyUsage(): OracleUsage;
|
|
140
|
-
/** Accumulate `more` into `into`, in place. Cache fields sum when present. */
|
|
141
|
-
declare function addUsage(into: OracleUsage, more: OracleUsage): void;
|
|
142
144
|
type OracleStopReason = "end_turn" | "max_tokens" | "stop_sequence" | "tool_use" | "pause_turn" | "refusal" | "error";
|
|
143
145
|
interface OracleResponse {
|
|
144
146
|
id: string;
|
|
@@ -150,59 +152,7 @@ interface OracleResponse {
|
|
|
150
152
|
stopReason: OracleStopReason;
|
|
151
153
|
usage: OracleUsage;
|
|
152
154
|
}
|
|
153
|
-
|
|
154
|
-
* provider. The anthropic adapter passes these through nearly 1:1; the openai
|
|
155
|
-
* and google adapters map their native streams onto this shape. */
|
|
156
|
-
type OracleEvent = MessageStartEvent | ContentBlockStartEvent | ContentBlockDeltaEvent | ContentBlockStopEvent | MessageDeltaEvent | MessageStopEvent | OracleErrorEvent;
|
|
157
|
-
interface MessageStartEvent {
|
|
158
|
-
type: "message_start";
|
|
159
|
-
message: {
|
|
160
|
-
id: string;
|
|
161
|
-
model: string;
|
|
162
|
-
provider: ProviderId;
|
|
163
|
-
role: "assistant";
|
|
164
|
-
content: [];
|
|
165
|
-
usage: OracleUsage;
|
|
166
|
-
};
|
|
167
|
-
}
|
|
168
|
-
interface ContentBlockStartEvent {
|
|
169
|
-
type: "content_block_start";
|
|
170
|
-
index: number;
|
|
171
|
-
contentBlock: OracleContentBlock;
|
|
172
|
-
}
|
|
173
|
-
type ContentBlockDelta = {
|
|
174
|
-
type: "text_delta";
|
|
175
|
-
text: string;
|
|
176
|
-
} | {
|
|
177
|
-
type: "thinking_delta";
|
|
178
|
-
thinking: string;
|
|
179
|
-
} | {
|
|
180
|
-
type: "input_json_delta";
|
|
181
|
-
partialJson: string;
|
|
182
|
-
};
|
|
183
|
-
interface ContentBlockDeltaEvent {
|
|
184
|
-
type: "content_block_delta";
|
|
185
|
-
index: number;
|
|
186
|
-
delta: ContentBlockDelta;
|
|
187
|
-
}
|
|
188
|
-
interface ContentBlockStopEvent {
|
|
189
|
-
type: "content_block_stop";
|
|
190
|
-
index: number;
|
|
191
|
-
}
|
|
192
|
-
interface MessageDeltaEvent {
|
|
193
|
-
type: "message_delta";
|
|
194
|
-
delta: {
|
|
195
|
-
stopReason?: OracleStopReason;
|
|
196
|
-
};
|
|
197
|
-
usage: OracleUsage;
|
|
198
|
-
}
|
|
199
|
-
interface MessageStopEvent {
|
|
200
|
-
type: "message_stop";
|
|
201
|
-
}
|
|
202
|
-
interface OracleErrorEvent {
|
|
203
|
-
type: "error";
|
|
204
|
-
error: OracleErrorShape;
|
|
205
|
-
}
|
|
155
|
+
|
|
206
156
|
/** The closed taxonomy of normalized error codes carried by every OdlaAIError
|
|
207
157
|
* and by the streaming `error` event. */
|
|
208
158
|
type OracleErrorType = "invalid_request" | "auth" | "rate_limit" | "context_window" | "tool_input_invalid" | "capability_unsupported" | "config" | "provider_error";
|
|
@@ -276,6 +226,61 @@ declare class ProviderError extends OdlaAIError {
|
|
|
276
226
|
cause?: unknown;
|
|
277
227
|
});
|
|
278
228
|
}
|
|
229
|
+
|
|
230
|
+
/** A discriminated union of SSE events with the same vocabulary regardless of
|
|
231
|
+
* provider. The anthropic adapter passes these through nearly 1:1; the openai
|
|
232
|
+
* and google adapters map their native streams onto this shape. */
|
|
233
|
+
type OracleEvent = MessageStartEvent | ContentBlockStartEvent | ContentBlockDeltaEvent | ContentBlockStopEvent | MessageDeltaEvent | MessageStopEvent | OracleErrorEvent;
|
|
234
|
+
interface MessageStartEvent {
|
|
235
|
+
type: "message_start";
|
|
236
|
+
message: {
|
|
237
|
+
id: string;
|
|
238
|
+
model: string;
|
|
239
|
+
provider: ProviderId;
|
|
240
|
+
role: "assistant";
|
|
241
|
+
content: [];
|
|
242
|
+
usage: OracleUsage;
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
interface ContentBlockStartEvent {
|
|
246
|
+
type: "content_block_start";
|
|
247
|
+
index: number;
|
|
248
|
+
contentBlock: OracleContentBlock;
|
|
249
|
+
}
|
|
250
|
+
type ContentBlockDelta = {
|
|
251
|
+
type: "text_delta";
|
|
252
|
+
text: string;
|
|
253
|
+
} | {
|
|
254
|
+
type: "thinking_delta";
|
|
255
|
+
thinking: string;
|
|
256
|
+
} | {
|
|
257
|
+
type: "input_json_delta";
|
|
258
|
+
partialJson: string;
|
|
259
|
+
};
|
|
260
|
+
interface ContentBlockDeltaEvent {
|
|
261
|
+
type: "content_block_delta";
|
|
262
|
+
index: number;
|
|
263
|
+
delta: ContentBlockDelta;
|
|
264
|
+
}
|
|
265
|
+
interface ContentBlockStopEvent {
|
|
266
|
+
type: "content_block_stop";
|
|
267
|
+
index: number;
|
|
268
|
+
}
|
|
269
|
+
interface MessageDeltaEvent {
|
|
270
|
+
type: "message_delta";
|
|
271
|
+
delta: {
|
|
272
|
+
stopReason?: OracleStopReason;
|
|
273
|
+
};
|
|
274
|
+
usage: OracleUsage;
|
|
275
|
+
}
|
|
276
|
+
interface MessageStopEvent {
|
|
277
|
+
type: "message_stop";
|
|
278
|
+
}
|
|
279
|
+
interface OracleErrorEvent {
|
|
280
|
+
type: "error";
|
|
281
|
+
error: OracleErrorShape;
|
|
282
|
+
}
|
|
283
|
+
|
|
279
284
|
declare function isTextBlock(b: OracleContentBlock): b is TextBlock;
|
|
280
285
|
declare function isImageBlock(b: OracleContentBlock): b is ImageBlock;
|
|
281
286
|
declare function isAudioBlock(b: OracleContentBlock): b is AudioBlock;
|
|
@@ -854,10 +859,15 @@ type OdlaOp = {
|
|
|
854
859
|
type OdlaQuery = Record<string, unknown>;
|
|
855
860
|
/** The subset of the odla-db Admin client odla-ai uses. */
|
|
856
861
|
interface OdlaDbClient {
|
|
857
|
-
/** Apply ops atomically; a stable `mutationId` gives exactly-once replay.
|
|
862
|
+
/** Apply ops atomically; a stable `mutationId` gives exactly-once replay.
|
|
863
|
+
* Mirrors odla-db 0.5's AdminDb: `duplicate` means the mutationId was
|
|
864
|
+
* already applied and the ops did not re-run. */
|
|
858
865
|
transact(ops: OdlaOp[], opts?: {
|
|
859
866
|
mutationId?: string;
|
|
860
|
-
}): Promise<
|
|
867
|
+
}): Promise<{
|
|
868
|
+
txId: number;
|
|
869
|
+
duplicate: boolean;
|
|
870
|
+
}>;
|
|
861
871
|
/** Run an InstaQL query; returns namespace → rows. */
|
|
862
872
|
query(query: OdlaQuery): Promise<Record<string, Record<string, unknown>[]>>;
|
|
863
873
|
/** Read one of this app's secrets by name (app-key credential; read-only). */
|
package/dist/index.d.ts
CHANGED
|
@@ -83,6 +83,17 @@ interface OracleMessage {
|
|
|
83
83
|
* multi-modal / tool turns. */
|
|
84
84
|
content: string | OracleContentBlock[];
|
|
85
85
|
}
|
|
86
|
+
|
|
87
|
+
interface OracleUsage {
|
|
88
|
+
inputTokens: number;
|
|
89
|
+
outputTokens: number;
|
|
90
|
+
cacheCreationTokens?: number;
|
|
91
|
+
cacheReadTokens?: number;
|
|
92
|
+
}
|
|
93
|
+
declare function emptyUsage(): OracleUsage;
|
|
94
|
+
/** Accumulate `more` into `into`, in place. Cache fields sum when present. */
|
|
95
|
+
declare function addUsage(into: OracleUsage, more: OracleUsage): void;
|
|
96
|
+
|
|
86
97
|
interface OracleTool {
|
|
87
98
|
name: string;
|
|
88
99
|
description: string;
|
|
@@ -130,15 +141,6 @@ interface OracleRequest {
|
|
|
130
141
|
* portability across providers. */
|
|
131
142
|
providerExtras?: Record<string, unknown>;
|
|
132
143
|
}
|
|
133
|
-
interface OracleUsage {
|
|
134
|
-
inputTokens: number;
|
|
135
|
-
outputTokens: number;
|
|
136
|
-
cacheCreationTokens?: number;
|
|
137
|
-
cacheReadTokens?: number;
|
|
138
|
-
}
|
|
139
|
-
declare function emptyUsage(): OracleUsage;
|
|
140
|
-
/** Accumulate `more` into `into`, in place. Cache fields sum when present. */
|
|
141
|
-
declare function addUsage(into: OracleUsage, more: OracleUsage): void;
|
|
142
144
|
type OracleStopReason = "end_turn" | "max_tokens" | "stop_sequence" | "tool_use" | "pause_turn" | "refusal" | "error";
|
|
143
145
|
interface OracleResponse {
|
|
144
146
|
id: string;
|
|
@@ -150,59 +152,7 @@ interface OracleResponse {
|
|
|
150
152
|
stopReason: OracleStopReason;
|
|
151
153
|
usage: OracleUsage;
|
|
152
154
|
}
|
|
153
|
-
|
|
154
|
-
* provider. The anthropic adapter passes these through nearly 1:1; the openai
|
|
155
|
-
* and google adapters map their native streams onto this shape. */
|
|
156
|
-
type OracleEvent = MessageStartEvent | ContentBlockStartEvent | ContentBlockDeltaEvent | ContentBlockStopEvent | MessageDeltaEvent | MessageStopEvent | OracleErrorEvent;
|
|
157
|
-
interface MessageStartEvent {
|
|
158
|
-
type: "message_start";
|
|
159
|
-
message: {
|
|
160
|
-
id: string;
|
|
161
|
-
model: string;
|
|
162
|
-
provider: ProviderId;
|
|
163
|
-
role: "assistant";
|
|
164
|
-
content: [];
|
|
165
|
-
usage: OracleUsage;
|
|
166
|
-
};
|
|
167
|
-
}
|
|
168
|
-
interface ContentBlockStartEvent {
|
|
169
|
-
type: "content_block_start";
|
|
170
|
-
index: number;
|
|
171
|
-
contentBlock: OracleContentBlock;
|
|
172
|
-
}
|
|
173
|
-
type ContentBlockDelta = {
|
|
174
|
-
type: "text_delta";
|
|
175
|
-
text: string;
|
|
176
|
-
} | {
|
|
177
|
-
type: "thinking_delta";
|
|
178
|
-
thinking: string;
|
|
179
|
-
} | {
|
|
180
|
-
type: "input_json_delta";
|
|
181
|
-
partialJson: string;
|
|
182
|
-
};
|
|
183
|
-
interface ContentBlockDeltaEvent {
|
|
184
|
-
type: "content_block_delta";
|
|
185
|
-
index: number;
|
|
186
|
-
delta: ContentBlockDelta;
|
|
187
|
-
}
|
|
188
|
-
interface ContentBlockStopEvent {
|
|
189
|
-
type: "content_block_stop";
|
|
190
|
-
index: number;
|
|
191
|
-
}
|
|
192
|
-
interface MessageDeltaEvent {
|
|
193
|
-
type: "message_delta";
|
|
194
|
-
delta: {
|
|
195
|
-
stopReason?: OracleStopReason;
|
|
196
|
-
};
|
|
197
|
-
usage: OracleUsage;
|
|
198
|
-
}
|
|
199
|
-
interface MessageStopEvent {
|
|
200
|
-
type: "message_stop";
|
|
201
|
-
}
|
|
202
|
-
interface OracleErrorEvent {
|
|
203
|
-
type: "error";
|
|
204
|
-
error: OracleErrorShape;
|
|
205
|
-
}
|
|
155
|
+
|
|
206
156
|
/** The closed taxonomy of normalized error codes carried by every OdlaAIError
|
|
207
157
|
* and by the streaming `error` event. */
|
|
208
158
|
type OracleErrorType = "invalid_request" | "auth" | "rate_limit" | "context_window" | "tool_input_invalid" | "capability_unsupported" | "config" | "provider_error";
|
|
@@ -276,6 +226,61 @@ declare class ProviderError extends OdlaAIError {
|
|
|
276
226
|
cause?: unknown;
|
|
277
227
|
});
|
|
278
228
|
}
|
|
229
|
+
|
|
230
|
+
/** A discriminated union of SSE events with the same vocabulary regardless of
|
|
231
|
+
* provider. The anthropic adapter passes these through nearly 1:1; the openai
|
|
232
|
+
* and google adapters map their native streams onto this shape. */
|
|
233
|
+
type OracleEvent = MessageStartEvent | ContentBlockStartEvent | ContentBlockDeltaEvent | ContentBlockStopEvent | MessageDeltaEvent | MessageStopEvent | OracleErrorEvent;
|
|
234
|
+
interface MessageStartEvent {
|
|
235
|
+
type: "message_start";
|
|
236
|
+
message: {
|
|
237
|
+
id: string;
|
|
238
|
+
model: string;
|
|
239
|
+
provider: ProviderId;
|
|
240
|
+
role: "assistant";
|
|
241
|
+
content: [];
|
|
242
|
+
usage: OracleUsage;
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
interface ContentBlockStartEvent {
|
|
246
|
+
type: "content_block_start";
|
|
247
|
+
index: number;
|
|
248
|
+
contentBlock: OracleContentBlock;
|
|
249
|
+
}
|
|
250
|
+
type ContentBlockDelta = {
|
|
251
|
+
type: "text_delta";
|
|
252
|
+
text: string;
|
|
253
|
+
} | {
|
|
254
|
+
type: "thinking_delta";
|
|
255
|
+
thinking: string;
|
|
256
|
+
} | {
|
|
257
|
+
type: "input_json_delta";
|
|
258
|
+
partialJson: string;
|
|
259
|
+
};
|
|
260
|
+
interface ContentBlockDeltaEvent {
|
|
261
|
+
type: "content_block_delta";
|
|
262
|
+
index: number;
|
|
263
|
+
delta: ContentBlockDelta;
|
|
264
|
+
}
|
|
265
|
+
interface ContentBlockStopEvent {
|
|
266
|
+
type: "content_block_stop";
|
|
267
|
+
index: number;
|
|
268
|
+
}
|
|
269
|
+
interface MessageDeltaEvent {
|
|
270
|
+
type: "message_delta";
|
|
271
|
+
delta: {
|
|
272
|
+
stopReason?: OracleStopReason;
|
|
273
|
+
};
|
|
274
|
+
usage: OracleUsage;
|
|
275
|
+
}
|
|
276
|
+
interface MessageStopEvent {
|
|
277
|
+
type: "message_stop";
|
|
278
|
+
}
|
|
279
|
+
interface OracleErrorEvent {
|
|
280
|
+
type: "error";
|
|
281
|
+
error: OracleErrorShape;
|
|
282
|
+
}
|
|
283
|
+
|
|
279
284
|
declare function isTextBlock(b: OracleContentBlock): b is TextBlock;
|
|
280
285
|
declare function isImageBlock(b: OracleContentBlock): b is ImageBlock;
|
|
281
286
|
declare function isAudioBlock(b: OracleContentBlock): b is AudioBlock;
|
|
@@ -854,10 +859,15 @@ type OdlaOp = {
|
|
|
854
859
|
type OdlaQuery = Record<string, unknown>;
|
|
855
860
|
/** The subset of the odla-db Admin client odla-ai uses. */
|
|
856
861
|
interface OdlaDbClient {
|
|
857
|
-
/** Apply ops atomically; a stable `mutationId` gives exactly-once replay.
|
|
862
|
+
/** Apply ops atomically; a stable `mutationId` gives exactly-once replay.
|
|
863
|
+
* Mirrors odla-db 0.5's AdminDb: `duplicate` means the mutationId was
|
|
864
|
+
* already applied and the ops did not re-run. */
|
|
858
865
|
transact(ops: OdlaOp[], opts?: {
|
|
859
866
|
mutationId?: string;
|
|
860
|
-
}): Promise<
|
|
867
|
+
}): Promise<{
|
|
868
|
+
txId: number;
|
|
869
|
+
duplicate: boolean;
|
|
870
|
+
}>;
|
|
861
871
|
/** Run an InstaQL query; returns namespace → rows. */
|
|
862
872
|
query(query: OdlaQuery): Promise<Record<string, Record<string, unknown>[]>>;
|
|
863
873
|
/** Read one of this app's secrets by name (app-key credential; read-only). */
|
package/dist/index.js
CHANGED
|
@@ -8,19 +8,41 @@ import {
|
|
|
8
8
|
ProviderError,
|
|
9
9
|
RateLimitError,
|
|
10
10
|
addUsage,
|
|
11
|
-
blocksOf,
|
|
12
11
|
emptyUsage,
|
|
13
|
-
extractText,
|
|
14
|
-
extractToolUses,
|
|
15
|
-
isAudioBlock,
|
|
16
|
-
isDocumentBlock,
|
|
17
|
-
isImageBlock,
|
|
18
|
-
isTextBlock,
|
|
19
|
-
isThinkingBlock,
|
|
20
|
-
isToolResultBlock,
|
|
21
|
-
isToolUseBlock,
|
|
22
12
|
normalizeError
|
|
23
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-QFT2DU2X.js";
|
|
14
|
+
|
|
15
|
+
// src/shape/helpers.ts
|
|
16
|
+
function isTextBlock(b) {
|
|
17
|
+
return b.type === "text";
|
|
18
|
+
}
|
|
19
|
+
function isImageBlock(b) {
|
|
20
|
+
return b.type === "image";
|
|
21
|
+
}
|
|
22
|
+
function isAudioBlock(b) {
|
|
23
|
+
return b.type === "audio";
|
|
24
|
+
}
|
|
25
|
+
function isDocumentBlock(b) {
|
|
26
|
+
return b.type === "document";
|
|
27
|
+
}
|
|
28
|
+
function isToolUseBlock(b) {
|
|
29
|
+
return b.type === "tool_use";
|
|
30
|
+
}
|
|
31
|
+
function isToolResultBlock(b) {
|
|
32
|
+
return b.type === "tool_result";
|
|
33
|
+
}
|
|
34
|
+
function isThinkingBlock(b) {
|
|
35
|
+
return b.type === "thinking";
|
|
36
|
+
}
|
|
37
|
+
function blocksOf(content) {
|
|
38
|
+
return typeof content === "string" ? [{ type: "text", text: content }] : content;
|
|
39
|
+
}
|
|
40
|
+
function extractText(content) {
|
|
41
|
+
return content.filter(isTextBlock).map((b) => b.text).join("");
|
|
42
|
+
}
|
|
43
|
+
function extractToolUses(content) {
|
|
44
|
+
return content.filter(isToolUseBlock);
|
|
45
|
+
}
|
|
24
46
|
|
|
25
47
|
// src/shape/capabilities.ts
|
|
26
48
|
function chatCapabilities(overrides = {}) {
|
|
@@ -250,17 +272,17 @@ async function getProvider(id, apiKey) {
|
|
|
250
272
|
let provider;
|
|
251
273
|
switch (id) {
|
|
252
274
|
case "anthropic": {
|
|
253
|
-
const { AnthropicProvider } = await import("./anthropic-
|
|
275
|
+
const { AnthropicProvider } = await import("./anthropic-BIGCVQE4.js");
|
|
254
276
|
provider = new AnthropicProvider(apiKey);
|
|
255
277
|
break;
|
|
256
278
|
}
|
|
257
279
|
case "openai": {
|
|
258
|
-
const { OpenAIProvider } = await import("./openai-
|
|
280
|
+
const { OpenAIProvider } = await import("./openai-PTZPJYTT.js");
|
|
259
281
|
provider = new OpenAIProvider(apiKey);
|
|
260
282
|
break;
|
|
261
283
|
}
|
|
262
284
|
case "google": {
|
|
263
|
-
const { GoogleProvider } = await import("./google-
|
|
285
|
+
const { GoogleProvider } = await import("./google-QY5B4T5O.js");
|
|
264
286
|
provider = new GoogleProvider(apiKey);
|
|
265
287
|
break;
|
|
266
288
|
}
|
|
@@ -386,6 +408,10 @@ function generateLlmsTxt(catalog = DEFAULT_CATALOG) {
|
|
|
386
408
|
const models = Object.values(catalog).map((s) => `- \`${s.id}\` (${s.provider}) \u2014 ${capsSummary(s.capabilities)}`).join("\n");
|
|
387
409
|
return `# @odla-ai/ai \u2014 LLM context
|
|
388
410
|
|
|
411
|
+
> EXPERIMENTAL \u2014 an agentic-coding experiment. This package is built and operated
|
|
412
|
+
> by autonomous coding agents as an experiment in agentic loops. APIs change
|
|
413
|
+
> without notice and nothing here is production-hardened. Use at your own risk.
|
|
414
|
+
|
|
389
415
|
One general-purpose interface for AI inference across Anthropic (Claude), OpenAI
|
|
390
416
|
(GPT), and Google (Gemini) \u2014 text, image, and audio \u2014 plus a tool-use agent
|
|
391
417
|
engine and an eval harness. Library-only: import in-process, bring your own keys.
|