@m6d/cortex-server 1.7.0 → 2.0.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 +8 -3
- package/contracts/README.md +23 -0
- package/contracts/graph/embed.ts +50 -0
- package/{src → contracts}/graph/helpers.ts +4 -10
- package/{src → contracts}/graph/neo4j.ts +14 -27
- package/contracts/graph/schema.ts +65 -0
- package/{src → contracts}/graph/types.ts +2 -29
- package/contracts/graph.ts +36 -0
- package/contracts/runtime.ts +208 -0
- package/contracts/wire.ts +143 -0
- package/dist/contracts/graph/embed.d.ts +22 -0
- package/dist/{src → contracts}/graph/helpers.d.ts +14 -12
- package/dist/{src → contracts}/graph/neo4j.d.ts +5 -5
- package/dist/contracts/graph/schema.d.ts +62 -0
- package/dist/{src → contracts}/graph/types.d.ts +1 -1
- package/dist/contracts/graph.d.ts +14 -0
- package/dist/contracts/runtime.d.ts +278 -0
- package/dist/contracts/wire.d.ts +120 -0
- package/dist/index.d.ts +1 -1
- package/dist/src/lib/adapters/database/index.d.ts +61 -0
- package/dist/src/lib/adapters/database/message-content.d.ts +30 -0
- package/dist/src/lib/adapters/database/mssql/attachments.d.ts +100 -0
- package/dist/src/lib/adapters/database/mssql/client.d.ts +8 -0
- package/dist/src/lib/adapters/database/mssql/index.d.ts +194 -0
- package/dist/src/lib/adapters/database/mssql/llm-requests.d.ts +17 -0
- package/dist/src/lib/adapters/database/mssql/messages.d.ts +37 -0
- package/dist/src/lib/adapters/database/mssql/threads.d.ts +50 -0
- package/dist/src/lib/adapters/database/postgres/attachments.d.ts +113 -0
- package/dist/src/lib/adapters/database/postgres/client.d.ts +8 -0
- package/dist/src/lib/adapters/database/postgres/index.d.ts +207 -0
- package/dist/src/lib/adapters/database/postgres/llm-requests.d.ts +17 -0
- package/dist/src/lib/adapters/database/postgres/messages.d.ts +37 -0
- package/dist/src/lib/adapters/database/postgres/threads.d.ts +50 -0
- package/{src/adapters/storage.ts → dist/src/lib/adapters/storage/index.d.ts} +1 -1
- package/dist/src/{adapters → lib/adapters/storage}/minio.d.ts +1 -1
- package/dist/src/lib/ai/active-runs.d.ts +63 -0
- package/dist/src/lib/ai/attachments.d.ts +30 -0
- package/dist/src/lib/ai/backend-url.d.ts +16 -0
- package/dist/src/lib/ai/cc-runtime.d.ts +61 -0
- package/dist/src/lib/ai/commit-gate.d.ts +21 -0
- package/dist/src/{ai → lib/ai}/context/builder.d.ts +6 -7
- package/dist/src/lib/ai/context/compression-middleware.d.ts +15 -0
- package/dist/src/lib/ai/context/compressor.d.ts +7 -0
- package/dist/src/lib/ai/context/intra-turn-compressor.d.ts +24 -0
- package/dist/src/lib/ai/context/optimize-thread-context.d.ts +9 -0
- package/dist/src/lib/ai/context/summarizer.d.ts +5 -0
- package/dist/src/{ai → lib/ai}/context/token-estimator.d.ts +5 -8
- package/dist/src/{ai → lib/ai}/context/types.d.ts +2 -0
- package/dist/src/{ai → lib/ai}/fetch.d.ts +1 -1
- package/dist/src/lib/ai/finish-turn.d.ts +23 -0
- package/dist/src/lib/ai/helpers.d.ts +38 -0
- package/dist/src/lib/ai/index.d.ts +7 -0
- package/dist/src/lib/ai/inspector.d.ts +41 -0
- package/dist/src/lib/ai/interceptors/request-interceptor.d.ts +13 -0
- package/dist/src/{ai → lib/ai}/prompt.d.ts +5 -4
- package/dist/src/lib/ai/redis-runs.d.ts +41 -0
- package/dist/src/lib/ai/redis-stream-log.d.ts +39 -0
- package/dist/src/lib/ai/tools/execute-code.tool.d.ts +18 -0
- package/dist/src/lib/ai/tools/query-graph.tool.d.ts +13 -0
- package/dist/src/lib/ai/tools/read-attachment.tool.d.ts +21 -0
- package/dist/src/lib/ai/tools/search-common.d.ts +17 -0
- package/dist/src/lib/ai/tools/search-knowledge.tool.d.ts +15 -0
- package/dist/src/lib/ai/tools/search-services.tool.d.ts +12 -0
- package/dist/src/lib/ai/tools/search-tools.tool.d.ts +12 -0
- package/dist/src/lib/ai/turn-tools.d.ts +39 -0
- package/dist/src/lib/ai/vision/rasterize-pdf.d.ts +26 -0
- package/dist/src/lib/ai/vision/rasterize-pdf.worker.d.ts +1 -0
- package/dist/src/lib/ai/vision/vision-reader.d.ts +45 -0
- package/dist/src/lib/cc/client.d.ts +183 -0
- package/dist/src/lib/cc/config-cache.d.ts +20 -0
- package/dist/src/lib/cc/format.d.ts +23 -0
- package/dist/src/lib/cc/registry.d.ts +34 -0
- package/dist/src/lib/cc/types.d.ts +27 -0
- package/dist/src/lib/config.d.ts +170 -0
- package/dist/src/lib/db/drizzle.config.mssql.d.ts +2 -0
- package/dist/src/lib/db/drizzle.config.pg.d.ts +2 -0
- package/dist/src/lib/db/migrate.d.ts +7 -0
- package/dist/src/{db/schema.d.ts → lib/db/schema.mssql.d.ts} +236 -24
- package/dist/src/lib/db/schema.pg.d.ts +546 -0
- package/dist/src/{factory.d.ts → lib/factory.d.ts} +2 -12
- package/dist/src/lib/graph/index.d.ts +10 -0
- package/dist/src/{graph → lib/graph}/resolver.d.ts +2 -3
- package/dist/src/{index.d.ts → lib/index.d.ts} +3 -4
- package/dist/src/lib/redis.d.ts +19 -0
- package/dist/src/{routes → lib/routes}/chat.d.ts +1 -1
- package/dist/src/{routes → lib/routes}/files.d.ts +1 -1
- package/dist/src/lib/routes/owned-thread.d.ts +17 -0
- package/dist/src/{routes → lib/routes}/threads.d.ts +1 -1
- package/dist/src/{routes → lib/routes}/ws.d.ts +1 -1
- package/dist/src/lib/types.d.ts +58 -0
- package/dist/src/{ws → lib/ws}/connections.d.ts +2 -1
- package/index.ts +1 -1
- package/package.json +35 -15
- package/src/lib/adapters/database/index.ts +78 -0
- package/src/lib/adapters/database/message-content.ts +39 -0
- package/src/lib/adapters/database/mssql/attachments.ts +90 -0
- package/src/lib/adapters/database/mssql/client.ts +11 -0
- package/src/lib/adapters/database/mssql/index.ts +23 -0
- package/src/lib/adapters/database/mssql/llm-requests.ts +43 -0
- package/src/lib/adapters/database/mssql/messages.ts +92 -0
- package/src/lib/adapters/database/mssql/threads.ts +83 -0
- package/src/lib/adapters/database/postgres/attachments.ts +88 -0
- package/src/lib/adapters/database/postgres/client.ts +11 -0
- package/src/lib/adapters/database/postgres/index.ts +23 -0
- package/src/lib/adapters/database/postgres/llm-requests.ts +45 -0
- package/src/lib/adapters/database/postgres/messages.ts +92 -0
- package/src/lib/adapters/database/postgres/threads.ts +84 -0
- package/{dist/src/adapters/storage.d.ts → src/lib/adapters/storage/index.ts} +1 -1
- package/src/{adapters → lib/adapters/storage}/minio.ts +7 -6
- package/src/lib/ai/active-runs.ts +157 -0
- package/src/lib/ai/attachments.ts +144 -0
- package/src/lib/ai/backend-url.ts +27 -0
- package/src/lib/ai/cc-runtime.ts +63 -0
- package/src/lib/ai/commit-gate.ts +116 -0
- package/src/{ai → lib/ai}/context/builder.ts +12 -14
- package/src/lib/ai/context/compression-middleware.ts +44 -0
- package/src/lib/ai/context/compressor.ts +267 -0
- package/src/lib/ai/context/intra-turn-compressor.ts +181 -0
- package/src/lib/ai/context/optimize-thread-context.ts +50 -0
- package/src/lib/ai/context/summarizer.ts +48 -0
- package/src/lib/ai/context/token-estimator.ts +65 -0
- package/src/{ai → lib/ai}/context/types.ts +4 -1
- package/src/{ai → lib/ai}/fetch.ts +10 -5
- package/src/lib/ai/finish-turn.ts +75 -0
- package/src/lib/ai/helpers.ts +100 -0
- package/src/lib/ai/index.ts +408 -0
- package/src/lib/ai/inspector.ts +112 -0
- package/src/lib/ai/interceptors/request-interceptor.ts +89 -0
- package/src/lib/ai/prompt.ts +355 -0
- package/src/lib/ai/redis-runs.ts +167 -0
- package/src/lib/ai/redis-stream-log.ts +219 -0
- package/src/lib/ai/tools/execute-code.tool.ts +267 -0
- package/src/{ai → lib/ai}/tools/query-graph.tool.ts +7 -8
- package/src/lib/ai/tools/read-attachment.tool.ts +59 -0
- package/src/lib/ai/tools/search-common.ts +15 -0
- package/src/lib/ai/tools/search-knowledge.tool.ts +33 -0
- package/src/lib/ai/tools/search-services.tool.ts +31 -0
- package/src/lib/ai/tools/search-tools.tool.ts +29 -0
- package/src/lib/ai/turn-tools.ts +154 -0
- package/src/lib/ai/vision/rasterize-pdf.ts +69 -0
- package/src/lib/ai/vision/rasterize-pdf.worker.ts +81 -0
- package/src/lib/ai/vision/vision-reader.ts +130 -0
- package/src/{auth → lib/auth}/middleware.ts +12 -3
- package/src/lib/cc/client.ts +273 -0
- package/src/lib/cc/config-cache.ts +32 -0
- package/src/lib/cc/format.ts +96 -0
- package/src/lib/cc/registry.ts +62 -0
- package/src/lib/cc/types.ts +44 -0
- package/src/lib/config.ts +212 -0
- package/src/lib/db/drizzle.config.mssql.ts +9 -0
- package/src/lib/db/drizzle.config.pg.ts +9 -0
- package/src/lib/db/migrate.ts +56 -0
- package/src/{db/migrations/20260309012148_cloudy_maria_hill → lib/db/migrations/mssql/20260326231647_nice_speedball}/migration.sql +12 -0
- package/src/{db/migrations/20260309012148_cloudy_maria_hill → lib/db/migrations/mssql/20260326231647_nice_speedball}/snapshot.json +106 -1
- package/src/lib/db/migrations/mssql/20260729092726_talented_wilson_fisk/migration.sql +20 -0
- package/src/lib/db/migrations/mssql/20260729092726_talented_wilson_fisk/snapshot.json +497 -0
- package/src/lib/db/migrations/mssql/20260801003652_perpetual_blue_shield/migration.sql +1 -0
- package/src/lib/db/migrations/mssql/20260801003652_perpetual_blue_shield/snapshot.json +516 -0
- package/src/lib/db/migrations/mssql/20260812174642_user_id_text/migration.sql +2 -0
- package/src/lib/db/migrations/mssql/20260812174642_user_id_text/snapshot.json +516 -0
- package/src/lib/db/migrations/pg/20260801084117_thick_ben_grimm/migration.sql +53 -0
- package/src/lib/db/migrations/pg/20260801084117_thick_ben_grimm/snapshot.json +584 -0
- package/src/lib/db/migrations/pg/20260812174622_user_id_text/migration.sql +2 -0
- package/src/lib/db/migrations/pg/20260812174622_user_id_text/snapshot.json +584 -0
- package/src/lib/db/schema.mssql.ts +94 -0
- package/src/lib/db/schema.pg.ts +95 -0
- package/src/lib/factory.ts +127 -0
- package/src/lib/graph/index.ts +19 -0
- package/src/lib/graph/resolver.ts +387 -0
- package/src/{index.ts → lib/index.ts} +13 -5
- package/src/lib/redis.ts +44 -0
- package/src/lib/routes/chat.ts +115 -0
- package/src/lib/routes/files.ts +129 -0
- package/src/lib/routes/owned-thread.ts +17 -0
- package/src/{routes → lib/routes}/threads.ts +22 -31
- package/src/{routes → lib/routes}/ws.ts +9 -3
- package/src/lib/types.ts +76 -0
- package/src/{ws → lib/ws}/connections.ts +9 -1
- package/tsconfig.json +48 -0
- package/dist/src/adapters/database.d.ts +0 -30
- package/dist/src/adapters/mssql.d.ts +0 -3
- package/dist/src/ai/active-streams.d.ts +0 -14
- package/dist/src/ai/context/compressor.d.ts +0 -7
- package/dist/src/ai/context/index.d.ts +0 -15
- package/dist/src/ai/context/summarizer.d.ts +0 -5
- package/dist/src/ai/helpers.d.ts +0 -5
- package/dist/src/ai/index.d.ts +0 -4
- package/dist/src/ai/interceptors/request-interceptor.d.ts +0 -12
- package/dist/src/ai/tools/call-endpoint.tool.d.ts +0 -7
- package/dist/src/ai/tools/capture-files.tool.d.ts +0 -6
- package/dist/src/ai/tools/execute-code.tool.d.ts +0 -4
- package/dist/src/ai/tools/query-graph.tool.d.ts +0 -5
- package/dist/src/cli/extract-endpoints.d.ts +0 -6
- package/dist/src/config.d.ts +0 -165
- package/dist/src/db/migrate.d.ts +0 -1
- package/dist/src/graph/expand-domains.d.ts +0 -2
- package/dist/src/graph/generate-cypher.d.ts +0 -22
- package/dist/src/graph/index.d.ts +0 -11
- package/dist/src/graph/seed.d.ts +0 -19
- package/dist/src/graph/validate.d.ts +0 -2
- package/dist/src/routes/index.d.ts +0 -4
- package/dist/src/types.d.ts +0 -74
- package/dist/src/ws/events.d.ts +0 -39
- package/dist/src/ws/index.d.ts +0 -3
- package/dist/src/ws/notify.d.ts +0 -2
- package/src/adapters/database.ts +0 -29
- package/src/adapters/mssql.ts +0 -195
- package/src/ai/active-streams.ts +0 -123
- package/src/ai/context/compressor.ts +0 -47
- package/src/ai/context/index.ts +0 -75
- package/src/ai/context/summarizer.ts +0 -50
- package/src/ai/context/token-estimator.ts +0 -60
- package/src/ai/helpers.ts +0 -32
- package/src/ai/index.ts +0 -277
- package/src/ai/interceptors/request-interceptor.ts +0 -61
- package/src/ai/prompt.ts +0 -126
- package/src/ai/tools/call-endpoint.tool.ts +0 -89
- package/src/ai/tools/capture-files.tool.ts +0 -20
- package/src/ai/tools/execute-code.tool.ts +0 -153
- package/src/cli/extract-endpoints.ts +0 -550
- package/src/config.ts +0 -182
- package/src/db/migrate.ts +0 -21
- package/src/db/migrations/20260315000000_add_context_meta/migration.sql +0 -1
- package/src/db/schema.ts +0 -70
- package/src/factory.ts +0 -171
- package/src/graph/expand-domains.ts +0 -276
- package/src/graph/generate-cypher.ts +0 -192
- package/src/graph/index.ts +0 -47
- package/src/graph/resolver.ts +0 -357
- package/src/graph/seed.ts +0 -162
- package/src/graph/validate.ts +0 -78
- package/src/routes/chat.ts +0 -86
- package/src/routes/files.ts +0 -100
- package/src/routes/index.ts +0 -4
- package/src/types.ts +0 -74
- package/src/ws/events.ts +0 -39
- package/src/ws/index.ts +0 -11
- package/src/ws/notify.ts +0 -9
- /package/dist/src/{auth → lib/auth}/middleware.d.ts +0 -0
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
import type { DatabaseAdapter } from "../../adapters/database.ts";
|
|
2
|
-
import type { StorageAdapter } from "../../adapters/storage.ts";
|
|
3
|
-
import { streamToBase64, tokenToUserId } from "../helpers.ts";
|
|
4
|
-
|
|
5
|
-
export type ResolvedFile = {
|
|
6
|
-
name: string;
|
|
7
|
-
bytes: string;
|
|
8
|
-
};
|
|
9
|
-
|
|
10
|
-
export type RequestInterceptorOptions = {
|
|
11
|
-
transformFile?: (file: ResolvedFile) => unknown;
|
|
12
|
-
};
|
|
13
|
-
|
|
14
|
-
export function createRequestInterceptor(
|
|
15
|
-
db: DatabaseAdapter,
|
|
16
|
-
storage: StorageAdapter,
|
|
17
|
-
options?: RequestInterceptorOptions,
|
|
18
|
-
) {
|
|
19
|
-
const transformFile = options?.transformFile ?? ((file: ResolvedFile) => file);
|
|
20
|
-
|
|
21
|
-
return async function resolveRequestBody(
|
|
22
|
-
body: Record<string, unknown>,
|
|
23
|
-
context: { token: string },
|
|
24
|
-
) {
|
|
25
|
-
const userId = tokenToUserId(context.token);
|
|
26
|
-
|
|
27
|
-
async function traverse(obj: Record<string, unknown>) {
|
|
28
|
-
await Promise.all(
|
|
29
|
-
Object.keys(obj).map(async (key) => {
|
|
30
|
-
const value = obj[key];
|
|
31
|
-
if (typeof value === "string" && value.startsWith("capturedFile")) {
|
|
32
|
-
const [_, uploadId] = value.split("#");
|
|
33
|
-
const file = await db.capturedFiles.getById(uploadId!, userId);
|
|
34
|
-
if (file) {
|
|
35
|
-
const fileStream = await storage.stream(`captured_files/${uploadId}`);
|
|
36
|
-
const bytes = await streamToBase64(fileStream);
|
|
37
|
-
obj[key] = transformFile({ name: file.name, bytes });
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
if (Array.isArray(value)) {
|
|
42
|
-
await Promise.all(
|
|
43
|
-
value.map(async (child) => {
|
|
44
|
-
if (typeof child === "object" && child !== null) {
|
|
45
|
-
await traverse(child as Record<string, unknown>);
|
|
46
|
-
}
|
|
47
|
-
}),
|
|
48
|
-
);
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
if (typeof value === "object" && value !== null && !Array.isArray(value)) {
|
|
52
|
-
await traverse(value as Record<string, unknown>);
|
|
53
|
-
}
|
|
54
|
-
}),
|
|
55
|
-
);
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
await traverse(body);
|
|
59
|
-
return body;
|
|
60
|
-
};
|
|
61
|
-
}
|
package/src/ai/prompt.ts
DELETED
|
@@ -1,126 +0,0 @@
|
|
|
1
|
-
import type { ResolvedContext } from "../graph/resolver.ts";
|
|
2
|
-
import type { PromptContext, ResolvedCortexAgentConfig } from "../config.ts";
|
|
3
|
-
import type { Thread } from "../types.ts";
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Resolves session data for the thread, loading from the configured
|
|
7
|
-
* session loader if not already cached on the thread.
|
|
8
|
-
*/
|
|
9
|
-
export async function resolveSession(
|
|
10
|
-
config: ResolvedCortexAgentConfig,
|
|
11
|
-
thread: Thread,
|
|
12
|
-
token: string,
|
|
13
|
-
) {
|
|
14
|
-
let session = thread.session;
|
|
15
|
-
|
|
16
|
-
if (!session && config.loadSessionData) {
|
|
17
|
-
session = await config.loadSessionData(token);
|
|
18
|
-
// Persist to DB for future cache hits
|
|
19
|
-
await config.db.threads.updateSession(thread.id, session);
|
|
20
|
-
thread.session = session;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
return session;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export async function buildSystemPrompt(
|
|
27
|
-
config: ResolvedCortexAgentConfig,
|
|
28
|
-
resolved: ResolvedContext | null,
|
|
29
|
-
promptContext: PromptContext,
|
|
30
|
-
) {
|
|
31
|
-
// Resolve the consumer's base system prompt
|
|
32
|
-
let basePrompt: string;
|
|
33
|
-
if (typeof config.systemPrompt === "function") {
|
|
34
|
-
basePrompt = await config.systemPrompt(promptContext);
|
|
35
|
-
} else {
|
|
36
|
-
basePrompt = config.systemPrompt;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
const sections: string[] = [basePrompt];
|
|
40
|
-
|
|
41
|
-
// Pre-resolved endpoints from knowledge graph
|
|
42
|
-
if (resolved) {
|
|
43
|
-
sections.push(buildResolvedSection(resolved));
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
return sections.join("\n");
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
function buildResolvedSection(resolved: ResolvedContext) {
|
|
50
|
-
const parts: string[] = [
|
|
51
|
-
`
|
|
52
|
-
## Pre-resolved API Endpoints
|
|
53
|
-
The following endpoints were automatically matched to the user's message.`,
|
|
54
|
-
];
|
|
55
|
-
|
|
56
|
-
for (const ep of resolved.readEndpoints) {
|
|
57
|
-
const rules = ep.rules.length > 0 ? `\n Rules: ${ep.rules.join("; ")}` : "";
|
|
58
|
-
const deps =
|
|
59
|
-
ep.dependencies.length > 0
|
|
60
|
-
? "\n Dependencies:\n" +
|
|
61
|
-
ep.dependencies
|
|
62
|
-
.map(
|
|
63
|
-
(d) =>
|
|
64
|
-
` - Call ${d.depMethod} ${d.depPath} first → use its "${d.fromField}" as "${d.paramName}"`,
|
|
65
|
-
)
|
|
66
|
-
.join("\n")
|
|
67
|
-
: "";
|
|
68
|
-
const meta = ep.metadata !== "{}" ? `\n- Metadata: ${ep.metadata}` : "";
|
|
69
|
-
parts.push(
|
|
70
|
-
`
|
|
71
|
-
### ${ep.concept} (read)
|
|
72
|
-
- Endpoint: ${ep.name}
|
|
73
|
-
- ${ep.method} ${ep.path}
|
|
74
|
-
- Params: ${ep.params}
|
|
75
|
-
- Body: ${ep.body}
|
|
76
|
-
- Response: ${ep.response}${rules}${deps}${meta}`,
|
|
77
|
-
);
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
for (const ep of resolved.writeEndpoints) {
|
|
81
|
-
const rules = ep.rules.length > 0 ? `\n Rules: ${ep.rules.join("; ")}` : "";
|
|
82
|
-
const deps =
|
|
83
|
-
ep.dependencies.length > 0
|
|
84
|
-
? "\n Dependencies:\n" +
|
|
85
|
-
ep.dependencies
|
|
86
|
-
.map(
|
|
87
|
-
(d) =>
|
|
88
|
-
` - Call ${d.depMethod} ${d.depPath} first → use its "${d.fromField}" as "${d.paramName}"`,
|
|
89
|
-
)
|
|
90
|
-
.join("\n")
|
|
91
|
-
: "";
|
|
92
|
-
const meta = ep.metadata !== "{}" ? `\n- Metadata: ${ep.metadata}` : "";
|
|
93
|
-
parts.push(
|
|
94
|
-
`
|
|
95
|
-
### ${ep.concept} (write)
|
|
96
|
-
- Endpoint: ${ep.name}
|
|
97
|
-
- ${ep.method} ${ep.path}
|
|
98
|
-
- Params: ${ep.params}
|
|
99
|
-
- Body: ${ep.body}
|
|
100
|
-
- Response: ${ep.response}${rules}${deps}${meta}`,
|
|
101
|
-
);
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
for (const svc of resolved.services) {
|
|
105
|
-
const rules = svc.rules.length > 0 ? `\n Rules: ${svc.rules.join("; ")}` : "";
|
|
106
|
-
const meta = svc.metadata !== "{}" ? `\n- Metadata: ${svc.metadata}` : "";
|
|
107
|
-
parts.push(
|
|
108
|
-
`
|
|
109
|
-
### ${svc.concept} via ${svc.serviceName} (service)
|
|
110
|
-
- Built-in ID: ${svc.builtInId}
|
|
111
|
-
- Description: ${svc.description || "N/A"}${rules}${meta}`,
|
|
112
|
-
);
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
if (
|
|
116
|
-
resolved.readEndpoints.length === 0 &&
|
|
117
|
-
resolved.writeEndpoints.length === 0 &&
|
|
118
|
-
resolved.services.length === 0
|
|
119
|
-
) {
|
|
120
|
-
parts.push(
|
|
121
|
-
"\nNo matching endpoints found. Use queryGraph to search the knowledge graph manually.",
|
|
122
|
-
);
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
return parts.join("");
|
|
126
|
-
}
|
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
import { tool } from "ai";
|
|
2
|
-
import z from "zod";
|
|
3
|
-
import type { ResolvedCortexAgentConfig } from "../../config.ts";
|
|
4
|
-
import { fetchBackend } from "../fetch.ts";
|
|
5
|
-
|
|
6
|
-
export function createCallEndpointTool(
|
|
7
|
-
backendFetch: NonNullable<ResolvedCortexAgentConfig["backendFetch"]>,
|
|
8
|
-
token: string,
|
|
9
|
-
) {
|
|
10
|
-
return tool({
|
|
11
|
-
title: "Call an API endpoint",
|
|
12
|
-
description:
|
|
13
|
-
"Call an API endpoint on the backend. Use queryGraph first to discover the correct endpoint, parameters, and business rules. For write operations (POST/PUT/DELETE), ALWAYS get explicit user confirmation before calling.",
|
|
14
|
-
inputSchema: z.object({
|
|
15
|
-
path: z
|
|
16
|
-
.string()
|
|
17
|
-
.describe(
|
|
18
|
-
'The API path including path parameters. Example: "/items/list" or "/resources/{id}"',
|
|
19
|
-
),
|
|
20
|
-
method: z.enum(["GET", "POST", "PUT", "DELETE"]).describe("The HTTP method"),
|
|
21
|
-
queryParams: z
|
|
22
|
-
.string()
|
|
23
|
-
.optional()
|
|
24
|
-
.describe("Optional JSON-encoded string of query parameters."),
|
|
25
|
-
body: z
|
|
26
|
-
.string()
|
|
27
|
-
.optional()
|
|
28
|
-
.describe(
|
|
29
|
-
"Optional JSON-encoded string of request body for POST/PUT. For parameters of type file, use `capturedFile#[uploadId]` as the value.",
|
|
30
|
-
),
|
|
31
|
-
}),
|
|
32
|
-
execute: async ({ path, method, queryParams, body }) => {
|
|
33
|
-
let fullPath = path;
|
|
34
|
-
if (queryParams) {
|
|
35
|
-
const params = JSON.parse(queryParams) as Record<string, unknown>;
|
|
36
|
-
const searchParams = new URLSearchParams();
|
|
37
|
-
for (const [key, value] of Object.entries(params)) {
|
|
38
|
-
if (value == null || value === "") continue;
|
|
39
|
-
if (Array.isArray(value)) {
|
|
40
|
-
for (const item of value) {
|
|
41
|
-
searchParams.append(key, String(item));
|
|
42
|
-
}
|
|
43
|
-
} else {
|
|
44
|
-
searchParams.set(key, String(value));
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
const qs = searchParams.toString();
|
|
48
|
-
if (qs) fullPath += `?${qs}`;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
const options: RequestInit = { method };
|
|
52
|
-
if (body && (method === "POST" || method === "PUT")) {
|
|
53
|
-
options.body = body;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
const response = await fetchBackend(fullPath, backendFetch, token, options);
|
|
57
|
-
|
|
58
|
-
if (!response.ok) {
|
|
59
|
-
let message: string;
|
|
60
|
-
let details: unknown = undefined;
|
|
61
|
-
try {
|
|
62
|
-
const errorBody = (await response.json()) as Record<string, unknown>;
|
|
63
|
-
message =
|
|
64
|
-
(errorBody.message as string) ||
|
|
65
|
-
(errorBody.title as string) ||
|
|
66
|
-
JSON.stringify(errorBody);
|
|
67
|
-
if (errorBody.errors) {
|
|
68
|
-
details = errorBody.errors;
|
|
69
|
-
}
|
|
70
|
-
} catch {
|
|
71
|
-
message = `Request failed with status ${response.status}`;
|
|
72
|
-
}
|
|
73
|
-
return JSON.stringify({
|
|
74
|
-
error: true,
|
|
75
|
-
status: response.status,
|
|
76
|
-
message,
|
|
77
|
-
...(details ? { details } : {}),
|
|
78
|
-
});
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
if (response.status === 204) {
|
|
82
|
-
return JSON.stringify({ success: true });
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
const data = await response.json();
|
|
86
|
-
return JSON.stringify(data);
|
|
87
|
-
},
|
|
88
|
-
});
|
|
89
|
-
}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { tool } from "ai";
|
|
2
|
-
import z from "zod";
|
|
3
|
-
|
|
4
|
-
export const captureFilesTool = tool({
|
|
5
|
-
description: "Let the user upload a file",
|
|
6
|
-
inputSchema: z.object({
|
|
7
|
-
files: z.array(
|
|
8
|
-
z.object({
|
|
9
|
-
label: z
|
|
10
|
-
.string()
|
|
11
|
-
.describe("A label to view to the user to know what file they need to upload"),
|
|
12
|
-
id: z
|
|
13
|
-
.string()
|
|
14
|
-
.describe(
|
|
15
|
-
"An ID to the file for you to use it when calling apis or later processing",
|
|
16
|
-
),
|
|
17
|
-
}),
|
|
18
|
-
),
|
|
19
|
-
}),
|
|
20
|
-
});
|
|
@@ -1,153 +0,0 @@
|
|
|
1
|
-
import { tool } from "ai";
|
|
2
|
-
import z from "zod";
|
|
3
|
-
import type { ResolvedCortexAgentConfig } from "../../config.ts";
|
|
4
|
-
import { fetchBackend } from "../fetch.ts";
|
|
5
|
-
import { getQuickJS, Scope, shouldInterruptAfterDeadline } from "quickjs-emscripten";
|
|
6
|
-
|
|
7
|
-
function buildQueryString(params: Record<string, unknown>) {
|
|
8
|
-
const searchParams = new URLSearchParams();
|
|
9
|
-
for (const [key, value] of Object.entries(params)) {
|
|
10
|
-
if (value == null || value === "") continue;
|
|
11
|
-
if (Array.isArray(value)) {
|
|
12
|
-
for (const item of value) {
|
|
13
|
-
searchParams.append(key, String(item));
|
|
14
|
-
}
|
|
15
|
-
} else {
|
|
16
|
-
searchParams.set(key, String(value));
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
const qs = searchParams.toString();
|
|
20
|
-
return qs ? `?${qs}` : "";
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
async function runInSandbox(
|
|
24
|
-
code: string,
|
|
25
|
-
backendFetch: NonNullable<ResolvedCortexAgentConfig["backendFetch"]>,
|
|
26
|
-
token: string,
|
|
27
|
-
) {
|
|
28
|
-
async function request(method: string, path: string, body?: unknown) {
|
|
29
|
-
const options: RequestInit = { method };
|
|
30
|
-
if (body !== undefined && (method === "POST" || method === "PUT")) {
|
|
31
|
-
options.body = JSON.stringify(body);
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
const response = await fetchBackend(path, backendFetch, token, options);
|
|
35
|
-
|
|
36
|
-
if (!response.ok) {
|
|
37
|
-
let message: string;
|
|
38
|
-
try {
|
|
39
|
-
const errorBody = await response.json();
|
|
40
|
-
message = JSON.stringify(errorBody);
|
|
41
|
-
} catch {
|
|
42
|
-
message = `HTTP ${response.status}`;
|
|
43
|
-
}
|
|
44
|
-
throw new Error(`API ${method} ${path} failed (${response.status}): ${message}`);
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
if (response.status === 204) return { success: true };
|
|
48
|
-
return response.json();
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
return await Scope.withScopeAsync(async (scope) => {
|
|
52
|
-
const QuickJS = await getQuickJS();
|
|
53
|
-
|
|
54
|
-
const runtime = scope.manage(QuickJS.newRuntime());
|
|
55
|
-
runtime.setMemoryLimit(1024 * 1024 * 20); // 20MB
|
|
56
|
-
runtime.setInterruptHandler(shouldInterruptAfterDeadline(Date.now() + 10_000)); // 60 seconds;
|
|
57
|
-
|
|
58
|
-
const vm = scope.manage(runtime.newContext());
|
|
59
|
-
|
|
60
|
-
function drainJobs() {
|
|
61
|
-
vm.runtime.executePendingJobs();
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
function makeApiFunction(fn: (...args: unknown[]) => Promise<unknown>) {
|
|
65
|
-
return scope.manage(
|
|
66
|
-
vm.newFunction(fn.name, (...argHandles) => {
|
|
67
|
-
const args = argHandles.map(vm.dump.bind(vm));
|
|
68
|
-
const promise = scope.manage(
|
|
69
|
-
vm.newPromise(
|
|
70
|
-
fn(...args).then((result) =>
|
|
71
|
-
scope.manage(
|
|
72
|
-
vm.unwrapResult(vm.evalCode(`(${JSON.stringify(result)})`)),
|
|
73
|
-
),
|
|
74
|
-
),
|
|
75
|
-
),
|
|
76
|
-
);
|
|
77
|
-
|
|
78
|
-
promise.settled.finally(() => {
|
|
79
|
-
drainJobs();
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
return promise.handle;
|
|
83
|
-
}),
|
|
84
|
-
);
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
const apiHandle = scope.manage(vm.newObject());
|
|
88
|
-
vm.setProp(
|
|
89
|
-
apiHandle,
|
|
90
|
-
"get",
|
|
91
|
-
makeApiFunction(async (path, queryParams?) => {
|
|
92
|
-
const fullPath = queryParams
|
|
93
|
-
? path + buildQueryString(queryParams as Record<string, unknown>)
|
|
94
|
-
: path;
|
|
95
|
-
return await request("GET", fullPath as string);
|
|
96
|
-
}),
|
|
97
|
-
);
|
|
98
|
-
vm.setProp(
|
|
99
|
-
apiHandle,
|
|
100
|
-
"post",
|
|
101
|
-
makeApiFunction(async (path, body) => await request("POST", path as string, body)),
|
|
102
|
-
);
|
|
103
|
-
vm.setProp(
|
|
104
|
-
apiHandle,
|
|
105
|
-
"put",
|
|
106
|
-
makeApiFunction(async (path, body) => await request("PUT", path as string, body)),
|
|
107
|
-
);
|
|
108
|
-
vm.setProp(
|
|
109
|
-
apiHandle,
|
|
110
|
-
"del",
|
|
111
|
-
makeApiFunction(async (path) => await request("DELETE", path as string)),
|
|
112
|
-
);
|
|
113
|
-
|
|
114
|
-
vm.setProp(vm.global, "api", apiHandle);
|
|
115
|
-
|
|
116
|
-
const runResult = vm.evalCode(`(async () => {
|
|
117
|
-
${code}
|
|
118
|
-
})()`);
|
|
119
|
-
const resultHandle = scope.manage(vm.unwrapResult(runResult));
|
|
120
|
-
const pending = vm.resolvePromise(resultHandle);
|
|
121
|
-
drainJobs();
|
|
122
|
-
const resolvedResult = await pending;
|
|
123
|
-
const result = scope.manage(vm.unwrapResult(resolvedResult));
|
|
124
|
-
return vm.dump(result);
|
|
125
|
-
});
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
export function createExecuteCodeTool(
|
|
129
|
-
backendFetch: NonNullable<ResolvedCortexAgentConfig["backendFetch"]>,
|
|
130
|
-
token: string,
|
|
131
|
-
) {
|
|
132
|
-
return tool({
|
|
133
|
-
title: "Executes JavaScript code",
|
|
134
|
-
description:
|
|
135
|
-
"Run a JavaScript script that calls APIs and returns only relevant data. The script has an `api` helper: api.get(path, params?), api.post(path, body?), api.put(path, body?), api.del(path). Each returns parsed JSON and throws on error. For parameters of type file, use `capturedFile#[uploadId]` as the value.",
|
|
136
|
-
inputSchema: z.object({
|
|
137
|
-
code: z
|
|
138
|
-
.string()
|
|
139
|
-
.describe(
|
|
140
|
-
"Async JS function body. Use the `api` helper to call endpoints. Return only the data needed for your response.",
|
|
141
|
-
),
|
|
142
|
-
}),
|
|
143
|
-
execute: async ({ code }) => {
|
|
144
|
-
try {
|
|
145
|
-
const result = await runInSandbox(code, backendFetch, token);
|
|
146
|
-
return JSON.stringify(result);
|
|
147
|
-
} catch (e) {
|
|
148
|
-
const message = e instanceof Error ? e.message : String(e);
|
|
149
|
-
return JSON.stringify({ error: true, message });
|
|
150
|
-
}
|
|
151
|
-
},
|
|
152
|
-
});
|
|
153
|
-
}
|