atabey 0.0.12 → 0.0.13
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/ATABEY.md +45 -499
- package/PRIVACY.md +161 -0
- package/README.md +353 -88
- package/bin/validate-al-registry.js +4 -4
- package/dist/framework-mcp/src/tools/definitions.js +23 -1
- package/dist/framework-mcp/src/tools/definitions.js.map +1 -1
- package/dist/framework-mcp/src/tools/gateway/llm_gateway_query.d.ts +19 -0
- package/dist/framework-mcp/src/tools/gateway/llm_gateway_query.js +138 -0
- package/dist/framework-mcp/src/tools/gateway/llm_gateway_query.js.map +1 -0
- package/dist/framework-mcp/src/tools/gateway/llm_gateway_status.d.ts +8 -0
- package/dist/framework-mcp/src/tools/gateway/llm_gateway_status.js +91 -0
- package/dist/framework-mcp/src/tools/gateway/llm_gateway_status.js.map +1 -0
- package/dist/framework-mcp/src/tools/index.d.ts +1 -1
- package/dist/framework-mcp/src/tools/index.js +35 -20
- package/dist/framework-mcp/src/tools/index.js.map +1 -1
- package/dist/framework-mcp/src/tools/quality/analyze_code_quality.d.ts +11 -0
- package/dist/framework-mcp/src/tools/quality/analyze_code_quality.js +166 -0
- package/dist/framework-mcp/src/tools/quality/analyze_code_quality.js.map +1 -0
- package/dist/framework-mcp/src/tools/quality/check_architecture_compliance.d.ts +11 -0
- package/dist/framework-mcp/src/tools/quality/check_architecture_compliance.js +135 -0
- package/dist/framework-mcp/src/tools/quality/check_architecture_compliance.js.map +1 -0
- package/dist/framework-mcp/src/tools/schemas.d.ts +88 -8
- package/dist/framework-mcp/src/tools/schemas.js +29 -0
- package/dist/framework-mcp/src/tools/schemas.js.map +1 -1
- package/dist/framework-mcp/src/tools/shell/run_command.js +2 -2
- package/dist/framework-mcp/src/tools/shell/run_command.js.map +1 -1
- package/dist/src/cli/commands/check.js +2 -2
- package/dist/src/cli/commands/check.js.map +1 -1
- package/dist/src/cli/commands/dashboard.d.ts +1 -1
- package/dist/src/cli/commands/dashboard.js +264 -41
- package/dist/src/cli/commands/dashboard.js.map +1 -1
- package/dist/src/cli/commands/gateway.d.ts +1 -0
- package/dist/src/cli/commands/gateway.js +172 -0
- package/dist/src/cli/commands/gateway.js.map +1 -0
- package/dist/src/cli/commands/init/create-agent.js +3 -3
- package/dist/src/cli/commands/init/create-agent.js.map +1 -1
- package/dist/src/cli/commands/init/scaffold-core.d.ts +1 -1
- package/dist/src/cli/commands/init/scaffold-core.js +1 -1
- package/dist/src/cli/commands/init/scaffold-core.js.map +1 -1
- package/dist/src/cli/commands/init.d.ts +2 -0
- package/dist/src/cli/commands/init.js +105 -23
- package/dist/src/cli/commands/init.js.map +1 -1
- package/dist/src/cli/commands/mcp.d.ts +7 -0
- package/dist/src/cli/commands/mcp.js +45 -22
- package/dist/src/cli/commands/mcp.js.map +1 -1
- package/dist/src/cli/commands/orchestrate.d.ts +8 -7
- package/dist/src/cli/commands/orchestrate.js +2 -1
- package/dist/src/cli/commands/orchestrate.js.map +1 -1
- package/dist/src/cli/commands/quickstart.d.ts +5 -5
- package/dist/src/cli/commands/quickstart.js +36 -36
- package/dist/src/cli/commands/quickstart.js.map +1 -1
- package/dist/src/cli/index.js +230 -320
- package/dist/src/cli/index.js.map +1 -1
- package/dist/src/cli/platforms/core.d.ts +12 -0
- package/dist/src/cli/platforms/core.js +73 -0
- package/dist/src/cli/platforms/core.js.map +1 -0
- package/dist/src/cli/platforms/index.d.ts +5 -0
- package/dist/src/cli/platforms/index.js +6 -0
- package/dist/src/cli/platforms/index.js.map +1 -0
- package/dist/src/cli/platforms/paths.d.ts +15 -0
- package/dist/src/cli/platforms/paths.js +102 -0
- package/dist/src/cli/platforms/paths.js.map +1 -0
- package/dist/src/cli/platforms/scaffold.d.ts +2 -0
- package/dist/src/cli/platforms/scaffold.js +73 -0
- package/dist/src/cli/platforms/scaffold.js.map +1 -0
- package/dist/src/cli/platforms/utils.d.ts +4 -0
- package/dist/src/cli/platforms/utils.js +76 -0
- package/dist/src/cli/platforms/utils.js.map +1 -0
- package/dist/src/cli/shims.js +4 -4
- package/dist/src/cli/utils/fs.d.ts +1 -1
- package/dist/src/cli/utils/fs.js +1 -1
- package/dist/src/cli/utils/fs.js.map +1 -1
- package/dist/src/modules/agents/definitions.d.ts +2 -2
- package/dist/src/modules/agents/definitions.js +59 -23
- package/dist/src/modules/agents/definitions.js.map +1 -1
- package/dist/src/modules/contracts/api.d.ts +178 -0
- package/dist/src/modules/contracts/api.js +56 -0
- package/dist/src/modules/contracts/api.js.map +1 -0
- package/dist/src/modules/contracts/index.d.ts +5 -0
- package/dist/src/modules/contracts/index.js +6 -0
- package/dist/src/modules/contracts/index.js.map +1 -0
- package/dist/src/modules/engines/agent-executor.d.ts +27 -28
- package/dist/src/modules/engines/agent-executor.js +97 -69
- package/dist/src/modules/engines/agent-executor.js.map +1 -1
- package/dist/src/modules/engines/quality-gate.d.ts +7 -7
- package/dist/src/modules/engines/quality-gate.js +7 -7
- package/dist/src/modules/engines/routing-engine.d.ts +18 -27
- package/dist/src/modules/engines/routing-engine.js +70 -44
- package/dist/src/modules/engines/routing-engine.js.map +1 -1
- package/dist/src/modules/gateway/circuit-breaker.d.ts +40 -0
- package/dist/src/modules/gateway/circuit-breaker.js +163 -0
- package/dist/src/modules/gateway/circuit-breaker.js.map +1 -0
- package/dist/src/modules/gateway/cost-tracker.d.ts +55 -0
- package/dist/src/modules/gateway/cost-tracker.js +127 -0
- package/dist/src/modules/gateway/cost-tracker.js.map +1 -0
- package/dist/src/modules/gateway/gateway.d.ts +68 -0
- package/dist/src/modules/gateway/gateway.js +235 -0
- package/dist/src/modules/gateway/gateway.js.map +1 -0
- package/dist/src/modules/gateway/index.d.ts +19 -0
- package/dist/src/modules/gateway/index.js +19 -0
- package/dist/src/modules/gateway/index.js.map +1 -0
- package/dist/src/modules/gateway/load-balancer.d.ts +86 -0
- package/dist/src/modules/gateway/load-balancer.js +230 -0
- package/dist/src/modules/gateway/load-balancer.js.map +1 -0
- package/dist/src/modules/gateway/providers/anthropic.d.ts +14 -0
- package/dist/src/modules/gateway/providers/anthropic.js +169 -0
- package/dist/src/modules/gateway/providers/anthropic.js.map +1 -0
- package/dist/src/modules/gateway/providers/base.d.ts +38 -0
- package/dist/src/modules/gateway/providers/base.js +42 -0
- package/dist/src/modules/gateway/providers/base.js.map +1 -0
- package/dist/src/modules/gateway/providers/google.d.ts +18 -0
- package/dist/src/modules/gateway/providers/google.js +176 -0
- package/dist/src/modules/gateway/providers/google.js.map +1 -0
- package/dist/src/modules/gateway/providers/grok.d.ts +14 -0
- package/dist/src/modules/gateway/providers/grok.js +166 -0
- package/dist/src/modules/gateway/providers/grok.js.map +1 -0
- package/dist/src/modules/gateway/providers/index.d.ts +21 -0
- package/dist/src/modules/gateway/providers/index.js +38 -0
- package/dist/src/modules/gateway/providers/index.js.map +1 -0
- package/dist/src/modules/gateway/providers/ollama.d.ts +23 -0
- package/dist/src/modules/gateway/providers/ollama.js +187 -0
- package/dist/src/modules/gateway/providers/ollama.js.map +1 -0
- package/dist/src/modules/gateway/providers/openai.d.ts +14 -0
- package/dist/src/modules/gateway/providers/openai.js +170 -0
- package/dist/src/modules/gateway/providers/openai.js.map +1 -0
- package/dist/src/modules/gateway/rate-limiter.d.ts +41 -0
- package/dist/src/modules/gateway/rate-limiter.js +119 -0
- package/dist/src/modules/gateway/rate-limiter.js.map +1 -0
- package/dist/src/modules/gateway/types.d.ts +114 -0
- package/dist/src/modules/gateway/types.js +8 -0
- package/dist/src/modules/gateway/types.js.map +1 -0
- package/dist/src/modules/memory/core.d.ts +4 -12
- package/dist/src/modules/memory/core.js +10 -17
- package/dist/src/modules/memory/core.js.map +1 -1
- package/dist/src/modules/memory/embedding.d.ts +28 -0
- package/dist/src/modules/memory/embedding.js +131 -0
- package/dist/src/modules/memory/embedding.js.map +1 -0
- package/dist/src/modules/providers/definitions.d.ts +9 -0
- package/dist/src/modules/providers/definitions.js +141 -0
- package/dist/src/modules/providers/definitions.js.map +1 -0
- package/dist/src/modules/providers/registry.d.ts +12 -0
- package/dist/src/modules/providers/registry.js +19 -0
- package/dist/src/modules/providers/registry.js.map +1 -0
- package/dist/src/modules/providers/shared.d.ts +1 -0
- package/dist/src/modules/providers/shared.js +105 -0
- package/dist/src/modules/providers/shared.js.map +1 -0
- package/dist/src/modules/providers/types.d.ts +14 -0
- package/dist/src/modules/providers/types.js +2 -0
- package/dist/src/modules/providers/types.js.map +1 -0
- package/dist/src/modules/skills/adapter-skills.d.ts +68 -0
- package/dist/src/modules/skills/adapter-skills.js +450 -0
- package/dist/src/modules/skills/adapter-skills.js.map +1 -0
- package/dist/src/shared/audit.d.ts +105 -0
- package/dist/src/shared/audit.js +220 -0
- package/dist/src/shared/audit.js.map +1 -0
- package/dist/src/shared/fs.js +4 -2
- package/dist/src/shared/fs.js.map +1 -1
- package/dist/src/shared/lock.d.ts +82 -0
- package/dist/src/shared/lock.js +160 -0
- package/dist/src/shared/lock.js.map +1 -0
- package/dist/src/shared/logger.d.ts +2 -0
- package/dist/src/shared/logger.js +15 -5
- package/dist/src/shared/logger.js.map +1 -1
- package/dist/src/shared/pii.d.ts +37 -0
- package/dist/src/shared/pii.js +122 -0
- package/dist/src/shared/pii.js.map +1 -0
- package/dist/src/shared/retention.d.ts +63 -0
- package/dist/src/shared/retention.js +171 -0
- package/dist/src/shared/retention.js.map +1 -0
- package/dist/src/shared/storage.d.ts +3 -1
- package/dist/src/shared/storage.js +3 -1
- package/dist/src/shared/storage.js.map +1 -1
- package/dist/tests/adapter.test.js +1 -1
- package/dist/tests/adapter.test.js.map +1 -1
- package/dist/tests/adapters/paths.test.js +4 -4
- package/dist/tests/adapters/paths.test.js.map +1 -1
- package/dist/tests/cli/commands/dashboard-coverage.test.d.ts +1 -0
- package/dist/tests/cli/commands/dashboard-coverage.test.js +88 -0
- package/dist/tests/cli/commands/dashboard-coverage.test.js.map +1 -0
- package/dist/tests/cli/init/adapter_init.test.js +4 -5
- package/dist/tests/cli/init/adapter_init.test.js.map +1 -1
- package/dist/tests/cli/init/unified_init.test.js +5 -7
- package/dist/tests/cli/init/unified_init.test.js.map +1 -1
- package/dist/tests/integration/agent_flow.test.js +14 -8
- package/dist/tests/integration/agent_flow.test.js.map +1 -1
- package/dist/tests/modules/adapters/adapters.test.js +2 -2
- package/dist/tests/modules/adapters/adapters.test.js.map +1 -1
- package/dist/tests/modules/contracts/contracts.test.d.ts +1 -0
- package/dist/tests/modules/contracts/contracts.test.js +73 -0
- package/dist/tests/modules/contracts/contracts.test.js.map +1 -0
- package/dist/tests/modules/engines/agent-executor.test.js +30 -23
- package/dist/tests/modules/engines/agent-executor.test.js.map +1 -1
- package/dist/tests/modules/gateway/circuit-breaker.test.d.ts +1 -0
- package/dist/tests/modules/gateway/circuit-breaker.test.js +124 -0
- package/dist/tests/modules/gateway/circuit-breaker.test.js.map +1 -0
- package/dist/tests/modules/gateway/cost-tracker.test.d.ts +1 -0
- package/dist/tests/modules/gateway/cost-tracker.test.js +74 -0
- package/dist/tests/modules/gateway/cost-tracker.test.js.map +1 -0
- package/dist/tests/modules/gateway/load-balancer.test.d.ts +1 -0
- package/dist/tests/modules/gateway/load-balancer.test.js +70 -0
- package/dist/tests/modules/gateway/load-balancer.test.js.map +1 -0
- package/dist/tests/modules/gateway/rate-limiter.test.d.ts +1 -0
- package/dist/tests/modules/gateway/rate-limiter.test.js +62 -0
- package/dist/tests/modules/gateway/rate-limiter.test.js.map +1 -0
- package/dist/tests/orchestrator-dependencies.test.js +23 -6
- package/dist/tests/orchestrator-dependencies.test.js.map +1 -1
- package/dist/tests/shared/audit.test.d.ts +1 -0
- package/dist/tests/shared/audit.test.js +53 -0
- package/dist/tests/shared/audit.test.js.map +1 -0
- package/dist/tests/storage-operations.test.d.ts +1 -0
- package/dist/tests/storage-operations.test.js +116 -0
- package/dist/tests/storage-operations.test.js.map +1 -0
- package/framework-mcp/README.md +324 -77
- package/framework-mcp/dist/dashboard/assets/index-BAPGLiWE.js +267 -0
- package/framework-mcp/dist/dashboard/index.html +15 -0
- package/framework-mcp/dist/framework-mcp/src/tools/definitions.js +23 -1
- package/framework-mcp/dist/framework-mcp/src/tools/gateway/llm_gateway_query.js +137 -0
- package/framework-mcp/dist/framework-mcp/src/tools/gateway/llm_gateway_status.js +90 -0
- package/framework-mcp/dist/framework-mcp/src/tools/index.js +35 -20
- package/framework-mcp/dist/framework-mcp/src/tools/quality/analyze_code_quality.js +165 -0
- package/framework-mcp/dist/framework-mcp/src/tools/quality/check_architecture_compliance.js +134 -0
- package/framework-mcp/dist/framework-mcp/src/tools/schemas.js +29 -0
- package/framework-mcp/dist/framework-mcp/src/tools/shell/run_command.js +2 -2
- package/framework-mcp/dist/src/modules/memory/core.js +10 -17
- package/framework-mcp/dist/src/modules/memory/embedding.js +130 -0
- package/framework-mcp/dist/src/shared/fs.js +4 -2
- package/framework-mcp/dist/src/shared/logger.js +15 -5
- package/framework-mcp/dist/src/shared/pii.js +121 -0
- package/framework-mcp/dist/src/shared/storage.js +3 -1
- package/framework-mcp/package.json +1 -1
- package/package.json +10 -4
- package/templates/full/ATABEY_FULL.md +515 -0
|
@@ -151,3 +151,32 @@ export const LogAgentActionSchema = z.object({
|
|
|
151
151
|
export const AskHumanSchema = z.object({
|
|
152
152
|
question: z.string().min(10, "Question must be clear and detailed."),
|
|
153
153
|
}).strict();
|
|
154
|
+
// ─── LLM Gateway ────────────────────────────────────────────────────
|
|
155
|
+
export const LLMGatewayQuerySchema = z.object({
|
|
156
|
+
messages: z.array(z.object({
|
|
157
|
+
role: z.enum(["system", "user", "assistant", "tool"]),
|
|
158
|
+
content: z.string().min(1),
|
|
159
|
+
})).min(1, "At least one message is required"),
|
|
160
|
+
system: z.string().optional(),
|
|
161
|
+
model: z.string().optional(),
|
|
162
|
+
provider: z.enum(["openai", "anthropic", "google", "grok", "ollama"]).optional(),
|
|
163
|
+
strategy: z.enum(["round-robin", "least-latency", "cost-optimized", "failover", "priority-based", "model-based"]).optional(),
|
|
164
|
+
temperature: z.number().min(0).max(2).optional(),
|
|
165
|
+
maxTokens: z.number().int().positive().optional(),
|
|
166
|
+
traceId: z.string().optional(),
|
|
167
|
+
}).strict();
|
|
168
|
+
export const LLMGatewayStatusSchema = z.object({
|
|
169
|
+
detail: z.enum(["overview", "providers", "stats"]).optional().default("overview"),
|
|
170
|
+
}).strict();
|
|
171
|
+
// ─── Code Quality Analysis ──────────────────────────────────────────
|
|
172
|
+
export const AnalyzeCodeQualitySchema = z.object({
|
|
173
|
+
path: z.string().min(1, "Path to analyze is required"),
|
|
174
|
+
checkTypes: z.boolean().optional().default(true),
|
|
175
|
+
checkLint: z.boolean().optional().default(true),
|
|
176
|
+
checkComplexity: z.boolean().optional().default(true),
|
|
177
|
+
}).strict();
|
|
178
|
+
// ─── Architecture Compliance ────────────────────────────────────────
|
|
179
|
+
export const CheckArchitectureComplianceSchema = z.object({
|
|
180
|
+
path: z.string().min(1, "Path to check is required"),
|
|
181
|
+
rules: z.array(z.string()).optional(),
|
|
182
|
+
}).strict();
|
|
@@ -60,8 +60,8 @@ const COMMAND_ALLOW_LIST = [
|
|
|
60
60
|
"cargo build",
|
|
61
61
|
"cargo check",
|
|
62
62
|
"cargo fmt",
|
|
63
|
-
// File operations (safe) —
|
|
64
|
-
// "
|
|
63
|
+
// File operations (safe) — NOTE: "rm -rf" and "rm -r" intentionally excluded.
|
|
64
|
+
// Only "rmdir" is allowed to prevent dangerous commands like "rm -rf /".
|
|
65
65
|
"mkdir",
|
|
66
66
|
"cp",
|
|
67
67
|
"mv",
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import crypto from "crypto";
|
|
2
|
+
import { generateEmbedding } from "./embedding.js";
|
|
2
3
|
import { VectorStore } from "./vector-store.js";
|
|
3
4
|
/**
|
|
4
5
|
* [MEMORY] Core Memory Service
|
|
5
6
|
* High-level API for managing project knowledge and embeddings.
|
|
6
|
-
* Uses
|
|
7
|
+
* Uses OpenAI Embedding API when available, falls back to TF-IDF.
|
|
7
8
|
*/
|
|
8
9
|
export class CoreMemory {
|
|
9
10
|
static VECTOR_DIM = 384;
|
|
@@ -18,14 +19,16 @@ export class CoreMemory {
|
|
|
18
19
|
}
|
|
19
20
|
/**
|
|
20
21
|
* Records a new piece of knowledge into the core memory.
|
|
21
|
-
*
|
|
22
|
+
* Uses OpenAI Embedding API when available, falls back to TF-IDF.
|
|
22
23
|
*/
|
|
23
24
|
static async remember(params) {
|
|
24
25
|
const id = crypto.createHash("sha256").update(params.content + (params.filePath || "")).digest("hex");
|
|
26
|
+
// Use provided vector or generate via embedding service
|
|
27
|
+
const vector = params.vector || await generateEmbedding(params.content);
|
|
25
28
|
const entry = {
|
|
26
29
|
id,
|
|
27
30
|
content: params.content,
|
|
28
|
-
vector
|
|
31
|
+
vector,
|
|
29
32
|
metadata: {
|
|
30
33
|
category: params.category,
|
|
31
34
|
traceId: params.traceId,
|
|
@@ -39,23 +42,15 @@ export class CoreMemory {
|
|
|
39
42
|
}
|
|
40
43
|
/**
|
|
41
44
|
* Searches the memory for relevant knowledge using cosine similarity.
|
|
45
|
+
* Uses OpenAI Embedding API when available for the query vector.
|
|
42
46
|
*/
|
|
43
47
|
static async recall(query, options) {
|
|
44
|
-
const vector = options.queryVector ||
|
|
48
|
+
const vector = options.queryVector || await generateEmbedding(query);
|
|
45
49
|
return VectorStore.search(vector, options.limit || 5, options.category);
|
|
46
50
|
}
|
|
47
51
|
/**
|
|
48
52
|
* Generates a TF-IDF style embedding vector from text.
|
|
49
|
-
*
|
|
50
|
-
* How it works:
|
|
51
|
-
* 1. Tokenizes the text into words
|
|
52
|
-
* 2. Removes stop words and short tokens
|
|
53
|
-
* 3. Calculates term frequency for each word
|
|
54
|
-
* 4. Maps each word to a deterministic position in the vector using hash
|
|
55
|
-
* 5. Normalizes the final vector
|
|
56
|
-
*
|
|
57
|
-
* This produces a sparse vector where semantically similar texts
|
|
58
|
-
* (sharing similar keywords) will have higher cosine similarity.
|
|
53
|
+
* Kept for backward compatibility and as fallback.
|
|
59
54
|
*/
|
|
60
55
|
static generateEmbedding(text) {
|
|
61
56
|
const vector = new Array(this.VECTOR_DIM).fill(0);
|
|
@@ -74,8 +69,6 @@ export class CoreMemory {
|
|
|
74
69
|
tf.set(token, (tf.get(token) || 0) + 1);
|
|
75
70
|
}
|
|
76
71
|
// Map each unique token to vector positions using hash
|
|
77
|
-
// A single token contributes to multiple positions (3-gram hash)
|
|
78
|
-
// to capture partial token similarity
|
|
79
72
|
for (const [token, freq] of tf) {
|
|
80
73
|
for (let i = 0; i < token.length - 1; i++) {
|
|
81
74
|
const ngram = token.substring(i, i + 2);
|
|
@@ -99,7 +92,7 @@ export class CoreMemory {
|
|
|
99
92
|
let hash = 0;
|
|
100
93
|
for (let i = 0; i < value.length; i++) {
|
|
101
94
|
hash = ((hash << 5) - hash) + value.charCodeAt(i);
|
|
102
|
-
hash |= 0;
|
|
95
|
+
hash |= 0;
|
|
103
96
|
}
|
|
104
97
|
return Math.abs(hash) % this.VECTOR_DIM;
|
|
105
98
|
}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* [MEMORY] Embedding Service
|
|
3
|
+
*
|
|
4
|
+
* Real embedding generation with OpenAI API integration.
|
|
5
|
+
* Falls back to TF-IDF if no API key is available.
|
|
6
|
+
*
|
|
7
|
+
* Supported methods:
|
|
8
|
+
* 1. OpenAI Embedding API (text-embedding-3-small) — 1536 dimensions
|
|
9
|
+
* 2. TF-IDF fallback (local method) — 384 dimensions
|
|
10
|
+
*/
|
|
11
|
+
import fs from "fs";
|
|
12
|
+
import path from "path";
|
|
13
|
+
import { logger } from "../../shared/logger.js";
|
|
14
|
+
import { CoreMemory } from "./core.js";
|
|
15
|
+
const EMBEDDING_API = "https://api.openai.com/v1/embeddings";
|
|
16
|
+
const EMBEDDING_MODEL = "text-embedding-3-small";
|
|
17
|
+
const EMBEDDING_DIM = 1536;
|
|
18
|
+
/**
|
|
19
|
+
* Reads the API key from environment variable or .env file.
|
|
20
|
+
*/
|
|
21
|
+
function getApiKey() {
|
|
22
|
+
if (process.env.OPENAI_API_KEY)
|
|
23
|
+
return process.env.OPENAI_API_KEY;
|
|
24
|
+
try {
|
|
25
|
+
const envPath = path.join(process.cwd(), ".env");
|
|
26
|
+
if (fs.existsSync(envPath)) {
|
|
27
|
+
const content = fs.readFileSync(envPath, "utf8");
|
|
28
|
+
const match = content.match(/^OPENAI_API_KEY=(.+)$/m);
|
|
29
|
+
if (match)
|
|
30
|
+
return match[1].trim();
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
// Silently ignore .env read errors
|
|
35
|
+
}
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Generates an embedding vector for the given text.
|
|
40
|
+
*
|
|
41
|
+
* Priority:
|
|
42
|
+
* 1. OpenAI API (if API key is available)
|
|
43
|
+
* 2. TF-IDF fallback (local)
|
|
44
|
+
*/
|
|
45
|
+
export async function generateEmbedding(text) {
|
|
46
|
+
const apiKey = getApiKey();
|
|
47
|
+
// Use OpenAI API if available
|
|
48
|
+
if (apiKey) {
|
|
49
|
+
try {
|
|
50
|
+
const response = await fetch(EMBEDDING_API, {
|
|
51
|
+
method: "POST",
|
|
52
|
+
headers: {
|
|
53
|
+
"Content-Type": "application/json",
|
|
54
|
+
"Authorization": `Bearer ${apiKey}`,
|
|
55
|
+
},
|
|
56
|
+
body: JSON.stringify({
|
|
57
|
+
input: text,
|
|
58
|
+
model: EMBEDDING_MODEL,
|
|
59
|
+
}),
|
|
60
|
+
});
|
|
61
|
+
if (!response.ok) {
|
|
62
|
+
logger.warn(`OpenAI API error: ${response.status}. Falling back to TF-IDF.`);
|
|
63
|
+
return fallbackEmbedding(text);
|
|
64
|
+
}
|
|
65
|
+
const data = await response.json();
|
|
66
|
+
if (data?.data?.[0]?.embedding) {
|
|
67
|
+
return data.data[0].embedding;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
catch (err) {
|
|
71
|
+
logger.warn(`OpenAI API call failed: ${err.message}. Falling back to TF-IDF.`);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
// Fallback: TF-IDF
|
|
75
|
+
return fallbackEmbedding(text);
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* TF-IDF fallback embedding using CoreMemory.generateEmbedding.
|
|
79
|
+
* OpenAI embedding is 1536 dimensions, TF-IDF is 384 dimensions.
|
|
80
|
+
* Pads TF-IDF output to 1536 for compatibility.
|
|
81
|
+
*/
|
|
82
|
+
function fallbackEmbedding(text) {
|
|
83
|
+
const tfidfVector = CoreMemory.generateEmbedding(text); // 384 dimensions
|
|
84
|
+
// Pad 384 → 1536
|
|
85
|
+
const padded = new Array(EMBEDDING_DIM).fill(0);
|
|
86
|
+
for (let i = 0; i < tfidfVector.length; i++) {
|
|
87
|
+
padded[i] = tfidfVector[i];
|
|
88
|
+
}
|
|
89
|
+
return padded;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Batch embedding generation. Single API call for multiple texts.
|
|
93
|
+
* OpenAI supports batch requests natively.
|
|
94
|
+
*/
|
|
95
|
+
export async function generateEmbeddings(texts) {
|
|
96
|
+
const apiKey = getApiKey();
|
|
97
|
+
if (apiKey) {
|
|
98
|
+
try {
|
|
99
|
+
const response = await fetch(EMBEDDING_API, {
|
|
100
|
+
method: "POST",
|
|
101
|
+
headers: {
|
|
102
|
+
"Content-Type": "application/json",
|
|
103
|
+
"Authorization": `Bearer ${apiKey}`,
|
|
104
|
+
},
|
|
105
|
+
body: JSON.stringify({
|
|
106
|
+
input: texts,
|
|
107
|
+
model: EMBEDDING_MODEL,
|
|
108
|
+
}),
|
|
109
|
+
});
|
|
110
|
+
if (response.ok) {
|
|
111
|
+
const data = await response.json();
|
|
112
|
+
if (data?.data) {
|
|
113
|
+
return data.data.map(d => d.embedding);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
catch {
|
|
118
|
+
// fallback
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
// Fallback for each text
|
|
122
|
+
return Promise.all(texts.map(t => fallbackEmbedding(t)));
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Checks if a vector is an OpenAI embedding (1536 dimensions)
|
|
126
|
+
* as opposed to TF-IDF (384 dimensions).
|
|
127
|
+
*/
|
|
128
|
+
export function isOpenAIEmbedding(vector) {
|
|
129
|
+
return vector.length === EMBEDDING_DIM;
|
|
130
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import { execFileSync } from "child_process";
|
|
1
2
|
import fs from "fs";
|
|
2
3
|
import path from "path";
|
|
3
|
-
import { execFileSync } from "child_process";
|
|
4
4
|
import { logger } from "./logger.js";
|
|
5
5
|
export function ensureDir(dirPath, dryRun = false) {
|
|
6
6
|
if (!fs.existsSync(dirPath)) {
|
|
@@ -41,7 +41,9 @@ export function appendFile(filePath, content, dryRun = false) {
|
|
|
41
41
|
return;
|
|
42
42
|
}
|
|
43
43
|
ensureDir(path.dirname(filePath));
|
|
44
|
-
|
|
44
|
+
// Atomic append: oku → ekle → atomic yaz
|
|
45
|
+
const existing = fs.existsSync(filePath) ? fs.readFileSync(filePath, "utf8") : "";
|
|
46
|
+
writeTextFile(filePath, existing + content);
|
|
45
47
|
}
|
|
46
48
|
export function writeJsonFile(filePath, value, dryRun = false) {
|
|
47
49
|
writeTextFile(filePath, JSON.stringify(value, null, 2), dryRun);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import chalk from "chalk";
|
|
2
2
|
import path from "path";
|
|
3
|
-
import {
|
|
3
|
+
import { appendFile, ensureDir } from "./fs.js";
|
|
4
|
+
import { containsPII, maskObject, maskText } from "./pii.js";
|
|
4
5
|
export var LogLevel;
|
|
5
6
|
(function (LogLevel) {
|
|
6
7
|
LogLevel[LogLevel["DEBUG"] = 0] = "DEBUG";
|
|
@@ -18,6 +19,8 @@ export class EnterpriseLogger {
|
|
|
18
19
|
minLevel: isProd ? LogLevel.INFO : LogLevel.DEBUG,
|
|
19
20
|
enableColors: !isProd,
|
|
20
21
|
jsonFormat: isProd,
|
|
22
|
+
enablePiiMasking: true, // KVKK: PII masking ON by default
|
|
23
|
+
piiWarning: true,
|
|
21
24
|
};
|
|
22
25
|
}
|
|
23
26
|
static getInstance() {
|
|
@@ -41,13 +44,20 @@ export class EnterpriseLogger {
|
|
|
41
44
|
formatMessage(level, message, meta) {
|
|
42
45
|
const timestamp = new Date().toISOString();
|
|
43
46
|
const pid = process.pid;
|
|
47
|
+
// [KVKK] PII masking — mask sensitive data before logging
|
|
48
|
+
const safeMessage = this.config.enablePiiMasking ? maskText(message) : message;
|
|
49
|
+
const safeMeta = this.config.enablePiiMasking && meta ? maskObject(meta) : meta;
|
|
50
|
+
// [KVKK] Warn if PII detected in production
|
|
51
|
+
if (this.config.piiWarning && (containsPII(message) || (meta && containsPII(JSON.stringify(meta))))) {
|
|
52
|
+
process.stderr.write(`[PII WARNING] Potential PII detected in log at ${timestamp}\n`);
|
|
53
|
+
}
|
|
44
54
|
if (this.config.jsonFormat) {
|
|
45
55
|
return JSON.stringify({
|
|
46
56
|
timestamp,
|
|
47
57
|
level: LogLevel[level],
|
|
48
58
|
pid,
|
|
49
|
-
message,
|
|
50
|
-
meta,
|
|
59
|
+
message: safeMessage,
|
|
60
|
+
meta: safeMeta,
|
|
51
61
|
});
|
|
52
62
|
}
|
|
53
63
|
const levelName = LogLevel[level].padEnd(5);
|
|
@@ -71,8 +81,8 @@ export class EnterpriseLogger {
|
|
|
71
81
|
break;
|
|
72
82
|
}
|
|
73
83
|
}
|
|
74
|
-
const metaStr =
|
|
75
|
-
return `[${timestamp}] [PID:${pid}] [${coloredLevel}]: ${
|
|
84
|
+
const metaStr = safeMeta ? ` | Meta: ${JSON.stringify(safeMeta)}` : "";
|
|
85
|
+
return `[${timestamp}] [PID:${pid}] [${coloredLevel}]: ${safeMessage}${metaStr}`;
|
|
76
86
|
}
|
|
77
87
|
log(level, message, meta) {
|
|
78
88
|
if (level < this.config.minLevel)
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* [PII] Personally Identifiable Information Masking Service
|
|
3
|
+
*
|
|
4
|
+
* Detects and masks sensitive data in compliance with KVKK/GDPR.
|
|
5
|
+
* Used in audit log, logger, and storage layers.
|
|
6
|
+
*
|
|
7
|
+
* Supported patterns:
|
|
8
|
+
* - Email addresses
|
|
9
|
+
* - Phone numbers
|
|
10
|
+
* - TC Identification number
|
|
11
|
+
* - API keys / tokens
|
|
12
|
+
* - IP addresses
|
|
13
|
+
* - Credit card numbers
|
|
14
|
+
* - Custom names (optional)
|
|
15
|
+
*/
|
|
16
|
+
// Sensitive patterns to detect and mask
|
|
17
|
+
const SENSITIVE_PATTERNS = [
|
|
18
|
+
// Email
|
|
19
|
+
{ pattern: /[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/g, replacement: "***@***" },
|
|
20
|
+
// Phone (international and Turkish)
|
|
21
|
+
{ pattern: /(\+90|0)?\s?[0-9]{3}\s?[0-9]{3}\s?[0-9]{2}\s?[0-9]{2}/g, replacement: "***-***-****" },
|
|
22
|
+
// TC Kimlik (11 digits starting with 1-9)
|
|
23
|
+
{ pattern: /\b[1-9][0-9]{10}\b/g, replacement: "***********" },
|
|
24
|
+
// API keys (common formats: sk-..., pk-..., xai-..., etc.)
|
|
25
|
+
{ pattern: /\b(sk-[a-zA-Z0-9]{20,}|pk-[a-zA-Z0-9]{20,}|xai-[a-zA-Z0-9]{20,}|AIza[0-9A-Za-z_-]{35}|ghp_[a-zA-Z0-9]{36,}|gho_[a-zA-Z0-9]{36,})\b/g, replacement: "***-REDACTED-***" },
|
|
26
|
+
// Bearer tokens in Authorization headers
|
|
27
|
+
{ pattern: /Bearer\s+[a-zA-Z0-9._-]+/g, replacement: "Bearer ***-REDACTED-***" },
|
|
28
|
+
// IP addresses
|
|
29
|
+
{ pattern: /\b(?:[0-9]{1,3}\.){3}[0-9]{1,3}\b/g, replacement: "***.***.***.***" },
|
|
30
|
+
// Credit card (16 digits, optional spaces/dashes)
|
|
31
|
+
{ pattern: /\b(?:\d[ -]*?){13,16}\b/g, replacement: "****-****-****-****" },
|
|
32
|
+
// JWT tokens
|
|
33
|
+
{ pattern: /eyJ[a-zA-Z0-9_-]+\.eyJ[a-zA-Z0-9_-]+\.[a-zA-Z0-9_-]+/g, replacement: "***-JWT-REDACTED-***" },
|
|
34
|
+
// Password fields in JSON
|
|
35
|
+
{ pattern: /"(password|passwd|secret|api_key|apiKey|apikey)"\s*:\s*"[^"]+"/gi, replacement: "\"$1\": \"***-REDACTED-***\"" },
|
|
36
|
+
];
|
|
37
|
+
// Fields that are considered sensitive and should always be redacted in structured data
|
|
38
|
+
const SENSITIVE_FIELDS = [
|
|
39
|
+
"password", "passwd", "secret", "apiKey", "api_key", "apikey",
|
|
40
|
+
"token", "accessToken", "refreshToken", "authToken",
|
|
41
|
+
"authorization", "Authorization",
|
|
42
|
+
"email", "phone", "phoneNumber", "telephone",
|
|
43
|
+
"creditCard", "cvv", "ssn", "tcKimlik", "identityNumber",
|
|
44
|
+
"ipAddress",
|
|
45
|
+
];
|
|
46
|
+
/**
|
|
47
|
+
* Mask sensitive data in a text string.
|
|
48
|
+
*/
|
|
49
|
+
export function maskText(text) {
|
|
50
|
+
if (!text || typeof text !== "string")
|
|
51
|
+
return text;
|
|
52
|
+
let masked = text;
|
|
53
|
+
for (const { pattern, replacement } of SENSITIVE_PATTERNS) {
|
|
54
|
+
masked = masked.replace(pattern, replacement);
|
|
55
|
+
}
|
|
56
|
+
return masked;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Recursively mask sensitive fields in an object.
|
|
60
|
+
* Returns a new object with sensitive values redacted.
|
|
61
|
+
*/
|
|
62
|
+
export function maskObject(obj, depth = 0) {
|
|
63
|
+
if (depth > 10)
|
|
64
|
+
return obj; // Prevent infinite recursion
|
|
65
|
+
if (obj === null || obj === undefined)
|
|
66
|
+
return obj;
|
|
67
|
+
if (typeof obj === "string")
|
|
68
|
+
return maskText(obj);
|
|
69
|
+
if (typeof obj !== "object")
|
|
70
|
+
return obj;
|
|
71
|
+
if (Array.isArray(obj)) {
|
|
72
|
+
return obj.map(item => maskObject(item, depth + 1));
|
|
73
|
+
}
|
|
74
|
+
const result = {};
|
|
75
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
76
|
+
// Check if the key itself is a sensitive field
|
|
77
|
+
if (SENSITIVE_FIELDS.includes(key)) {
|
|
78
|
+
result[key] = typeof value === "string" ? "***-REDACTED-***" : maskObject(value, depth + 1);
|
|
79
|
+
}
|
|
80
|
+
else if (typeof value === "string") {
|
|
81
|
+
result[key] = maskText(value);
|
|
82
|
+
}
|
|
83
|
+
else if (typeof value === "object") {
|
|
84
|
+
result[key] = maskObject(value, depth + 1);
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
result[key] = value;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return result;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Check if a string contains potential PII.
|
|
94
|
+
* Useful for warning before sending data to external APIs.
|
|
95
|
+
*/
|
|
96
|
+
export function containsPII(text) {
|
|
97
|
+
for (const { pattern } of SENSITIVE_PATTERNS) {
|
|
98
|
+
if (pattern.test(text))
|
|
99
|
+
return true;
|
|
100
|
+
}
|
|
101
|
+
return false;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Classify a piece of data based on content analysis.
|
|
105
|
+
*/
|
|
106
|
+
export function classifyData(text) {
|
|
107
|
+
if (!text)
|
|
108
|
+
return "public";
|
|
109
|
+
// Check for highly sensitive data
|
|
110
|
+
if (/\b(sk-[a-zA-Z0-9]{20,}|Bearer\s+|eyJ[a-zA-Z0-9_-]+\.)/.test(text) ||
|
|
111
|
+
/\b[1-9][0-9]{10}\b/.test(text) ||
|
|
112
|
+
/"(password|secret|apiKey)"/i.test(text)) {
|
|
113
|
+
return "restricted";
|
|
114
|
+
}
|
|
115
|
+
// Check for moderately sensitive data
|
|
116
|
+
if (/[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/.test(text) ||
|
|
117
|
+
/(\+90|0)?\s?[0-9]{3}\s?[0-9]{3}\s?[0-9]{2}\s?[0-9]{2}/.test(text)) {
|
|
118
|
+
return "confidential";
|
|
119
|
+
}
|
|
120
|
+
return "internal";
|
|
121
|
+
}
|
|
@@ -8,7 +8,7 @@ import { asAgentID, asLogID, asMessageID, asTaskID } from "./types.js";
|
|
|
8
8
|
* [DB] Atabey Storage Engine
|
|
9
9
|
* Central SQLite database for enterprise-scale agent state management.
|
|
10
10
|
*/
|
|
11
|
-
export class
|
|
11
|
+
export class AtabeyStorage {
|
|
12
12
|
static db = null;
|
|
13
13
|
static getDB() {
|
|
14
14
|
if (!this.db) {
|
|
@@ -207,3 +207,5 @@ export class Storage {
|
|
|
207
207
|
}
|
|
208
208
|
}
|
|
209
209
|
}
|
|
210
|
+
/** @deprecated Use AtabeyStorage instead. Kept for backward compatibility. */
|
|
211
|
+
export const Storage = AtabeyStorage;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "atabey",
|
|
3
|
-
"version": "0.0.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.0.13",
|
|
4
|
+
"description": "MCP-Powered AI Governance & Autonomous Orchestration Framework. Plugs into Claude Code, Gemini CLI, and Cursor as an MCP server.",
|
|
5
5
|
"author": "Yusuf BEKAR",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"readme": "README.md",
|
|
@@ -21,7 +21,10 @@
|
|
|
21
21
|
"agents",
|
|
22
22
|
"mcp",
|
|
23
23
|
"typescript",
|
|
24
|
-
"framework"
|
|
24
|
+
"framework",
|
|
25
|
+
"kvkk",
|
|
26
|
+
"gdpr",
|
|
27
|
+
"privacy"
|
|
25
28
|
],
|
|
26
29
|
"workspaces": [
|
|
27
30
|
"framework-mcp"
|
|
@@ -38,6 +41,7 @@
|
|
|
38
41
|
"LICENSE",
|
|
39
42
|
"mcp.json",
|
|
40
43
|
"ATABEY.md",
|
|
44
|
+
"PRIVACY.md",
|
|
41
45
|
"framework-mcp/dist",
|
|
42
46
|
"framework-mcp/package.json"
|
|
43
47
|
],
|
|
@@ -48,7 +52,7 @@
|
|
|
48
52
|
"build": "npm run build:core && npm run build:mcp && npm run build:ui",
|
|
49
53
|
"build:core": "tsc",
|
|
50
54
|
"build:mcp": "npm run build --prefix framework-mcp",
|
|
51
|
-
"build:ui": "npm run build --prefix
|
|
55
|
+
"build:ui": "npm run build --prefix framework-mcp/dashboard",
|
|
52
56
|
"lint": "eslint .",
|
|
53
57
|
"test": "vitest run",
|
|
54
58
|
"test:watch": "vitest",
|
|
@@ -65,6 +69,7 @@
|
|
|
65
69
|
"chalk": "^5.6.2",
|
|
66
70
|
"js-yaml": "^4.2.0",
|
|
67
71
|
"typescript": "^5.9.3",
|
|
72
|
+
"ws": "^8.21.0",
|
|
68
73
|
"zod": "^3.24.2"
|
|
69
74
|
},
|
|
70
75
|
"devDependencies": {
|
|
@@ -72,6 +77,7 @@
|
|
|
72
77
|
"@pandacss/dev": "^1.11.1",
|
|
73
78
|
"@types/better-sqlite3": "^7.6.13",
|
|
74
79
|
"@types/node": "^25.9.1",
|
|
80
|
+
"@types/ws": "^8.18.1",
|
|
75
81
|
"@vitest/coverage-v8": "^3.2.6",
|
|
76
82
|
"eslint": "^10.4.0",
|
|
77
83
|
"globals": "^17.6.0",
|