@jamesaphoenix/tx-core 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/dist/db.d.ts +42 -0
- package/dist/db.d.ts.map +1 -0
- package/dist/db.js +46 -0
- package/dist/db.js.map +1 -0
- package/dist/errors.d.ts +231 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +139 -0
- package/dist/errors.js.map +1 -0
- package/dist/id.d.ts +6 -0
- package/dist/id.d.ts.map +1 -0
- package/dist/id.js +21 -0
- package/dist/id.js.map +1 -0
- package/dist/index.d.ts +25 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +56 -0
- package/dist/index.js.map +1 -0
- package/dist/layer.d.ts +50 -0
- package/dist/layer.d.ts.map +1 -0
- package/dist/layer.js +155 -0
- package/dist/layer.js.map +1 -0
- package/dist/mappers/anchor.d.ts +14 -0
- package/dist/mappers/anchor.d.ts.map +1 -0
- package/dist/mappers/anchor.js +38 -0
- package/dist/mappers/anchor.js.map +1 -0
- package/dist/mappers/attempt.d.ts +15 -0
- package/dist/mappers/attempt.d.ts.map +1 -0
- package/dist/mappers/attempt.js +23 -0
- package/dist/mappers/attempt.js.map +1 -0
- package/dist/mappers/candidate.d.ts +23 -0
- package/dist/mappers/candidate.d.ts.map +1 -0
- package/dist/mappers/candidate.js +53 -0
- package/dist/mappers/candidate.js.map +1 -0
- package/dist/mappers/claim.d.ts +30 -0
- package/dist/mappers/claim.d.ts.map +1 -0
- package/dist/mappers/claim.js +32 -0
- package/dist/mappers/claim.js.map +1 -0
- package/dist/mappers/deduplication.d.ts +39 -0
- package/dist/mappers/deduplication.d.ts.map +1 -0
- package/dist/mappers/deduplication.js +53 -0
- package/dist/mappers/deduplication.js.map +1 -0
- package/dist/mappers/edge.d.ts +10 -0
- package/dist/mappers/edge.d.ts.map +1 -0
- package/dist/mappers/edge.js +19 -0
- package/dist/mappers/edge.js.map +1 -0
- package/dist/mappers/file-learning.d.ts +14 -0
- package/dist/mappers/file-learning.d.ts.map +1 -0
- package/dist/mappers/file-learning.js +75 -0
- package/dist/mappers/file-learning.js.map +1 -0
- package/dist/mappers/index.d.ts +17 -0
- package/dist/mappers/index.d.ts.map +1 -0
- package/dist/mappers/index.js +30 -0
- package/dist/mappers/index.js.map +1 -0
- package/dist/mappers/learning.d.ts +19 -0
- package/dist/mappers/learning.d.ts.map +1 -0
- package/dist/mappers/learning.js +41 -0
- package/dist/mappers/learning.js.map +1 -0
- package/dist/mappers/orchestrator-state.d.ts +33 -0
- package/dist/mappers/orchestrator-state.d.ts.map +1 -0
- package/dist/mappers/orchestrator-state.js +34 -0
- package/dist/mappers/orchestrator-state.js.map +1 -0
- package/dist/mappers/run.d.ts +32 -0
- package/dist/mappers/run.d.ts.map +1 -0
- package/dist/mappers/run.js +64 -0
- package/dist/mappers/run.js.map +1 -0
- package/dist/mappers/task.d.ts +23 -0
- package/dist/mappers/task.d.ts.map +1 -0
- package/dist/mappers/task.js +54 -0
- package/dist/mappers/task.js.map +1 -0
- package/dist/mappers/tracked-project.d.ts +15 -0
- package/dist/mappers/tracked-project.d.ts.map +1 -0
- package/dist/mappers/tracked-project.js +23 -0
- package/dist/mappers/tracked-project.js.map +1 -0
- package/dist/mappers/worker.d.ts +33 -0
- package/dist/mappers/worker.d.ts.map +1 -0
- package/dist/mappers/worker.js +35 -0
- package/dist/mappers/worker.js.map +1 -0
- package/dist/repo/anchor-repo.d.ts +52 -0
- package/dist/repo/anchor-repo.d.ts.map +1 -0
- package/dist/repo/anchor-repo.js +204 -0
- package/dist/repo/anchor-repo.js.map +1 -0
- package/dist/repo/attempt-repo.d.ts +25 -0
- package/dist/repo/attempt-repo.d.ts.map +1 -0
- package/dist/repo/attempt-repo.js +78 -0
- package/dist/repo/attempt-repo.js.map +1 -0
- package/dist/repo/candidate-repo.d.ts +16 -0
- package/dist/repo/candidate-repo.d.ts.map +1 -0
- package/dist/repo/candidate-repo.js +143 -0
- package/dist/repo/candidate-repo.js.map +1 -0
- package/dist/repo/claim-repo.d.ts +17 -0
- package/dist/repo/claim-repo.d.ts.map +1 -0
- package/dist/repo/claim-repo.js +62 -0
- package/dist/repo/claim-repo.js.map +1 -0
- package/dist/repo/deduplication-repo.d.ts +37 -0
- package/dist/repo/deduplication-repo.d.ts.map +1 -0
- package/dist/repo/deduplication-repo.js +133 -0
- package/dist/repo/deduplication-repo.js.map +1 -0
- package/dist/repo/dep-repo.d.ts +19 -0
- package/dist/repo/dep-repo.d.ts.map +1 -0
- package/dist/repo/dep-repo.js +104 -0
- package/dist/repo/dep-repo.js.map +1 -0
- package/dist/repo/edge-repo.d.ts +26 -0
- package/dist/repo/edge-repo.d.ts.map +1 -0
- package/dist/repo/edge-repo.js +227 -0
- package/dist/repo/edge-repo.js.map +1 -0
- package/dist/repo/file-learning-repo.d.ts +17 -0
- package/dist/repo/file-learning-repo.d.ts.map +1 -0
- package/dist/repo/file-learning-repo.js +60 -0
- package/dist/repo/file-learning-repo.js.map +1 -0
- package/dist/repo/index.d.ts +18 -0
- package/dist/repo/index.d.ts.map +1 -0
- package/dist/repo/index.js +18 -0
- package/dist/repo/index.js.map +1 -0
- package/dist/repo/learning-repo.d.ts +31 -0
- package/dist/repo/learning-repo.d.ts.map +1 -0
- package/dist/repo/learning-repo.js +165 -0
- package/dist/repo/learning-repo.js.map +1 -0
- package/dist/repo/orchestrator-state-repo.d.ts +27 -0
- package/dist/repo/orchestrator-state-repo.d.ts.map +1 -0
- package/dist/repo/orchestrator-state-repo.js +96 -0
- package/dist/repo/orchestrator-state-repo.js.map +1 -0
- package/dist/repo/run-repo.d.ts +31 -0
- package/dist/repo/run-repo.d.ts.map +1 -0
- package/dist/repo/run-repo.js +132 -0
- package/dist/repo/run-repo.js.map +1 -0
- package/dist/repo/task-repo.d.ts +21 -0
- package/dist/repo/task-repo.d.ts.map +1 -0
- package/dist/repo/task-repo.js +169 -0
- package/dist/repo/task-repo.js.map +1 -0
- package/dist/repo/tracked-project-repo.d.ts +16 -0
- package/dist/repo/tracked-project-repo.d.ts.map +1 -0
- package/dist/repo/tracked-project-repo.js +54 -0
- package/dist/repo/tracked-project-repo.js.map +1 -0
- package/dist/repo/worker-repo.d.ts +19 -0
- package/dist/repo/worker-repo.d.ts.map +1 -0
- package/dist/repo/worker-repo.js +72 -0
- package/dist/repo/worker-repo.js.map +1 -0
- package/dist/schemas/index.d.ts +8 -0
- package/dist/schemas/index.d.ts.map +1 -0
- package/dist/schemas/index.js +7 -0
- package/dist/schemas/index.js.map +1 -0
- package/dist/schemas/sync.d.ts +296 -0
- package/dist/schemas/sync.d.ts.map +1 -0
- package/dist/schemas/sync.js +146 -0
- package/dist/schemas/sync.js.map +1 -0
- package/dist/schemas/worker.d.ts +77 -0
- package/dist/schemas/worker.d.ts.map +1 -0
- package/dist/schemas/worker.js +80 -0
- package/dist/schemas/worker.js.map +1 -0
- package/dist/services/anchor-service.d.ts +147 -0
- package/dist/services/anchor-service.d.ts.map +1 -0
- package/dist/services/anchor-service.js +540 -0
- package/dist/services/anchor-service.js.map +1 -0
- package/dist/services/anchor-verification.d.ts +94 -0
- package/dist/services/anchor-verification.d.ts.map +1 -0
- package/dist/services/anchor-verification.js +617 -0
- package/dist/services/anchor-verification.js.map +1 -0
- package/dist/services/ast-grep-service.d.ts +58 -0
- package/dist/services/ast-grep-service.d.ts.map +1 -0
- package/dist/services/ast-grep-service.js +356 -0
- package/dist/services/ast-grep-service.js.map +1 -0
- package/dist/services/attempt-service.d.ts +24 -0
- package/dist/services/attempt-service.d.ts.map +1 -0
- package/dist/services/attempt-service.js +55 -0
- package/dist/services/attempt-service.js.map +1 -0
- package/dist/services/auto-sync-service.d.ts +56 -0
- package/dist/services/auto-sync-service.d.ts.map +1 -0
- package/dist/services/auto-sync-service.js +66 -0
- package/dist/services/auto-sync-service.js.map +1 -0
- package/dist/services/candidate-extractor-service.d.ts +56 -0
- package/dist/services/candidate-extractor-service.d.ts.map +1 -0
- package/dist/services/candidate-extractor-service.js +365 -0
- package/dist/services/candidate-extractor-service.js.map +1 -0
- package/dist/services/claim-service.d.ts +52 -0
- package/dist/services/claim-service.d.ts.map +1 -0
- package/dist/services/claim-service.js +134 -0
- package/dist/services/claim-service.js.map +1 -0
- package/dist/services/daemon-service.d.ts +214 -0
- package/dist/services/daemon-service.d.ts.map +1 -0
- package/dist/services/daemon-service.js +522 -0
- package/dist/services/daemon-service.js.map +1 -0
- package/dist/services/deduplication-service.d.ts +67 -0
- package/dist/services/deduplication-service.d.ts.map +1 -0
- package/dist/services/deduplication-service.js +145 -0
- package/dist/services/deduplication-service.js.map +1 -0
- package/dist/services/dep-service.d.ts +14 -0
- package/dist/services/dep-service.d.ts.map +1 -0
- package/dist/services/dep-service.js +34 -0
- package/dist/services/dep-service.js.map +1 -0
- package/dist/services/diversifier-service.d.ts +46 -0
- package/dist/services/diversifier-service.d.ts.map +1 -0
- package/dist/services/diversifier-service.js +197 -0
- package/dist/services/diversifier-service.js.map +1 -0
- package/dist/services/edge-service.d.ts +78 -0
- package/dist/services/edge-service.d.ts.map +1 -0
- package/dist/services/edge-service.js +158 -0
- package/dist/services/edge-service.js.map +1 -0
- package/dist/services/embedding-service.d.ts +138 -0
- package/dist/services/embedding-service.d.ts.map +1 -0
- package/dist/services/embedding-service.js +318 -0
- package/dist/services/embedding-service.js.map +1 -0
- package/dist/services/feedback-tracker.d.ts +64 -0
- package/dist/services/feedback-tracker.d.ts.map +1 -0
- package/dist/services/feedback-tracker.js +110 -0
- package/dist/services/feedback-tracker.js.map +1 -0
- package/dist/services/file-learning-service.d.ts +17 -0
- package/dist/services/file-learning-service.d.ts.map +1 -0
- package/dist/services/file-learning-service.js +41 -0
- package/dist/services/file-learning-service.js.map +1 -0
- package/dist/services/file-watcher-service.d.ts +141 -0
- package/dist/services/file-watcher-service.d.ts.map +1 -0
- package/dist/services/file-watcher-service.js +278 -0
- package/dist/services/file-watcher-service.js.map +1 -0
- package/dist/services/graph-expansion.d.ts +155 -0
- package/dist/services/graph-expansion.d.ts.map +1 -0
- package/dist/services/graph-expansion.js +466 -0
- package/dist/services/graph-expansion.js.map +1 -0
- package/dist/services/hierarchy-service.d.ts +16 -0
- package/dist/services/hierarchy-service.d.ts.map +1 -0
- package/dist/services/hierarchy-service.js +66 -0
- package/dist/services/hierarchy-service.js.map +1 -0
- package/dist/services/index.d.ts +36 -0
- package/dist/services/index.d.ts.map +1 -0
- package/dist/services/index.js +36 -0
- package/dist/services/index.js.map +1 -0
- package/dist/services/learning-service.d.ts +39 -0
- package/dist/services/learning-service.d.ts.map +1 -0
- package/dist/services/learning-service.js +151 -0
- package/dist/services/learning-service.js.map +1 -0
- package/dist/services/migration-service.d.ts +67 -0
- package/dist/services/migration-service.d.ts.map +1 -0
- package/dist/services/migration-service.js +144 -0
- package/dist/services/migration-service.js.map +1 -0
- package/dist/services/orchestrator-service.d.ts +52 -0
- package/dist/services/orchestrator-service.d.ts.map +1 -0
- package/dist/services/orchestrator-service.js +203 -0
- package/dist/services/orchestrator-service.js.map +1 -0
- package/dist/services/promotion-service.d.ts +67 -0
- package/dist/services/promotion-service.d.ts.map +1 -0
- package/dist/services/promotion-service.js +151 -0
- package/dist/services/promotion-service.js.map +1 -0
- package/dist/services/query-expansion-service.d.ts +55 -0
- package/dist/services/query-expansion-service.d.ts.map +1 -0
- package/dist/services/query-expansion-service.js +174 -0
- package/dist/services/query-expansion-service.js.map +1 -0
- package/dist/services/ready-service.d.ts +16 -0
- package/dist/services/ready-service.d.ts.map +1 -0
- package/dist/services/ready-service.js +70 -0
- package/dist/services/ready-service.js.map +1 -0
- package/dist/services/reranker-service.d.ts +51 -0
- package/dist/services/reranker-service.d.ts.map +1 -0
- package/dist/services/reranker-service.js +128 -0
- package/dist/services/reranker-service.js.map +1 -0
- package/dist/services/retriever-service.d.ts +49 -0
- package/dist/services/retriever-service.d.ts.map +1 -0
- package/dist/services/retriever-service.js +419 -0
- package/dist/services/retriever-service.js.map +1 -0
- package/dist/services/score-service.d.ts +43 -0
- package/dist/services/score-service.d.ts.map +1 -0
- package/dist/services/score-service.js +82 -0
- package/dist/services/score-service.js.map +1 -0
- package/dist/services/swarm-verification.d.ts +104 -0
- package/dist/services/swarm-verification.d.ts.map +1 -0
- package/dist/services/swarm-verification.js +400 -0
- package/dist/services/swarm-verification.js.map +1 -0
- package/dist/services/sync-service.d.ts +115 -0
- package/dist/services/sync-service.d.ts.map +1 -0
- package/dist/services/sync-service.js +350 -0
- package/dist/services/sync-service.js.map +1 -0
- package/dist/services/task-service.d.ts +22 -0
- package/dist/services/task-service.d.ts.map +1 -0
- package/dist/services/task-service.js +221 -0
- package/dist/services/task-service.js.map +1 -0
- package/dist/services/worker-process.d.ts +41 -0
- package/dist/services/worker-process.d.ts.map +1 -0
- package/dist/services/worker-process.js +280 -0
- package/dist/services/worker-process.js.map +1 -0
- package/dist/services/worker-service.d.ts +74 -0
- package/dist/services/worker-service.d.ts.map +1 -0
- package/dist/services/worker-service.js +148 -0
- package/dist/services/worker-service.js.map +1 -0
- package/dist/utils/glob.d.ts +15 -0
- package/dist/utils/glob.d.ts.map +1 -0
- package/dist/utils/glob.js +27 -0
- package/dist/utils/glob.js.map +1 -0
- package/dist/utils/math.d.ts +6 -0
- package/dist/utils/math.d.ts.map +1 -0
- package/dist/utils/math.js +21 -0
- package/dist/utils/math.js.map +1 -0
- package/package.json +72 -0
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import { Context, Effect, Layer } from "effect";
|
|
2
|
+
import { EdgeRepository } from "../repo/edge-repo.js";
|
|
3
|
+
import { EdgeNotFoundError, ValidationError } from "../errors.js";
|
|
4
|
+
/** Valid edge types - imported at runtime for validation */
|
|
5
|
+
const VALID_EDGE_TYPES = [
|
|
6
|
+
"ANCHORED_TO",
|
|
7
|
+
"DERIVED_FROM",
|
|
8
|
+
"IMPORTS",
|
|
9
|
+
"CO_CHANGES_WITH",
|
|
10
|
+
"SIMILAR_TO",
|
|
11
|
+
"LINKS_TO",
|
|
12
|
+
"USED_IN_RUN",
|
|
13
|
+
"INVALIDATED_BY"
|
|
14
|
+
];
|
|
15
|
+
/** Valid node types - imported at runtime for validation */
|
|
16
|
+
const VALID_NODE_TYPES = ["learning", "file", "task", "run"];
|
|
17
|
+
export class EdgeService extends Context.Tag("EdgeService")() {
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Validate edge type.
|
|
21
|
+
*/
|
|
22
|
+
const validateEdgeType = (edgeType) => Effect.gen(function* () {
|
|
23
|
+
if (!VALID_EDGE_TYPES.includes(edgeType)) {
|
|
24
|
+
return yield* Effect.fail(new ValidationError({
|
|
25
|
+
reason: `Invalid edge type: ${edgeType}. Valid types: ${VALID_EDGE_TYPES.join(", ")}`
|
|
26
|
+
}));
|
|
27
|
+
}
|
|
28
|
+
return edgeType;
|
|
29
|
+
});
|
|
30
|
+
/**
|
|
31
|
+
* Validate node type.
|
|
32
|
+
*/
|
|
33
|
+
const validateNodeType = (nodeType, field) => Effect.gen(function* () {
|
|
34
|
+
if (!VALID_NODE_TYPES.includes(nodeType)) {
|
|
35
|
+
return yield* Effect.fail(new ValidationError({
|
|
36
|
+
reason: `Invalid ${field}: ${nodeType}. Valid types: ${VALID_NODE_TYPES.join(", ")}`
|
|
37
|
+
}));
|
|
38
|
+
}
|
|
39
|
+
return nodeType;
|
|
40
|
+
});
|
|
41
|
+
/**
|
|
42
|
+
* Validate weight is in [0, 1] range.
|
|
43
|
+
*/
|
|
44
|
+
const validateWeight = (weight) => Effect.gen(function* () {
|
|
45
|
+
const w = weight ?? 1.0;
|
|
46
|
+
if (w < 0 || w > 1) {
|
|
47
|
+
return yield* Effect.fail(new ValidationError({
|
|
48
|
+
reason: `Weight must be between 0 and 1, got: ${w}`
|
|
49
|
+
}));
|
|
50
|
+
}
|
|
51
|
+
return w;
|
|
52
|
+
});
|
|
53
|
+
/**
|
|
54
|
+
* Validate node ID is non-empty.
|
|
55
|
+
*/
|
|
56
|
+
const validateNodeId = (nodeId, field) => Effect.gen(function* () {
|
|
57
|
+
if (!nodeId || nodeId.trim().length === 0) {
|
|
58
|
+
return yield* Effect.fail(new ValidationError({
|
|
59
|
+
reason: `${field} is required and cannot be empty`
|
|
60
|
+
}));
|
|
61
|
+
}
|
|
62
|
+
return nodeId;
|
|
63
|
+
});
|
|
64
|
+
export const EdgeServiceLive = Layer.effect(EdgeService, Effect.gen(function* () {
|
|
65
|
+
const edgeRepo = yield* EdgeRepository;
|
|
66
|
+
return {
|
|
67
|
+
createEdge: (input) => Effect.gen(function* () {
|
|
68
|
+
// Validate all inputs
|
|
69
|
+
yield* validateEdgeType(input.edgeType);
|
|
70
|
+
yield* validateNodeType(input.sourceType, "sourceType");
|
|
71
|
+
yield* validateNodeType(input.targetType, "targetType");
|
|
72
|
+
yield* validateNodeId(input.sourceId, "sourceId");
|
|
73
|
+
yield* validateNodeId(input.targetId, "targetId");
|
|
74
|
+
yield* validateWeight(input.weight);
|
|
75
|
+
// Create the edge
|
|
76
|
+
return yield* edgeRepo.create(input);
|
|
77
|
+
}),
|
|
78
|
+
findNeighbors: (nodeType, nodeId, options = {}) => Effect.gen(function* () {
|
|
79
|
+
const depth = options.depth ?? 1;
|
|
80
|
+
const direction = options.direction ?? "both";
|
|
81
|
+
const edgeTypes = options.edgeTypes;
|
|
82
|
+
// For depth 1, use the repository directly
|
|
83
|
+
if (depth === 1) {
|
|
84
|
+
const neighbors = yield* edgeRepo.findNeighbors(nodeType, nodeId, { direction, edgeTypes });
|
|
85
|
+
return neighbors.map(n => ({ ...n, depth: 1 }));
|
|
86
|
+
}
|
|
87
|
+
// Multi-hop BFS traversal
|
|
88
|
+
const visited = new Set([`${nodeType}:${nodeId}`]);
|
|
89
|
+
const result = [];
|
|
90
|
+
let frontier = [{ nodeType, nodeId }];
|
|
91
|
+
for (let currentDepth = 1; currentDepth <= depth; currentDepth++) {
|
|
92
|
+
const nextFrontier = [];
|
|
93
|
+
for (const node of frontier) {
|
|
94
|
+
const neighbors = yield* edgeRepo.findNeighbors(node.nodeType, node.nodeId, { direction, edgeTypes });
|
|
95
|
+
for (const neighbor of neighbors) {
|
|
96
|
+
const key = `${neighbor.nodeType}:${neighbor.nodeId}`;
|
|
97
|
+
if (!visited.has(key)) {
|
|
98
|
+
visited.add(key);
|
|
99
|
+
result.push({ ...neighbor, depth: currentDepth });
|
|
100
|
+
nextFrontier.push({ nodeType: neighbor.nodeType, nodeId: neighbor.nodeId });
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
frontier = nextFrontier;
|
|
105
|
+
if (frontier.length === 0)
|
|
106
|
+
break;
|
|
107
|
+
}
|
|
108
|
+
return result;
|
|
109
|
+
}),
|
|
110
|
+
findPath: (fromType, fromId, toType, toId, maxDepth = 5) => edgeRepo.findPath(fromType, fromId, toType, toId, maxDepth),
|
|
111
|
+
invalidateEdge: (id) => edgeRepo.invalidate(id),
|
|
112
|
+
get: (id) => Effect.gen(function* () {
|
|
113
|
+
const edge = yield* edgeRepo.findById(id);
|
|
114
|
+
if (!edge) {
|
|
115
|
+
return yield* Effect.fail(new EdgeNotFoundError({ id }));
|
|
116
|
+
}
|
|
117
|
+
return edge;
|
|
118
|
+
}),
|
|
119
|
+
update: (id, input) => Effect.gen(function* () {
|
|
120
|
+
// Validate weight if provided
|
|
121
|
+
if (input.weight !== undefined) {
|
|
122
|
+
yield* validateWeight(input.weight);
|
|
123
|
+
}
|
|
124
|
+
// Get existing edge to verify it exists
|
|
125
|
+
const existing = yield* edgeRepo.findById(id);
|
|
126
|
+
if (!existing) {
|
|
127
|
+
return yield* Effect.fail(new EdgeNotFoundError({ id }));
|
|
128
|
+
}
|
|
129
|
+
// Update the edge
|
|
130
|
+
const updated = yield* edgeRepo.update(id, input);
|
|
131
|
+
if (!updated) {
|
|
132
|
+
return yield* Effect.fail(new EdgeNotFoundError({ id }));
|
|
133
|
+
}
|
|
134
|
+
return updated;
|
|
135
|
+
}),
|
|
136
|
+
findByType: (edgeType) => Effect.gen(function* () {
|
|
137
|
+
yield* validateEdgeType(edgeType);
|
|
138
|
+
return yield* edgeRepo.findByEdgeType(edgeType);
|
|
139
|
+
}),
|
|
140
|
+
findFromSource: (sourceType, sourceId) => edgeRepo.findBySource(sourceType, sourceId),
|
|
141
|
+
findFromMultipleSources: (sourceType, sourceIds) => edgeRepo.findByMultipleSources(sourceType, sourceIds),
|
|
142
|
+
findToTarget: (targetType, targetId) => edgeRepo.findByTarget(targetType, targetId),
|
|
143
|
+
countByType: () => Effect.gen(function* () {
|
|
144
|
+
const dbCounts = yield* edgeRepo.countByType();
|
|
145
|
+
const counts = new Map();
|
|
146
|
+
// Initialize all types with 0
|
|
147
|
+
for (const type of VALID_EDGE_TYPES) {
|
|
148
|
+
counts.set(type, 0);
|
|
149
|
+
}
|
|
150
|
+
// Merge in the actual counts from database
|
|
151
|
+
for (const [edgeType, count] of dbCounts) {
|
|
152
|
+
counts.set(edgeType, count);
|
|
153
|
+
}
|
|
154
|
+
return counts;
|
|
155
|
+
})
|
|
156
|
+
};
|
|
157
|
+
}));
|
|
158
|
+
//# sourceMappingURL=edge-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"edge-service.js","sourceRoot":"","sources":["../../src/services/edge-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAA;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AACrD,OAAO,EAAiB,iBAAiB,EAAE,eAAe,EAAE,MAAM,cAAc,CAAA;AAUhF,4DAA4D;AAC5D,MAAM,gBAAgB,GAAwB;IAC5C,aAAa;IACb,cAAc;IACd,SAAS;IACT,iBAAiB;IACjB,YAAY;IACZ,UAAU;IACV,aAAa;IACb,gBAAgB;CACjB,CAAA;AAED,4DAA4D;AAC5D,MAAM,gBAAgB,GAAwB,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,CAAA;AAwBjF,MAAM,OAAO,WAAY,SAAQ,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,EA2ExD;CAAG;AAEN;;GAEG;AACH,MAAM,gBAAgB,GAAG,CAAC,QAAkB,EAA4C,EAAE,CACxF,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IAClB,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;QACzC,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,eAAe,CAAC;YAC5C,MAAM,EAAE,sBAAsB,QAAQ,kBAAkB,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;SACtF,CAAC,CAAC,CAAA;IACL,CAAC;IACD,OAAO,QAAQ,CAAA;AACjB,CAAC,CAAC,CAAA;AAEJ;;GAEG;AACH,MAAM,gBAAgB,GAAG,CAAC,QAAkB,EAAE,KAAa,EAA4C,EAAE,CACvG,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IAClB,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;QACzC,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,eAAe,CAAC;YAC5C,MAAM,EAAE,WAAW,KAAK,KAAK,QAAQ,kBAAkB,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;SACrF,CAAC,CAAC,CAAA;IACL,CAAC;IACD,OAAO,QAAQ,CAAA;AACjB,CAAC,CAAC,CAAA;AAEJ;;GAEG;AACH,MAAM,cAAc,GAAG,CAAC,MAA0B,EAA0C,EAAE,CAC5F,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IAClB,MAAM,CAAC,GAAG,MAAM,IAAI,GAAG,CAAA;IACvB,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QACnB,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,eAAe,CAAC;YAC5C,MAAM,EAAE,wCAAwC,CAAC,EAAE;SACpD,CAAC,CAAC,CAAA;IACL,CAAC;IACD,OAAO,CAAC,CAAA;AACV,CAAC,CAAC,CAAA;AAEJ;;GAEG;AACH,MAAM,cAAc,GAAG,CAAC,MAAc,EAAE,KAAa,EAA0C,EAAE,CAC/F,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IAClB,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1C,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,eAAe,CAAC;YAC5C,MAAM,EAAE,GAAG,KAAK,kCAAkC;SACnD,CAAC,CAAC,CAAA;IACL,CAAC;IACD,OAAO,MAAM,CAAA;AACf,CAAC,CAAC,CAAA;AAEJ,MAAM,CAAC,MAAM,eAAe,GAAG,KAAK,CAAC,MAAM,CACzC,WAAW,EACX,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IAClB,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,cAAc,CAAA;IAEtC,OAAO;QACL,UAAU,EAAE,CAAC,KAAK,EAAE,EAAE,CACpB,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;YAClB,sBAAsB;YACtB,KAAK,CAAC,CAAC,gBAAgB,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAA;YACvC,KAAK,CAAC,CAAC,gBAAgB,CAAC,KAAK,CAAC,UAAU,EAAE,YAAY,CAAC,CAAA;YACvD,KAAK,CAAC,CAAC,gBAAgB,CAAC,KAAK,CAAC,UAAU,EAAE,YAAY,CAAC,CAAA;YACvD,KAAK,CAAC,CAAC,cAAc,CAAC,KAAK,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAA;YACjD,KAAK,CAAC,CAAC,cAAc,CAAC,KAAK,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAA;YACjD,KAAK,CAAC,CAAC,cAAc,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;YAEnC,kBAAkB;YAClB,OAAO,KAAK,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;QACtC,CAAC,CAAC;QAEJ,aAAa,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,GAAG,EAAE,EAAE,EAAE,CAChD,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;YAClB,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,CAAC,CAAA;YAChC,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,MAAM,CAAA;YAC7C,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,CAAA;YAEnC,2CAA2C;YAC3C,IAAI,KAAK,KAAK,CAAC,EAAE,CAAC;gBAChB,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,QAAQ,CAAC,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,SAAS,EAAE,SAAS,EAAE,CAAC,CAAA;gBAC3F,OAAO,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC,CAAA;YACjD,CAAC;YAED,0BAA0B;YAC1B,MAAM,OAAO,GAAG,IAAI,GAAG,CAAS,CAAC,GAAG,QAAQ,IAAI,MAAM,EAAE,CAAC,CAAC,CAAA;YAC1D,MAAM,MAAM,GAAwB,EAAE,CAAA;YACtC,IAAI,QAAQ,GAAkD,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAA;YAEpF,KAAK,IAAI,YAAY,GAAG,CAAC,EAAE,YAAY,IAAI,KAAK,EAAE,YAAY,EAAE,EAAE,CAAC;gBACjE,MAAM,YAAY,GAAkD,EAAE,CAAA;gBAEtE,KAAK,MAAM,IAAI,IAAI,QAAQ,EAAE,CAAC;oBAC5B,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,QAAQ,CAAC,aAAa,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,SAAS,EAAE,CAAC,CAAA;oBAErG,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;wBACjC,MAAM,GAAG,GAAG,GAAG,QAAQ,CAAC,QAAQ,IAAI,QAAQ,CAAC,MAAM,EAAE,CAAA;wBACrD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;4BACtB,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;4BAChB,MAAM,CAAC,IAAI,CAAC,EAAE,GAAG,QAAQ,EAAE,KAAK,EAAE,YAAY,EAAE,CAAC,CAAA;4BACjD,YAAY,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAA;wBAC7E,CAAC;oBACH,CAAC;gBACH,CAAC;gBAED,QAAQ,GAAG,YAAY,CAAA;gBACvB,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;oBAAE,MAAK;YAClC,CAAC;YAED,OAAO,MAAM,CAAA;QACf,CAAC,CAAC;QAEJ,QAAQ,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,GAAG,CAAC,EAAE,EAAE,CACzD,QAAQ,CAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,CAAC;QAE7D,cAAc,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;QAE/C,GAAG,EAAE,CAAC,EAAE,EAAE,EAAE,CACV,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;YAClB,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAA;YACzC,IAAI,CAAC,IAAI,EAAE,CAAC;gBACV,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,iBAAiB,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAA;YAC1D,CAAC;YACD,OAAO,IAAI,CAAA;QACb,CAAC,CAAC;QAEJ,MAAM,EAAE,CAAC,EAAE,EAAE,KAAK,EAAE,EAAE,CACpB,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;YAClB,8BAA8B;YAC9B,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;gBAC/B,KAAK,CAAC,CAAC,cAAc,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;YACrC,CAAC;YAED,wCAAwC;YACxC,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAA;YAC7C,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACd,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,iBAAiB,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAA;YAC1D,CAAC;YAED,kBAAkB;YAClB,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,EAAE,KAAK,CAAC,CAAA;YACjD,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,iBAAiB,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAA;YAC1D,CAAC;YACD,OAAO,OAAO,CAAA;QAChB,CAAC,CAAC;QAEJ,UAAU,EAAE,CAAC,QAAQ,EAAE,EAAE,CACvB,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;YAClB,KAAK,CAAC,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAA;YACjC,OAAO,KAAK,CAAC,CAAC,QAAQ,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAA;QACjD,CAAC,CAAC;QAEJ,cAAc,EAAE,CAAC,UAAU,EAAE,QAAQ,EAAE,EAAE,CACvC,QAAQ,CAAC,YAAY,CAAC,UAAU,EAAE,QAAQ,CAAC;QAE7C,uBAAuB,EAAE,CAAC,UAAU,EAAE,SAAS,EAAE,EAAE,CACjD,QAAQ,CAAC,qBAAqB,CAAC,UAAU,EAAE,SAAS,CAAC;QAEvD,YAAY,EAAE,CAAC,UAAU,EAAE,QAAQ,EAAE,EAAE,CACrC,QAAQ,CAAC,YAAY,CAAC,UAAU,EAAE,QAAQ,CAAC;QAE7C,WAAW,EAAE,GAAG,EAAE,CAChB,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;YAClB,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAA;YAC9C,MAAM,MAAM,GAAG,IAAI,GAAG,EAAoB,CAAA;YAE1C,8BAA8B;YAC9B,KAAK,MAAM,IAAI,IAAI,gBAAgB,EAAE,CAAC;gBACpC,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,CAAA;YACrB,CAAC;YAED,2CAA2C;YAC3C,KAAK,MAAM,CAAC,QAAQ,EAAE,KAAK,CAAC,IAAI,QAAQ,EAAE,CAAC;gBACzC,MAAM,CAAC,GAAG,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAA;YAC7B,CAAC;YAED,OAAO,MAAM,CAAA;QACf,CAAC,CAAC;KACL,CAAA;AACH,CAAC,CAAC,CACH,CAAA"}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { Context, Effect, Layer } from "effect";
|
|
2
|
+
import { EmbeddingUnavailableError } from "../errors.js";
|
|
3
|
+
declare const EmbeddingService_base: Context.TagClass<EmbeddingService, "EmbeddingService", {
|
|
4
|
+
/** Embed a single text string */
|
|
5
|
+
readonly embed: (text: string) => Effect.Effect<Float32Array, EmbeddingUnavailableError>;
|
|
6
|
+
/** Embed multiple texts in batch */
|
|
7
|
+
readonly embedBatch: (texts: readonly string[]) => Effect.Effect<readonly Float32Array[], EmbeddingUnavailableError>;
|
|
8
|
+
/** Check if embedding functionality is available */
|
|
9
|
+
readonly isAvailable: () => Effect.Effect<boolean>;
|
|
10
|
+
/** The dimension of embedding vectors (0 if unavailable) */
|
|
11
|
+
readonly dimensions: number;
|
|
12
|
+
}>;
|
|
13
|
+
/**
|
|
14
|
+
* EmbeddingService provides vector embeddings for text using local models.
|
|
15
|
+
*
|
|
16
|
+
* Design: DD-010 specifies lazy-loading with node-llama-cpp and embeddinggemma-300M GGUF model.
|
|
17
|
+
* The service gracefully degrades when the model is unavailable.
|
|
18
|
+
*/
|
|
19
|
+
export declare class EmbeddingService extends EmbeddingService_base {
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Noop fallback - always returns failure.
|
|
23
|
+
* Used when node-llama-cpp is not available or embeddings are disabled.
|
|
24
|
+
*/
|
|
25
|
+
export declare const EmbeddingServiceNoop: Layer.Layer<EmbeddingService, never, never>;
|
|
26
|
+
/**
|
|
27
|
+
* Live implementation with node-llama-cpp.
|
|
28
|
+
* Lazy-loads the model on first use and caches the context.
|
|
29
|
+
*/
|
|
30
|
+
export declare const EmbeddingServiceLive: Layer.Layer<EmbeddingService, never, never>;
|
|
31
|
+
/**
|
|
32
|
+
* OpenAI implementation using text-embedding-3 models.
|
|
33
|
+
* Uses OPENAI_API_KEY from environment and optional TX_OPENAI_EMBEDDING_MODEL config.
|
|
34
|
+
*
|
|
35
|
+
* Supported models:
|
|
36
|
+
* - text-embedding-3-small (1536 dimensions, default)
|
|
37
|
+
* - text-embedding-3-large (3072 dimensions)
|
|
38
|
+
* - text-embedding-ada-002 (1536 dimensions, legacy)
|
|
39
|
+
*/
|
|
40
|
+
export declare const EmbeddingServiceOpenAI: Layer.Layer<EmbeddingService, EmbeddingUnavailableError, never>;
|
|
41
|
+
/**
|
|
42
|
+
* Auto-detecting layer that selects the appropriate embedding backend.
|
|
43
|
+
*
|
|
44
|
+
* Priority:
|
|
45
|
+
* 1. TX_EMBEDDER env var override ("openai", "local", "noop")
|
|
46
|
+
* 2. OPENAI_API_KEY set → Use OpenAI (text-embedding-3-small)
|
|
47
|
+
* 3. node-llama-cpp available → Use local embeddings
|
|
48
|
+
* 4. Neither available → Use Noop (graceful degradation)
|
|
49
|
+
*/
|
|
50
|
+
export declare const EmbeddingServiceAuto: Layer.Layer<EmbeddingService, boolean | EmbeddingUnavailableError, never>;
|
|
51
|
+
/**
|
|
52
|
+
* Configuration for a custom embedder implementation.
|
|
53
|
+
*
|
|
54
|
+
* SDK users can provide their own embedding function to integrate
|
|
55
|
+
* with any embedding API or model.
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* ```typescript
|
|
59
|
+
* import { createEmbedderLayer } from "@jamesaphoenix/tx-core"
|
|
60
|
+
*
|
|
61
|
+
* const myEmbedder = createEmbedderLayer({
|
|
62
|
+
* embed: async (text) => {
|
|
63
|
+
* const response = await fetch("https://my-embedding-api.com/embed", {
|
|
64
|
+
* method: "POST",
|
|
65
|
+
* body: JSON.stringify({ text })
|
|
66
|
+
* })
|
|
67
|
+
* const data = await response.json()
|
|
68
|
+
* return new Float32Array(data.embedding)
|
|
69
|
+
* },
|
|
70
|
+
* dimensions: 768,
|
|
71
|
+
* name: "my-custom-embedder"
|
|
72
|
+
* })
|
|
73
|
+
* ```
|
|
74
|
+
*/
|
|
75
|
+
export interface EmbedderConfig {
|
|
76
|
+
/**
|
|
77
|
+
* Embed a single text string into a vector.
|
|
78
|
+
* @param text - The text to embed
|
|
79
|
+
* @returns A Float32Array containing the embedding vector
|
|
80
|
+
*/
|
|
81
|
+
readonly embed: (text: string) => Promise<Float32Array>;
|
|
82
|
+
/**
|
|
83
|
+
* Embed multiple texts in batch.
|
|
84
|
+
* Optional - if not provided, defaults to sequential `embed` calls.
|
|
85
|
+
* @param texts - Array of texts to embed
|
|
86
|
+
* @returns Array of Float32Array embeddings in the same order as input
|
|
87
|
+
*/
|
|
88
|
+
readonly embedBatch?: (texts: readonly string[]) => Promise<readonly Float32Array[]>;
|
|
89
|
+
/**
|
|
90
|
+
* The dimension of embedding vectors produced by this embedder.
|
|
91
|
+
* This must match the actual vector size returned by embed().
|
|
92
|
+
*/
|
|
93
|
+
readonly dimensions: number;
|
|
94
|
+
/**
|
|
95
|
+
* Human-readable name for logging and debugging.
|
|
96
|
+
* @default "custom-embedder"
|
|
97
|
+
*/
|
|
98
|
+
readonly name?: string;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Create an EmbeddingService layer from a custom embedder configuration.
|
|
102
|
+
*
|
|
103
|
+
* This factory allows SDK users to integrate any embedding provider
|
|
104
|
+
* (OpenAI, Cohere, local models, etc.) by providing simple async functions.
|
|
105
|
+
*
|
|
106
|
+
* @param config - Configuration with embed function and dimensions
|
|
107
|
+
* @returns An Effect Layer providing EmbeddingService
|
|
108
|
+
*
|
|
109
|
+
* @example
|
|
110
|
+
* ```typescript
|
|
111
|
+
* import { createEmbedderLayer, makeMinimalLayer } from "@jamesaphoenix/tx-core"
|
|
112
|
+
* import { Layer, Effect } from "effect"
|
|
113
|
+
*
|
|
114
|
+
* // Create custom embedder layer
|
|
115
|
+
* const myEmbedder = createEmbedderLayer({
|
|
116
|
+
* embed: async (text) => callMyEmbeddingAPI(text),
|
|
117
|
+
* dimensions: 768,
|
|
118
|
+
* name: "my-custom-embedder"
|
|
119
|
+
* })
|
|
120
|
+
*
|
|
121
|
+
* // Use with tx application layer
|
|
122
|
+
* const appLayer = makeMinimalLayer(":memory:").pipe(
|
|
123
|
+
* Layer.provideMerge(myEmbedder)
|
|
124
|
+
* )
|
|
125
|
+
*
|
|
126
|
+
* // Run effects with custom embedder
|
|
127
|
+
* const program = Effect.gen(function* () {
|
|
128
|
+
* const embedding = yield* EmbeddingService
|
|
129
|
+
* const vector = yield* embedding.embed("Hello world")
|
|
130
|
+
* console.log(`Vector dimensions: ${vector.length}`)
|
|
131
|
+
* })
|
|
132
|
+
*
|
|
133
|
+
* Effect.runPromise(program.pipe(Effect.provide(appLayer)))
|
|
134
|
+
* ```
|
|
135
|
+
*/
|
|
136
|
+
export declare const createEmbedderLayer: (config: EmbedderConfig) => Layer.Layer<EmbeddingService>;
|
|
137
|
+
export {};
|
|
138
|
+
//# sourceMappingURL=embedding-service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"embedding-service.d.ts","sourceRoot":"","sources":["../../src/services/embedding-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAuB,MAAM,QAAQ,CAAA;AACpE,OAAO,EAAE,yBAAyB,EAAE,MAAM,cAAc,CAAA;;IA6DpD,iCAAiC;oBACjB,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,YAAY,EAAE,yBAAyB,CAAC;IACxF,oCAAoC;yBACf,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,KAAK,MAAM,CAAC,MAAM,CAAC,SAAS,YAAY,EAAE,EAAE,yBAAyB,CAAC;IACpH,oDAAoD;0BAC9B,MAAM,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC;IAClD,4DAA4D;yBACvC,MAAM;;AAhB/B;;;;;GAKG;AACH,qBAAa,gBAAiB,SAAQ,qBAYnC;CAAG;AAEN;;;GAGG;AACH,eAAO,MAAM,oBAAoB,6CAQhC,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,oBAAoB,6CAkGhC,CAAA;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,sBAAsB,iEAiGlC,CAAA;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,oBAAoB,2EAgDhC,CAAA;AAMD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,WAAW,cAAc;IAC7B;;;;OAIG;IACH,QAAQ,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,YAAY,CAAC,CAAA;IAEvD;;;;;OAKG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,KAAK,OAAO,CAAC,SAAS,YAAY,EAAE,CAAC,CAAA;IAEpF;;;OAGG;IACH,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAE3B;;;OAGG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CACvB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,eAAO,MAAM,mBAAmB,GAAI,QAAQ,cAAc,KAAG,KAAK,CAAC,KAAK,CAAC,gBAAgB,CA8CxF,CAAA"}
|
|
@@ -0,0 +1,318 @@
|
|
|
1
|
+
import { Context, Effect, Layer, Ref, Config, Option } from "effect";
|
|
2
|
+
import { EmbeddingUnavailableError } from "../errors.js";
|
|
3
|
+
/**
|
|
4
|
+
* Model dimensions for OpenAI text-embedding-3 models.
|
|
5
|
+
* @see https://platform.openai.com/docs/models/embeddings
|
|
6
|
+
*/
|
|
7
|
+
const OPENAI_MODEL_DIMENSIONS = {
|
|
8
|
+
"text-embedding-3-small": 1536,
|
|
9
|
+
"text-embedding-3-large": 3072,
|
|
10
|
+
"text-embedding-ada-002": 1536 // Legacy model
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* EmbeddingService provides vector embeddings for text using local models.
|
|
14
|
+
*
|
|
15
|
+
* Design: DD-010 specifies lazy-loading with node-llama-cpp and embeddinggemma-300M GGUF model.
|
|
16
|
+
* The service gracefully degrades when the model is unavailable.
|
|
17
|
+
*/
|
|
18
|
+
export class EmbeddingService extends Context.Tag("EmbeddingService")() {
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Noop fallback - always returns failure.
|
|
22
|
+
* Used when node-llama-cpp is not available or embeddings are disabled.
|
|
23
|
+
*/
|
|
24
|
+
export const EmbeddingServiceNoop = Layer.succeed(EmbeddingService, {
|
|
25
|
+
embed: () => Effect.fail(new EmbeddingUnavailableError({ reason: "No embedding model configured" })),
|
|
26
|
+
embedBatch: () => Effect.fail(new EmbeddingUnavailableError({ reason: "No embedding model configured" })),
|
|
27
|
+
isAvailable: () => Effect.succeed(false),
|
|
28
|
+
dimensions: 0
|
|
29
|
+
});
|
|
30
|
+
/**
|
|
31
|
+
* Live implementation with node-llama-cpp.
|
|
32
|
+
* Lazy-loads the model on first use and caches the context.
|
|
33
|
+
*/
|
|
34
|
+
export const EmbeddingServiceLive = Layer.scoped(EmbeddingService, Effect.gen(function* () {
|
|
35
|
+
// State for lazy-loaded context
|
|
36
|
+
const stateRef = yield* Ref.make({
|
|
37
|
+
context: null,
|
|
38
|
+
lastActivity: Date.now()
|
|
39
|
+
});
|
|
40
|
+
/**
|
|
41
|
+
* Ensure the embedding context is loaded.
|
|
42
|
+
* Lazy-loads node-llama-cpp and the model on first call.
|
|
43
|
+
*/
|
|
44
|
+
const ensureContext = Effect.gen(function* () {
|
|
45
|
+
const state = yield* Ref.get(stateRef);
|
|
46
|
+
if (state.context) {
|
|
47
|
+
yield* Ref.update(stateRef, s => ({ ...s, lastActivity: Date.now() }));
|
|
48
|
+
return state.context;
|
|
49
|
+
}
|
|
50
|
+
// Lazy load node-llama-cpp
|
|
51
|
+
const nodeLlamaCpp = yield* Effect.tryPromise({
|
|
52
|
+
try: async () => {
|
|
53
|
+
const mod = await import("node-llama-cpp");
|
|
54
|
+
return mod;
|
|
55
|
+
},
|
|
56
|
+
catch: () => new EmbeddingUnavailableError({ reason: "node-llama-cpp not installed" })
|
|
57
|
+
});
|
|
58
|
+
// Get llama instance
|
|
59
|
+
const llama = yield* Effect.tryPromise({
|
|
60
|
+
try: () => nodeLlamaCpp.getLlama(),
|
|
61
|
+
catch: (e) => new EmbeddingUnavailableError({ reason: `Failed to initialize llama: ${String(e)}` })
|
|
62
|
+
});
|
|
63
|
+
// Load model - uses HuggingFace model spec format
|
|
64
|
+
const model = yield* Effect.tryPromise({
|
|
65
|
+
try: () => llama.loadModel({
|
|
66
|
+
modelPath: "hf:ggml-org/embeddinggemma-300M-GGUF/embeddinggemma-300M-Q8_0.gguf"
|
|
67
|
+
}),
|
|
68
|
+
catch: (e) => new EmbeddingUnavailableError({ reason: `Failed to load model: ${String(e)}` })
|
|
69
|
+
});
|
|
70
|
+
// Create embedding context
|
|
71
|
+
const context = yield* Effect.tryPromise({
|
|
72
|
+
try: () => model.createEmbeddingContext({ threads: 4 }),
|
|
73
|
+
catch: (e) => new EmbeddingUnavailableError({ reason: `Failed to create embedding context: ${String(e)}` })
|
|
74
|
+
});
|
|
75
|
+
yield* Ref.set(stateRef, { context, lastActivity: Date.now() });
|
|
76
|
+
return context;
|
|
77
|
+
});
|
|
78
|
+
/**
|
|
79
|
+
* Format text for query embeddings (search queries).
|
|
80
|
+
* Uses Nomic-style task prefixes for better semantic matching.
|
|
81
|
+
*/
|
|
82
|
+
const formatQuery = (text) => `task: search result | query: ${text}`;
|
|
83
|
+
/**
|
|
84
|
+
* Format text for document embeddings (stored documents).
|
|
85
|
+
*/
|
|
86
|
+
const formatDoc = (text) => `text: ${text}`;
|
|
87
|
+
return {
|
|
88
|
+
embed: (text) => Effect.gen(function* () {
|
|
89
|
+
const ctx = yield* ensureContext;
|
|
90
|
+
const result = yield* Effect.tryPromise({
|
|
91
|
+
try: () => ctx.getEmbeddingFor(formatQuery(text)),
|
|
92
|
+
catch: (e) => new EmbeddingUnavailableError({ reason: `Embedding failed: ${String(e)}` })
|
|
93
|
+
});
|
|
94
|
+
return new Float32Array(result.vector);
|
|
95
|
+
}),
|
|
96
|
+
embedBatch: (texts) => Effect.gen(function* () {
|
|
97
|
+
const ctx = yield* ensureContext;
|
|
98
|
+
const results = [];
|
|
99
|
+
for (const text of texts) {
|
|
100
|
+
const result = yield* Effect.tryPromise({
|
|
101
|
+
try: () => ctx.getEmbeddingFor(formatDoc(text)),
|
|
102
|
+
catch: (e) => new EmbeddingUnavailableError({ reason: `Batch embedding failed: ${String(e)}` })
|
|
103
|
+
});
|
|
104
|
+
yield* Ref.update(stateRef, s => ({ ...s, lastActivity: Date.now() }));
|
|
105
|
+
results.push(new Float32Array(result.vector));
|
|
106
|
+
}
|
|
107
|
+
return results;
|
|
108
|
+
}),
|
|
109
|
+
isAvailable: () => Effect.succeed(true),
|
|
110
|
+
dimensions: 256
|
|
111
|
+
};
|
|
112
|
+
}));
|
|
113
|
+
/**
|
|
114
|
+
* OpenAI implementation using text-embedding-3 models.
|
|
115
|
+
* Uses OPENAI_API_KEY from environment and optional TX_OPENAI_EMBEDDING_MODEL config.
|
|
116
|
+
*
|
|
117
|
+
* Supported models:
|
|
118
|
+
* - text-embedding-3-small (1536 dimensions, default)
|
|
119
|
+
* - text-embedding-3-large (3072 dimensions)
|
|
120
|
+
* - text-embedding-ada-002 (1536 dimensions, legacy)
|
|
121
|
+
*/
|
|
122
|
+
export const EmbeddingServiceOpenAI = Layer.effect(EmbeddingService, Effect.gen(function* () {
|
|
123
|
+
// Read API key from environment
|
|
124
|
+
const apiKey = yield* Config.string("OPENAI_API_KEY").pipe(Effect.mapError(() => new EmbeddingUnavailableError({
|
|
125
|
+
reason: "OPENAI_API_KEY environment variable is not set"
|
|
126
|
+
})));
|
|
127
|
+
// Read model from environment with default
|
|
128
|
+
const model = yield* Config.string("TX_OPENAI_EMBEDDING_MODEL").pipe(Config.withDefault("text-embedding-3-small"), Effect.mapError(() => new EmbeddingUnavailableError({
|
|
129
|
+
reason: "Failed to read TX_OPENAI_EMBEDDING_MODEL config"
|
|
130
|
+
})));
|
|
131
|
+
// Determine dimensions based on model
|
|
132
|
+
const dimensions = OPENAI_MODEL_DIMENSIONS[model] ?? 1536;
|
|
133
|
+
// Lazy-load client
|
|
134
|
+
let client = null;
|
|
135
|
+
const ensureClient = Effect.gen(function* () {
|
|
136
|
+
if (client)
|
|
137
|
+
return client;
|
|
138
|
+
// Dynamic import of OpenAI SDK (optional peer dependency)
|
|
139
|
+
const OpenAI = yield* Effect.tryPromise({
|
|
140
|
+
try: async () => {
|
|
141
|
+
// @ts-expect-error - openai is an optional peer dependency
|
|
142
|
+
const mod = await import("openai");
|
|
143
|
+
return mod.default;
|
|
144
|
+
},
|
|
145
|
+
catch: () => new EmbeddingUnavailableError({
|
|
146
|
+
reason: "openai package is not installed"
|
|
147
|
+
})
|
|
148
|
+
});
|
|
149
|
+
client = new OpenAI({ apiKey });
|
|
150
|
+
return client;
|
|
151
|
+
});
|
|
152
|
+
return {
|
|
153
|
+
embed: (text) => Effect.gen(function* () {
|
|
154
|
+
const openai = yield* ensureClient;
|
|
155
|
+
const response = yield* Effect.tryPromise({
|
|
156
|
+
try: () => openai.embeddings.create({
|
|
157
|
+
model,
|
|
158
|
+
input: text
|
|
159
|
+
}),
|
|
160
|
+
catch: (e) => new EmbeddingUnavailableError({
|
|
161
|
+
reason: `OpenAI embedding failed: ${String(e)}`
|
|
162
|
+
})
|
|
163
|
+
});
|
|
164
|
+
if (!response.data[0]?.embedding) {
|
|
165
|
+
return yield* Effect.fail(new EmbeddingUnavailableError({
|
|
166
|
+
reason: "OpenAI returned empty embedding"
|
|
167
|
+
}));
|
|
168
|
+
}
|
|
169
|
+
return new Float32Array(response.data[0].embedding);
|
|
170
|
+
}),
|
|
171
|
+
embedBatch: (texts) => Effect.gen(function* () {
|
|
172
|
+
if (texts.length === 0) {
|
|
173
|
+
return [];
|
|
174
|
+
}
|
|
175
|
+
const openai = yield* ensureClient;
|
|
176
|
+
// OpenAI supports batch embedding via array input
|
|
177
|
+
const response = yield* Effect.tryPromise({
|
|
178
|
+
try: () => openai.embeddings.create({
|
|
179
|
+
model,
|
|
180
|
+
input: [...texts] // Convert readonly to mutable
|
|
181
|
+
}),
|
|
182
|
+
catch: (e) => new EmbeddingUnavailableError({
|
|
183
|
+
reason: `OpenAI batch embedding failed: ${String(e)}`
|
|
184
|
+
})
|
|
185
|
+
});
|
|
186
|
+
// Sort by index to ensure correct order
|
|
187
|
+
const sorted = [...response.data].sort((a, b) => a.index - b.index);
|
|
188
|
+
return sorted.map(item => new Float32Array(item.embedding));
|
|
189
|
+
}),
|
|
190
|
+
isAvailable: () => Effect.succeed(true),
|
|
191
|
+
dimensions
|
|
192
|
+
};
|
|
193
|
+
}));
|
|
194
|
+
/**
|
|
195
|
+
* Auto-detecting layer that selects the appropriate embedding backend.
|
|
196
|
+
*
|
|
197
|
+
* Priority:
|
|
198
|
+
* 1. TX_EMBEDDER env var override ("openai", "local", "noop")
|
|
199
|
+
* 2. OPENAI_API_KEY set → Use OpenAI (text-embedding-3-small)
|
|
200
|
+
* 3. node-llama-cpp available → Use local embeddings
|
|
201
|
+
* 4. Neither available → Use Noop (graceful degradation)
|
|
202
|
+
*/
|
|
203
|
+
export const EmbeddingServiceAuto = Layer.unwrapEffect(Effect.gen(function* () {
|
|
204
|
+
// Check for TX_EMBEDDER override first
|
|
205
|
+
const embedderOverride = yield* Config.string("TX_EMBEDDER").pipe(Effect.option);
|
|
206
|
+
if (Option.isSome(embedderOverride)) {
|
|
207
|
+
const override = embedderOverride.value.toLowerCase().trim();
|
|
208
|
+
switch (override) {
|
|
209
|
+
case "openai":
|
|
210
|
+
yield* Effect.logDebug("EmbeddingService: Using OpenAI (TX_EMBEDDER override)");
|
|
211
|
+
return EmbeddingServiceOpenAI;
|
|
212
|
+
case "local":
|
|
213
|
+
yield* Effect.logDebug("EmbeddingService: Using local node-llama-cpp (TX_EMBEDDER override)");
|
|
214
|
+
return EmbeddingServiceLive;
|
|
215
|
+
case "noop":
|
|
216
|
+
yield* Effect.logDebug("EmbeddingService: Using noop (TX_EMBEDDER override)");
|
|
217
|
+
return EmbeddingServiceNoop;
|
|
218
|
+
default:
|
|
219
|
+
// Invalid override value - continue with auto-detection
|
|
220
|
+
yield* Effect.logDebug(`EmbeddingService: Invalid TX_EMBEDDER value "${override}", falling back to auto-detection`);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
// Check for OpenAI API key
|
|
224
|
+
const openaiKey = yield* Config.string("OPENAI_API_KEY").pipe(Effect.option);
|
|
225
|
+
if (Option.isSome(openaiKey) && openaiKey.value.trim().length > 0) {
|
|
226
|
+
yield* Effect.logDebug("EmbeddingService: Using OpenAI (OPENAI_API_KEY detected)");
|
|
227
|
+
return EmbeddingServiceOpenAI;
|
|
228
|
+
}
|
|
229
|
+
// Fall back to node-llama-cpp if available
|
|
230
|
+
const llamaAvailable = yield* Effect.tryPromise({
|
|
231
|
+
try: async () => {
|
|
232
|
+
await import("node-llama-cpp");
|
|
233
|
+
return true;
|
|
234
|
+
},
|
|
235
|
+
catch: () => false
|
|
236
|
+
});
|
|
237
|
+
if (llamaAvailable) {
|
|
238
|
+
yield* Effect.logDebug("EmbeddingService: Using local node-llama-cpp (package available)");
|
|
239
|
+
return EmbeddingServiceLive;
|
|
240
|
+
}
|
|
241
|
+
yield* Effect.logDebug("EmbeddingService: Using noop (no embedder available)");
|
|
242
|
+
return EmbeddingServiceNoop;
|
|
243
|
+
}));
|
|
244
|
+
/**
|
|
245
|
+
* Create an EmbeddingService layer from a custom embedder configuration.
|
|
246
|
+
*
|
|
247
|
+
* This factory allows SDK users to integrate any embedding provider
|
|
248
|
+
* (OpenAI, Cohere, local models, etc.) by providing simple async functions.
|
|
249
|
+
*
|
|
250
|
+
* @param config - Configuration with embed function and dimensions
|
|
251
|
+
* @returns An Effect Layer providing EmbeddingService
|
|
252
|
+
*
|
|
253
|
+
* @example
|
|
254
|
+
* ```typescript
|
|
255
|
+
* import { createEmbedderLayer, makeMinimalLayer } from "@jamesaphoenix/tx-core"
|
|
256
|
+
* import { Layer, Effect } from "effect"
|
|
257
|
+
*
|
|
258
|
+
* // Create custom embedder layer
|
|
259
|
+
* const myEmbedder = createEmbedderLayer({
|
|
260
|
+
* embed: async (text) => callMyEmbeddingAPI(text),
|
|
261
|
+
* dimensions: 768,
|
|
262
|
+
* name: "my-custom-embedder"
|
|
263
|
+
* })
|
|
264
|
+
*
|
|
265
|
+
* // Use with tx application layer
|
|
266
|
+
* const appLayer = makeMinimalLayer(":memory:").pipe(
|
|
267
|
+
* Layer.provideMerge(myEmbedder)
|
|
268
|
+
* )
|
|
269
|
+
*
|
|
270
|
+
* // Run effects with custom embedder
|
|
271
|
+
* const program = Effect.gen(function* () {
|
|
272
|
+
* const embedding = yield* EmbeddingService
|
|
273
|
+
* const vector = yield* embedding.embed("Hello world")
|
|
274
|
+
* console.log(`Vector dimensions: ${vector.length}`)
|
|
275
|
+
* })
|
|
276
|
+
*
|
|
277
|
+
* Effect.runPromise(program.pipe(Effect.provide(appLayer)))
|
|
278
|
+
* ```
|
|
279
|
+
*/
|
|
280
|
+
export const createEmbedderLayer = (config) => {
|
|
281
|
+
const embedderName = config.name ?? "custom-embedder";
|
|
282
|
+
return Layer.succeed(EmbeddingService, {
|
|
283
|
+
embed: (text) => Effect.tryPromise({
|
|
284
|
+
try: () => config.embed(text),
|
|
285
|
+
catch: (error) => new EmbeddingUnavailableError({
|
|
286
|
+
reason: `${embedderName} embed failed: ${String(error)}`
|
|
287
|
+
})
|
|
288
|
+
}),
|
|
289
|
+
embedBatch: (texts) => {
|
|
290
|
+
// Use custom batch implementation if provided
|
|
291
|
+
if (config.embedBatch) {
|
|
292
|
+
return Effect.tryPromise({
|
|
293
|
+
try: () => config.embedBatch(texts),
|
|
294
|
+
catch: (error) => new EmbeddingUnavailableError({
|
|
295
|
+
reason: `${embedderName} embedBatch failed: ${String(error)}`
|
|
296
|
+
})
|
|
297
|
+
});
|
|
298
|
+
}
|
|
299
|
+
// Fall back to sequential embed calls
|
|
300
|
+
return Effect.gen(function* () {
|
|
301
|
+
const results = [];
|
|
302
|
+
for (const text of texts) {
|
|
303
|
+
const embedding = yield* Effect.tryPromise({
|
|
304
|
+
try: () => config.embed(text),
|
|
305
|
+
catch: (error) => new EmbeddingUnavailableError({
|
|
306
|
+
reason: `${embedderName} embed failed: ${String(error)}`
|
|
307
|
+
})
|
|
308
|
+
});
|
|
309
|
+
results.push(embedding);
|
|
310
|
+
}
|
|
311
|
+
return results;
|
|
312
|
+
});
|
|
313
|
+
},
|
|
314
|
+
isAvailable: () => Effect.succeed(true),
|
|
315
|
+
dimensions: config.dimensions
|
|
316
|
+
});
|
|
317
|
+
};
|
|
318
|
+
//# sourceMappingURL=embedding-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"embedding-service.js","sourceRoot":"","sources":["../../src/services/embedding-service.ts"],"names":[],"mappings":"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"}
|