@xandout/libra-harness 0.1.8
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 +486 -0
- package/dist/agent.d.ts +174 -0
- package/dist/agent.d.ts.map +1 -0
- package/dist/agent.js +575 -0
- package/dist/agent.js.map +1 -0
- package/dist/ai-sdk-model.d.ts +26 -0
- package/dist/ai-sdk-model.d.ts.map +1 -0
- package/dist/ai-sdk-model.js +260 -0
- package/dist/ai-sdk-model.js.map +1 -0
- package/dist/context.d.ts +75 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +2 -0
- package/dist/context.js.map +1 -0
- package/dist/errors.d.ts +33 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +59 -0
- package/dist/errors.js.map +1 -0
- package/dist/extension.d.ts +63 -0
- package/dist/extension.d.ts.map +1 -0
- package/dist/extension.js +2 -0
- package/dist/extension.js.map +1 -0
- package/dist/extras/extension-loader.d.ts +205 -0
- package/dist/extras/extension-loader.d.ts.map +1 -0
- package/dist/extras/extension-loader.js +315 -0
- package/dist/extras/extension-loader.js.map +1 -0
- package/dist/extras/extensions/auto-steer/extension.d.ts +46 -0
- package/dist/extras/extensions/auto-steer/extension.d.ts.map +1 -0
- package/dist/extras/extensions/auto-steer/extension.js +52 -0
- package/dist/extras/extensions/auto-steer/extension.js.map +1 -0
- package/dist/extras/extensions/auto-steer/extension.json +7 -0
- package/dist/extras/extensions/auto-steer/index.d.ts +3 -0
- package/dist/extras/extensions/auto-steer/index.d.ts.map +1 -0
- package/dist/extras/extensions/auto-steer/index.js +2 -0
- package/dist/extras/extensions/auto-steer/index.js.map +1 -0
- package/dist/extras/extensions/disk-session/extension.d.ts +167 -0
- package/dist/extras/extensions/disk-session/extension.d.ts.map +1 -0
- package/dist/extras/extensions/disk-session/extension.js +492 -0
- package/dist/extras/extensions/disk-session/extension.js.map +1 -0
- package/dist/extras/extensions/disk-session/extension.json +6 -0
- package/dist/extras/extensions/disk-session/extension.test.d.ts +2 -0
- package/dist/extras/extensions/disk-session/extension.test.d.ts.map +1 -0
- package/dist/extras/extensions/disk-session/extension.test.js +672 -0
- package/dist/extras/extensions/disk-session/extension.test.js.map +1 -0
- package/dist/extras/extensions/disk-session/index.d.ts +3 -0
- package/dist/extras/extensions/disk-session/index.d.ts.map +1 -0
- package/dist/extras/extensions/disk-session/index.js +2 -0
- package/dist/extras/extensions/disk-session/index.js.map +1 -0
- package/dist/extras/extensions/emoji/extension.d.ts +20 -0
- package/dist/extras/extensions/emoji/extension.d.ts.map +1 -0
- package/dist/extras/extensions/emoji/extension.js +22 -0
- package/dist/extras/extensions/emoji/extension.js.map +1 -0
- package/dist/extras/extensions/emoji/extension.json +7 -0
- package/dist/extras/extensions/emoji/index.d.ts +3 -0
- package/dist/extras/extensions/emoji/index.d.ts.map +1 -0
- package/dist/extras/extensions/emoji/index.js +2 -0
- package/dist/extras/extensions/emoji/index.js.map +1 -0
- package/dist/extras/extensions/filesystem/extension.d.ts +53 -0
- package/dist/extras/extensions/filesystem/extension.d.ts.map +1 -0
- package/dist/extras/extensions/filesystem/extension.js +350 -0
- package/dist/extras/extensions/filesystem/extension.js.map +1 -0
- package/dist/extras/extensions/filesystem/extension.json +6 -0
- package/dist/extras/extensions/filesystem/extension.test.d.ts +2 -0
- package/dist/extras/extensions/filesystem/extension.test.d.ts.map +1 -0
- package/dist/extras/extensions/filesystem/extension.test.js +387 -0
- package/dist/extras/extensions/filesystem/extension.test.js.map +1 -0
- package/dist/extras/extensions/filesystem/index.d.ts +2 -0
- package/dist/extras/extensions/filesystem/index.d.ts.map +1 -0
- package/dist/extras/extensions/filesystem/index.js +2 -0
- package/dist/extras/extensions/filesystem/index.js.map +1 -0
- package/dist/extras/extensions/keyword-extractor/extension.d.ts +53 -0
- package/dist/extras/extensions/keyword-extractor/extension.d.ts.map +1 -0
- package/dist/extras/extensions/keyword-extractor/extension.js +61 -0
- package/dist/extras/extensions/keyword-extractor/extension.js.map +1 -0
- package/dist/extras/extensions/keyword-extractor/extension.json +6 -0
- package/dist/extras/extensions/keyword-extractor/extension.test.d.ts +2 -0
- package/dist/extras/extensions/keyword-extractor/extension.test.d.ts.map +1 -0
- package/dist/extras/extensions/keyword-extractor/extension.test.js +105 -0
- package/dist/extras/extensions/keyword-extractor/extension.test.js.map +1 -0
- package/dist/extras/extensions/keyword-extractor/index.d.ts +5 -0
- package/dist/extras/extensions/keyword-extractor/index.d.ts.map +1 -0
- package/dist/extras/extensions/keyword-extractor/index.js +3 -0
- package/dist/extras/extensions/keyword-extractor/index.js.map +1 -0
- package/dist/extras/extensions/keyword-extractor/nlp.d.ts +68 -0
- package/dist/extras/extensions/keyword-extractor/nlp.d.ts.map +1 -0
- package/dist/extras/extensions/keyword-extractor/nlp.js +156 -0
- package/dist/extras/extensions/keyword-extractor/nlp.js.map +1 -0
- package/dist/extras/extensions/keyword-extractor/nlp.test.d.ts +2 -0
- package/dist/extras/extensions/keyword-extractor/nlp.test.d.ts.map +1 -0
- package/dist/extras/extensions/keyword-extractor/nlp.test.js +176 -0
- package/dist/extras/extensions/keyword-extractor/nlp.test.js.map +1 -0
- package/dist/extras/extensions/logger/extension.d.ts +52 -0
- package/dist/extras/extensions/logger/extension.d.ts.map +1 -0
- package/dist/extras/extensions/logger/extension.js +68 -0
- package/dist/extras/extensions/logger/extension.js.map +1 -0
- package/dist/extras/extensions/logger/extension.json +7 -0
- package/dist/extras/extensions/logger/index.d.ts +3 -0
- package/dist/extras/extensions/logger/index.d.ts.map +1 -0
- package/dist/extras/extensions/logger/index.js +2 -0
- package/dist/extras/extensions/logger/index.js.map +1 -0
- package/dist/extras/extensions/mcp/extension.d.ts +63 -0
- package/dist/extras/extensions/mcp/extension.d.ts.map +1 -0
- package/dist/extras/extensions/mcp/extension.js +437 -0
- package/dist/extras/extensions/mcp/extension.js.map +1 -0
- package/dist/extras/extensions/mcp/extension.json +7 -0
- package/dist/extras/extensions/mcp/extension.test.d.ts +2 -0
- package/dist/extras/extensions/mcp/extension.test.d.ts.map +1 -0
- package/dist/extras/extensions/mcp/extension.test.js +286 -0
- package/dist/extras/extensions/mcp/extension.test.js.map +1 -0
- package/dist/extras/extensions/mcp/index.d.ts +3 -0
- package/dist/extras/extensions/mcp/index.d.ts.map +1 -0
- package/dist/extras/extensions/mcp/index.js +2 -0
- package/dist/extras/extensions/mcp/index.js.map +1 -0
- package/dist/extras/extensions/mem-session/extension.d.ts +24 -0
- package/dist/extras/extensions/mem-session/extension.d.ts.map +1 -0
- package/dist/extras/extensions/mem-session/extension.js +49 -0
- package/dist/extras/extensions/mem-session/extension.js.map +1 -0
- package/dist/extras/extensions/mem-session/extension.json +6 -0
- package/dist/extras/extensions/mem-session/index.d.ts +2 -0
- package/dist/extras/extensions/mem-session/index.d.ts.map +1 -0
- package/dist/extras/extensions/mem-session/index.js +2 -0
- package/dist/extras/extensions/mem-session/index.js.map +1 -0
- package/dist/extras/extensions/memory/extension.d.ts +54 -0
- package/dist/extras/extensions/memory/extension.d.ts.map +1 -0
- package/dist/extras/extensions/memory/extension.js +143 -0
- package/dist/extras/extensions/memory/extension.js.map +1 -0
- package/dist/extras/extensions/memory/extension.json +7 -0
- package/dist/extras/extensions/memory/index.d.ts +5 -0
- package/dist/extras/extensions/memory/index.d.ts.map +1 -0
- package/dist/extras/extensions/memory/index.js +3 -0
- package/dist/extras/extensions/memory/index.js.map +1 -0
- package/dist/extras/extensions/memory/llm-extractor.d.ts +42 -0
- package/dist/extras/extensions/memory/llm-extractor.d.ts.map +1 -0
- package/dist/extras/extensions/memory/llm-extractor.js +89 -0
- package/dist/extras/extensions/memory/llm-extractor.js.map +1 -0
- package/dist/extras/extensions/memory/types.d.ts +142 -0
- package/dist/extras/extensions/memory/types.d.ts.map +1 -0
- package/dist/extras/extensions/memory/types.js +2 -0
- package/dist/extras/extensions/memory/types.js.map +1 -0
- package/dist/extras/extensions/otel/extension.d.ts +57 -0
- package/dist/extras/extensions/otel/extension.d.ts.map +1 -0
- package/dist/extras/extensions/otel/extension.js +253 -0
- package/dist/extras/extensions/otel/extension.js.map +1 -0
- package/dist/extras/extensions/otel/extension.json +7 -0
- package/dist/extras/extensions/otel/extension.test.d.ts +2 -0
- package/dist/extras/extensions/otel/extension.test.d.ts.map +1 -0
- package/dist/extras/extensions/otel/extension.test.js +399 -0
- package/dist/extras/extensions/otel/extension.test.js.map +1 -0
- package/dist/extras/extensions/otel/index.d.ts +4 -0
- package/dist/extras/extensions/otel/index.d.ts.map +1 -0
- package/dist/extras/extensions/otel/index.js +3 -0
- package/dist/extras/extensions/otel/index.js.map +1 -0
- package/dist/extras/extensions/otel/jsonl-span-exporter.d.ts +60 -0
- package/dist/extras/extensions/otel/jsonl-span-exporter.d.ts.map +1 -0
- package/dist/extras/extensions/otel/jsonl-span-exporter.js +134 -0
- package/dist/extras/extensions/otel/jsonl-span-exporter.js.map +1 -0
- package/dist/extras/extensions/scripts/extension.d.ts +180 -0
- package/dist/extras/extensions/scripts/extension.d.ts.map +1 -0
- package/dist/extras/extensions/scripts/extension.js +618 -0
- package/dist/extras/extensions/scripts/extension.js.map +1 -0
- package/dist/extras/extensions/scripts/extension.json +7 -0
- package/dist/extras/extensions/scripts/extension.test.d.ts +2 -0
- package/dist/extras/extensions/scripts/extension.test.d.ts.map +1 -0
- package/dist/extras/extensions/scripts/extension.test.js +552 -0
- package/dist/extras/extensions/scripts/extension.test.js.map +1 -0
- package/dist/extras/extensions/scripts/index.d.ts +3 -0
- package/dist/extras/extensions/scripts/index.d.ts.map +1 -0
- package/dist/extras/extensions/scripts/index.js +2 -0
- package/dist/extras/extensions/scripts/index.js.map +1 -0
- package/dist/extras/extensions/skills/extension.d.ts +105 -0
- package/dist/extras/extensions/skills/extension.d.ts.map +1 -0
- package/dist/extras/extensions/skills/extension.js +419 -0
- package/dist/extras/extensions/skills/extension.js.map +1 -0
- package/dist/extras/extensions/skills/extension.json +7 -0
- package/dist/extras/extensions/skills/extension.test.d.ts +2 -0
- package/dist/extras/extensions/skills/extension.test.d.ts.map +1 -0
- package/dist/extras/extensions/skills/extension.test.js +184 -0
- package/dist/extras/extensions/skills/extension.test.js.map +1 -0
- package/dist/extras/extensions/skills/index.d.ts +4 -0
- package/dist/extras/extensions/skills/index.d.ts.map +1 -0
- package/dist/extras/extensions/skills/index.js +3 -0
- package/dist/extras/extensions/skills/index.js.map +1 -0
- package/dist/extras/extensions/streaming/extension.d.ts +15 -0
- package/dist/extras/extensions/streaming/extension.d.ts.map +1 -0
- package/dist/extras/extensions/streaming/extension.js +41 -0
- package/dist/extras/extensions/streaming/extension.js.map +1 -0
- package/dist/extras/extensions/streaming/extension.json +6 -0
- package/dist/extras/extensions/streaming/index.d.ts +2 -0
- package/dist/extras/extensions/streaming/index.d.ts.map +1 -0
- package/dist/extras/extensions/streaming/index.js +2 -0
- package/dist/extras/extensions/streaming/index.js.map +1 -0
- package/dist/extras/extensions/structured-output/extension.d.ts +11 -0
- package/dist/extras/extensions/structured-output/extension.d.ts.map +1 -0
- package/dist/extras/extensions/structured-output/extension.js +102 -0
- package/dist/extras/extensions/structured-output/extension.js.map +1 -0
- package/dist/extras/extensions/structured-output/extension.json +7 -0
- package/dist/extras/extensions/structured-output/index.d.ts +3 -0
- package/dist/extras/extensions/structured-output/index.d.ts.map +1 -0
- package/dist/extras/extensions/structured-output/index.js +2 -0
- package/dist/extras/extensions/structured-output/index.js.map +1 -0
- package/dist/extras/extensions/timestamp/extension.d.ts +11 -0
- package/dist/extras/extensions/timestamp/extension.d.ts.map +1 -0
- package/dist/extras/extensions/timestamp/extension.js +21 -0
- package/dist/extras/extensions/timestamp/extension.js.map +1 -0
- package/dist/extras/extensions/timestamp/extension.json +6 -0
- package/dist/extras/extensions/timestamp/index.d.ts +2 -0
- package/dist/extras/extensions/timestamp/index.d.ts.map +1 -0
- package/dist/extras/extensions/timestamp/index.js +2 -0
- package/dist/extras/extensions/timestamp/index.js.map +1 -0
- package/dist/extras/extensions/token-stats/extension.d.ts +50 -0
- package/dist/extras/extensions/token-stats/extension.d.ts.map +1 -0
- package/dist/extras/extensions/token-stats/extension.js +99 -0
- package/dist/extras/extensions/token-stats/extension.js.map +1 -0
- package/dist/extras/extensions/token-stats/extension.json +7 -0
- package/dist/extras/extensions/token-stats/extension.test.d.ts +2 -0
- package/dist/extras/extensions/token-stats/extension.test.d.ts.map +1 -0
- package/dist/extras/extensions/token-stats/extension.test.js +197 -0
- package/dist/extras/extensions/token-stats/extension.test.js.map +1 -0
- package/dist/extras/extensions/token-stats/index.d.ts +3 -0
- package/dist/extras/extensions/token-stats/index.d.ts.map +1 -0
- package/dist/extras/extensions/token-stats/index.js +2 -0
- package/dist/extras/extensions/token-stats/index.js.map +1 -0
- package/dist/extras/extensions/tool-buffer/extension.d.ts +89 -0
- package/dist/extras/extensions/tool-buffer/extension.d.ts.map +1 -0
- package/dist/extras/extensions/tool-buffer/extension.js +182 -0
- package/dist/extras/extensions/tool-buffer/extension.js.map +1 -0
- package/dist/extras/extensions/tool-buffer/extension.json +7 -0
- package/dist/extras/extensions/tool-buffer/extension.test.d.ts +2 -0
- package/dist/extras/extensions/tool-buffer/extension.test.d.ts.map +1 -0
- package/dist/extras/extensions/tool-buffer/extension.test.js +549 -0
- package/dist/extras/extensions/tool-buffer/extension.test.js.map +1 -0
- package/dist/extras/extensions/tool-buffer/index.d.ts +3 -0
- package/dist/extras/extensions/tool-buffer/index.d.ts.map +1 -0
- package/dist/extras/extensions/tool-buffer/index.js +2 -0
- package/dist/extras/extensions/tool-buffer/index.js.map +1 -0
- package/dist/extras/extensions/weather-tool/extension.d.ts +22 -0
- package/dist/extras/extensions/weather-tool/extension.d.ts.map +1 -0
- package/dist/extras/extensions/weather-tool/extension.js +33 -0
- package/dist/extras/extensions/weather-tool/extension.js.map +1 -0
- package/dist/extras/extensions/weather-tool/extension.json +7 -0
- package/dist/extras/extensions/weather-tool/index.d.ts +3 -0
- package/dist/extras/extensions/weather-tool/index.d.ts.map +1 -0
- package/dist/extras/extensions/weather-tool/index.js +2 -0
- package/dist/extras/extensions/weather-tool/index.js.map +1 -0
- package/dist/extras/models/ai-sdk-resolver.d.ts +15 -0
- package/dist/extras/models/ai-sdk-resolver.d.ts.map +1 -0
- package/dist/extras/models/ai-sdk-resolver.js +57 -0
- package/dist/extras/models/ai-sdk-resolver.js.map +1 -0
- package/dist/extras/models/index.d.ts +5 -0
- package/dist/extras/models/index.d.ts.map +1 -0
- package/dist/extras/models/index.js +3 -0
- package/dist/extras/models/index.js.map +1 -0
- package/dist/extras/models/routing-model.d.ts +18 -0
- package/dist/extras/models/routing-model.d.ts.map +1 -0
- package/dist/extras/models/routing-model.js +24 -0
- package/dist/extras/models/routing-model.js.map +1 -0
- package/dist/extras/openai-provider/index.d.ts +3 -0
- package/dist/extras/openai-provider/index.d.ts.map +1 -0
- package/dist/extras/openai-provider/index.js +2 -0
- package/dist/extras/openai-provider/index.js.map +1 -0
- package/dist/extras/openai-provider/server.d.ts +34 -0
- package/dist/extras/openai-provider/server.d.ts.map +1 -0
- package/dist/extras/openai-provider/server.js +335 -0
- package/dist/extras/openai-provider/server.js.map +1 -0
- package/dist/handle.d.ts +56 -0
- package/dist/handle.d.ts.map +1 -0
- package/dist/handle.js +2 -0
- package/dist/handle.js.map +1 -0
- package/dist/hooks.d.ts +98 -0
- package/dist/hooks.d.ts.map +1 -0
- package/dist/hooks.js +53 -0
- package/dist/hooks.js.map +1 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/dist/model.d.ts +75 -0
- package/dist/model.d.ts.map +1 -0
- package/dist/model.js +2 -0
- package/dist/model.js.map +1 -0
- package/dist/tool.d.ts +78 -0
- package/dist/tool.d.ts.map +1 -0
- package/dist/tool.js +78 -0
- package/dist/tool.js.map +1 -0
- package/dist/types.d.ts +83 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +21 -0
- package/dist/types.js.map +1 -0
- package/package.json +178 -0
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* weather-tool extension — registers a `get_weather` tool.
|
|
3
|
+
*
|
|
4
|
+
* Demonstrates the simplest tool-registering extension. Accepts an
|
|
5
|
+
* optional `fetchWeather` function via config for real API integration.
|
|
6
|
+
*/
|
|
7
|
+
export default function createWeatherToolExtension(config) {
|
|
8
|
+
const fetchWeather = config?.fetchWeather ??
|
|
9
|
+
(async (city) => `It's 72\u00b0F and sunny in ${city}.`);
|
|
10
|
+
return {
|
|
11
|
+
name: 'weather-tool',
|
|
12
|
+
priority: 50,
|
|
13
|
+
install(agent) {
|
|
14
|
+
agent.tool({
|
|
15
|
+
name: 'get_weather',
|
|
16
|
+
description: 'Get the current weather for a city.',
|
|
17
|
+
parameters: {
|
|
18
|
+
type: 'object',
|
|
19
|
+
properties: {
|
|
20
|
+
city: { type: 'string', description: 'The city name' },
|
|
21
|
+
},
|
|
22
|
+
required: ['city'],
|
|
23
|
+
},
|
|
24
|
+
async execute(args) {
|
|
25
|
+
const city = args.city;
|
|
26
|
+
const content = await fetchWeather(city);
|
|
27
|
+
return { toolCallId: '', content };
|
|
28
|
+
},
|
|
29
|
+
});
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=extension.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extension.js","sourceRoot":"","sources":["../../../../src/extras/extensions/weather-tool/extension.ts"],"names":[],"mappings":"AAgBA;;;;;GAKG;AACH,MAAM,CAAC,OAAO,UAAU,0BAA0B,CAChD,MAA0B;IAE1B,MAAM,YAAY,GAChB,MAAM,EAAE,YAAY;QACpB,CAAC,KAAK,EAAE,IAAY,EAAE,EAAE,CAAC,+BAA+B,IAAI,GAAG,CAAC,CAAC;IAEnE,OAAO;QACL,IAAI,EAAE,cAAc;QACpB,QAAQ,EAAE,EAAE;QACZ,OAAO,CAAC,KAAK;YACX,KAAK,CAAC,IAAI,CAAC;gBACT,IAAI,EAAE,aAAa;gBACnB,WAAW,EAAE,qCAAqC;gBAClD,UAAU,EAAE;oBACV,IAAI,EAAE,QAAQ;oBACd,UAAU,EAAE;wBACV,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,eAAe,EAAE;qBACvD;oBACD,QAAQ,EAAE,CAAC,MAAM,CAAC;iBACnB;gBACD,KAAK,CAAC,OAAO,CAAC,IAAI;oBAChB,MAAM,IAAI,GAAG,IAAI,CAAC,IAAc,CAAC;oBACjC,MAAM,OAAO,GAAG,MAAM,YAAY,CAAC,IAAI,CAAC,CAAC;oBACzC,OAAO,EAAE,UAAU,EAAE,EAAE,EAAE,OAAO,EAAE,CAAC;gBACrC,CAAC;aACF,CAAC,CAAC;QACL,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/extras/extensions/weather-tool/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,0BAA0B,EAAE,MAAM,gBAAgB,CAAC;AACvE,YAAY,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/extras/extensions/weather-tool/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,0BAA0B,EAAE,MAAM,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { LanguageModelV4 } from '@ai-sdk/provider';
|
|
2
|
+
import type { Model } from '../../model.js';
|
|
3
|
+
export type AISdkProviderFactory = (modelId: string) => LanguageModelV4;
|
|
4
|
+
export interface AISdkProviderDefinition {
|
|
5
|
+
envVar: string;
|
|
6
|
+
load(): Promise<AISdkProviderFactory>;
|
|
7
|
+
}
|
|
8
|
+
export interface ResolveModelOptions {
|
|
9
|
+
env?: Readonly<Record<string, string | undefined>>;
|
|
10
|
+
providers?: Readonly<Record<string, AISdkProviderDefinition>>;
|
|
11
|
+
}
|
|
12
|
+
export declare const nativeAISdkProviders: Readonly<Record<string, AISdkProviderDefinition>>;
|
|
13
|
+
export declare function resolveModel(modelId: string, options?: ResolveModelOptions): Promise<Model>;
|
|
14
|
+
export declare function configuredProviders(env?: Readonly<Record<string, string | undefined>>, providers?: Readonly<Record<string, AISdkProviderDefinition>>): string[];
|
|
15
|
+
//# sourceMappingURL=ai-sdk-resolver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai-sdk-resolver.d.ts","sourceRoot":"","sources":["../../../src/extras/models/ai-sdk-resolver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAExD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAE5C,MAAM,MAAM,oBAAoB,GAAG,CAAC,OAAO,EAAE,MAAM,KAAK,eAAe,CAAC;AAExE,MAAM,WAAW,uBAAuB;IACtC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,IAAI,OAAO,CAAC,oBAAoB,CAAC,CAAC;CACvC;AAED,MAAM,WAAW,mBAAmB;IAClC,GAAG,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC;IACnD,SAAS,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,uBAAuB,CAAC,CAAC,CAAC;CAC/D;AAED,eAAO,MAAM,oBAAoB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,uBAAuB,CAAC,CA6BlF,CAAC;AAEF,wBAAsB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,mBAAwB,GAAG,OAAO,CAAC,KAAK,CAAC,CAqBrG;AAED,wBAAgB,mBAAmB,CACjC,GAAG,GAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAe,EAC/D,SAAS,GAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,uBAAuB,CAAC,CAAwB,GAClF,MAAM,EAAE,CAKV"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { AISdkModel } from '../../ai-sdk-model.js';
|
|
2
|
+
export const nativeAISdkProviders = {
|
|
3
|
+
openai: {
|
|
4
|
+
envVar: 'OPENAI_API_KEY',
|
|
5
|
+
async load() {
|
|
6
|
+
const { openai } = await import('@ai-sdk/openai');
|
|
7
|
+
return openai;
|
|
8
|
+
},
|
|
9
|
+
},
|
|
10
|
+
anthropic: {
|
|
11
|
+
envVar: 'ANTHROPIC_API_KEY',
|
|
12
|
+
async load() {
|
|
13
|
+
const { anthropic } = await import('@ai-sdk/anthropic');
|
|
14
|
+
return anthropic;
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
google: {
|
|
18
|
+
envVar: 'GOOGLE_GENERATIVE_AI_API_KEY',
|
|
19
|
+
async load() {
|
|
20
|
+
const { google } = await import('@ai-sdk/google');
|
|
21
|
+
return google;
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
deepseek: {
|
|
25
|
+
envVar: 'DEEPSEEK_API_KEY',
|
|
26
|
+
async load() {
|
|
27
|
+
const { deepseek } = await import('@ai-sdk/deepseek');
|
|
28
|
+
return deepseek;
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
export async function resolveModel(modelId, options = {}) {
|
|
33
|
+
const separator = modelId.indexOf('/');
|
|
34
|
+
if (separator <= 0 || separator === modelId.length - 1) {
|
|
35
|
+
throw new Error(`Invalid model ID "${modelId}". Expected "provider/model".`);
|
|
36
|
+
}
|
|
37
|
+
const providerId = modelId.slice(0, separator);
|
|
38
|
+
const providerModelId = modelId.slice(separator + 1);
|
|
39
|
+
const providers = options.providers ?? nativeAISdkProviders;
|
|
40
|
+
const definition = providers[providerId];
|
|
41
|
+
if (!definition) {
|
|
42
|
+
throw new Error(`Unsupported provider "${providerId}". Supported providers: ${Object.keys(providers).sort().join(', ')}.`);
|
|
43
|
+
}
|
|
44
|
+
const env = options.env ?? process.env;
|
|
45
|
+
if (!env[definition.envVar]?.trim()) {
|
|
46
|
+
throw new Error(`Cannot resolve "${modelId}": ${definition.envVar} is not configured.`);
|
|
47
|
+
}
|
|
48
|
+
const provider = await definition.load();
|
|
49
|
+
return new AISdkModel(provider(providerModelId));
|
|
50
|
+
}
|
|
51
|
+
export function configuredProviders(env = process.env, providers = nativeAISdkProviders) {
|
|
52
|
+
return Object.entries(providers)
|
|
53
|
+
.filter(([, definition]) => Boolean(env[definition.envVar]?.trim()))
|
|
54
|
+
.map(([providerId]) => providerId)
|
|
55
|
+
.sort();
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=ai-sdk-resolver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai-sdk-resolver.js","sourceRoot":"","sources":["../../../src/extras/models/ai-sdk-resolver.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAenD,MAAM,CAAC,MAAM,oBAAoB,GAAsD;IACrF,MAAM,EAAE;QACN,MAAM,EAAE,gBAAgB;QACxB,KAAK,CAAC,IAAI;YACR,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,gBAAgB,CAAC,CAAC;YAClD,OAAO,MAAM,CAAC;QAChB,CAAC;KACF;IACD,SAAS,EAAE;QACT,MAAM,EAAE,mBAAmB;QAC3B,KAAK,CAAC,IAAI;YACR,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,MAAM,CAAC,mBAAmB,CAAC,CAAC;YACxD,OAAO,SAAS,CAAC;QACnB,CAAC;KACF;IACD,MAAM,EAAE;QACN,MAAM,EAAE,8BAA8B;QACtC,KAAK,CAAC,IAAI;YACR,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,gBAAgB,CAAC,CAAC;YAClD,OAAO,MAAM,CAAC;QAChB,CAAC;KACF;IACD,QAAQ,EAAE;QACR,MAAM,EAAE,kBAAkB;QAC1B,KAAK,CAAC,IAAI;YACR,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,MAAM,CAAC,kBAAkB,CAAC,CAAC;YACtD,OAAO,QAAQ,CAAC;QAClB,CAAC;KACF;CACF,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,OAAe,EAAE,OAAO,GAAwB,EAAE;IACnF,MAAM,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACvC,IAAI,SAAS,IAAI,CAAC,IAAI,SAAS,KAAK,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvD,MAAM,IAAI,KAAK,CAAC,qBAAqB,OAAO,+BAA+B,CAAC,CAAC;IAC/E,CAAC;IAED,MAAM,UAAU,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;IAC/C,MAAM,eAAe,GAAG,OAAO,CAAC,KAAK,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC;IACrD,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,oBAAoB,CAAC;IAC5D,MAAM,UAAU,GAAG,SAAS,CAAC,UAAU,CAAC,CAAC;IACzC,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,MAAM,IAAI,KAAK,CAAC,yBAAyB,UAAU,2BAA2B,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC7H,CAAC;IAED,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC;IACvC,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,EAAE,CAAC;QACpC,MAAM,IAAI,KAAK,CAAC,mBAAmB,OAAO,MAAM,UAAU,CAAC,MAAM,qBAAqB,CAAC,CAAC;IAC1F,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,UAAU,CAAC,IAAI,EAAE,CAAC;IACzC,OAAO,IAAI,UAAU,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC,CAAC;AACnD,CAAC;AAED,MAAM,UAAU,mBAAmB,CACjC,GAAG,GAAiD,OAAO,CAAC,GAAG,EAC/D,SAAS,GAAsD,oBAAoB;IAEnF,OAAO,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC;SAC7B,MAAM,CAAC,CAAC,CAAC,EAAE,UAAU,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;SACnE,GAAG,CAAC,CAAC,CAAC,UAAU,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC;SACjC,IAAI,EAAE,CAAC;AACZ,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { configuredProviders, nativeAISdkProviders, resolveModel, } from './ai-sdk-resolver.js';
|
|
2
|
+
export type { AISdkProviderDefinition, AISdkProviderFactory, ResolveModelOptions, } from './ai-sdk-resolver.js';
|
|
3
|
+
export { createRoutingModel, hasFileInput, hasImageInput, RoutingModel, } from './routing-model.js';
|
|
4
|
+
export type { ModelRoute, RoutingModelConfig } from './routing-model.js';
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/extras/models/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mBAAmB,EACnB,oBAAoB,EACpB,YAAY,GACb,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EACV,uBAAuB,EACvB,oBAAoB,EACpB,mBAAmB,GACpB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,kBAAkB,EAClB,YAAY,EACZ,aAAa,EACb,YAAY,GACb,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/extras/models/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mBAAmB,EACnB,oBAAoB,EACpB,YAAY,GACb,MAAM,sBAAsB,CAAC;AAM9B,OAAO,EACL,kBAAkB,EAClB,YAAY,EACZ,aAAa,EACb,YAAY,GACb,MAAM,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { Model, ModelRequest, ModelResponse } from '../../model.js';
|
|
2
|
+
export interface ModelRoute {
|
|
3
|
+
when(request: ModelRequest): boolean | Promise<boolean>;
|
|
4
|
+
model: Model;
|
|
5
|
+
}
|
|
6
|
+
export interface RoutingModelConfig {
|
|
7
|
+
default: Model;
|
|
8
|
+
routes: readonly ModelRoute[];
|
|
9
|
+
}
|
|
10
|
+
export declare class RoutingModel implements Model {
|
|
11
|
+
private readonly config;
|
|
12
|
+
constructor(config: RoutingModelConfig);
|
|
13
|
+
generate(request: ModelRequest): Promise<ModelResponse>;
|
|
14
|
+
}
|
|
15
|
+
export declare function createRoutingModel(config: RoutingModelConfig): Model;
|
|
16
|
+
export declare function hasFileInput(request: ModelRequest): boolean;
|
|
17
|
+
export declare function hasImageInput(request: ModelRequest): boolean;
|
|
18
|
+
//# sourceMappingURL=routing-model.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"routing-model.d.ts","sourceRoot":"","sources":["../../../src/extras/models/routing-model.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAGzE,MAAM,WAAW,UAAU;IACzB,IAAI,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACxD,KAAK,EAAE,KAAK,CAAC;CACd;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,KAAK,CAAC;IACf,MAAM,EAAE,SAAS,UAAU,EAAE,CAAC;CAC/B;AAED,qBAAa,YAAa,YAAW,KAAK;IAC5B,OAAO,CAAC,QAAQ,CAAC,MAAM;IAAnC,YAA6B,MAAM,EAAE,kBAAkB,EAAI;IAErD,QAAQ,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,aAAa,CAAC,CAK5D;CACF;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,kBAAkB,GAAG,KAAK,CAEpE;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAE3D;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAE5D"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { hasFileContent } from '../../types.js';
|
|
2
|
+
export class RoutingModel {
|
|
3
|
+
config;
|
|
4
|
+
constructor(config) {
|
|
5
|
+
this.config = config;
|
|
6
|
+
}
|
|
7
|
+
async generate(request) {
|
|
8
|
+
for (const route of this.config.routes) {
|
|
9
|
+
if (await route.when(request))
|
|
10
|
+
return route.model.generate(request);
|
|
11
|
+
}
|
|
12
|
+
return this.config.default.generate(request);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
export function createRoutingModel(config) {
|
|
16
|
+
return new RoutingModel(config);
|
|
17
|
+
}
|
|
18
|
+
export function hasFileInput(request) {
|
|
19
|
+
return request.messages.some((message) => hasFileContent(message.content));
|
|
20
|
+
}
|
|
21
|
+
export function hasImageInput(request) {
|
|
22
|
+
return request.messages.some((message) => hasFileContent(message.content, 'image/'));
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=routing-model.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"routing-model.js","sourceRoot":"","sources":["../../../src/extras/models/routing-model.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAYhD,MAAM,OAAO,YAAY;IACM,MAAM;IAAnC,YAA6B,MAA0B;sBAA1B,MAAM;IAAuB,CAAC;IAE3D,KAAK,CAAC,QAAQ,CAAC,OAAqB;QAClC,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;YACvC,IAAI,MAAM,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC;gBAAE,OAAO,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QACtE,CAAC;QACD,OAAO,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IAC/C,CAAC;CACF;AAED,MAAM,UAAU,kBAAkB,CAAC,MAA0B;IAC3D,OAAO,IAAI,YAAY,CAAC,MAAM,CAAC,CAAC;AAClC,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,OAAqB;IAChD,OAAO,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,cAAc,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC;AAC7E,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,OAAqB;IACjD,OAAO,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,cAAc,CAAC,OAAO,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC;AACvF,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/extras/openai-provider/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,4BAA4B,EAAE,MAAM,aAAa,CAAC;AAC3D,YAAY,EAAE,8BAA8B,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/extras/openai-provider/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,4BAA4B,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { type Server } from 'node:http';
|
|
2
|
+
import { Agent } from '../../agent.js';
|
|
3
|
+
export interface OpenAICompatibleProviderConfig {
|
|
4
|
+
agents: Readonly<Record<string, Agent>>;
|
|
5
|
+
apiKeys: readonly string[];
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Create an OpenAI-compatible HTTP server that exposes Libra agents as models.
|
|
9
|
+
*
|
|
10
|
+
* Each agent in the `agents` record becomes an OpenAI model ID. The server
|
|
11
|
+
* implements `GET /v1/models` and `POST /v1/chat/completions` with bearer/x-api-key
|
|
12
|
+
* authentication, text and image content, SSE streaming, and client-defined
|
|
13
|
+
* (external) tool calling.
|
|
14
|
+
*
|
|
15
|
+
* The HTTP server stays out of the core agent — this is an adapter/extra, not
|
|
16
|
+
* part of the agent harness itself. Use it when you want to expose Libra agents
|
|
17
|
+
* to OpenAI-compatible frameworks and SDKs.
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```typescript
|
|
21
|
+
* import { Agent } from '@xandout/libra-harness';
|
|
22
|
+
* import { createOpenAICompatibleServer } from '@xandout/libra-harness/extras/openai-provider';
|
|
23
|
+
*
|
|
24
|
+
* const server = createOpenAICompatibleServer({
|
|
25
|
+
* agents: {
|
|
26
|
+
* 'my-agent': new Agent({ model, systemPrompt: 'You are helpful.' }),
|
|
27
|
+
* },
|
|
28
|
+
* apiKeys: ['your-provider-key'],
|
|
29
|
+
* });
|
|
30
|
+
* server.listen(8787, '127.0.0.1');
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
export declare function createOpenAICompatibleServer(config: OpenAICompatibleProviderConfig): Server;
|
|
34
|
+
//# sourceMappingURL=server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../../src/extras/openai-provider/server.ts"],"names":[],"mappings":"AACA,OAAO,EAAsC,KAAK,MAAM,EAAuB,MAAM,WAAW,CAAC;AACjG,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AA8CvC,MAAM,WAAW,8BAA8B;IAC7C,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC;IACxC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;CAC5B;AAoSD;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,4BAA4B,CAAC,MAAM,EAAE,8BAA8B,GAAG,MAAM,CAc3F"}
|
|
@@ -0,0 +1,335 @@
|
|
|
1
|
+
import { randomUUID, timingSafeEqual } from 'node:crypto';
|
|
2
|
+
import { createServer } from 'node:http';
|
|
3
|
+
const HISTORY_KEY = 'openaiCompatibleProviderMessages';
|
|
4
|
+
const MAX_BODY_BYTES = 10_485_760;
|
|
5
|
+
const preparedAgents = new WeakSet();
|
|
6
|
+
class ApiError extends Error {
|
|
7
|
+
status;
|
|
8
|
+
type;
|
|
9
|
+
code;
|
|
10
|
+
param;
|
|
11
|
+
constructor(status, message, type = 'invalid_request_error', code = null, param = null) {
|
|
12
|
+
super(message);
|
|
13
|
+
this.status = status;
|
|
14
|
+
this.type = type;
|
|
15
|
+
this.code = code;
|
|
16
|
+
this.param = param;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
function prepareAgent(agent) {
|
|
20
|
+
if (preparedAgents.has(agent))
|
|
21
|
+
return;
|
|
22
|
+
agent.hook('beforeContext', 'openai-compatible-provider', async (ctx) => {
|
|
23
|
+
const messages = ctx.turn.metadata[HISTORY_KEY];
|
|
24
|
+
if (!Array.isArray(messages))
|
|
25
|
+
return;
|
|
26
|
+
ctx.turn.messages.splice(0, ctx.turn.messages.length, ...messages);
|
|
27
|
+
});
|
|
28
|
+
preparedAgents.add(agent);
|
|
29
|
+
}
|
|
30
|
+
const DATA_URL_RE = /^data:([^;,]+)?(;base64)?,(.*)$/s;
|
|
31
|
+
const EXT_TO_MEDIA = {
|
|
32
|
+
png: 'image/png', jpg: 'image/jpeg', jpeg: 'image/jpeg', gif: 'image/gif',
|
|
33
|
+
webp: 'image/webp', bmp: 'image/bmp', svg: 'image/svg+xml',
|
|
34
|
+
};
|
|
35
|
+
function mediaTypeFromUrl(url) {
|
|
36
|
+
try {
|
|
37
|
+
const ext = new URL(url).pathname.split('.').pop()?.toLowerCase() ?? '';
|
|
38
|
+
return EXT_TO_MEDIA[ext] ?? 'image/png';
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
return 'image/png';
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
function toFileData(imageUrl) {
|
|
45
|
+
const match = imageUrl.match(DATA_URL_RE);
|
|
46
|
+
if (match) {
|
|
47
|
+
const mediaType = match[1] || 'image/png';
|
|
48
|
+
const isBase64 = Boolean(match[2]);
|
|
49
|
+
const payload = match[3];
|
|
50
|
+
if (isBase64)
|
|
51
|
+
return { mediaType, data: { type: 'data', data: payload } };
|
|
52
|
+
return { mediaType, data: { type: 'data', data: decodeURIComponent(payload) } };
|
|
53
|
+
}
|
|
54
|
+
return { mediaType: mediaTypeFromUrl(imageUrl), data: { type: 'url', url: imageUrl } };
|
|
55
|
+
}
|
|
56
|
+
function toLibraContent(content, param) {
|
|
57
|
+
if (typeof content === 'string')
|
|
58
|
+
return content;
|
|
59
|
+
if (content === null)
|
|
60
|
+
return '';
|
|
61
|
+
if (!Array.isArray(content))
|
|
62
|
+
throw new ApiError(400, 'Message content must be a string or content-part array.', 'invalid_request_error', null, param);
|
|
63
|
+
const parts = [];
|
|
64
|
+
for (let i = 0; i < content.length; i++) {
|
|
65
|
+
const part = content[i];
|
|
66
|
+
const partParam = `${param}.${i}`;
|
|
67
|
+
if (part.type === 'text') {
|
|
68
|
+
if (typeof part.text !== 'string')
|
|
69
|
+
throw new ApiError(400, 'text part must include a string "text".', 'invalid_request_error', null, partParam);
|
|
70
|
+
parts.push({ type: 'text', text: part.text });
|
|
71
|
+
}
|
|
72
|
+
else if (part.type === 'image_url') {
|
|
73
|
+
const url = part.image_url?.url;
|
|
74
|
+
if (typeof url !== 'string' || !url)
|
|
75
|
+
throw new ApiError(400, 'image_url part must include image_url.url.', 'invalid_request_error', null, partParam);
|
|
76
|
+
const { mediaType, data } = toFileData(url);
|
|
77
|
+
parts.push({ type: 'file', mediaType, data });
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
throw new ApiError(400, `Unsupported content part type: ${part.type}. Supported: text, image_url.`, 'invalid_request_error', null, partParam);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
return parts;
|
|
84
|
+
}
|
|
85
|
+
function contentToText(content, param) {
|
|
86
|
+
const result = toLibraContent(content, param);
|
|
87
|
+
if (typeof result === 'string')
|
|
88
|
+
return result;
|
|
89
|
+
return result.filter((p) => p.type === 'text').map((p) => p.text).join('');
|
|
90
|
+
}
|
|
91
|
+
function toLibraMessages(messages) {
|
|
92
|
+
if (messages.length === 0)
|
|
93
|
+
throw new ApiError(400, 'messages must not be empty.', 'invalid_request_error', null, 'messages');
|
|
94
|
+
return messages.map((message, index) => {
|
|
95
|
+
const param = `messages.${index}`;
|
|
96
|
+
if (message.role === 'developer' || message.role === 'system') {
|
|
97
|
+
return { role: 'system', content: contentToText(message.content, `${param}.content`) };
|
|
98
|
+
}
|
|
99
|
+
if (message.role === 'user') {
|
|
100
|
+
return { role: 'user', content: toLibraContent(message.content, `${param}.content`) };
|
|
101
|
+
}
|
|
102
|
+
if (message.role === 'assistant') {
|
|
103
|
+
const content = contentToText(message.content, `${param}.content`);
|
|
104
|
+
const toolCalls = message.tool_calls?.map((tc) => ({
|
|
105
|
+
id: tc.id,
|
|
106
|
+
name: tc.function.name,
|
|
107
|
+
arguments: tc.function.arguments,
|
|
108
|
+
}));
|
|
109
|
+
return { role: 'assistant', content, ...(toolCalls?.length && { toolCalls }) };
|
|
110
|
+
}
|
|
111
|
+
if (message.role === 'tool' && message.tool_call_id) {
|
|
112
|
+
return { role: 'tool', content: contentToText(message.content, `${param}.content`), toolCallId: message.tool_call_id, name: message.name };
|
|
113
|
+
}
|
|
114
|
+
throw new ApiError(400, `Unsupported message role: ${message.role}`, 'invalid_request_error', null, `${param}.role`);
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
function toExternalTools(tools) {
|
|
118
|
+
return tools.map((tool) => {
|
|
119
|
+
if (tool.type !== 'function' || !tool.function?.name) {
|
|
120
|
+
throw new ApiError(400, 'Each tool must be type "function" with a function.name.', 'invalid_request_error', null, 'tools');
|
|
121
|
+
}
|
|
122
|
+
return {
|
|
123
|
+
name: tool.function.name,
|
|
124
|
+
...(tool.function.description && { description: tool.function.description }),
|
|
125
|
+
parameters: tool.function.parameters ?? { type: 'object', properties: {} },
|
|
126
|
+
external: true,
|
|
127
|
+
// Never called — external tools are returned to the caller.
|
|
128
|
+
async execute() {
|
|
129
|
+
return { toolCallId: '', content: 'External tool — executed by the caller.' };
|
|
130
|
+
},
|
|
131
|
+
};
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
function safeEqual(actual, expected) {
|
|
135
|
+
const actualBytes = Buffer.from(actual);
|
|
136
|
+
const expectedBytes = Buffer.from(expected);
|
|
137
|
+
return actualBytes.length === expectedBytes.length && timingSafeEqual(actualBytes, expectedBytes);
|
|
138
|
+
}
|
|
139
|
+
function requestApiKey(req) {
|
|
140
|
+
const authorization = req.headers.authorization;
|
|
141
|
+
if (authorization?.startsWith('Bearer '))
|
|
142
|
+
return authorization.slice(7);
|
|
143
|
+
const header = req.headers['x-api-key'];
|
|
144
|
+
return Array.isArray(header) ? header[0] : header;
|
|
145
|
+
}
|
|
146
|
+
function authenticate(req, apiKeys) {
|
|
147
|
+
const candidate = requestApiKey(req);
|
|
148
|
+
return candidate !== undefined && apiKeys.some((key) => safeEqual(candidate, key));
|
|
149
|
+
}
|
|
150
|
+
async function readJson(req) {
|
|
151
|
+
req.setEncoding('utf8');
|
|
152
|
+
let body = '';
|
|
153
|
+
for await (const chunk of req) {
|
|
154
|
+
body += chunk;
|
|
155
|
+
if (Buffer.byteLength(body) > MAX_BODY_BYTES)
|
|
156
|
+
throw new ApiError(413, 'Request body is too large.', 'invalid_request_error');
|
|
157
|
+
}
|
|
158
|
+
try {
|
|
159
|
+
return JSON.parse(body || '{}');
|
|
160
|
+
}
|
|
161
|
+
catch {
|
|
162
|
+
throw new ApiError(400, 'Request body must be valid JSON.', 'invalid_request_error');
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
function sendJson(res, status, body, headers = {}) {
|
|
166
|
+
res.writeHead(status, {
|
|
167
|
+
'content-type': 'application/json; charset=utf-8',
|
|
168
|
+
'cache-control': 'no-store',
|
|
169
|
+
...headers,
|
|
170
|
+
});
|
|
171
|
+
res.end(JSON.stringify(body));
|
|
172
|
+
}
|
|
173
|
+
function sendError(res, error) {
|
|
174
|
+
sendJson(res, error.status, {
|
|
175
|
+
error: {
|
|
176
|
+
message: error.message,
|
|
177
|
+
type: error.type,
|
|
178
|
+
param: error.param,
|
|
179
|
+
code: error.code,
|
|
180
|
+
},
|
|
181
|
+
}, error.status === 401 ? { 'www-authenticate': 'Bearer' } : {});
|
|
182
|
+
}
|
|
183
|
+
function completionId() {
|
|
184
|
+
return `chatcmpl-${randomUUID().replaceAll('-', '')}`;
|
|
185
|
+
}
|
|
186
|
+
function openAICompletion(id, created, model, content, finishReason, toolCalls) {
|
|
187
|
+
const message = { role: 'assistant', content };
|
|
188
|
+
if (toolCalls?.length) {
|
|
189
|
+
message.tool_calls = toolCalls.map((tc) => ({
|
|
190
|
+
id: tc.id,
|
|
191
|
+
type: 'function',
|
|
192
|
+
function: { name: tc.name, arguments: tc.arguments },
|
|
193
|
+
}));
|
|
194
|
+
}
|
|
195
|
+
return {
|
|
196
|
+
id,
|
|
197
|
+
object: 'chat.completion',
|
|
198
|
+
created,
|
|
199
|
+
model,
|
|
200
|
+
choices: [{ index: 0, message, finish_reason: finishReason }],
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
function sendStream(res, id, created, model, content, finishReason, toolCalls) {
|
|
204
|
+
res.writeHead(200, {
|
|
205
|
+
'content-type': 'text/event-stream; charset=utf-8',
|
|
206
|
+
'cache-control': 'no-cache, no-transform',
|
|
207
|
+
connection: 'keep-alive',
|
|
208
|
+
});
|
|
209
|
+
const chunk = (delta, finish_reason) => {
|
|
210
|
+
res.write(`data: ${JSON.stringify({
|
|
211
|
+
id,
|
|
212
|
+
object: 'chat.completion.chunk',
|
|
213
|
+
created,
|
|
214
|
+
model,
|
|
215
|
+
choices: [{ index: 0, delta, finish_reason }],
|
|
216
|
+
})}\n\n`);
|
|
217
|
+
};
|
|
218
|
+
chunk({ role: 'assistant' }, null);
|
|
219
|
+
if (content)
|
|
220
|
+
chunk({ content }, null);
|
|
221
|
+
if (toolCalls?.length) {
|
|
222
|
+
for (const tc of toolCalls) {
|
|
223
|
+
chunk({ tool_calls: [{ index: 0, id: tc.id, type: 'function', function: { name: tc.name, arguments: tc.arguments } }] }, null);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
chunk({}, finishReason);
|
|
227
|
+
res.end('data: [DONE]\n\n');
|
|
228
|
+
}
|
|
229
|
+
async function handleRequest(req, res, agents, apiKeys) {
|
|
230
|
+
const pathname = new URL(req.url ?? '/', 'http://localhost').pathname;
|
|
231
|
+
if (!authenticate(req, apiKeys)) {
|
|
232
|
+
sendError(res, new ApiError(401, 'Invalid or missing API key.', 'authentication_error', 'invalid_api_key'));
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
235
|
+
if (req.method === 'GET' && pathname === '/v1/models') {
|
|
236
|
+
sendJson(res, 200, {
|
|
237
|
+
object: 'list',
|
|
238
|
+
data: Object.keys(agents).map((id) => ({ id, object: 'model', created: 0, owned_by: 'libra-provider' })),
|
|
239
|
+
});
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
242
|
+
if (req.method !== 'POST' || pathname !== '/v1/chat/completions') {
|
|
243
|
+
throw new ApiError(404, 'Not found.', 'invalid_request_error', 'not_found');
|
|
244
|
+
}
|
|
245
|
+
const body = await readJson(req);
|
|
246
|
+
if (typeof body.model !== 'string')
|
|
247
|
+
throw new ApiError(400, 'model is required.', 'invalid_request_error', null, 'model');
|
|
248
|
+
const agent = agents[body.model];
|
|
249
|
+
if (!agent)
|
|
250
|
+
throw new ApiError(404, `Unknown model: ${body.model}`, 'invalid_request_error', 'model_not_found', 'model');
|
|
251
|
+
if (!Array.isArray(body.messages))
|
|
252
|
+
throw new ApiError(400, 'messages must be an array.', 'invalid_request_error', null, 'messages');
|
|
253
|
+
if (body.n !== undefined && body.n !== 1)
|
|
254
|
+
throw new ApiError(400, 'Only n=1 is supported.', 'invalid_request_error', null, 'n');
|
|
255
|
+
// Convert client-defined OpenAI tools to external Libra tools.
|
|
256
|
+
// External tools are not executed by the agent — their calls are returned
|
|
257
|
+
// to the caller as tool_calls in the response.
|
|
258
|
+
const externalTools = body.tools ? toExternalTools(body.tools) : undefined;
|
|
259
|
+
const messages = toLibraMessages(body.messages);
|
|
260
|
+
const latestUserMessage = [...messages].reverse().find((message) => message.role === 'user');
|
|
261
|
+
if (!latestUserMessage)
|
|
262
|
+
throw new ApiError(400, 'At least one user message is required.', 'invalid_request_error', null, 'messages');
|
|
263
|
+
const abort = new AbortController();
|
|
264
|
+
req.once('aborted', () => abort.abort());
|
|
265
|
+
res.once('close', () => {
|
|
266
|
+
if (!res.writableEnded)
|
|
267
|
+
abort.abort();
|
|
268
|
+
});
|
|
269
|
+
const result = await agent.run({
|
|
270
|
+
message: latestUserMessage.content,
|
|
271
|
+
metadata: { [HISTORY_KEY]: messages },
|
|
272
|
+
...(externalTools?.length && { tools: externalTools }),
|
|
273
|
+
signal: abort.signal,
|
|
274
|
+
});
|
|
275
|
+
if (result.finishReason === 'error')
|
|
276
|
+
throw new ApiError(502, 'The Libra agent failed to complete the request.', 'server_error');
|
|
277
|
+
const id = completionId();
|
|
278
|
+
const created = Math.floor(Date.now() / 1000);
|
|
279
|
+
const pendingCalls = result.pendingToolCalls;
|
|
280
|
+
const finishReason = result.finishReason === 'max_iterations'
|
|
281
|
+
? 'length'
|
|
282
|
+
: result.finishReason === 'tool_calls'
|
|
283
|
+
? 'tool_calls'
|
|
284
|
+
: 'stop';
|
|
285
|
+
if (body.stream === true)
|
|
286
|
+
sendStream(res, id, created, body.model, result.message, finishReason, pendingCalls);
|
|
287
|
+
else
|
|
288
|
+
sendJson(res, 200, openAICompletion(id, created, body.model, result.message, finishReason, pendingCalls));
|
|
289
|
+
}
|
|
290
|
+
/**
|
|
291
|
+
* Create an OpenAI-compatible HTTP server that exposes Libra agents as models.
|
|
292
|
+
*
|
|
293
|
+
* Each agent in the `agents` record becomes an OpenAI model ID. The server
|
|
294
|
+
* implements `GET /v1/models` and `POST /v1/chat/completions` with bearer/x-api-key
|
|
295
|
+
* authentication, text and image content, SSE streaming, and client-defined
|
|
296
|
+
* (external) tool calling.
|
|
297
|
+
*
|
|
298
|
+
* The HTTP server stays out of the core agent — this is an adapter/extra, not
|
|
299
|
+
* part of the agent harness itself. Use it when you want to expose Libra agents
|
|
300
|
+
* to OpenAI-compatible frameworks and SDKs.
|
|
301
|
+
*
|
|
302
|
+
* @example
|
|
303
|
+
* ```typescript
|
|
304
|
+
* import { Agent } from '@xandout/libra-harness';
|
|
305
|
+
* import { createOpenAICompatibleServer } from '@xandout/libra-harness/extras/openai-provider';
|
|
306
|
+
*
|
|
307
|
+
* const server = createOpenAICompatibleServer({
|
|
308
|
+
* agents: {
|
|
309
|
+
* 'my-agent': new Agent({ model, systemPrompt: 'You are helpful.' }),
|
|
310
|
+
* },
|
|
311
|
+
* apiKeys: ['your-provider-key'],
|
|
312
|
+
* });
|
|
313
|
+
* server.listen(8787, '127.0.0.1');
|
|
314
|
+
* ```
|
|
315
|
+
*/
|
|
316
|
+
export function createOpenAICompatibleServer(config) {
|
|
317
|
+
const apiKeys = [...new Set(config.apiKeys.map((key) => key.trim()).filter(Boolean))];
|
|
318
|
+
if (apiKeys.length === 0)
|
|
319
|
+
throw new Error('At least one provider API key is required.');
|
|
320
|
+
const agents = { ...config.agents };
|
|
321
|
+
if (Object.keys(agents).length === 0)
|
|
322
|
+
throw new Error('At least one Libra agent is required.');
|
|
323
|
+
Object.values(agents).forEach(prepareAgent);
|
|
324
|
+
return createServer((req, res) => {
|
|
325
|
+
void handleRequest(req, res, agents, apiKeys).catch((error) => {
|
|
326
|
+
if (res.writableEnded)
|
|
327
|
+
return;
|
|
328
|
+
if (error instanceof ApiError)
|
|
329
|
+
sendError(res, error);
|
|
330
|
+
else
|
|
331
|
+
sendError(res, new ApiError(500, 'Internal server error.', 'server_error'));
|
|
332
|
+
});
|
|
333
|
+
});
|
|
334
|
+
}
|
|
335
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../../src/extras/openai-provider/server.ts"],"names":[],"mappings":"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"}
|