@davidjinguoxu/agentcore 0.4.1
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 +198 -0
- package/config/default-triggers.json +119 -0
- package/dist/adapters/runtime-adapter.d.ts +124 -0
- package/dist/adapters/runtime-adapter.d.ts.map +1 -0
- package/dist/adapters/runtime-adapter.js +5 -0
- package/dist/adapters/runtime-adapter.js.map +1 -0
- package/dist/config/datacore-constants.d.ts +21 -0
- package/dist/config/datacore-constants.d.ts.map +1 -0
- package/dist/config/datacore-constants.js +68 -0
- package/dist/config/datacore-constants.js.map +1 -0
- package/dist/domain/embeddable.d.ts +19 -0
- package/dist/domain/embeddable.d.ts.map +1 -0
- package/dist/domain/embeddable.js +106 -0
- package/dist/domain/embeddable.js.map +1 -0
- package/dist/domain/gold-store.d.ts +11 -0
- package/dist/domain/gold-store.d.ts.map +1 -0
- package/dist/domain/gold-store.js +210 -0
- package/dist/domain/gold-store.js.map +1 -0
- package/dist/domain/inbox.d.ts +14 -0
- package/dist/domain/inbox.d.ts.map +1 -0
- package/dist/domain/inbox.js +138 -0
- package/dist/domain/inbox.js.map +1 -0
- package/dist/domain/office-status.d.ts +31 -0
- package/dist/domain/office-status.d.ts.map +1 -0
- package/dist/domain/office-status.js +138 -0
- package/dist/domain/office-status.js.map +1 -0
- package/dist/domain/questions.d.ts +3 -0
- package/dist/domain/questions.d.ts.map +1 -0
- package/dist/domain/questions.js +60 -0
- package/dist/domain/questions.js.map +1 -0
- package/dist/domain/run-manager.d.ts +14 -0
- package/dist/domain/run-manager.d.ts.map +1 -0
- package/dist/domain/run-manager.js +25 -0
- package/dist/domain/run-manager.js.map +1 -0
- package/dist/domain/task-event-index.d.ts +31 -0
- package/dist/domain/task-event-index.d.ts.map +1 -0
- package/dist/domain/task-event-index.js +117 -0
- package/dist/domain/task-event-index.js.map +1 -0
- package/dist/domain/tasks.d.ts +3 -0
- package/dist/domain/tasks.d.ts.map +1 -0
- package/dist/domain/tasks.js +112 -0
- package/dist/domain/tasks.js.map +1 -0
- package/dist/domain/warm-start-builders.d.ts +18 -0
- package/dist/domain/warm-start-builders.d.ts.map +1 -0
- package/dist/domain/warm-start-builders.js +157 -0
- package/dist/domain/warm-start-builders.js.map +1 -0
- package/dist/domain/warm-start-extractors.d.ts +37 -0
- package/dist/domain/warm-start-extractors.d.ts.map +1 -0
- package/dist/domain/warm-start-extractors.js +372 -0
- package/dist/domain/warm-start-extractors.js.map +1 -0
- package/dist/domain/warm-start.d.ts +17 -0
- package/dist/domain/warm-start.d.ts.map +1 -0
- package/dist/domain/warm-start.js +225 -0
- package/dist/domain/warm-start.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp-slim-ack.d.ts +12 -0
- package/dist/mcp-slim-ack.d.ts.map +1 -0
- package/dist/mcp-slim-ack.js +16 -0
- package/dist/mcp-slim-ack.js.map +1 -0
- package/dist/routing/capability-registry.d.ts +38 -0
- package/dist/routing/capability-registry.d.ts.map +1 -0
- package/dist/routing/capability-registry.js +52 -0
- package/dist/routing/capability-registry.js.map +1 -0
- package/dist/routing/runtime-target-resolver.d.ts +42 -0
- package/dist/routing/runtime-target-resolver.d.ts.map +1 -0
- package/dist/routing/runtime-target-resolver.js +139 -0
- package/dist/routing/runtime-target-resolver.js.map +1 -0
- package/dist/search/azure-search-client.d.ts +53 -0
- package/dist/search/azure-search-client.d.ts.map +1 -0
- package/dist/search/azure-search-client.js +191 -0
- package/dist/search/azure-search-client.js.map +1 -0
- package/dist/search/circuit-breaker.d.ts +46 -0
- package/dist/search/circuit-breaker.d.ts.map +1 -0
- package/dist/search/circuit-breaker.js +87 -0
- package/dist/search/circuit-breaker.js.map +1 -0
- package/dist/search/deep-search.d.ts +24 -0
- package/dist/search/deep-search.d.ts.map +1 -0
- package/dist/search/deep-search.js +98 -0
- package/dist/search/deep-search.js.map +1 -0
- package/dist/search/search.d.ts +3 -0
- package/dist/search/search.d.ts.map +1 -0
- package/dist/search/search.js +76 -0
- package/dist/search/search.js.map +1 -0
- package/dist/server.d.ts +3 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +39 -0
- package/dist/server.js.map +1 -0
- package/dist/skills/index.d.ts +3 -0
- package/dist/skills/index.d.ts.map +1 -0
- package/dist/skills/index.js +8 -0
- package/dist/skills/index.js.map +1 -0
- package/dist/skills/knowledge.d.ts +3 -0
- package/dist/skills/knowledge.d.ts.map +1 -0
- package/dist/skills/knowledge.js +78 -0
- package/dist/skills/knowledge.js.map +1 -0
- package/dist/skills/task-workflow.d.ts +3 -0
- package/dist/skills/task-workflow.d.ts.map +1 -0
- package/dist/skills/task-workflow.js +205 -0
- package/dist/skills/task-workflow.js.map +1 -0
- package/dist/storage/active-backend.d.ts +4 -0
- package/dist/storage/active-backend.d.ts.map +1 -0
- package/dist/storage/active-backend.js +12 -0
- package/dist/storage/active-backend.js.map +1 -0
- package/dist/storage/backend.d.ts +12 -0
- package/dist/storage/backend.d.ts.map +1 -0
- package/dist/storage/backend.js +5 -0
- package/dist/storage/backend.js.map +1 -0
- package/dist/storage/cosmos-client.d.ts +6 -0
- package/dist/storage/cosmos-client.d.ts.map +1 -0
- package/dist/storage/cosmos-client.js +38 -0
- package/dist/storage/cosmos-client.js.map +1 -0
- package/dist/storage/lancedb-backend.d.ts +13 -0
- package/dist/storage/lancedb-backend.d.ts.map +1 -0
- package/dist/storage/lancedb-backend.js +373 -0
- package/dist/storage/lancedb-backend.js.map +1 -0
- package/dist/storage/store.d.ts +8 -0
- package/dist/storage/store.d.ts.map +1 -0
- package/dist/storage/store.js +294 -0
- package/dist/storage/store.js.map +1 -0
- package/dist/storage/task-compaction.d.ts +12 -0
- package/dist/storage/task-compaction.d.ts.map +1 -0
- package/dist/storage/task-compaction.js +112 -0
- package/dist/storage/task-compaction.js.map +1 -0
- package/dist/storage/task-context-snapshot.d.ts +6 -0
- package/dist/storage/task-context-snapshot.d.ts.map +1 -0
- package/dist/storage/task-context-snapshot.js +87 -0
- package/dist/storage/task-context-snapshot.js.map +1 -0
- package/dist/storage/trigger-engine.d.ts +39 -0
- package/dist/storage/trigger-engine.d.ts.map +1 -0
- package/dist/storage/trigger-engine.js +212 -0
- package/dist/storage/trigger-engine.js.map +1 -0
- package/dist/tools.d.ts +3 -0
- package/dist/tools.d.ts.map +1 -0
- package/dist/tools.js +413 -0
- package/dist/tools.js.map +1 -0
- package/dist/transport/client.d.ts +68 -0
- package/dist/transport/client.d.ts.map +1 -0
- package/dist/transport/client.js +210 -0
- package/dist/transport/client.js.map +1 -0
- package/dist/transport/http-server.d.ts +3 -0
- package/dist/transport/http-server.d.ts.map +1 -0
- package/dist/transport/http-server.js +337 -0
- package/dist/transport/http-server.js.map +1 -0
- package/dist/types.d.ts +185 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/package.json +71 -0
- package/scripts/run-server.mjs +3 -0
- package/scripts/stdio-only.mjs +23 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"azure-search-client.d.ts","sourceRoot":"","sources":["../../src/search/azure-search-client.ts"],"names":[],"mappings":"AAaA,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,iBAAiB,EAAE,CAAC;CAC9B;AAED,wBAAgB,oBAAoB,IAAI,OAAO,CAE9C;AAED,wBAAgB,oBAAoB,IAAI,OAAO,CAM9C;AA4BD;;;GAGG;AACH,wBAAsB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,CA2BtE;AAED;;;;GAIG;AACH,wBAAsB,UAAU,CAAC,MAAM,EAAE;IACvC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,GAAG,OAAO,CAAC,IAAI,CAAC,CA2ChB;AAED;;GAEG;AACH,wBAAsB,YAAY,CAChC,KAAK,EAAE,MAAM,EACb,OAAO,GAAE;IACP,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,QAAQ,GAAG,UAAU,CAAC;CACzB,GACL,OAAO,CAAC,iBAAiB,CAAC,CA8F5B"}
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
// azure-search-client.ts — How does Azure AI Search connect?
|
|
2
|
+
// Handles: credential guard, text embedding via Azure OpenAI, event indexing, vector search.
|
|
3
|
+
// Uses raw fetch — no @azure/search-documents SDK dependency.
|
|
4
|
+
// Falls back gracefully: if not configured, callers should use Databricks instead.
|
|
5
|
+
function azureOpenAiEmbeddingsApiVersion() {
|
|
6
|
+
return process.env.AZURE_OPENAI_EMBEDDINGS_API_VERSION ?? "2024-02-01";
|
|
7
|
+
}
|
|
8
|
+
function azureSearchRestApiVersion() {
|
|
9
|
+
return process.env.AZURE_SEARCH_API_VERSION ?? "2024-07-01";
|
|
10
|
+
}
|
|
11
|
+
export function isAzureSearchEnabled() {
|
|
12
|
+
return !!(process.env.AZURE_SEARCH_ENDPOINT && process.env.AZURE_SEARCH_KEY);
|
|
13
|
+
}
|
|
14
|
+
export function isAzureOpenAIEnabled() {
|
|
15
|
+
return !!(process.env.AZURE_OPENAI_ENDPOINT &&
|
|
16
|
+
process.env.AZURE_OPENAI_KEY &&
|
|
17
|
+
process.env.AZURE_OPENAI_EMBEDDING_DEPLOYMENT);
|
|
18
|
+
}
|
|
19
|
+
function getConfig() {
|
|
20
|
+
const endpoint = process.env.AZURE_SEARCH_ENDPOINT;
|
|
21
|
+
const key = process.env.AZURE_SEARCH_KEY;
|
|
22
|
+
const indexName = process.env.AZURE_SEARCH_INDEX ?? "datacore-events";
|
|
23
|
+
const openAiEndpoint = process.env.AZURE_OPENAI_ENDPOINT ?? "";
|
|
24
|
+
const openAiKey = process.env.AZURE_OPENAI_KEY ?? "";
|
|
25
|
+
const openAiDeployment = process.env.AZURE_OPENAI_EMBEDDING_DEPLOYMENT ?? "text-embedding-ada-002";
|
|
26
|
+
if (!endpoint || !key) {
|
|
27
|
+
throw new Error("AZURE_SEARCH_ENDPOINT and AZURE_SEARCH_KEY must be set. " +
|
|
28
|
+
"Get these from: Azure Portal → search-datacore → Keys.");
|
|
29
|
+
}
|
|
30
|
+
return {
|
|
31
|
+
endpoint: endpoint.replace(/\/$/, ""),
|
|
32
|
+
key,
|
|
33
|
+
indexName,
|
|
34
|
+
openAiEndpoint: openAiEndpoint.replace(/\/$/, ""),
|
|
35
|
+
openAiKey,
|
|
36
|
+
openAiDeployment,
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Embed a text string using Azure OpenAI.
|
|
41
|
+
* Returns a 1536-dim vector (text-embedding-ada-002) or null if not configured.
|
|
42
|
+
*/
|
|
43
|
+
export async function embedText(text) {
|
|
44
|
+
if (!isAzureOpenAIEnabled())
|
|
45
|
+
return null;
|
|
46
|
+
const cfg = getConfig();
|
|
47
|
+
const url = `${cfg.openAiEndpoint}/openai/deployments/${cfg.openAiDeployment}` +
|
|
48
|
+
`/embeddings?api-version=${azureOpenAiEmbeddingsApiVersion()}`;
|
|
49
|
+
const response = await fetch(url, {
|
|
50
|
+
method: "POST",
|
|
51
|
+
headers: {
|
|
52
|
+
"Content-Type": "application/json",
|
|
53
|
+
"api-key": cfg.openAiKey,
|
|
54
|
+
},
|
|
55
|
+
body: JSON.stringify({ input: text.slice(0, 8192) }),
|
|
56
|
+
});
|
|
57
|
+
if (!response.ok) {
|
|
58
|
+
const text = await response.text();
|
|
59
|
+
throw new Error(`Azure OpenAI embeddings ${response.status}: ${text}`);
|
|
60
|
+
}
|
|
61
|
+
const data = (await response.json());
|
|
62
|
+
return data.data[0]?.embedding ?? null;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Index a single Bronze event into Azure AI Search.
|
|
66
|
+
* Silently skips if Azure Search is not configured.
|
|
67
|
+
* Skips embedding if Azure OpenAI is not configured (text-only index).
|
|
68
|
+
*/
|
|
69
|
+
export async function indexEvent(record) {
|
|
70
|
+
if (!isAzureSearchEnabled())
|
|
71
|
+
return;
|
|
72
|
+
const cfg = getConfig();
|
|
73
|
+
const id = record._event_id ?? crypto.randomUUID();
|
|
74
|
+
// Attempt embedding — non-fatal if unavailable
|
|
75
|
+
let vector = null;
|
|
76
|
+
try {
|
|
77
|
+
vector = await embedText(record.content ?? "");
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
// Embedding failure is non-fatal — index without vector
|
|
81
|
+
}
|
|
82
|
+
const doc = {
|
|
83
|
+
id,
|
|
84
|
+
content: record.content ?? "",
|
|
85
|
+
source: record.source ?? "",
|
|
86
|
+
type: record.type ?? "",
|
|
87
|
+
timestamp: record._timestamp ?? new Date().toISOString(),
|
|
88
|
+
context: record.context ? JSON.stringify(record.context) : "",
|
|
89
|
+
};
|
|
90
|
+
if (vector !== null) {
|
|
91
|
+
doc["content_vector"] = vector;
|
|
92
|
+
}
|
|
93
|
+
const url = `${cfg.endpoint}/indexes/${cfg.indexName}/docs/index?api-version=${azureSearchRestApiVersion()}`;
|
|
94
|
+
const response = await fetch(url, {
|
|
95
|
+
method: "POST",
|
|
96
|
+
headers: {
|
|
97
|
+
"Content-Type": "application/json",
|
|
98
|
+
"api-key": cfg.key,
|
|
99
|
+
},
|
|
100
|
+
body: JSON.stringify({
|
|
101
|
+
value: [{ "@search.action": "mergeOrUpload", ...doc }],
|
|
102
|
+
}),
|
|
103
|
+
});
|
|
104
|
+
if (!response.ok) {
|
|
105
|
+
const errText = await response.text();
|
|
106
|
+
throw new Error(`Azure AI Search index ${response.status}: ${errText}`);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Run a vector + keyword hybrid search against Azure AI Search.
|
|
111
|
+
*/
|
|
112
|
+
export async function vectorSearch(query, options = {}) {
|
|
113
|
+
const cfg = getConfig();
|
|
114
|
+
const { numResults = 5, source, type, mode = "hybrid" } = options;
|
|
115
|
+
// Build $filter expression
|
|
116
|
+
const filters = [];
|
|
117
|
+
if (source)
|
|
118
|
+
filters.push(`source eq '${source.replace(/'/g, "''")}'`);
|
|
119
|
+
if (type)
|
|
120
|
+
filters.push(`type eq '${type.replace(/'/g, "''")}'`);
|
|
121
|
+
// Attempt to get a query vector for hybrid/semantic search
|
|
122
|
+
let queryVector = null;
|
|
123
|
+
try {
|
|
124
|
+
queryVector = await embedText(query);
|
|
125
|
+
}
|
|
126
|
+
catch {
|
|
127
|
+
// Non-fatal — fall back to keyword-only if embedding fails
|
|
128
|
+
}
|
|
129
|
+
const body = {
|
|
130
|
+
search: query,
|
|
131
|
+
top: Math.min(numResults, 20),
|
|
132
|
+
select: "id,content,source,type,timestamp",
|
|
133
|
+
queryType: "simple",
|
|
134
|
+
};
|
|
135
|
+
if (filters.length > 0) {
|
|
136
|
+
body["$filter"] = filters.join(" and ");
|
|
137
|
+
}
|
|
138
|
+
// Add vector search if we have an embedding
|
|
139
|
+
if (queryVector !== null && mode !== "semantic") {
|
|
140
|
+
body["vectorQueries"] = [
|
|
141
|
+
{
|
|
142
|
+
kind: "vector",
|
|
143
|
+
vector: queryVector,
|
|
144
|
+
fields: "content_vector",
|
|
145
|
+
k: Math.min(numResults, 20),
|
|
146
|
+
},
|
|
147
|
+
];
|
|
148
|
+
}
|
|
149
|
+
else if (queryVector !== null) {
|
|
150
|
+
// Semantic-only: vector query only, no keyword
|
|
151
|
+
body["search"] = undefined;
|
|
152
|
+
body["vectorQueries"] = [
|
|
153
|
+
{
|
|
154
|
+
kind: "vector",
|
|
155
|
+
vector: queryVector,
|
|
156
|
+
fields: "content_vector",
|
|
157
|
+
k: Math.min(numResults, 20),
|
|
158
|
+
},
|
|
159
|
+
];
|
|
160
|
+
}
|
|
161
|
+
const url = `${cfg.endpoint}/indexes/${cfg.indexName}/docs/search?api-version=${azureSearchRestApiVersion()}`;
|
|
162
|
+
const response = await fetch(url, {
|
|
163
|
+
method: "POST",
|
|
164
|
+
headers: {
|
|
165
|
+
"Content-Type": "application/json",
|
|
166
|
+
"api-key": cfg.key,
|
|
167
|
+
},
|
|
168
|
+
body: JSON.stringify(body),
|
|
169
|
+
});
|
|
170
|
+
if (!response.ok) {
|
|
171
|
+
const errText = await response.text();
|
|
172
|
+
throw new Error(`Azure AI Search query ${response.status}: ${errText}`);
|
|
173
|
+
}
|
|
174
|
+
const data = (await response.json());
|
|
175
|
+
const results = data.value.map((doc) => ({
|
|
176
|
+
eventId: doc.id ?? null,
|
|
177
|
+
timestamp: doc.timestamp ?? null,
|
|
178
|
+
source: doc.source ?? null,
|
|
179
|
+
type: doc.type ?? null,
|
|
180
|
+
content: doc.content ?? null,
|
|
181
|
+
score: doc["@search.score"] ?? 0,
|
|
182
|
+
}));
|
|
183
|
+
return {
|
|
184
|
+
query,
|
|
185
|
+
mode,
|
|
186
|
+
indexName: cfg.indexName,
|
|
187
|
+
totalResults: results.length,
|
|
188
|
+
results,
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
//# sourceMappingURL=azure-search-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"azure-search-client.js","sourceRoot":"","sources":["../../src/search/azure-search-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
export declare class CircuitOpenError extends Error {
|
|
2
|
+
constructor(message: string);
|
|
3
|
+
}
|
|
4
|
+
type State = "CLOSED" | "OPEN" | "HALF_OPEN";
|
|
5
|
+
export interface CircuitBreakerOptions {
|
|
6
|
+
/** Number of consecutive failures before opening. Default: 3 */
|
|
7
|
+
failureThreshold?: number;
|
|
8
|
+
/** Ms to wait in OPEN before allowing a probe. Default: 30_000 */
|
|
9
|
+
recoveryMs?: number;
|
|
10
|
+
/** Name for use in error messages. Default: 'circuit' */
|
|
11
|
+
name?: string;
|
|
12
|
+
}
|
|
13
|
+
export declare class CircuitBreaker {
|
|
14
|
+
private state;
|
|
15
|
+
private failures;
|
|
16
|
+
private openedAt;
|
|
17
|
+
private readonly failureThreshold;
|
|
18
|
+
private readonly recoveryMs;
|
|
19
|
+
private readonly name;
|
|
20
|
+
constructor(options?: CircuitBreakerOptions);
|
|
21
|
+
/** Returns current state — exposed for tests and observability. */
|
|
22
|
+
getState(): State;
|
|
23
|
+
/**
|
|
24
|
+
* Ignore a thrown error — undo the failure that call() would otherwise count.
|
|
25
|
+
* Use for non-retriable errors (e.g. 4xx) that are the caller's fault.
|
|
26
|
+
* Must be called synchronously from within the catch block of breaker.call().
|
|
27
|
+
*/
|
|
28
|
+
ignore(): void;
|
|
29
|
+
/** Returns current failure count — exposed for tests. */
|
|
30
|
+
getFailures(): number;
|
|
31
|
+
/**
|
|
32
|
+
* Execute `fn` through the breaker.
|
|
33
|
+
* - CLOSED: runs fn normally.
|
|
34
|
+
* - OPEN: throws CircuitOpenError immediately (no fn call).
|
|
35
|
+
* - HALF_OPEN: runs fn as a probe; success → CLOSED, failure → OPEN.
|
|
36
|
+
*/
|
|
37
|
+
call<T>(fn: () => Promise<T>): Promise<T>;
|
|
38
|
+
/** Record a success: reset failures and close the circuit. */
|
|
39
|
+
private onSuccess;
|
|
40
|
+
/** Record a failure: increment count and open if threshold reached. */
|
|
41
|
+
private onFailure;
|
|
42
|
+
}
|
|
43
|
+
/** Shared singleton for deepSearch — one breaker per process lifetime. */
|
|
44
|
+
export declare const deepSearchBreaker: CircuitBreaker;
|
|
45
|
+
export {};
|
|
46
|
+
//# sourceMappingURL=circuit-breaker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"circuit-breaker.d.ts","sourceRoot":"","sources":["../../src/search/circuit-breaker.ts"],"names":[],"mappings":"AAGA,qBAAa,gBAAiB,SAAQ,KAAK;gBAC7B,OAAO,EAAE,MAAM;CAI5B;AAED,KAAK,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,WAAW,CAAC;AAE7C,MAAM,WAAW,qBAAqB;IACpC,gEAAgE;IAChE,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,kEAAkE;IAClE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,yDAAyD;IACzD,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,KAAK,CAAmB;IAChC,OAAO,CAAC,QAAQ,CAAK;IACrB,OAAO,CAAC,QAAQ,CAAuB;IAEvC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;IAC1C,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAS;gBAElB,OAAO,GAAE,qBAA0B;IAM/C,mEAAmE;IACnE,QAAQ,IAAI,KAAK;IAIjB;;;;OAIG;IACH,MAAM,IAAI,IAAI;IAQd,yDAAyD;IACzD,WAAW,IAAI,MAAM;IAIrB;;;;;OAKG;IACG,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAsB/C,8DAA8D;IAC9D,OAAO,CAAC,SAAS;IAMjB,uEAAuE;IACvE,OAAO,CAAC,SAAS;CAOlB;AAED,0EAA0E;AAC1E,eAAO,MAAM,iBAAiB,gBAI5B,CAAC"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
// circuit-breaker.ts — Prevents hammering a failing remote API.
|
|
2
|
+
// States: CLOSED (normal) → OPEN (trip) → HALF_OPEN (probe).
|
|
3
|
+
export class CircuitOpenError extends Error {
|
|
4
|
+
constructor(message) {
|
|
5
|
+
super(message);
|
|
6
|
+
this.name = "CircuitOpenError";
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
export class CircuitBreaker {
|
|
10
|
+
state = "CLOSED";
|
|
11
|
+
failures = 0;
|
|
12
|
+
openedAt = null;
|
|
13
|
+
failureThreshold;
|
|
14
|
+
recoveryMs;
|
|
15
|
+
name;
|
|
16
|
+
constructor(options = {}) {
|
|
17
|
+
this.failureThreshold = options.failureThreshold ?? 3;
|
|
18
|
+
this.recoveryMs = options.recoveryMs ?? 30_000;
|
|
19
|
+
this.name = options.name ?? "circuit";
|
|
20
|
+
}
|
|
21
|
+
/** Returns current state — exposed for tests and observability. */
|
|
22
|
+
getState() {
|
|
23
|
+
return this.state;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Ignore a thrown error — undo the failure that call() would otherwise count.
|
|
27
|
+
* Use for non-retriable errors (e.g. 4xx) that are the caller's fault.
|
|
28
|
+
* Must be called synchronously from within the catch block of breaker.call().
|
|
29
|
+
*/
|
|
30
|
+
ignore() {
|
|
31
|
+
this.failures = Math.max(0, this.failures - 1);
|
|
32
|
+
if (this.state === "OPEN" && this.failures < this.failureThreshold) {
|
|
33
|
+
this.state = "CLOSED";
|
|
34
|
+
this.openedAt = null;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
/** Returns current failure count — exposed for tests. */
|
|
38
|
+
getFailures() {
|
|
39
|
+
return this.failures;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Execute `fn` through the breaker.
|
|
43
|
+
* - CLOSED: runs fn normally.
|
|
44
|
+
* - OPEN: throws CircuitOpenError immediately (no fn call).
|
|
45
|
+
* - HALF_OPEN: runs fn as a probe; success → CLOSED, failure → OPEN.
|
|
46
|
+
*/
|
|
47
|
+
async call(fn) {
|
|
48
|
+
if (this.state === "OPEN") {
|
|
49
|
+
const elapsed = Date.now() - (this.openedAt ?? 0);
|
|
50
|
+
if (elapsed < this.recoveryMs) {
|
|
51
|
+
throw new CircuitOpenError(`${this.name} is OPEN — backing off for ${Math.ceil((this.recoveryMs - elapsed) / 1000)}s more`);
|
|
52
|
+
}
|
|
53
|
+
// Recovery window has passed — probe with HALF_OPEN
|
|
54
|
+
this.state = "HALF_OPEN";
|
|
55
|
+
}
|
|
56
|
+
try {
|
|
57
|
+
const result = await fn();
|
|
58
|
+
this.onSuccess();
|
|
59
|
+
return result;
|
|
60
|
+
}
|
|
61
|
+
catch (err) {
|
|
62
|
+
this.onFailure();
|
|
63
|
+
throw err;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
/** Record a success: reset failures and close the circuit. */
|
|
67
|
+
onSuccess() {
|
|
68
|
+
this.failures = 0;
|
|
69
|
+
this.state = "CLOSED";
|
|
70
|
+
this.openedAt = null;
|
|
71
|
+
}
|
|
72
|
+
/** Record a failure: increment count and open if threshold reached. */
|
|
73
|
+
onFailure() {
|
|
74
|
+
this.failures += 1;
|
|
75
|
+
if (this.failures >= this.failureThreshold || this.state === "HALF_OPEN") {
|
|
76
|
+
this.state = "OPEN";
|
|
77
|
+
this.openedAt = Date.now();
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
/** Shared singleton for deepSearch — one breaker per process lifetime. */
|
|
82
|
+
export const deepSearchBreaker = new CircuitBreaker({
|
|
83
|
+
name: "databricks-vector-search",
|
|
84
|
+
failureThreshold: 3,
|
|
85
|
+
recoveryMs: 30_000,
|
|
86
|
+
});
|
|
87
|
+
//# sourceMappingURL=circuit-breaker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"circuit-breaker.js","sourceRoot":"","sources":["../../src/search/circuit-breaker.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export { CircuitOpenError } from "./circuit-breaker.js";
|
|
2
|
+
export interface DeepSearchInput {
|
|
3
|
+
query: string;
|
|
4
|
+
numResults?: number;
|
|
5
|
+
source?: string;
|
|
6
|
+
type?: string;
|
|
7
|
+
mode?: "hybrid" | "semantic";
|
|
8
|
+
}
|
|
9
|
+
export interface DeepSearchResult {
|
|
10
|
+
eventId: string | null;
|
|
11
|
+
timestamp: string | null;
|
|
12
|
+
source: string | null;
|
|
13
|
+
type: string | null;
|
|
14
|
+
content: string | null;
|
|
15
|
+
}
|
|
16
|
+
export interface DeepSearchOutput {
|
|
17
|
+
query: string;
|
|
18
|
+
mode: string;
|
|
19
|
+
indexName: string;
|
|
20
|
+
totalResults: number;
|
|
21
|
+
results: DeepSearchResult[];
|
|
22
|
+
}
|
|
23
|
+
export declare function deepSearch(input: DeepSearchInput): Promise<DeepSearchOutput>;
|
|
24
|
+
//# sourceMappingURL=deep-search.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deep-search.d.ts","sourceRoot":"","sources":["../../src/search/deep-search.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAExD,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,QAAQ,GAAG,UAAU,CAAC;CAC9B;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,gBAAgB,EAAE,CAAC;CAC7B;AAkBD,wBAAsB,UAAU,CAC9B,KAAK,EAAE,eAAe,GACrB,OAAO,CAAC,gBAAgB,CAAC,CAuF3B"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
// deep-search.ts — How does deep semantic search work?
|
|
2
|
+
// Primary: Azure AI Search (when AZURE_SEARCH_ENDPOINT + AZURE_SEARCH_KEY set).
|
|
3
|
+
// Fallback: Azure Databricks Vector Search (when DATABRICKS_HOST + DATABRICKS_TOKEN set).
|
|
4
|
+
// Uses a circuit breaker on the Databricks path to prevent hammering a failing API.
|
|
5
|
+
import { deepSearchBreaker } from "./circuit-breaker.js";
|
|
6
|
+
import { isAzureSearchEnabled, vectorSearch } from "./azure-search-client.js";
|
|
7
|
+
export { CircuitOpenError } from "./circuit-breaker.js";
|
|
8
|
+
function getConfig() {
|
|
9
|
+
const host = process.env.DATABRICKS_HOST;
|
|
10
|
+
const token = process.env.DATABRICKS_TOKEN;
|
|
11
|
+
const indexName = process.env.DATABRICKS_INDEX_NAME ||
|
|
12
|
+
"datacore_databricks.datacore.bronze_events_index";
|
|
13
|
+
if (!host || !token) {
|
|
14
|
+
throw new Error("DATABRICKS_HOST and DATABRICKS_TOKEN must be set. " +
|
|
15
|
+
"Get a token from Databricks > User Settings > Developer > Access tokens.");
|
|
16
|
+
}
|
|
17
|
+
return { host: host.replace(/\/$/, ""), token, indexName };
|
|
18
|
+
}
|
|
19
|
+
export async function deepSearch(input) {
|
|
20
|
+
// --- PRIMARY: Azure AI Search ---
|
|
21
|
+
if (isAzureSearchEnabled()) {
|
|
22
|
+
const result = await vectorSearch(input.query, {
|
|
23
|
+
numResults: input.numResults,
|
|
24
|
+
source: input.source,
|
|
25
|
+
type: input.type,
|
|
26
|
+
mode: input.mode,
|
|
27
|
+
});
|
|
28
|
+
return result;
|
|
29
|
+
}
|
|
30
|
+
// --- FALLBACK: Azure Databricks Vector Search ---
|
|
31
|
+
const { host, token, indexName } = getConfig();
|
|
32
|
+
const { query, numResults = 5, source, type, mode = "hybrid" } = input;
|
|
33
|
+
const columns = ["event_id", "timestamp", "source", "type", "content"];
|
|
34
|
+
const body = {
|
|
35
|
+
columns,
|
|
36
|
+
query_text: query,
|
|
37
|
+
num_results: Math.min(numResults, 20),
|
|
38
|
+
query_type: mode === "semantic" ? "ANN" : "HYBRID",
|
|
39
|
+
};
|
|
40
|
+
const filters = {};
|
|
41
|
+
if (source)
|
|
42
|
+
filters["source"] = [source];
|
|
43
|
+
if (type)
|
|
44
|
+
filters["type"] = [type];
|
|
45
|
+
if (Object.keys(filters).length > 0) {
|
|
46
|
+
body.filters_json = JSON.stringify(filters);
|
|
47
|
+
}
|
|
48
|
+
const url = `${host}/api/2.0/vector-search/indexes/${indexName}/query`;
|
|
49
|
+
// Tag 4xx errors so the outer catch can call ignore() after onFailure() runs
|
|
50
|
+
class CallerError extends Error {
|
|
51
|
+
}
|
|
52
|
+
try {
|
|
53
|
+
return await deepSearchBreaker.call(async () => {
|
|
54
|
+
const response = await fetch(url, {
|
|
55
|
+
method: "POST",
|
|
56
|
+
headers: {
|
|
57
|
+
Authorization: `Bearer ${token}`,
|
|
58
|
+
"Content-Type": "application/json",
|
|
59
|
+
},
|
|
60
|
+
body: JSON.stringify(body),
|
|
61
|
+
});
|
|
62
|
+
if (!response.ok) {
|
|
63
|
+
const text = await response.text();
|
|
64
|
+
if (response.status >= 400 && response.status < 500) {
|
|
65
|
+
// Tag as caller error — will be unwrapped below after breaker.onFailure() runs
|
|
66
|
+
throw new CallerError(`Databricks API ${response.status}: ${text}`);
|
|
67
|
+
}
|
|
68
|
+
// 5xx / 429 — server-side failure, let the breaker count it
|
|
69
|
+
throw new Error(`Databricks API ${response.status}: ${text}`);
|
|
70
|
+
}
|
|
71
|
+
const data = (await response.json());
|
|
72
|
+
const colNames = data.manifest.columns.map((c) => c.name);
|
|
73
|
+
const results = data.result.data_array.map((row) => {
|
|
74
|
+
const obj = {};
|
|
75
|
+
colNames.forEach((name, i) => {
|
|
76
|
+
obj[name] = row[i] ?? null;
|
|
77
|
+
});
|
|
78
|
+
return {
|
|
79
|
+
eventId: obj["event_id"] ?? null,
|
|
80
|
+
timestamp: obj["timestamp"] ?? null,
|
|
81
|
+
source: obj["source"] ?? null,
|
|
82
|
+
type: obj["type"] ?? null,
|
|
83
|
+
content: obj["content"] ?? null,
|
|
84
|
+
};
|
|
85
|
+
});
|
|
86
|
+
return { query, mode, indexName, totalResults: results.length, results };
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
catch (err) {
|
|
90
|
+
// 4xx caller errors: undo the failure that breaker.call() just counted
|
|
91
|
+
if (err instanceof CallerError) {
|
|
92
|
+
deepSearchBreaker.ignore();
|
|
93
|
+
throw new Error(err.message, { cause: err });
|
|
94
|
+
}
|
|
95
|
+
throw err;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=deep-search.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deep-search.js","sourceRoot":"","sources":["../../src/search/deep-search.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../src/search/search.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAEV,WAAW,EAEX,YAAY,EACb,MAAM,aAAa,CAAC;AA6CrB,wBAAsB,YAAY,CAAC,EACjC,KAAK,EACL,UAAgC,EAChC,MAAM,EACN,IAAI,GACL,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC,CA2CrC"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
// search.ts — How is data found?
|
|
2
|
+
// Reads via readAllRecords (Cosmos in production, JSONL in tests/local).
|
|
3
|
+
// Filtering and snippet generation happen in-memory after fetch.
|
|
4
|
+
import { readAllRecords, getBronzeDir } from "../storage/store.js";
|
|
5
|
+
const DEFAULT_MAX_RESULTS = 10;
|
|
6
|
+
function buildSearchHaystack(record) {
|
|
7
|
+
const parts = [
|
|
8
|
+
typeof record.content === "string" ? record.content : "",
|
|
9
|
+
typeof record.type === "string" ? record.type : "",
|
|
10
|
+
typeof record.source === "string" ? record.source : "",
|
|
11
|
+
];
|
|
12
|
+
if (record.context !== undefined) {
|
|
13
|
+
parts.push(JSON.stringify(record.context));
|
|
14
|
+
}
|
|
15
|
+
parts.push(JSON.stringify(record));
|
|
16
|
+
return parts.filter(Boolean).join("\n");
|
|
17
|
+
}
|
|
18
|
+
function buildSnippet(haystack, query) {
|
|
19
|
+
const normalizedHaystack = haystack.replace(/\s+/g, " ").trim();
|
|
20
|
+
const lowerHaystack = normalizedHaystack.toLowerCase();
|
|
21
|
+
const lowerQuery = query.toLowerCase();
|
|
22
|
+
const index = lowerHaystack.indexOf(lowerQuery);
|
|
23
|
+
if (index === -1) {
|
|
24
|
+
return normalizedHaystack.slice(0, 180);
|
|
25
|
+
}
|
|
26
|
+
const start = Math.max(0, index - 50);
|
|
27
|
+
const end = Math.min(normalizedHaystack.length, index + query.length + 80);
|
|
28
|
+
const prefix = start > 0 ? "..." : "";
|
|
29
|
+
const suffix = end < normalizedHaystack.length ? "..." : "";
|
|
30
|
+
return `${prefix}${normalizedHaystack.slice(start, end)}${suffix}`;
|
|
31
|
+
}
|
|
32
|
+
function incrementCounter(counter, value) {
|
|
33
|
+
if (typeof value !== "string")
|
|
34
|
+
return;
|
|
35
|
+
const key = value.trim();
|
|
36
|
+
if (!key)
|
|
37
|
+
return;
|
|
38
|
+
counter[key] = (counter[key] ?? 0) + 1;
|
|
39
|
+
}
|
|
40
|
+
export async function searchEvents({ query, maxResults = DEFAULT_MAX_RESULTS, source, type, }) {
|
|
41
|
+
const normalizedQuery = query.trim();
|
|
42
|
+
const limit = Math.max(1, Math.min(100, maxResults ?? DEFAULT_MAX_RESULTS));
|
|
43
|
+
const { records, parseErrors } = await readAllRecords({ source, type });
|
|
44
|
+
const lowerQuery = normalizedQuery.toLowerCase();
|
|
45
|
+
const matched = records.filter((r) => {
|
|
46
|
+
const haystack = buildSearchHaystack(r).toLowerCase();
|
|
47
|
+
return haystack.includes(lowerQuery);
|
|
48
|
+
});
|
|
49
|
+
matched.sort((a, b) => (b._timestamp ?? "").localeCompare(a._timestamp ?? ""));
|
|
50
|
+
const sourceCounts = {};
|
|
51
|
+
const typeCounts = {};
|
|
52
|
+
for (const r of matched) {
|
|
53
|
+
incrementCounter(sourceCounts, r._source ?? r.source);
|
|
54
|
+
incrementCounter(typeCounts, r.type);
|
|
55
|
+
}
|
|
56
|
+
const results = matched.slice(0, limit).map((r) => ({
|
|
57
|
+
eventId: r._event_id ?? null,
|
|
58
|
+
timestamp: r._timestamp ?? null,
|
|
59
|
+
source: r._source ?? r.source ?? null,
|
|
60
|
+
type: r.type ?? null,
|
|
61
|
+
trust: r._trust ?? null,
|
|
62
|
+
snippet: buildSnippet(buildSearchHaystack(r), normalizedQuery),
|
|
63
|
+
filePath: r._filePath ?? "",
|
|
64
|
+
}));
|
|
65
|
+
return {
|
|
66
|
+
bronzeDir: getBronzeDir(),
|
|
67
|
+
filesScanned: records.length,
|
|
68
|
+
eventsScanned: matched.length,
|
|
69
|
+
parseErrors,
|
|
70
|
+
totalMatches: results.length,
|
|
71
|
+
results,
|
|
72
|
+
sourceCounts,
|
|
73
|
+
typeCounts,
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=search.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search.js","sourceRoot":"","sources":["../../src/search/search.ts"],"names":[],"mappings":"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"}
|
package/dist/server.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":""}
|
package/dist/server.js
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// server.ts — How does the MCP server start?
|
|
3
|
+
// Two transports: MCP stdio (for AI agents) + HTTP REST (for infrastructure).
|
|
4
|
+
// Same process, same database.
|
|
5
|
+
// Set DATACORE_STDIO=0 (or HTTP_ONLY=1) to run in container mode (HTTP only).
|
|
6
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
7
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
8
|
+
import { registerTools } from "./tools.js";
|
|
9
|
+
import { startHttpServer } from "./transport/http-server.js";
|
|
10
|
+
import { getMcpServerPackageVersion } from "./config/datacore-constants.js";
|
|
11
|
+
const server = new McpServer({
|
|
12
|
+
name: "datacore",
|
|
13
|
+
version: getMcpServerPackageVersion(),
|
|
14
|
+
});
|
|
15
|
+
registerTools(server);
|
|
16
|
+
// Start HTTP first so triggers can POST to /log as soon as MCP connects
|
|
17
|
+
const httpServer = await startHttpServer();
|
|
18
|
+
const httpOnly = process.env["DATACORE_STDIO"] === "0" ||
|
|
19
|
+
process.env["DATACORE_HTTP_ONLY"] === "1";
|
|
20
|
+
if (httpOnly) {
|
|
21
|
+
// Container mode — HTTP transport only, no stdio
|
|
22
|
+
function shutdownHttp() {
|
|
23
|
+
httpServer.close();
|
|
24
|
+
process.exit(0);
|
|
25
|
+
}
|
|
26
|
+
process.on("SIGINT", shutdownHttp);
|
|
27
|
+
process.on("SIGTERM", shutdownHttp);
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
await server.connect(new StdioServerTransport());
|
|
31
|
+
async function shutdown() {
|
|
32
|
+
httpServer.close();
|
|
33
|
+
await server.close();
|
|
34
|
+
process.exit(0);
|
|
35
|
+
}
|
|
36
|
+
process.on("SIGINT", shutdown);
|
|
37
|
+
process.on("SIGTERM", shutdown);
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":";AAEA,6CAA6C;AAC7C,8EAA8E;AAC9E,+BAA+B;AAC/B,8EAA8E;AAC9E,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,0BAA0B,EAAE,MAAM,gCAAgC,CAAC;AAE5E,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;IAC3B,IAAI,EAAE,UAAU;IAChB,OAAO,EAAE,0BAA0B,EAAE;CACtC,CAAC,CAAC;AAEH,aAAa,CAAC,MAAM,CAAC,CAAC;AAEtB,wEAAwE;AACxE,MAAM,UAAU,GAAG,MAAM,eAAe,EAAE,CAAC;AAE3C,MAAM,QAAQ,GACZ,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,KAAK,GAAG;IACrC,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,KAAK,GAAG,CAAC;AAE5C,IAAI,QAAQ,EAAE,CAAC;IACb,iDAAiD;IACjD,SAAS,YAAY;QACnB,UAAU,CAAC,KAAK,EAAE,CAAC;QACnB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IACD,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;IACnC,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;AACtC,CAAC;KAAM,CAAC;IACN,MAAM,MAAM,CAAC,OAAO,CAAC,IAAI,oBAAoB,EAAE,CAAC,CAAC;IAEjD,KAAK,UAAU,QAAQ;QACrB,UAAU,CAAC,KAAK,EAAE,CAAC;QACnB,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;QACrB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IACD,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IAC/B,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;AAClC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/skills/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAIzE,wBAAgB,cAAc,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAGtD"}
|