agentic-server 0.21.2 → 0.22.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 +41 -48
- package/esm/index.js +17 -17
- package/esm/providers.js +77 -0
- package/esm/router.js +236 -459
- package/esm/server.js +31 -0
- package/esm/transforms.js +111 -0
- package/esm/types.js +1 -0
- package/index.d.ts +19 -19
- package/index.js +22 -21
- package/package.json +9 -16
- package/providers.d.ts +8 -0
- package/providers.js +82 -0
- package/router.d.ts +10 -18
- package/router.js +238 -493
- package/server.d.ts +10 -0
- package/server.js +38 -0
- package/transforms.d.ts +11 -0
- package/transforms.js +117 -0
- package/types.d.ts +64 -0
- package/types.js +2 -0
package/esm/server.js
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import express from 'express';
|
|
2
|
+
import { createRouter } from './router';
|
|
3
|
+
/** Identity headers trusted only when isPublic === false (private network). */
|
|
4
|
+
const IDENTITY_HEADERS = [
|
|
5
|
+
'x-database-id',
|
|
6
|
+
'x-entity-id',
|
|
7
|
+
'x-actor-id'
|
|
8
|
+
];
|
|
9
|
+
/**
|
|
10
|
+
* Create a standalone Express app for the agentic server.
|
|
11
|
+
* Used by both standalone mode and integration tests.
|
|
12
|
+
*/
|
|
13
|
+
export const createAgenticServer = (options) => {
|
|
14
|
+
const app = express();
|
|
15
|
+
app.use(express.json());
|
|
16
|
+
// When isPublic === true, strip identity headers from all incoming requests.
|
|
17
|
+
// Public deployments cannot trust client-supplied tenant context.
|
|
18
|
+
// When isPublic === false (default), the server is on a private network
|
|
19
|
+
// and trusts identity headers directly — same pattern as the GraphQL server
|
|
20
|
+
// with API_IS_PUBLIC=false.
|
|
21
|
+
if (options.isPublic) {
|
|
22
|
+
app.use((req, _res, next) => {
|
|
23
|
+
for (const header of IDENTITY_HEADERS) {
|
|
24
|
+
req.headers[header] = undefined;
|
|
25
|
+
}
|
|
26
|
+
next();
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
app.use(createRouter(options));
|
|
30
|
+
return app;
|
|
31
|
+
};
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
export function transformChatRequest(provider, body) {
|
|
2
|
+
let model = body.model || provider.defaultModel;
|
|
3
|
+
if (typeof model === 'string' && model.includes('/')) {
|
|
4
|
+
const prefix = model.split('/')[0];
|
|
5
|
+
if (prefix === provider.type) {
|
|
6
|
+
model = model.split('/').slice(1).join('/');
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
if (provider.type === 'ollama') {
|
|
10
|
+
return {
|
|
11
|
+
model: model || 'llama3',
|
|
12
|
+
messages: body.messages,
|
|
13
|
+
stream: false,
|
|
14
|
+
...(body.temperature !== undefined && {
|
|
15
|
+
options: { temperature: body.temperature }
|
|
16
|
+
})
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
if (provider.type === 'anthropic') {
|
|
20
|
+
const messages = body.messages;
|
|
21
|
+
const systemMsg = messages?.find((m) => m.role === 'system');
|
|
22
|
+
const nonSystem = messages?.filter((m) => m.role !== 'system') || [];
|
|
23
|
+
return {
|
|
24
|
+
model: model || 'claude-sonnet-4-20250514',
|
|
25
|
+
messages: nonSystem,
|
|
26
|
+
max_tokens: body.max_tokens || 4096,
|
|
27
|
+
...(systemMsg && { system: systemMsg.content }),
|
|
28
|
+
...(body.temperature !== undefined && { temperature: body.temperature })
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
// OpenAI-compatible (default)
|
|
32
|
+
return { ...body, model: model || 'gpt-4o' };
|
|
33
|
+
}
|
|
34
|
+
export function transformEmbedRequest(provider, body) {
|
|
35
|
+
const model = body.model || provider.defaultModel;
|
|
36
|
+
if (provider.type === 'ollama') {
|
|
37
|
+
return {
|
|
38
|
+
model: model || 'nomic-embed-text',
|
|
39
|
+
input: body.input
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
return { ...body, model: model || 'text-embedding-3-small' };
|
|
43
|
+
}
|
|
44
|
+
export function transformChatResponse(data, provider) {
|
|
45
|
+
if (provider.type === 'ollama') {
|
|
46
|
+
const msg = data.message;
|
|
47
|
+
const promptTokens = data.prompt_eval_count || 0;
|
|
48
|
+
const completionTokens = data.eval_count || 0;
|
|
49
|
+
const usage = {
|
|
50
|
+
prompt_tokens: promptTokens,
|
|
51
|
+
completion_tokens: completionTokens,
|
|
52
|
+
total_tokens: promptTokens + completionTokens
|
|
53
|
+
};
|
|
54
|
+
return {
|
|
55
|
+
body: {
|
|
56
|
+
id: `chatcmpl-${Date.now()}`,
|
|
57
|
+
object: 'chat.completion',
|
|
58
|
+
choices: [{
|
|
59
|
+
message: msg || { role: 'assistant', content: '' },
|
|
60
|
+
finish_reason: 'stop',
|
|
61
|
+
index: 0
|
|
62
|
+
}],
|
|
63
|
+
usage
|
|
64
|
+
},
|
|
65
|
+
usage
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
if (provider.type === 'anthropic') {
|
|
69
|
+
const content = data.content;
|
|
70
|
+
const text = content?.find((c) => c.type === 'text')?.text || '';
|
|
71
|
+
const inputUsage = data.usage || {};
|
|
72
|
+
const usage = {
|
|
73
|
+
prompt_tokens: inputUsage.input_tokens || 0,
|
|
74
|
+
completion_tokens: inputUsage.output_tokens || 0,
|
|
75
|
+
total_tokens: (inputUsage.input_tokens || 0) + (inputUsage.output_tokens || 0)
|
|
76
|
+
};
|
|
77
|
+
return {
|
|
78
|
+
body: {
|
|
79
|
+
id: data.id || `chatcmpl-${Date.now()}`,
|
|
80
|
+
object: 'chat.completion',
|
|
81
|
+
choices: [{
|
|
82
|
+
message: { role: 'assistant', content: text },
|
|
83
|
+
finish_reason: 'stop',
|
|
84
|
+
index: 0
|
|
85
|
+
}],
|
|
86
|
+
usage
|
|
87
|
+
},
|
|
88
|
+
usage
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
// OpenAI — pass through
|
|
92
|
+
const usage = (data.usage || { prompt_tokens: 0, completion_tokens: 0, total_tokens: 0 });
|
|
93
|
+
return { body: data, usage };
|
|
94
|
+
}
|
|
95
|
+
export function transformEmbedResponse(data, provider) {
|
|
96
|
+
if (provider.type === 'ollama') {
|
|
97
|
+
const raw = (data.embeddings || data.embedding || []);
|
|
98
|
+
const embeddings = Array.isArray(raw[0]) ? raw : [raw];
|
|
99
|
+
const usage = { prompt_tokens: 0, completion_tokens: 0, total_tokens: 0 };
|
|
100
|
+
return {
|
|
101
|
+
body: {
|
|
102
|
+
object: 'list',
|
|
103
|
+
data: embeddings.map((emb, i) => ({ object: 'embedding', embedding: emb, index: i })),
|
|
104
|
+
usage
|
|
105
|
+
},
|
|
106
|
+
usage
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
const usage = (data.usage || { prompt_tokens: 0, completion_tokens: 0, total_tokens: 0 });
|
|
110
|
+
return { body: data, usage };
|
|
111
|
+
}
|
package/esm/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/index.d.ts
CHANGED
|
@@ -1,28 +1,28 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* agentic-server — Standalone
|
|
2
|
+
* agentic-server — Standalone OpenAI-compatible LLM gateway
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* in express-context — no custom caching here.
|
|
4
|
+
* A stateless multi-provider proxy that:
|
|
5
|
+
* 1. Accepts OpenAI-compatible requests (`/v1/chat/completions`, `/v1/embeddings`)
|
|
6
|
+
* 2. Enforces tenant isolation via X-Database-Id / X-Entity-Id / X-Actor-Id headers
|
|
7
|
+
* 3. Routes to configured LLM provider(s) (OpenAI, Anthropic, Ollama)
|
|
8
|
+
* 4. Records inference usage through an injected {@link InferenceSink}
|
|
9
|
+
* (fire-and-forget) — the gateway is backend-agnostic and never imports a
|
|
10
|
+
* concrete metering implementation.
|
|
12
11
|
*
|
|
13
12
|
* @example
|
|
14
13
|
* ```typescript
|
|
15
|
-
* import
|
|
16
|
-
* import { createContextMiddleware } from '@constructive-io/express-context';
|
|
17
|
-
* import { createAgenticRouter } from 'agentic-server';
|
|
14
|
+
* import { createAgenticServer } from 'agentic-server';
|
|
18
15
|
*
|
|
19
|
-
* const app =
|
|
20
|
-
*
|
|
21
|
-
*
|
|
16
|
+
* const app = createAgenticServer({
|
|
17
|
+
* providerType: 'ollama',
|
|
18
|
+
* providerBaseUrl: 'http://localhost:11434',
|
|
19
|
+
* inferenceSink: { logInference: (entry) => myBackend.record(entry) },
|
|
20
|
+
* });
|
|
22
21
|
* app.listen(3001);
|
|
23
22
|
* ```
|
|
24
23
|
*/
|
|
25
|
-
export {
|
|
26
|
-
export
|
|
27
|
-
export type {
|
|
28
|
-
export {
|
|
24
|
+
export { buildProviderHeaders, resolveProvider, resolveUpstreamUrl } from './providers';
|
|
25
|
+
export { createRouter } from './router';
|
|
26
|
+
export type { AgenticServerStartOptions } from './server';
|
|
27
|
+
export { createAgenticServer } from './server';
|
|
28
|
+
export type { AgenticServerOptions, InferenceEntry, InferenceSink, ProviderConfig, ResolvedProvider, UsageResult } from './types';
|
package/index.js
CHANGED
|
@@ -1,33 +1,34 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/**
|
|
3
|
-
* agentic-server — Standalone
|
|
3
|
+
* agentic-server — Standalone OpenAI-compatible LLM gateway
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
* in express-context — no custom caching here.
|
|
5
|
+
* A stateless multi-provider proxy that:
|
|
6
|
+
* 1. Accepts OpenAI-compatible requests (`/v1/chat/completions`, `/v1/embeddings`)
|
|
7
|
+
* 2. Enforces tenant isolation via X-Database-Id / X-Entity-Id / X-Actor-Id headers
|
|
8
|
+
* 3. Routes to configured LLM provider(s) (OpenAI, Anthropic, Ollama)
|
|
9
|
+
* 4. Records inference usage through an injected {@link InferenceSink}
|
|
10
|
+
* (fire-and-forget) — the gateway is backend-agnostic and never imports a
|
|
11
|
+
* concrete metering implementation.
|
|
13
12
|
*
|
|
14
13
|
* @example
|
|
15
14
|
* ```typescript
|
|
16
|
-
* import
|
|
17
|
-
* import { createContextMiddleware } from '@constructive-io/express-context';
|
|
18
|
-
* import { createAgenticRouter } from 'agentic-server';
|
|
15
|
+
* import { createAgenticServer } from 'agentic-server';
|
|
19
16
|
*
|
|
20
|
-
* const app =
|
|
21
|
-
*
|
|
22
|
-
*
|
|
17
|
+
* const app = createAgenticServer({
|
|
18
|
+
* providerType: 'ollama',
|
|
19
|
+
* providerBaseUrl: 'http://localhost:11434',
|
|
20
|
+
* inferenceSink: { logInference: (entry) => myBackend.record(entry) },
|
|
21
|
+
* });
|
|
23
22
|
* app.listen(3001);
|
|
24
23
|
* ```
|
|
25
24
|
*/
|
|
26
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
27
|
-
exports.
|
|
26
|
+
exports.createAgenticServer = exports.createRouter = exports.resolveUpstreamUrl = exports.resolveProvider = exports.buildProviderHeaders = void 0;
|
|
27
|
+
var providers_1 = require("./providers");
|
|
28
|
+
Object.defineProperty(exports, "buildProviderHeaders", { enumerable: true, get: function () { return providers_1.buildProviderHeaders; } });
|
|
29
|
+
Object.defineProperty(exports, "resolveProvider", { enumerable: true, get: function () { return providers_1.resolveProvider; } });
|
|
30
|
+
Object.defineProperty(exports, "resolveUpstreamUrl", { enumerable: true, get: function () { return providers_1.resolveUpstreamUrl; } });
|
|
28
31
|
var router_1 = require("./router");
|
|
29
|
-
Object.defineProperty(exports, "
|
|
30
|
-
var
|
|
31
|
-
Object.defineProperty(exports, "
|
|
32
|
-
Object.defineProperty(exports, "getLlmEnvOptions", { enumerable: true, get: function () { return llm_env_1.getEnvOptions; } });
|
|
33
|
-
Object.defineProperty(exports, "llmDefaults", { enumerable: true, get: function () { return llm_env_1.llmDefaults; } });
|
|
32
|
+
Object.defineProperty(exports, "createRouter", { enumerable: true, get: function () { return router_1.createRouter; } });
|
|
33
|
+
var server_1 = require("./server");
|
|
34
|
+
Object.defineProperty(exports, "createAgenticServer", { enumerable: true, get: function () { return server_1.createAgenticServer; } });
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agentic-server",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Standalone
|
|
3
|
+
"version": "0.22.0",
|
|
4
|
+
"description": "Standalone OpenAI-compatible LLM gateway — multi-provider proxy with pluggable inference metering",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"module": "esm/index.js",
|
|
7
7
|
"types": "index.d.ts",
|
|
@@ -29,34 +29,27 @@
|
|
|
29
29
|
"test:watch": "jest --watch"
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@
|
|
33
|
-
"@constructive-io/express-context": "^0.23.2",
|
|
34
|
-
"@constructive-io/llm-env": "^0.12.2",
|
|
35
|
-
"@pgpmjs/logger": "^2.23.2",
|
|
36
|
-
"pg": "^8.21.0",
|
|
37
|
-
"pg-cache": "^3.24.2"
|
|
32
|
+
"@pgpmjs/logger": "^2.23.2"
|
|
38
33
|
},
|
|
39
34
|
"devDependencies": {
|
|
40
35
|
"@types/express": "^5.0.6",
|
|
41
36
|
"@types/node": "^22.19.11",
|
|
42
|
-
"@types/pg": "^8.20.0",
|
|
43
|
-
"@types/supertest": "^7.2.0",
|
|
44
37
|
"express": "^5.2.1",
|
|
45
|
-
"makage": "^0.3.0"
|
|
46
|
-
"supertest": "^7.2.2"
|
|
38
|
+
"makage": "^0.3.0"
|
|
47
39
|
},
|
|
48
40
|
"peerDependencies": {
|
|
49
41
|
"express": "^5.0.0"
|
|
50
42
|
},
|
|
51
43
|
"keywords": [
|
|
52
|
-
"agentic-kit",
|
|
53
44
|
"express",
|
|
54
45
|
"llm",
|
|
46
|
+
"gateway",
|
|
47
|
+
"openai",
|
|
55
48
|
"ollama",
|
|
56
|
-
"
|
|
57
|
-
"
|
|
49
|
+
"anthropic",
|
|
50
|
+
"proxy",
|
|
58
51
|
"metering",
|
|
59
52
|
"constructive"
|
|
60
53
|
],
|
|
61
|
-
"gitHead": "
|
|
54
|
+
"gitHead": "6d3e25dc5c9f93421dba49ddedf93239f87213a8"
|
|
62
55
|
}
|
package/providers.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { AgenticServerOptions, ResolvedProvider } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Resolve which provider to use for a given request.
|
|
4
|
+
* Priority: model-based routing → explicit provider header → default.
|
|
5
|
+
*/
|
|
6
|
+
export declare function resolveProvider(options: AgenticServerOptions, requestModel?: string, requestProvider?: string): ResolvedProvider;
|
|
7
|
+
export declare function resolveUpstreamUrl(provider: ResolvedProvider, path: string): string;
|
|
8
|
+
export declare function buildProviderHeaders(provider: ResolvedProvider): Record<string, string>;
|
package/providers.js
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.resolveProvider = resolveProvider;
|
|
4
|
+
exports.resolveUpstreamUrl = resolveUpstreamUrl;
|
|
5
|
+
exports.buildProviderHeaders = buildProviderHeaders;
|
|
6
|
+
/**
|
|
7
|
+
* Resolve which provider to use for a given request.
|
|
8
|
+
* Priority: model-based routing → explicit provider header → default.
|
|
9
|
+
*/
|
|
10
|
+
function resolveProvider(options, requestModel, requestProvider) {
|
|
11
|
+
const providers = options.providers || [];
|
|
12
|
+
if (providers.length > 0) {
|
|
13
|
+
if (requestProvider) {
|
|
14
|
+
const match = providers.find((p) => p.type === requestProvider);
|
|
15
|
+
if (match)
|
|
16
|
+
return match;
|
|
17
|
+
}
|
|
18
|
+
// Route by model prefix: "anthropic/claude-3" → anthropic provider
|
|
19
|
+
if (requestModel && requestModel.includes('/')) {
|
|
20
|
+
const prefix = requestModel.split('/')[0];
|
|
21
|
+
const match = providers.find((p) => p.type === prefix);
|
|
22
|
+
if (match) {
|
|
23
|
+
return { ...match, defaultModel: requestModel.split('/').slice(1).join('/') };
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
// Route by known model patterns
|
|
27
|
+
if (requestModel) {
|
|
28
|
+
if (requestModel.startsWith('claude')) {
|
|
29
|
+
const match = providers.find((p) => p.type === 'anthropic');
|
|
30
|
+
if (match)
|
|
31
|
+
return match;
|
|
32
|
+
}
|
|
33
|
+
if (requestModel.startsWith('gpt') || requestModel.startsWith('o1') || requestModel.startsWith('o3')) {
|
|
34
|
+
const match = providers.find((p) => p.type === 'openai');
|
|
35
|
+
if (match)
|
|
36
|
+
return match;
|
|
37
|
+
}
|
|
38
|
+
if (requestModel.startsWith('llama') ||
|
|
39
|
+
requestModel.startsWith('mistral') ||
|
|
40
|
+
requestModel.startsWith('gemma') ||
|
|
41
|
+
requestModel.startsWith('nomic')) {
|
|
42
|
+
const match = providers.find((p) => p.type === 'ollama');
|
|
43
|
+
if (match)
|
|
44
|
+
return match;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return providers[0];
|
|
48
|
+
}
|
|
49
|
+
// Legacy single-provider mode (default: ollama for local dev)
|
|
50
|
+
return {
|
|
51
|
+
type: options.providerType || 'ollama',
|
|
52
|
+
baseUrl: options.providerBaseUrl || 'http://localhost:11434',
|
|
53
|
+
apiKey: options.providerApiKey,
|
|
54
|
+
defaultModel: options.defaultModel
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
function resolveUpstreamUrl(provider, path) {
|
|
58
|
+
if (provider.type === 'ollama') {
|
|
59
|
+
if (path === '/v1/chat/completions')
|
|
60
|
+
return `${provider.baseUrl}/api/chat`;
|
|
61
|
+
if (path === '/v1/embeddings')
|
|
62
|
+
return `${provider.baseUrl}/api/embed`;
|
|
63
|
+
}
|
|
64
|
+
if (provider.type === 'anthropic') {
|
|
65
|
+
if (path === '/v1/chat/completions')
|
|
66
|
+
return `${provider.baseUrl}/v1/messages`;
|
|
67
|
+
}
|
|
68
|
+
return `${provider.baseUrl}${path}`;
|
|
69
|
+
}
|
|
70
|
+
function buildProviderHeaders(provider) {
|
|
71
|
+
const headers = { 'Content-Type': 'application/json' };
|
|
72
|
+
if (provider.apiKey) {
|
|
73
|
+
if (provider.type === 'anthropic') {
|
|
74
|
+
headers['x-api-key'] = provider.apiKey;
|
|
75
|
+
headers['anthropic-version'] = '2023-06-01';
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
headers['Authorization'] = `Bearer ${provider.apiKey}`;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return headers;
|
|
82
|
+
}
|
package/router.d.ts
CHANGED
|
@@ -1,21 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* router —
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* POST /v1/embed → generate embedding
|
|
11
|
-
*
|
|
12
|
-
* All routes require `req.constructive` (from @constructive-io/express-context).
|
|
13
|
-
* Billing (check_quota + record_usage) and inference logging are automatic
|
|
14
|
-
* when the billing/inference_log modules are provisioned.
|
|
15
|
-
*
|
|
16
|
-
* LLM provider config is resolved per-database via `ctx.useLlm()` from the
|
|
17
|
-
* llm_module table, falling back to env vars (EMBEDDER_*, CHAT_*) when the
|
|
18
|
-
* module is not provisioned.
|
|
2
|
+
* Express router — OpenAI-compatible LLM proxy with multi-provider routing.
|
|
3
|
+
*
|
|
4
|
+
* Supports:
|
|
5
|
+
* - Multiple providers (OpenAI, Anthropic, Ollama) configured at startup
|
|
6
|
+
* - Model-based routing: "anthropic/claude-3.5-sonnet" → anthropic provider
|
|
7
|
+
* - Header-based routing: X-LLM-Provider: ollama → ollama provider
|
|
8
|
+
* - Fire-and-forget inference metering via an injected InferenceSink
|
|
9
|
+
* - /v1/usage reporting endpoint for external usage submission
|
|
19
10
|
*/
|
|
20
11
|
import { Router } from 'express';
|
|
21
|
-
|
|
12
|
+
import type { AgenticServerOptions } from './types';
|
|
13
|
+
export declare const createRouter: (options: AgenticServerOptions) => Router;
|