@cogitator-ai/openai-compat 21.1.13 → 21.2.0
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/README.md +183 -46
- package/dist/client/openai-adapter.d.ts +35 -7
- package/dist/client/openai-adapter.d.ts.map +1 -1
- package/dist/client/openai-adapter.js +139 -57
- package/dist/client/openai-adapter.js.map +1 -1
- package/dist/client/thread-manager.d.ts +4 -3
- package/dist/client/thread-manager.d.ts.map +1 -1
- package/dist/client/thread-manager.js +7 -5
- package/dist/client/thread-manager.js.map +1 -1
- package/dist/index.d.ts +7 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -3
- package/dist/index.js.map +1 -1
- package/dist/server/agents/agent-turn.d.ts +134 -0
- package/dist/server/agents/agent-turn.d.ts.map +1 -0
- package/dist/server/agents/agent-turn.js +340 -0
- package/dist/server/agents/agent-turn.js.map +1 -0
- package/dist/server/agents/shared.d.ts +62 -0
- package/dist/server/agents/shared.d.ts.map +1 -0
- package/dist/server/agents/shared.js +136 -0
- package/dist/server/agents/shared.js.map +1 -0
- package/dist/server/api-server.d.ts +50 -10
- package/dist/server/api-server.d.ts.map +1 -1
- package/dist/server/api-server.js +61 -24
- package/dist/server/api-server.js.map +1 -1
- package/dist/server/routes/chat-completions.d.ts +15 -0
- package/dist/server/routes/chat-completions.d.ts.map +1 -0
- package/dist/server/routes/chat-completions.js +305 -0
- package/dist/server/routes/chat-completions.js.map +1 -0
- package/dist/server/routes/models.d.ts +8 -0
- package/dist/server/routes/models.d.ts.map +1 -0
- package/dist/server/routes/models.js +27 -0
- package/dist/server/routes/models.js.map +1 -0
- package/dist/server/routes/responses.d.ts +229 -0
- package/dist/server/routes/responses.d.ts.map +1 -0
- package/dist/server/routes/responses.js +484 -0
- package/dist/server/routes/responses.js.map +1 -0
- package/dist/server/routes/runs.d.ts +5 -1
- package/dist/server/routes/runs.d.ts.map +1 -1
- package/dist/server/routes/runs.js +16 -6
- package/dist/server/routes/runs.js.map +1 -1
- package/dist/types/openai-types.d.ts +3 -1
- package/dist/types/openai-types.d.ts.map +1 -1
- package/package.json +11 -7
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { encodeHeartbeat, startHeartbeat } from '@cogitator-ai/server-shared';
|
|
2
|
+
import { CogitatorError } from '@cogitator-ai/types';
|
|
3
|
+
import { InvalidRequestError } from '../../client/errors.js';
|
|
4
|
+
import { formatOpenAIError } from '../middleware/error-handler.js';
|
|
5
|
+
const IMAGE_MIME_TYPES = new Set([
|
|
6
|
+
'image/jpeg',
|
|
7
|
+
'image/png',
|
|
8
|
+
'image/gif',
|
|
9
|
+
'image/webp',
|
|
10
|
+
]);
|
|
11
|
+
/** The agents the OpenAI endpoints serve, by the model id clients send. */
|
|
12
|
+
export class AgentDirectory {
|
|
13
|
+
agents;
|
|
14
|
+
createdAt = Math.floor(Date.now() / 1000);
|
|
15
|
+
constructor(agents) {
|
|
16
|
+
this.agents = agents;
|
|
17
|
+
}
|
|
18
|
+
get(model) {
|
|
19
|
+
return Object.hasOwn(this.agents, model) ? this.agents[model] : undefined;
|
|
20
|
+
}
|
|
21
|
+
names() {
|
|
22
|
+
return Object.keys(this.agents);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
/** An image of a request, as the runtime takes it: a data URL becomes base64 data. */
|
|
26
|
+
export function toImageInput(url) {
|
|
27
|
+
const match = /^data:([^;,]+);base64,(.*)$/s.exec(url);
|
|
28
|
+
if (match && IMAGE_MIME_TYPES.has(match[1])) {
|
|
29
|
+
return { data: match[2], mimeType: match[1] };
|
|
30
|
+
}
|
|
31
|
+
return url;
|
|
32
|
+
}
|
|
33
|
+
/** The body parsed with `schema`, or an `InvalidRequestError` naming the parameter at fault. */
|
|
34
|
+
export function parseRequestBody(schema, body) {
|
|
35
|
+
const parsed = schema.safeParse(body ?? {});
|
|
36
|
+
if (parsed.success)
|
|
37
|
+
return parsed.data;
|
|
38
|
+
const issue = parsed.error.issues[0];
|
|
39
|
+
const param = issue.path.map(String).join('.');
|
|
40
|
+
throw new InvalidRequestError(param ? `${param}: ${issue.message}` : issue.message, param || undefined);
|
|
41
|
+
}
|
|
42
|
+
export function sendModelNotFound(reply, model) {
|
|
43
|
+
return reply
|
|
44
|
+
.status(404)
|
|
45
|
+
.send(formatOpenAIError('model_not_found', `The model '${model}' does not exist or you do not have access to it.`, 'invalid_request_error', 'model'));
|
|
46
|
+
}
|
|
47
|
+
/** The message a client may see for a failed run: deliberate errors as they are, others masked. */
|
|
48
|
+
export function clientErrorMessage(error, context) {
|
|
49
|
+
if (error instanceof InvalidRequestError || CogitatorError.isCogitatorError(error)) {
|
|
50
|
+
return error.message;
|
|
51
|
+
}
|
|
52
|
+
console.error(`[CogitatorOpenAI] ${context} failed:`, error);
|
|
53
|
+
return 'Internal server error';
|
|
54
|
+
}
|
|
55
|
+
/** Answer a request that failed before any output was sent, in the OpenAI error format. */
|
|
56
|
+
export function sendTurnError(reply, error, context) {
|
|
57
|
+
if (error instanceof InvalidRequestError) {
|
|
58
|
+
return reply
|
|
59
|
+
.status(400)
|
|
60
|
+
.send(formatOpenAIError('invalid_request', error.message, 'invalid_request_error', error.param));
|
|
61
|
+
}
|
|
62
|
+
return reply
|
|
63
|
+
.status(500)
|
|
64
|
+
.send(formatOpenAIError('server_error', clientErrorMessage(error, context), 'server_error'));
|
|
65
|
+
}
|
|
66
|
+
/** Usage in the Chat Completions shape. */
|
|
67
|
+
export function chatUsage(usage) {
|
|
68
|
+
return {
|
|
69
|
+
prompt_tokens: usage.inputTokens,
|
|
70
|
+
completion_tokens: usage.outputTokens,
|
|
71
|
+
total_tokens: usage.totalTokens,
|
|
72
|
+
prompt_tokens_details: { cached_tokens: usage.cachedInputTokens },
|
|
73
|
+
completion_tokens_details: { reasoning_tokens: usage.reasoningTokens },
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
/** Usage in the Responses shape. */
|
|
77
|
+
export function responseUsage(usage) {
|
|
78
|
+
return {
|
|
79
|
+
input_tokens: usage.inputTokens,
|
|
80
|
+
input_tokens_details: { cached_tokens: usage.cachedInputTokens },
|
|
81
|
+
output_tokens: usage.outputTokens,
|
|
82
|
+
output_tokens_details: { reasoning_tokens: usage.reasoningTokens },
|
|
83
|
+
total_tokens: usage.totalTokens,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* A signal that aborts when the client disconnects before the response is sent. It watches the
|
|
88
|
+
* response, since the request emits `close` as soon as its body has been read.
|
|
89
|
+
*/
|
|
90
|
+
export function abortOnDisconnect(reply) {
|
|
91
|
+
const controller = new AbortController();
|
|
92
|
+
reply.raw.on('close', () => {
|
|
93
|
+
if (!reply.raw.writableFinished)
|
|
94
|
+
controller.abort(new Error('Client disconnected'));
|
|
95
|
+
});
|
|
96
|
+
return controller.signal;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Take over the reply for Server-Sent Events. While it is open a heartbeat comment goes out
|
|
100
|
+
* every `heartbeatMs`, and the signal aborts when the client disconnects, so the run stops.
|
|
101
|
+
*/
|
|
102
|
+
export function openEventStream(reply, heartbeatMs) {
|
|
103
|
+
reply.hijack();
|
|
104
|
+
const raw = reply.raw;
|
|
105
|
+
raw.writeHead(200, {
|
|
106
|
+
'Content-Type': 'text/event-stream',
|
|
107
|
+
'Cache-Control': 'no-cache',
|
|
108
|
+
Connection: 'keep-alive',
|
|
109
|
+
'X-Accel-Buffering': 'no',
|
|
110
|
+
});
|
|
111
|
+
const controller = new AbortController();
|
|
112
|
+
raw.on('close', () => {
|
|
113
|
+
if (!raw.writableFinished)
|
|
114
|
+
controller.abort(new Error('Client disconnected'));
|
|
115
|
+
});
|
|
116
|
+
const writable = () => !controller.signal.aborted && !raw.writableEnded && !raw.destroyed;
|
|
117
|
+
const stopHeartbeat = startHeartbeat(() => {
|
|
118
|
+
if (!writable())
|
|
119
|
+
return false;
|
|
120
|
+
raw.write(encodeHeartbeat());
|
|
121
|
+
return true;
|
|
122
|
+
}, heartbeatMs);
|
|
123
|
+
return {
|
|
124
|
+
signal: controller.signal,
|
|
125
|
+
write(frame) {
|
|
126
|
+
if (writable())
|
|
127
|
+
raw.write(frame);
|
|
128
|
+
},
|
|
129
|
+
end() {
|
|
130
|
+
stopHeartbeat();
|
|
131
|
+
if (!raw.writableEnded)
|
|
132
|
+
raw.end();
|
|
133
|
+
},
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
//# sourceMappingURL=shared.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shared.js","sourceRoot":"","sources":["../../../src/server/agents/shared.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,21 +1,51 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* OpenAI-Compatible REST API Server
|
|
3
3
|
*
|
|
4
|
-
* Exposes Cogitator
|
|
4
|
+
* Exposes registered Cogitator agents over the Chat Completions and Responses APIs, and the
|
|
5
|
+
* deprecated Assistants API.
|
|
5
6
|
*/
|
|
6
7
|
import { type FastifyInstance } from 'fastify';
|
|
7
8
|
import type { Cogitator } from '@cogitator-ai/core';
|
|
8
|
-
import type { Tool } from '@cogitator-ai/types';
|
|
9
|
+
import type { Agent, Tool } from '@cogitator-ai/types';
|
|
9
10
|
import type { ThreadStorage } from '../client/storage.js';
|
|
10
11
|
import { OpenAIAdapter } from '../client/openai-adapter.js';
|
|
11
12
|
export interface OpenAIServerConfig {
|
|
12
13
|
/** Port to listen on */
|
|
13
14
|
port?: number;
|
|
14
|
-
/**
|
|
15
|
+
/**
|
|
16
|
+
* Host to bind to. Default: `127.0.0.1`, reachable from this machine only. Binding a
|
|
17
|
+
* public interface (`0.0.0.0`, `::` or an external address) needs `apiKeys`, or
|
|
18
|
+
* `allowUnauthenticatedPublicAccess`.
|
|
19
|
+
*/
|
|
15
20
|
host?: string;
|
|
16
|
-
/**
|
|
21
|
+
/**
|
|
22
|
+
* API keys for authentication. Without keys every caller may create assistants with any
|
|
23
|
+
* instructions and run the server's tools, so `start()` refuses a public `host` unless
|
|
24
|
+
* `allowUnauthenticatedPublicAccess` is set.
|
|
25
|
+
*/
|
|
17
26
|
apiKeys?: string[];
|
|
18
|
-
/**
|
|
27
|
+
/**
|
|
28
|
+
* Serve a public `host` without `apiKeys`, for a server behind a gateway that
|
|
29
|
+
* authenticates callers itself. Default: `false`.
|
|
30
|
+
*/
|
|
31
|
+
allowUnauthenticatedPublicAccess?: boolean;
|
|
32
|
+
/**
|
|
33
|
+
* How often a run stream writes an SSE comment while the run is silent, in milliseconds,
|
|
34
|
+
* so a proxy or load balancer does not cut a run that waits on a slow tool. Default: 5000.
|
|
35
|
+
* `0` turns heartbeats off.
|
|
36
|
+
*/
|
|
37
|
+
sseHeartbeatMs?: number;
|
|
38
|
+
/**
|
|
39
|
+
* Agents served by `POST /v1/chat/completions` and `POST /v1/responses`, by the model id
|
|
40
|
+
* clients send (and `GET /v1/models` lists). Each answers with its own instructions, model and
|
|
41
|
+
* tools, and functions a client declares in `tools` come back to it as tool calls.
|
|
42
|
+
*/
|
|
43
|
+
agents?: Record<string, Agent>;
|
|
44
|
+
/** Largest request body `POST /v1/chat/completions` and `POST /v1/responses` accept, in bytes (default: 20 MB) */
|
|
45
|
+
maxRequestBodyBytes?: number;
|
|
46
|
+
/** How many responses `POST /v1/responses` keeps in memory for `previous_response_id` and `GET` (default: 1000) */
|
|
47
|
+
maxStoredResponses?: number;
|
|
48
|
+
/** Tools every Assistants API run can use */
|
|
19
49
|
tools?: Tool[];
|
|
20
50
|
/**
|
|
21
51
|
* Cogitator model used for assistants/runs that request the advertised
|
|
@@ -28,12 +58,17 @@ export interface OpenAIServerConfig {
|
|
|
28
58
|
storage?: ThreadStorage;
|
|
29
59
|
/** Enable request logging */
|
|
30
60
|
logging?: boolean;
|
|
31
|
-
/**
|
|
61
|
+
/**
|
|
62
|
+
* CORS for browsers on other origins. Default: none, so a web page on another origin
|
|
63
|
+
* cannot call the server from a visitor's browser. Set `origin` to the origins that may.
|
|
64
|
+
*/
|
|
32
65
|
cors?: {
|
|
33
66
|
origin?: string | string[] | boolean;
|
|
34
67
|
methods?: string[];
|
|
35
68
|
};
|
|
36
69
|
}
|
|
70
|
+
/** True for a host only this machine can reach: `localhost`, `::1` or `127.0.0.0/8` */
|
|
71
|
+
export declare function isLoopbackHost(host: string): boolean;
|
|
37
72
|
/**
|
|
38
73
|
* OpenAI-Compatible API Server
|
|
39
74
|
*
|
|
@@ -45,19 +80,24 @@ export interface OpenAIServerConfig {
|
|
|
45
80
|
* const cogitator = new Cogitator({ ... });
|
|
46
81
|
* const server = createOpenAIServer(cogitator, {
|
|
47
82
|
* port: 8080,
|
|
48
|
-
*
|
|
83
|
+
* agents: { support: supportAgent },
|
|
49
84
|
* });
|
|
50
85
|
*
|
|
51
86
|
* await server.start();
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
*
|
|
87
|
+
* const openai = new OpenAI({ baseURL: server.getBaseUrl(), apiKey: 'unused' });
|
|
88
|
+
* const completion = await openai.chat.completions.create({
|
|
89
|
+
* model: 'support',
|
|
90
|
+
* messages: [{ role: 'user', content: 'Hi' }],
|
|
91
|
+
* });
|
|
55
92
|
* ```
|
|
56
93
|
*/
|
|
57
94
|
export declare class OpenAIServer {
|
|
58
95
|
private fastify;
|
|
59
96
|
private config;
|
|
60
97
|
private adapter;
|
|
98
|
+
private agentRunner;
|
|
99
|
+
private directory;
|
|
100
|
+
private responses;
|
|
61
101
|
private started;
|
|
62
102
|
private ready;
|
|
63
103
|
private boundPort?;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api-server.d.ts","sourceRoot":"","sources":["../../src/server/api-server.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"api-server.d.ts","sourceRoot":"","sources":["../../src/server/api-server.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAgB,EAAE,KAAK,eAAe,EAAE,MAAM,SAAS,CAAC;AAExD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAC;AAEvD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAazD,MAAM,WAAW,kBAAkB;IACjC,wBAAwB;IACxB,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IAEnB;;;OAGG;IACH,gCAAgC,CAAC,EAAE,OAAO,CAAC;IAE3C;;;;OAIG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IAE/B,kHAAkH;IAClH,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAE7B,mHAAmH;IACnH,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAE5B,6CAA6C;IAC7C,KAAK,CAAC,EAAE,IAAI,EAAE,CAAC;IAEf;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB,wEAAwE;IACxE,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,0EAA0E;IAC1E,OAAO,CAAC,EAAE,aAAa,CAAC;IAExB,6BAA6B;IAC7B,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB;;;OAGG;IACH,IAAI,CAAC,EAAE;QACL,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,OAAO,CAAC;QACrC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;KACpB,CAAC;CACH;AAID,uFAAuF;AACvF,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEpD;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,OAAO,CAAkB;IACjC,OAAO,CAAC,MAAM,CACkD;IAChE,OAAO,CAAC,OAAO,CAAgB;IAC/B,OAAO,CAAC,WAAW,CAAkB;IACrC,OAAO,CAAC,SAAS,CAAiB;IAClC,OAAO,CAAC,SAAS,CAAgB;IACjC,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,KAAK,CAAgB;IAC7B,OAAO,CAAC,SAAS,CAAC,CAAS;gBAEf,SAAS,EAAE,SAAS,EAAE,MAAM,GAAE,kBAAuB;IAmCjE;;OAEG;YACW,WAAW;IAiDzB;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IA+B5B;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAS3B;;OAEG;IACH,MAAM,IAAI,MAAM;IAOhB;;OAEG;IACH,UAAU,IAAI,MAAM;IAIpB;;;OAGG;IACG,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;IAKrC;;OAEG;IACH,UAAU,IAAI,eAAe;IAI7B;;OAEG;IACH,SAAS,IAAI,OAAO;IAIpB;;OAEG;IACH,UAAU,IAAI,aAAa;CAG5B;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,SAAS,EACpB,MAAM,CAAC,EAAE,kBAAkB,GAC1B,YAAY,CAEd"}
|
|
@@ -1,17 +1,29 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* OpenAI-Compatible REST API Server
|
|
3
3
|
*
|
|
4
|
-
* Exposes Cogitator
|
|
4
|
+
* Exposes registered Cogitator agents over the Chat Completions and Responses APIs, and the
|
|
5
|
+
* deprecated Assistants API.
|
|
5
6
|
*/
|
|
6
7
|
import Fastify from 'fastify';
|
|
7
8
|
import fastifyCors from '@fastify/cors';
|
|
8
|
-
import {
|
|
9
|
+
import { resolveSseHeartbeatMs } from '@cogitator-ai/server-shared';
|
|
10
|
+
import { OpenAIAdapter } from '../client/openai-adapter.js';
|
|
9
11
|
import { createAuthMiddleware } from './middleware/auth.js';
|
|
10
12
|
import { errorHandler, notFoundHandler } from './middleware/error-handler.js';
|
|
11
13
|
import { registerAssistantRoutes } from './routes/assistants.js';
|
|
12
14
|
import { registerThreadRoutes } from './routes/threads.js';
|
|
13
15
|
import { registerRunRoutes } from './routes/runs.js';
|
|
14
16
|
import { registerFileRoutes } from './routes/files.js';
|
|
17
|
+
import { registerChatCompletionRoutes } from './routes/chat-completions.js';
|
|
18
|
+
import { registerResponseRoutes, ResponseStore } from './routes/responses.js';
|
|
19
|
+
import { registerModelRoutes } from './routes/models.js';
|
|
20
|
+
import { AgentTurnRunner } from './agents/agent-turn.js';
|
|
21
|
+
import { AgentDirectory } from './agents/shared.js';
|
|
22
|
+
const LOOPBACK_HOSTS = new Set(['localhost', '::1', '[::1]']);
|
|
23
|
+
/** True for a host only this machine can reach: `localhost`, `::1` or `127.0.0.0/8` */
|
|
24
|
+
export function isLoopbackHost(host) {
|
|
25
|
+
return LOOPBACK_HOSTS.has(host.toLowerCase()) || /^127(?:\.\d{1,3}){3}$/.test(host);
|
|
26
|
+
}
|
|
15
27
|
/**
|
|
16
28
|
* OpenAI-Compatible API Server
|
|
17
29
|
*
|
|
@@ -23,39 +35,52 @@ import { registerFileRoutes } from './routes/files.js';
|
|
|
23
35
|
* const cogitator = new Cogitator({ ... });
|
|
24
36
|
* const server = createOpenAIServer(cogitator, {
|
|
25
37
|
* port: 8080,
|
|
26
|
-
*
|
|
38
|
+
* agents: { support: supportAgent },
|
|
27
39
|
* });
|
|
28
40
|
*
|
|
29
41
|
* await server.start();
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
42
|
+
* const openai = new OpenAI({ baseURL: server.getBaseUrl(), apiKey: 'unused' });
|
|
43
|
+
* const completion = await openai.chat.completions.create({
|
|
44
|
+
* model: 'support',
|
|
45
|
+
* messages: [{ role: 'user', content: 'Hi' }],
|
|
46
|
+
* });
|
|
33
47
|
* ```
|
|
34
48
|
*/
|
|
35
49
|
export class OpenAIServer {
|
|
36
50
|
fastify;
|
|
37
51
|
config;
|
|
38
52
|
adapter;
|
|
53
|
+
agentRunner;
|
|
54
|
+
directory;
|
|
55
|
+
responses;
|
|
39
56
|
started = false;
|
|
40
57
|
ready;
|
|
41
58
|
boundPort;
|
|
42
59
|
constructor(cogitator, config = {}) {
|
|
43
60
|
this.config = {
|
|
44
61
|
port: config.port ?? 8080,
|
|
45
|
-
host: config.host ?? '
|
|
62
|
+
host: config.host ?? '127.0.0.1',
|
|
46
63
|
apiKeys: config.apiKeys ?? [],
|
|
64
|
+
allowUnauthenticatedPublicAccess: config.allowUnauthenticatedPublicAccess ?? false,
|
|
65
|
+
sseHeartbeatMs: resolveSseHeartbeatMs(config.sseHeartbeatMs),
|
|
66
|
+
agents: config.agents ?? {},
|
|
67
|
+
maxRequestBodyBytes: config.maxRequestBodyBytes ?? 20 * 1024 * 1024,
|
|
68
|
+
maxStoredResponses: config.maxStoredResponses ?? 1000,
|
|
47
69
|
tools: config.tools ?? [],
|
|
48
70
|
defaultModel: config.defaultModel,
|
|
49
71
|
storage: config.storage,
|
|
50
72
|
maxFileSize: config.maxFileSize ?? 512 * 1024 * 1024,
|
|
51
73
|
logging: config.logging ?? false,
|
|
52
|
-
cors: config.cors
|
|
74
|
+
cors: config.cors,
|
|
53
75
|
};
|
|
54
76
|
this.adapter = new OpenAIAdapter(cogitator, {
|
|
55
77
|
tools: this.config.tools,
|
|
56
78
|
defaultModel: this.config.defaultModel,
|
|
57
79
|
storage: this.config.storage,
|
|
58
80
|
});
|
|
81
|
+
this.directory = new AgentDirectory(this.config.agents);
|
|
82
|
+
this.agentRunner = new AgentTurnRunner(cogitator);
|
|
83
|
+
this.responses = new ResponseStore(this.config.maxStoredResponses);
|
|
59
84
|
this.fastify = Fastify({
|
|
60
85
|
logger: this.config.logging ? { level: 'info' } : false,
|
|
61
86
|
});
|
|
@@ -66,10 +91,12 @@ export class OpenAIServer {
|
|
|
66
91
|
* Set up the Fastify server
|
|
67
92
|
*/
|
|
68
93
|
async setupServer() {
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
94
|
+
if (this.config.cors) {
|
|
95
|
+
await this.fastify.register(fastifyCors, {
|
|
96
|
+
origin: this.config.cors.origin ?? false,
|
|
97
|
+
methods: this.config.cors.methods ?? ['GET', 'POST', 'DELETE', 'OPTIONS'],
|
|
98
|
+
});
|
|
99
|
+
}
|
|
73
100
|
await this.fastify.register(import('@fastify/multipart'), {
|
|
74
101
|
limits: {
|
|
75
102
|
fileSize: this.config.maxFileSize,
|
|
@@ -86,20 +113,23 @@ export class OpenAIServer {
|
|
|
86
113
|
this.fastify.setErrorHandler(errorHandler);
|
|
87
114
|
this.fastify.setNotFoundHandler(notFoundHandler);
|
|
88
115
|
this.fastify.get('/health', async () => ({ status: 'ok' }));
|
|
89
|
-
this.fastify
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
116
|
+
registerModelRoutes(this.fastify, this.directory);
|
|
117
|
+
registerChatCompletionRoutes(this.fastify, {
|
|
118
|
+
directory: this.directory,
|
|
119
|
+
runner: this.agentRunner,
|
|
120
|
+
heartbeatMs: this.config.sseHeartbeatMs,
|
|
121
|
+
bodyLimit: this.config.maxRequestBodyBytes,
|
|
122
|
+
});
|
|
123
|
+
registerResponseRoutes(this.fastify, {
|
|
124
|
+
directory: this.directory,
|
|
125
|
+
runner: this.agentRunner,
|
|
126
|
+
store: this.responses,
|
|
127
|
+
heartbeatMs: this.config.sseHeartbeatMs,
|
|
128
|
+
bodyLimit: this.config.maxRequestBodyBytes,
|
|
129
|
+
});
|
|
100
130
|
registerAssistantRoutes(this.fastify, this.adapter);
|
|
101
131
|
registerThreadRoutes(this.fastify, this.adapter);
|
|
102
|
-
registerRunRoutes(this.fastify, this.adapter);
|
|
132
|
+
registerRunRoutes(this.fastify, this.adapter, { heartbeatMs: this.config.sseHeartbeatMs });
|
|
103
133
|
registerFileRoutes(this.fastify, this.adapter);
|
|
104
134
|
}
|
|
105
135
|
/**
|
|
@@ -109,6 +139,13 @@ export class OpenAIServer {
|
|
|
109
139
|
if (this.started) {
|
|
110
140
|
throw new Error('Server already started');
|
|
111
141
|
}
|
|
142
|
+
if (this.config.apiKeys.length === 0 &&
|
|
143
|
+
!this.config.allowUnauthenticatedPublicAccess &&
|
|
144
|
+
!isLoopbackHost(this.config.host)) {
|
|
145
|
+
throw new Error(`Refusing to serve ${this.config.host} without apiKeys: anyone who can reach it could ` +
|
|
146
|
+
'create assistants and run the server tools. Set apiKeys, bind a loopback host such as ' +
|
|
147
|
+
'127.0.0.1, or set allowUnauthenticatedPublicAccess when a gateway authenticates callers.');
|
|
148
|
+
}
|
|
112
149
|
await this.ready;
|
|
113
150
|
await this.fastify.listen({
|
|
114
151
|
port: this.config.port,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api-server.js","sourceRoot":"","sources":["../../src/server/api-server.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"api-server.js","sourceRoot":"","sources":["../../src/server/api-server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Chat Completions API (`POST /v1/chat/completions`) over registered Cogitator agents: the
|
|
3
|
+
* request's `model` names the agent.
|
|
4
|
+
*/
|
|
5
|
+
import type { FastifyInstance } from 'fastify';
|
|
6
|
+
import { type AgentTurnRunner } from '../agents/agent-turn.js';
|
|
7
|
+
import { type AgentDirectory } from '../agents/shared.js';
|
|
8
|
+
export interface ChatCompletionRouteOptions {
|
|
9
|
+
directory: AgentDirectory;
|
|
10
|
+
runner: AgentTurnRunner;
|
|
11
|
+
heartbeatMs: number;
|
|
12
|
+
bodyLimit: number;
|
|
13
|
+
}
|
|
14
|
+
export declare function registerChatCompletionRoutes(fastify: FastifyInstance, options: ChatCompletionRouteOptions): void;
|
|
15
|
+
//# sourceMappingURL=chat-completions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chat-completions.d.ts","sourceRoot":"","sources":["../../../src/server/routes/chat-completions.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAM/C,OAAO,EAIL,KAAK,eAAe,EAGrB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,KAAK,cAAc,EASpB,MAAM,kBAAkB,CAAC;AAgL1B,MAAM,WAAW,0BAA0B;IACzC,SAAS,EAAE,cAAc,CAAC;IAC1B,MAAM,EAAE,eAAe,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,4BAA4B,CAC1C,OAAO,EAAE,eAAe,EACxB,OAAO,EAAE,0BAA0B,QA4IpC"}
|