@jamesaphoenix/tx-core 0.4.2 → 0.4.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +480 -0
- package/dist/db.d.ts +28 -14
- package/dist/db.d.ts.map +1 -1
- package/dist/db.js +108 -14
- package/dist/db.js.map +1 -1
- package/dist/errors.d.ts +178 -34
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +119 -26
- package/dist/errors.js.map +1 -1
- package/dist/id.d.ts +10 -0
- package/dist/id.d.ts.map +1 -1
- package/dist/id.js +17 -1
- package/dist/id.js.map +1 -1
- package/dist/index.d.ts +15 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +62 -8
- package/dist/index.js.map +1 -1
- package/dist/layer.d.ts +23 -14
- package/dist/layer.d.ts.map +1 -1
- package/dist/layer.js +75 -76
- package/dist/layer.js.map +1 -1
- package/dist/mappers/attempt.d.ts +3 -1
- package/dist/mappers/attempt.d.ts.map +1 -1
- package/dist/mappers/attempt.js +23 -9
- package/dist/mappers/attempt.js.map +1 -1
- package/dist/mappers/claim.d.ts +1 -1
- package/dist/mappers/claim.d.ts.map +1 -1
- package/dist/mappers/claim.js +11 -4
- package/dist/mappers/claim.js.map +1 -1
- package/dist/mappers/deduplication.d.ts +13 -1
- package/dist/mappers/deduplication.d.ts.map +1 -1
- package/dist/mappers/deduplication.js +22 -3
- package/dist/mappers/deduplication.js.map +1 -1
- package/dist/mappers/doc.d.ts +24 -0
- package/dist/mappers/doc.d.ts.map +1 -0
- package/dist/mappers/doc.js +161 -0
- package/dist/mappers/doc.js.map +1 -0
- package/dist/mappers/file-learning.d.ts.map +1 -1
- package/dist/mappers/file-learning.js +2 -1
- package/dist/mappers/file-learning.js.map +1 -1
- package/dist/mappers/index.d.ts +6 -7
- package/dist/mappers/index.d.ts.map +1 -1
- package/dist/mappers/index.js +10 -12
- package/dist/mappers/index.js.map +1 -1
- package/dist/mappers/learning.d.ts +9 -1
- package/dist/mappers/learning.d.ts.map +1 -1
- package/dist/mappers/learning.js +94 -14
- package/dist/mappers/learning.js.map +1 -1
- package/dist/mappers/orchestrator-state.d.ts +1 -1
- package/dist/mappers/orchestrator-state.d.ts.map +1 -1
- package/dist/mappers/orchestrator-state.js +31 -5
- package/dist/mappers/orchestrator-state.js.map +1 -1
- package/dist/mappers/parse-date.d.ts +11 -0
- package/dist/mappers/parse-date.d.ts.map +1 -0
- package/dist/mappers/parse-date.js +18 -0
- package/dist/mappers/parse-date.js.map +1 -0
- package/dist/mappers/run.d.ts +14 -4
- package/dist/mappers/run.d.ts.map +1 -1
- package/dist/mappers/run.js +49 -18
- package/dist/mappers/run.js.map +1 -1
- package/dist/mappers/task.d.ts +5 -1
- package/dist/mappers/task.d.ts.map +1 -1
- package/dist/mappers/task.js +66 -16
- package/dist/mappers/task.js.map +1 -1
- package/dist/mappers/tracked-project.d.ts +3 -1
- package/dist/mappers/tracked-project.d.ts.map +1 -1
- package/dist/mappers/tracked-project.js +23 -9
- package/dist/mappers/tracked-project.js.map +1 -1
- package/dist/mappers/worker.d.ts +1 -1
- package/dist/mappers/worker.d.ts.map +1 -1
- package/dist/mappers/worker.js +44 -6
- package/dist/mappers/worker.js.map +1 -1
- package/dist/repo/attempt-repo.d.ts +2 -2
- package/dist/repo/attempt-repo.d.ts.map +1 -1
- package/dist/repo/attempt-repo.js +16 -6
- package/dist/repo/attempt-repo.js.map +1 -1
- package/dist/repo/claim-repo.d.ts +46 -2
- package/dist/repo/claim-repo.d.ts.map +1 -1
- package/dist/repo/claim-repo.js +113 -6
- package/dist/repo/claim-repo.js.map +1 -1
- package/dist/repo/deduplication-repo.d.ts +9 -1
- package/dist/repo/deduplication-repo.d.ts.map +1 -1
- package/dist/repo/deduplication-repo.js +46 -9
- package/dist/repo/deduplication-repo.js.map +1 -1
- package/dist/repo/dep-repo.d.ts +27 -3
- package/dist/repo/dep-repo.d.ts.map +1 -1
- package/dist/repo/dep-repo.js +166 -39
- package/dist/repo/dep-repo.js.map +1 -1
- package/dist/repo/doc-repo.d.ts +59 -0
- package/dist/repo/doc-repo.d.ts.map +1 -0
- package/dist/repo/doc-repo.js +276 -0
- package/dist/repo/doc-repo.js.map +1 -0
- package/dist/repo/file-learning-repo.d.ts +3 -3
- package/dist/repo/file-learning-repo.d.ts.map +1 -1
- package/dist/repo/file-learning-repo.js +19 -8
- package/dist/repo/file-learning-repo.js.map +1 -1
- package/dist/repo/index.d.ts +4 -6
- package/dist/repo/index.d.ts.map +1 -1
- package/dist/repo/index.js +3 -5
- package/dist/repo/index.js.map +1 -1
- package/dist/repo/learning-repo.d.ts +10 -3
- package/dist/repo/learning-repo.d.ts.map +1 -1
- package/dist/repo/learning-repo.js +68 -11
- package/dist/repo/learning-repo.js.map +1 -1
- package/dist/repo/orchestrator-state-repo.d.ts.map +1 -1
- package/dist/repo/orchestrator-state-repo.js +8 -1
- package/dist/repo/orchestrator-state-repo.js.map +1 -1
- package/dist/repo/run-repo.d.ts +3 -3
- package/dist/repo/run-repo.d.ts.map +1 -1
- package/dist/repo/run-repo.js +40 -19
- package/dist/repo/run-repo.js.map +1 -1
- package/dist/repo/task-repo.d.ts +14 -3
- package/dist/repo/task-repo.d.ts.map +1 -1
- package/dist/repo/task-repo.js +194 -20
- package/dist/repo/task-repo.js.map +1 -1
- package/dist/repo/tracked-project-repo.d.ts.map +1 -1
- package/dist/repo/tracked-project-repo.js +15 -1
- package/dist/repo/tracked-project-repo.js.map +1 -1
- package/dist/repo/worker-repo.d.ts +3 -2
- package/dist/repo/worker-repo.d.ts.map +1 -1
- package/dist/repo/worker-repo.js +54 -8
- package/dist/repo/worker-repo.js.map +1 -1
- package/dist/schemas/sync.js +2 -2
- package/dist/schemas/sync.js.map +1 -1
- package/dist/schemas/worker.d.ts +1 -0
- package/dist/schemas/worker.d.ts.map +1 -1
- package/dist/schemas/worker.js +1 -0
- package/dist/schemas/worker.js.map +1 -1
- package/dist/services/agent-service.d.ts +57 -0
- package/dist/services/agent-service.d.ts.map +1 -0
- package/dist/services/agent-service.js +81 -0
- package/dist/services/agent-service.js.map +1 -0
- package/dist/services/attempt-service.d.ts.map +1 -1
- package/dist/services/attempt-service.js +1 -4
- package/dist/services/attempt-service.js.map +1 -1
- package/dist/services/auto-sync-service.d.ts.map +1 -1
- package/dist/services/auto-sync-service.js +18 -10
- package/dist/services/auto-sync-service.js.map +1 -1
- package/dist/services/claim-service.d.ts +8 -2
- package/dist/services/claim-service.d.ts.map +1 -1
- package/dist/services/claim-service.js +37 -23
- package/dist/services/claim-service.js.map +1 -1
- package/dist/services/cycle-scan-service.d.ts +32 -0
- package/dist/services/cycle-scan-service.d.ts.map +1 -0
- package/dist/services/cycle-scan-service.js +546 -0
- package/dist/services/cycle-scan-service.js.map +1 -0
- package/dist/services/daemon-service.d.ts +40 -2
- package/dist/services/daemon-service.d.ts.map +1 -1
- package/dist/services/daemon-service.js +199 -52
- package/dist/services/daemon-service.js.map +1 -1
- package/dist/services/deduplication-service.d.ts +8 -4
- package/dist/services/deduplication-service.d.ts.map +1 -1
- package/dist/services/deduplication-service.js +79 -25
- package/dist/services/deduplication-service.js.map +1 -1
- package/dist/services/dep-service.d.ts +2 -2
- package/dist/services/dep-service.d.ts.map +1 -1
- package/dist/services/dep-service.js +9 -5
- package/dist/services/dep-service.js.map +1 -1
- package/dist/services/diversifier-service.d.ts +2 -1
- package/dist/services/diversifier-service.d.ts.map +1 -1
- package/dist/services/diversifier-service.js +37 -43
- package/dist/services/diversifier-service.js.map +1 -1
- package/dist/services/doc-service.d.ts +49 -0
- package/dist/services/doc-service.d.ts.map +1 -0
- package/dist/services/doc-service.js +605 -0
- package/dist/services/doc-service.js.map +1 -0
- package/dist/services/embedding-service.d.ts +66 -2
- package/dist/services/embedding-service.d.ts.map +1 -1
- package/dist/services/embedding-service.js +138 -24
- package/dist/services/embedding-service.js.map +1 -1
- package/dist/services/file-learning-service.d.ts.map +1 -1
- package/dist/services/file-learning-service.js +8 -7
- package/dist/services/file-learning-service.js.map +1 -1
- package/dist/services/file-watcher-service.d.ts.map +1 -1
- package/dist/services/file-watcher-service.js +58 -11
- package/dist/services/file-watcher-service.js.map +1 -1
- package/dist/services/hierarchy-service.d.ts +1 -1
- package/dist/services/hierarchy-service.d.ts.map +1 -1
- package/dist/services/hierarchy-service.js +50 -32
- package/dist/services/hierarchy-service.js.map +1 -1
- package/dist/services/index.d.ts +13 -15
- package/dist/services/index.d.ts.map +1 -1
- package/dist/services/index.js +13 -15
- package/dist/services/index.js.map +1 -1
- package/dist/services/learning-service.d.ts +3 -3
- package/dist/services/learning-service.d.ts.map +1 -1
- package/dist/services/learning-service.js +75 -42
- package/dist/services/learning-service.js.map +1 -1
- package/dist/services/llm-service.d.ts +62 -0
- package/dist/services/llm-service.d.ts.map +1 -0
- package/dist/services/llm-service.js +172 -0
- package/dist/services/llm-service.js.map +1 -0
- package/dist/services/migration-service.d.ts +1 -1
- package/dist/services/migration-service.d.ts.map +1 -1
- package/dist/services/migration-service.js +18 -7
- package/dist/services/migration-service.js.map +1 -1
- package/dist/services/orchestrator-service.d.ts +4 -3
- package/dist/services/orchestrator-service.d.ts.map +1 -1
- package/dist/services/orchestrator-service.js +66 -27
- package/dist/services/orchestrator-service.js.map +1 -1
- package/dist/services/query-expansion-service.d.ts +30 -9
- package/dist/services/query-expansion-service.d.ts.map +1 -1
- package/dist/services/query-expansion-service.js +54 -63
- package/dist/services/query-expansion-service.js.map +1 -1
- package/dist/services/ready-service.d.ts +21 -1
- package/dist/services/ready-service.d.ts.map +1 -1
- package/dist/services/ready-service.js +44 -21
- package/dist/services/ready-service.js.map +1 -1
- package/dist/services/retriever-service.d.ts +10 -10
- package/dist/services/retriever-service.d.ts.map +1 -1
- package/dist/services/retriever-service.js +53 -161
- package/dist/services/retriever-service.js.map +1 -1
- package/dist/services/sync-service.d.ts +17 -4
- package/dist/services/sync-service.d.ts.map +1 -1
- package/dist/services/sync-service.js +381 -116
- package/dist/services/sync-service.js.map +1 -1
- package/dist/services/task-service.d.ts +6 -4
- package/dist/services/task-service.d.ts.map +1 -1
- package/dist/services/task-service.js +165 -35
- package/dist/services/task-service.js.map +1 -1
- package/dist/services/tracing-service.d.ts +55 -0
- package/dist/services/tracing-service.d.ts.map +1 -0
- package/dist/services/tracing-service.js +99 -0
- package/dist/services/tracing-service.js.map +1 -0
- package/dist/services/transcript-adapter.d.ts +99 -0
- package/dist/services/transcript-adapter.d.ts.map +1 -0
- package/dist/services/transcript-adapter.js +283 -0
- package/dist/services/transcript-adapter.js.map +1 -0
- package/dist/services/validation-service.d.ts +85 -0
- package/dist/services/validation-service.d.ts.map +1 -0
- package/dist/services/validation-service.js +289 -0
- package/dist/services/validation-service.js.map +1 -0
- package/dist/services/worker-process.d.ts +23 -4
- package/dist/services/worker-process.d.ts.map +1 -1
- package/dist/services/worker-process.js +168 -72
- package/dist/services/worker-process.js.map +1 -1
- package/dist/services/worker-service.d.ts.map +1 -1
- package/dist/services/worker-service.js +7 -12
- package/dist/services/worker-service.js.map +1 -1
- package/dist/sync/claude-task-writer.d.ts +49 -0
- package/dist/sync/claude-task-writer.d.ts.map +1 -0
- package/dist/sync/claude-task-writer.js +135 -0
- package/dist/sync/claude-task-writer.js.map +1 -0
- package/dist/utils/doc-hash.d.ts +10 -0
- package/dist/utils/doc-hash.d.ts.map +1 -0
- package/dist/utils/doc-hash.js +14 -0
- package/dist/utils/doc-hash.js.map +1 -0
- package/dist/utils/doc-renderer.d.ts +44 -0
- package/dist/utils/doc-renderer.d.ts.map +1 -0
- package/dist/utils/doc-renderer.js +202 -0
- package/dist/utils/doc-renderer.js.map +1 -0
- package/dist/utils/math.d.ts +5 -1
- package/dist/utils/math.d.ts.map +1 -1
- package/dist/utils/math.js +12 -4
- package/dist/utils/math.js.map +1 -1
- package/dist/utils/sql.d.ts +9 -0
- package/dist/utils/sql.d.ts.map +1 -0
- package/dist/utils/sql.js +9 -0
- package/dist/utils/sql.js.map +1 -0
- package/dist/utils/toml-config.d.ts +22 -0
- package/dist/utils/toml-config.d.ts.map +1 -0
- package/dist/utils/toml-config.js +75 -0
- package/dist/utils/toml-config.js.map +1 -0
- package/dist/worker/hooks.d.ts +102 -0
- package/dist/worker/hooks.d.ts.map +1 -0
- package/dist/worker/hooks.js +11 -0
- package/dist/worker/hooks.js.map +1 -0
- package/dist/worker/index.d.ts +9 -0
- package/dist/worker/index.d.ts.map +1 -0
- package/dist/worker/index.js +8 -0
- package/dist/worker/index.js.map +1 -0
- package/dist/worker/run-worker.d.ts +33 -0
- package/dist/worker/run-worker.d.ts.map +1 -0
- package/dist/worker/run-worker.js +265 -0
- package/dist/worker/run-worker.js.map +1 -0
- package/package.json +14 -12
- package/dist/mappers/anchor.d.ts +0 -14
- package/dist/mappers/anchor.d.ts.map +0 -1
- package/dist/mappers/anchor.js +0 -38
- package/dist/mappers/anchor.js.map +0 -1
- package/dist/mappers/candidate.d.ts +0 -23
- package/dist/mappers/candidate.d.ts.map +0 -1
- package/dist/mappers/candidate.js +0 -53
- package/dist/mappers/candidate.js.map +0 -1
- package/dist/mappers/edge.d.ts +0 -10
- package/dist/mappers/edge.d.ts.map +0 -1
- package/dist/mappers/edge.js +0 -19
- package/dist/mappers/edge.js.map +0 -1
- package/dist/repo/anchor-repo.d.ts +0 -52
- package/dist/repo/anchor-repo.d.ts.map +0 -1
- package/dist/repo/anchor-repo.js +0 -204
- package/dist/repo/anchor-repo.js.map +0 -1
- package/dist/repo/candidate-repo.d.ts +0 -16
- package/dist/repo/candidate-repo.d.ts.map +0 -1
- package/dist/repo/candidate-repo.js +0 -143
- package/dist/repo/candidate-repo.js.map +0 -1
- package/dist/repo/edge-repo.d.ts +0 -26
- package/dist/repo/edge-repo.d.ts.map +0 -1
- package/dist/repo/edge-repo.js +0 -227
- package/dist/repo/edge-repo.js.map +0 -1
- package/dist/services/anchor-service.d.ts +0 -147
- package/dist/services/anchor-service.d.ts.map +0 -1
- package/dist/services/anchor-service.js +0 -540
- package/dist/services/anchor-service.js.map +0 -1
- package/dist/services/anchor-verification.d.ts +0 -94
- package/dist/services/anchor-verification.d.ts.map +0 -1
- package/dist/services/anchor-verification.js +0 -617
- package/dist/services/anchor-verification.js.map +0 -1
- package/dist/services/ast-grep-service.d.ts +0 -58
- package/dist/services/ast-grep-service.d.ts.map +0 -1
- package/dist/services/ast-grep-service.js +0 -356
- package/dist/services/ast-grep-service.js.map +0 -1
- package/dist/services/candidate-extractor-service.d.ts +0 -56
- package/dist/services/candidate-extractor-service.d.ts.map +0 -1
- package/dist/services/candidate-extractor-service.js +0 -365
- package/dist/services/candidate-extractor-service.js.map +0 -1
- package/dist/services/edge-service.d.ts +0 -78
- package/dist/services/edge-service.d.ts.map +0 -1
- package/dist/services/edge-service.js +0 -158
- package/dist/services/edge-service.js.map +0 -1
- package/dist/services/feedback-tracker.d.ts +0 -64
- package/dist/services/feedback-tracker.d.ts.map +0 -1
- package/dist/services/feedback-tracker.js +0 -110
- package/dist/services/feedback-tracker.js.map +0 -1
- package/dist/services/graph-expansion.d.ts +0 -155
- package/dist/services/graph-expansion.d.ts.map +0 -1
- package/dist/services/graph-expansion.js +0 -466
- package/dist/services/graph-expansion.js.map +0 -1
- package/dist/services/promotion-service.d.ts +0 -67
- package/dist/services/promotion-service.d.ts.map +0 -1
- package/dist/services/promotion-service.js +0 -151
- package/dist/services/promotion-service.js.map +0 -1
- package/dist/services/swarm-verification.d.ts +0 -104
- package/dist/services/swarm-verification.d.ts.map +0 -1
- package/dist/services/swarm-verification.js +0 -400
- package/dist/services/swarm-verification.js.map +0 -1
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { Context, Effect, Layer, Schema } from "effect";
|
|
2
|
+
import { LlmUnavailableError } from "../errors.js";
|
|
3
|
+
/**
|
|
4
|
+
* Options for LLM text completion.
|
|
5
|
+
*/
|
|
6
|
+
export declare const LlmOptionsSchema: Schema.Struct<{
|
|
7
|
+
/** Model to use (default varies by backend) */
|
|
8
|
+
model: Schema.optional<typeof Schema.String>;
|
|
9
|
+
/** Maximum tokens in response */
|
|
10
|
+
maxTokens: Schema.optional<typeof Schema.Number>;
|
|
11
|
+
/** Temperature for generation (0-1) */
|
|
12
|
+
temperature: Schema.optional<typeof Schema.Number>;
|
|
13
|
+
}>;
|
|
14
|
+
export type LlmOptions = typeof LlmOptionsSchema.Type;
|
|
15
|
+
declare const LlmService_base: Context.TagClass<LlmService, "LlmService", {
|
|
16
|
+
/** Send a prompt and get a text completion */
|
|
17
|
+
readonly complete: (prompt: string, options?: LlmOptions) => Effect.Effect<string, LlmUnavailableError>;
|
|
18
|
+
/** Check if an LLM backend is available */
|
|
19
|
+
readonly isAvailable: () => Effect.Effect<boolean>;
|
|
20
|
+
/** Get the name of the active backend */
|
|
21
|
+
readonly backend: () => string;
|
|
22
|
+
}>;
|
|
23
|
+
/**
|
|
24
|
+
* LlmService provides centralized LLM text completion with swappable backends.
|
|
25
|
+
*
|
|
26
|
+
* Backends:
|
|
27
|
+
* - claude-agent-sdk: Uses @anthropic-ai/claude-agent-sdk query() (primary)
|
|
28
|
+
* - anthropic-sdk: Uses @anthropic-ai/sdk messages.create() (fallback)
|
|
29
|
+
* - noop: Returns empty string (tests, core commands)
|
|
30
|
+
*
|
|
31
|
+
* Design: See DD-022 for full specification.
|
|
32
|
+
*/
|
|
33
|
+
export declare class LlmService extends LlmService_base {
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Noop implementation — returns empty string for all completions.
|
|
37
|
+
* Used in test layers and core commands where no LLM is needed.
|
|
38
|
+
*/
|
|
39
|
+
export declare const LlmServiceNoop: Layer.Layer<LlmService, never, never>;
|
|
40
|
+
/**
|
|
41
|
+
* Claude Agent SDK implementation.
|
|
42
|
+
* Uses query() from @anthropic-ai/claude-agent-sdk with maxTurns: 1 and no tools
|
|
43
|
+
* for single-turn text completion.
|
|
44
|
+
*
|
|
45
|
+
* Reads ANTHROPIC_API_KEY automatically from environment.
|
|
46
|
+
*/
|
|
47
|
+
export declare const LlmServiceClaudeAgentSdk: Layer.Layer<LlmService, LlmUnavailableError, never>;
|
|
48
|
+
/**
|
|
49
|
+
* Anthropic SDK implementation.
|
|
50
|
+
* Uses client.messages.create() from @anthropic-ai/sdk.
|
|
51
|
+
* Extracted from the original QueryExpansionServiceLive.
|
|
52
|
+
*
|
|
53
|
+
* Requires ANTHROPIC_API_KEY environment variable.
|
|
54
|
+
*/
|
|
55
|
+
export declare const LlmServiceAnthropicSdk: Layer.Layer<LlmService, LlmUnavailableError, never>;
|
|
56
|
+
/**
|
|
57
|
+
* Auto-detecting layer.
|
|
58
|
+
* Priority: TX_LLM_BACKEND env override > Claude Agent SDK > Anthropic SDK > Noop.
|
|
59
|
+
*/
|
|
60
|
+
export declare const LlmServiceAuto: Layer.Layer<LlmService, LlmUnavailableError, never>;
|
|
61
|
+
export {};
|
|
62
|
+
//# sourceMappingURL=llm-service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"llm-service.d.ts","sourceRoot":"","sources":["../../src/services/llm-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAkB,MAAM,EAAE,MAAM,QAAQ,CAAA;AACvE,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAA;AAElD;;GAEG;AACH,eAAO,MAAM,gBAAgB;IAC3B,+CAA+C;;IAE/C,iCAAiC;;IAEjC,uCAAuC;;EAEvC,CAAA;AACF,MAAM,MAAM,UAAU,GAAG,OAAO,gBAAgB,CAAC,IAAI,CAAA;;IAgDjD,8CAA8C;uBAC3B,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,UAAU,KAAK,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC;IACvG,2CAA2C;0BACrB,MAAM,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC;IAClD,yCAAyC;sBACvB,MAAM,MAAM;;AAlBlC;;;;;;;;;GASG;AACH,qBAAa,UAAW,SAAQ,eAU7B;CAAG;AAEN;;;GAGG;AACH,eAAO,MAAM,cAAc,uCAIzB,CAAA;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,wBAAwB,qDAkDpC,CAAA;AAED;;;;;;GAMG;AACH,eAAO,MAAM,sBAAsB,qDA+ClC,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,cAAc,qDAyC1B,CAAA"}
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import { Context, Effect, Layer, Config, Option, Schema } from "effect";
|
|
2
|
+
import { LlmUnavailableError } from "../errors.js";
|
|
3
|
+
/**
|
|
4
|
+
* Options for LLM text completion.
|
|
5
|
+
*/
|
|
6
|
+
export const LlmOptionsSchema = Schema.Struct({
|
|
7
|
+
/** Model to use (default varies by backend) */
|
|
8
|
+
model: Schema.optional(Schema.String),
|
|
9
|
+
/** Maximum tokens in response */
|
|
10
|
+
maxTokens: Schema.optional(Schema.Number),
|
|
11
|
+
/** Temperature for generation (0-1) */
|
|
12
|
+
temperature: Schema.optional(Schema.Number)
|
|
13
|
+
});
|
|
14
|
+
/**
|
|
15
|
+
* LlmService provides centralized LLM text completion with swappable backends.
|
|
16
|
+
*
|
|
17
|
+
* Backends:
|
|
18
|
+
* - claude-agent-sdk: Uses @anthropic-ai/claude-agent-sdk query() (primary)
|
|
19
|
+
* - anthropic-sdk: Uses @anthropic-ai/sdk messages.create() (fallback)
|
|
20
|
+
* - noop: Returns empty string (tests, core commands)
|
|
21
|
+
*
|
|
22
|
+
* Design: See DD-022 for full specification.
|
|
23
|
+
*/
|
|
24
|
+
export class LlmService extends Context.Tag("LlmService")() {
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Noop implementation — returns empty string for all completions.
|
|
28
|
+
* Used in test layers and core commands where no LLM is needed.
|
|
29
|
+
*/
|
|
30
|
+
export const LlmServiceNoop = Layer.succeed(LlmService, {
|
|
31
|
+
complete: (_prompt, _options) => Effect.succeed(""),
|
|
32
|
+
isAvailable: () => Effect.succeed(false),
|
|
33
|
+
backend: () => "noop"
|
|
34
|
+
});
|
|
35
|
+
/**
|
|
36
|
+
* Claude Agent SDK implementation.
|
|
37
|
+
* Uses query() from @anthropic-ai/claude-agent-sdk with maxTurns: 1 and no tools
|
|
38
|
+
* for single-turn text completion.
|
|
39
|
+
*
|
|
40
|
+
* Reads ANTHROPIC_API_KEY automatically from environment.
|
|
41
|
+
*/
|
|
42
|
+
export const LlmServiceClaudeAgentSdk = Layer.effect(LlmService, Effect.gen(function* () {
|
|
43
|
+
// Dynamic import of Claude Agent SDK (optional peer dependency)
|
|
44
|
+
const queryFn = yield* Effect.tryPromise({
|
|
45
|
+
try: async () => {
|
|
46
|
+
// @ts-ignore - @anthropic-ai/claude-agent-sdk is an optional peer dependency
|
|
47
|
+
const mod = await import("@anthropic-ai/claude-agent-sdk");
|
|
48
|
+
return mod.query;
|
|
49
|
+
},
|
|
50
|
+
catch: (e) => new LlmUnavailableError({
|
|
51
|
+
reason: `@anthropic-ai/claude-agent-sdk not installed: ${e instanceof Error ? e.message : String(e)}`
|
|
52
|
+
})
|
|
53
|
+
});
|
|
54
|
+
return {
|
|
55
|
+
complete: (prompt, options) => Effect.tryPromise({
|
|
56
|
+
try: async () => {
|
|
57
|
+
let result = "";
|
|
58
|
+
let errorMessage = null;
|
|
59
|
+
for await (const message of queryFn({
|
|
60
|
+
prompt,
|
|
61
|
+
options: {
|
|
62
|
+
maxTurns: 1,
|
|
63
|
+
allowedTools: [],
|
|
64
|
+
...(options?.model ? { model: options.model } : {})
|
|
65
|
+
}
|
|
66
|
+
})) {
|
|
67
|
+
if (message.type === "result") {
|
|
68
|
+
if (message.subtype === "success" && message.result) {
|
|
69
|
+
result = message.result;
|
|
70
|
+
}
|
|
71
|
+
else if (message.subtype !== "success") {
|
|
72
|
+
errorMessage = message.errors?.join(", ") ?? message.subtype ?? "unknown error";
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
if (errorMessage) {
|
|
77
|
+
return Promise.reject(new Error(`Agent SDK error: ${errorMessage}`));
|
|
78
|
+
}
|
|
79
|
+
return result;
|
|
80
|
+
},
|
|
81
|
+
catch: (e) => new LlmUnavailableError({
|
|
82
|
+
reason: `Claude Agent SDK call failed: ${e instanceof Error ? e.message : String(e)}`
|
|
83
|
+
})
|
|
84
|
+
}),
|
|
85
|
+
isAvailable: () => Effect.succeed(true),
|
|
86
|
+
backend: () => "claude-agent-sdk"
|
|
87
|
+
};
|
|
88
|
+
}));
|
|
89
|
+
/**
|
|
90
|
+
* Anthropic SDK implementation.
|
|
91
|
+
* Uses client.messages.create() from @anthropic-ai/sdk.
|
|
92
|
+
* Extracted from the original QueryExpansionServiceLive.
|
|
93
|
+
*
|
|
94
|
+
* Requires ANTHROPIC_API_KEY environment variable.
|
|
95
|
+
*/
|
|
96
|
+
export const LlmServiceAnthropicSdk = Layer.effect(LlmService, Effect.gen(function* () {
|
|
97
|
+
// Read API key from environment
|
|
98
|
+
const apiKey = yield* Config.string("ANTHROPIC_API_KEY").pipe(Effect.mapError(() => new LlmUnavailableError({
|
|
99
|
+
reason: "ANTHROPIC_API_KEY environment variable is not set"
|
|
100
|
+
})));
|
|
101
|
+
// Eagerly initialize the client during layer construction.
|
|
102
|
+
// This avoids a mutable closure variable that is not fiber-safe.
|
|
103
|
+
const Anthropic = yield* Effect.tryPromise({
|
|
104
|
+
try: async () => {
|
|
105
|
+
// @ts-ignore - @anthropic-ai/sdk is an optional peer dependency
|
|
106
|
+
const mod = await import("@anthropic-ai/sdk");
|
|
107
|
+
return mod.default;
|
|
108
|
+
},
|
|
109
|
+
catch: (e) => new LlmUnavailableError({
|
|
110
|
+
reason: `@anthropic-ai/sdk not installed: ${e instanceof Error ? e.message : String(e)}`
|
|
111
|
+
})
|
|
112
|
+
});
|
|
113
|
+
const anthropicClient = new Anthropic({ apiKey });
|
|
114
|
+
return {
|
|
115
|
+
complete: (prompt, options) => Effect.gen(function* () {
|
|
116
|
+
const anthropic = anthropicClient;
|
|
117
|
+
const response = yield* Effect.tryPromise({
|
|
118
|
+
try: () => anthropic.messages.create({
|
|
119
|
+
model: options?.model ?? "claude-haiku-4-5-20251001",
|
|
120
|
+
max_tokens: options?.maxTokens ?? 1024,
|
|
121
|
+
messages: [{ role: "user", content: prompt }]
|
|
122
|
+
}),
|
|
123
|
+
catch: (e) => new LlmUnavailableError({
|
|
124
|
+
reason: `Anthropic API call failed: ${e instanceof Error ? e.message : String(e)}`
|
|
125
|
+
})
|
|
126
|
+
});
|
|
127
|
+
const textContent = response.content.find(c => c.type === "text");
|
|
128
|
+
return textContent?.text ?? "";
|
|
129
|
+
}),
|
|
130
|
+
isAvailable: () => Effect.succeed(true),
|
|
131
|
+
backend: () => "anthropic-sdk"
|
|
132
|
+
};
|
|
133
|
+
}));
|
|
134
|
+
/**
|
|
135
|
+
* Auto-detecting layer.
|
|
136
|
+
* Priority: TX_LLM_BACKEND env override > Claude Agent SDK > Anthropic SDK > Noop.
|
|
137
|
+
*/
|
|
138
|
+
export const LlmServiceAuto = Layer.unwrapEffect(Effect.gen(function* () {
|
|
139
|
+
// Check for explicit backend override
|
|
140
|
+
const backendOverride = yield* Config.string("TX_LLM_BACKEND").pipe(Effect.option);
|
|
141
|
+
if (Option.isSome(backendOverride)) {
|
|
142
|
+
const backend = backendOverride.value.trim().toLowerCase();
|
|
143
|
+
switch (backend) {
|
|
144
|
+
case "claude-agent-sdk":
|
|
145
|
+
return LlmServiceClaudeAgentSdk;
|
|
146
|
+
case "anthropic-sdk":
|
|
147
|
+
return LlmServiceAnthropicSdk;
|
|
148
|
+
case "noop":
|
|
149
|
+
return LlmServiceNoop;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
// Auto-detect: try Claude Agent SDK first
|
|
153
|
+
const agentSdkAvailable = yield* Effect.tryPromise(
|
|
154
|
+
// @ts-ignore - @anthropic-ai/claude-agent-sdk is an optional peer dependency
|
|
155
|
+
() => import("@anthropic-ai/claude-agent-sdk").then(() => true)).pipe(Effect.orElseSucceed(() => false));
|
|
156
|
+
if (agentSdkAvailable) {
|
|
157
|
+
return LlmServiceClaudeAgentSdk;
|
|
158
|
+
}
|
|
159
|
+
// Try Anthropic SDK (needs API key + package)
|
|
160
|
+
const apiKey = yield* Config.string("ANTHROPIC_API_KEY").pipe(Effect.option);
|
|
161
|
+
if (Option.isSome(apiKey) && apiKey.value.trim().length > 0) {
|
|
162
|
+
const anthropicAvailable = yield* Effect.tryPromise(
|
|
163
|
+
// @ts-ignore - @anthropic-ai/sdk is an optional peer dependency
|
|
164
|
+
() => import("@anthropic-ai/sdk").then(() => true)).pipe(Effect.orElseSucceed(() => false));
|
|
165
|
+
if (anthropicAvailable) {
|
|
166
|
+
return LlmServiceAnthropicSdk;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
// Fallback to noop
|
|
170
|
+
return LlmServiceNoop;
|
|
171
|
+
}));
|
|
172
|
+
//# sourceMappingURL=llm-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"llm-service.js","sourceRoot":"","sources":["../../src/services/llm-service.ts"],"names":[],"mappings":"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"}
|
|
@@ -28,7 +28,7 @@ export interface MigrationStatus {
|
|
|
28
28
|
}
|
|
29
29
|
/**
|
|
30
30
|
* All migrations loaded from the migrations/ directory.
|
|
31
|
-
* Sorted by version number.
|
|
31
|
+
* Sorted by version number. Uses top-level await for non-blocking I/O.
|
|
32
32
|
*/
|
|
33
33
|
export declare const MIGRATIONS: readonly Migration[];
|
|
34
34
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"migration-service.d.ts","sourceRoot":"","sources":["../../src/services/migration-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAA;AAI/C,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAE5C;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAA;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAA;IAC/B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;IAC9B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;IAC7B,QAAQ,CAAC,iBAAiB,EAAE,SAAS,gBAAgB,EAAE,CAAA;IACvD,QAAQ,CAAC,iBAAiB,EAAE,SAAS,SAAS,EAAE,CAAA;CACjD;
|
|
1
|
+
{"version":3,"file":"migration-service.d.ts","sourceRoot":"","sources":["../../src/services/migration-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAA;AAI/C,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAE5C;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAA;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAA;IAC/B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;IAC9B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;IAC7B,QAAQ,CAAC,iBAAiB,EAAE,SAAS,gBAAgB,EAAE,CAAA;IACvD,QAAQ,CAAC,iBAAiB,EAAE,SAAS,SAAS,EAAE,CAAA;CACjD;AAmED;;;GAGG;AACH,eAAO,MAAM,UAAU,EAAE,SAAS,SAAS,EAAkC,CAAA;AAE7E;;GAEG;AACH,eAAO,MAAM,gBAAgB,QAAO,MAGnC,CAAA;;IASG;;;OAGG;wBACiB,MAAM,MAAM,CAAC,MAAM,CAAC,eAAe,EAAE,aAAa,CAAC;IAEvE;;;;OAIG;kBACW,MAAM,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC;IAExD;;OAEG;gCACyB,MAAM,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC;IAEtE;;OAEG;mCAC4B,MAAM,MAAM,CAAC,MAAM,CAAC,SAAS,gBAAgB,EAAE,EAAE,aAAa,CAAC;;AA5BlG;;;GAGG;AACH,qBAAa,gBAAiB,SAAQ,qBA0BnC;CAAG;AAEN,eAAO,MAAM,oBAAoB,oDAkFhC,CAAA"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Context, Effect, Layer } from "effect";
|
|
2
|
-
import {
|
|
2
|
+
import { readdir, readFile } from "node:fs/promises";
|
|
3
3
|
import { dirname, join, resolve } from "node:path";
|
|
4
4
|
import { fileURLToPath } from "node:url";
|
|
5
5
|
import { SqliteClient } from "../db.js";
|
|
@@ -33,12 +33,13 @@ const parseMigrationFilename = (filename) => {
|
|
|
33
33
|
/**
|
|
34
34
|
* Load all migrations from the migrations/ directory.
|
|
35
35
|
* Migrations are sorted by version number.
|
|
36
|
+
* Uses async fs operations to avoid blocking the event loop.
|
|
36
37
|
*/
|
|
37
|
-
const loadMigrationsFromDir = () => {
|
|
38
|
+
const loadMigrationsFromDir = async () => {
|
|
38
39
|
const migrationsDir = getMigrationsDir();
|
|
39
40
|
let files;
|
|
40
41
|
try {
|
|
41
|
-
files =
|
|
42
|
+
files = await readdir(migrationsDir);
|
|
42
43
|
}
|
|
43
44
|
catch {
|
|
44
45
|
// Migrations directory doesn't exist - return empty array
|
|
@@ -51,7 +52,7 @@ const loadMigrationsFromDir = () => {
|
|
|
51
52
|
const parsed = parseMigrationFilename(filename);
|
|
52
53
|
if (!parsed)
|
|
53
54
|
continue;
|
|
54
|
-
const sql =
|
|
55
|
+
const sql = await readFile(join(migrationsDir, filename), "utf-8");
|
|
55
56
|
migrations.push({
|
|
56
57
|
version: parsed.version,
|
|
57
58
|
description: parsed.description,
|
|
@@ -64,9 +65,9 @@ const loadMigrationsFromDir = () => {
|
|
|
64
65
|
};
|
|
65
66
|
/**
|
|
66
67
|
* All migrations loaded from the migrations/ directory.
|
|
67
|
-
* Sorted by version number.
|
|
68
|
+
* Sorted by version number. Uses top-level await for non-blocking I/O.
|
|
68
69
|
*/
|
|
69
|
-
export const MIGRATIONS = loadMigrationsFromDir();
|
|
70
|
+
export const MIGRATIONS = await loadMigrationsFromDir();
|
|
70
71
|
/**
|
|
71
72
|
* Get the latest migration version.
|
|
72
73
|
*/
|
|
@@ -133,7 +134,17 @@ export const MigrationServiceLive = Layer.effect(MigrationService, Effect.gen(fu
|
|
|
133
134
|
const pendingMigrations = MIGRATIONS.filter(m => m.version > currentVersion);
|
|
134
135
|
for (const migration of pendingMigrations) {
|
|
135
136
|
yield* Effect.try({
|
|
136
|
-
try: () =>
|
|
137
|
+
try: () => {
|
|
138
|
+
db.exec("BEGIN IMMEDIATE");
|
|
139
|
+
try {
|
|
140
|
+
db.exec(migration.sql);
|
|
141
|
+
db.exec("COMMIT");
|
|
142
|
+
}
|
|
143
|
+
catch (e) {
|
|
144
|
+
db.exec("ROLLBACK");
|
|
145
|
+
throw e;
|
|
146
|
+
}
|
|
147
|
+
},
|
|
137
148
|
catch: (cause) => new DatabaseError({ cause })
|
|
138
149
|
});
|
|
139
150
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"migration-service.js","sourceRoot":"","sources":["../../src/services/migration-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAA;AAC/C,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"migration-service.js","sourceRoot":"","sources":["../../src/services/migration-service.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,12 +5,13 @@
|
|
|
5
5
|
* Uses Effect-TS patterns per DD-002.
|
|
6
6
|
*/
|
|
7
7
|
import { Context, Effect, Layer } from "effect";
|
|
8
|
+
import { SqliteClient } from "../db.js";
|
|
8
9
|
import { OrchestratorStateRepository } from "../repo/orchestrator-state-repo.js";
|
|
9
10
|
import { TaskRepository } from "../repo/task-repo.js";
|
|
10
11
|
import { ClaimRepository } from "../repo/claim-repo.js";
|
|
11
12
|
import { WorkerService } from "./worker-service.js";
|
|
12
13
|
import { ClaimService } from "./claim-service.js";
|
|
13
|
-
import { DatabaseError, OrchestratorError } from "../errors.js";
|
|
14
|
+
import { DatabaseError, OrchestratorError, TaskNotFoundError } from "../errors.js";
|
|
14
15
|
import type { OrchestratorState, ReconciliationResult } from "../schemas/worker.js";
|
|
15
16
|
/**
|
|
16
17
|
* Configuration options for the orchestrator.
|
|
@@ -43,10 +44,10 @@ declare const OrchestratorService_base: Context.TagClass<OrchestratorService, "O
|
|
|
43
44
|
* Detects dead workers, expires claims, recovers orphaned tasks,
|
|
44
45
|
* and fixes state inconsistencies.
|
|
45
46
|
*/
|
|
46
|
-
readonly reconcile: () => Effect.Effect<ReconciliationResult, DatabaseError>;
|
|
47
|
+
readonly reconcile: () => Effect.Effect<ReconciliationResult, DatabaseError | TaskNotFoundError>;
|
|
47
48
|
}>;
|
|
48
49
|
export declare class OrchestratorService extends OrchestratorService_base {
|
|
49
50
|
}
|
|
50
|
-
export declare const OrchestratorServiceLive: Layer.Layer<OrchestratorService, never, TaskRepository | ClaimRepository | OrchestratorStateRepository | WorkerService | ClaimService>;
|
|
51
|
+
export declare const OrchestratorServiceLive: Layer.Layer<OrchestratorService, never, SqliteClient | TaskRepository | ClaimRepository | OrchestratorStateRepository | WorkerService | ClaimService>;
|
|
51
52
|
export {};
|
|
52
53
|
//# sourceMappingURL=orchestrator-service.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"orchestrator-service.d.ts","sourceRoot":"","sources":["../../src/services/orchestrator-service.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"orchestrator-service.d.ts","sourceRoot":"","sources":["../../src/services/orchestrator-service.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,EAAQ,KAAK,EAAE,MAAM,QAAQ,CAAA;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AACvC,OAAO,EAAE,2BAA2B,EAAE,MAAM,oCAAoC,CAAA;AAChF,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AACjD,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAA;AAClF,OAAO,KAAK,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAA;AAEnF;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAA;IAChC,QAAQ,CAAC,wBAAwB,CAAC,EAAE,MAAM,CAAA;IAC1C,QAAQ,CAAC,oBAAoB,CAAC,EAAE,MAAM,CAAA;IACtC,QAAQ,CAAC,wBAAwB,CAAC,EAAE,MAAM,CAAA;IAC1C,QAAQ,CAAC,sBAAsB,CAAC,EAAE,MAAM,CAAA;IACxC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAA;CACnC;;IAiBG;;;OAGG;oBACa,CACd,MAAM,CAAC,EAAE,kBAAkB,KACxB,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,iBAAiB,GAAG,aAAa,CAAC;IAE3D;;;OAGG;mBACY,CACb,QAAQ,EAAE,OAAO,KACd,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,iBAAiB,GAAG,aAAa,CAAC;IAE3D;;OAEG;qBACc,MAAM,MAAM,CAAC,MAAM,CAAC,iBAAiB,EAAE,aAAa,CAAC;IAEtE;;;;OAIG;wBACiB,MAAM,MAAM,CAAC,MAAM,CAAC,oBAAoB,EAAE,aAAa,GAAG,iBAAiB,CAAC;;AA7BpG,qBAAa,mBAAoB,SAAQ,wBA+BtC;CAAG;AAEN,eAAO,MAAM,uBAAuB,uJAmTnC,CAAA"}
|
|
@@ -4,13 +4,14 @@
|
|
|
4
4
|
* Manages orchestrator lifecycle and reconciliation loop.
|
|
5
5
|
* Uses Effect-TS patterns per DD-002.
|
|
6
6
|
*/
|
|
7
|
-
import { Context, Effect, Layer } from "effect";
|
|
7
|
+
import { Context, Effect, Exit, Layer } from "effect";
|
|
8
|
+
import { SqliteClient } from "../db.js";
|
|
8
9
|
import { OrchestratorStateRepository } from "../repo/orchestrator-state-repo.js";
|
|
9
10
|
import { TaskRepository } from "../repo/task-repo.js";
|
|
10
11
|
import { ClaimRepository } from "../repo/claim-repo.js";
|
|
11
12
|
import { WorkerService } from "./worker-service.js";
|
|
12
13
|
import { ClaimService } from "./claim-service.js";
|
|
13
|
-
import { OrchestratorError } from "../errors.js";
|
|
14
|
+
import { DatabaseError, OrchestratorError } from "../errors.js";
|
|
14
15
|
/**
|
|
15
16
|
* Default orchestrator configuration values.
|
|
16
17
|
*/
|
|
@@ -25,11 +26,38 @@ const DEFAULT_CONFIG = {
|
|
|
25
26
|
export class OrchestratorService extends Context.Tag("OrchestratorService")() {
|
|
26
27
|
}
|
|
27
28
|
export const OrchestratorServiceLive = Layer.effect(OrchestratorService, Effect.gen(function* () {
|
|
29
|
+
const db = yield* SqliteClient;
|
|
28
30
|
const stateRepo = yield* OrchestratorStateRepository;
|
|
29
31
|
const workerService = yield* WorkerService;
|
|
30
32
|
const claimService = yield* ClaimService;
|
|
31
33
|
const taskRepo = yield* TaskRepository;
|
|
32
34
|
const claimRepo = yield* ClaimRepository;
|
|
35
|
+
/**
|
|
36
|
+
* Helper to wrap an Effect in a database transaction.
|
|
37
|
+
* Ensures atomicity: either all operations succeed and COMMIT,
|
|
38
|
+
* or any failure triggers ROLLBACK.
|
|
39
|
+
*/
|
|
40
|
+
const withTransaction = (effect) => Effect.acquireUseRelease(
|
|
41
|
+
// Acquire: Begin transaction
|
|
42
|
+
Effect.try({
|
|
43
|
+
try: () => {
|
|
44
|
+
db.exec("BEGIN IMMEDIATE");
|
|
45
|
+
return undefined;
|
|
46
|
+
},
|
|
47
|
+
catch: (cause) => new DatabaseError({ cause })
|
|
48
|
+
}),
|
|
49
|
+
// Use: Run the wrapped effect
|
|
50
|
+
() => effect,
|
|
51
|
+
// Release: Commit on success, rollback on failure
|
|
52
|
+
(_, exit) => Exit.isSuccess(exit)
|
|
53
|
+
? Effect.try({
|
|
54
|
+
try: () => db.exec("COMMIT"),
|
|
55
|
+
catch: (cause) => new DatabaseError({ cause })
|
|
56
|
+
}).pipe(Effect.orDie)
|
|
57
|
+
: Effect.try({
|
|
58
|
+
try: () => db.exec("ROLLBACK"),
|
|
59
|
+
catch: (cause) => new DatabaseError({ cause })
|
|
60
|
+
}).pipe(Effect.catchAll((rollbackError) => Effect.log(`ROLLBACK failed: ${rollbackError.cause}`))));
|
|
33
61
|
return {
|
|
34
62
|
start: (config) => Effect.gen(function* () {
|
|
35
63
|
const currentState = yield* stateRepo.get();
|
|
@@ -107,36 +135,38 @@ export const OrchestratorServiceLive = Layer.effect(OrchestratorService, Effect.
|
|
|
107
135
|
yield* Effect.log("Orchestrator stopped");
|
|
108
136
|
}),
|
|
109
137
|
status: () => stateRepo.get(),
|
|
110
|
-
reconcile: () =>
|
|
138
|
+
reconcile: () =>
|
|
139
|
+
// Wrap entire reconciliation in a transaction for atomicity.
|
|
140
|
+
// Prevents race conditions where state changes between steps.
|
|
141
|
+
// See: tx-a1c2b151 - OrchestratorService missing transaction boundaries
|
|
142
|
+
withTransaction(Effect.gen(function* () {
|
|
111
143
|
const startTime = Date.now();
|
|
112
144
|
let deadWorkersFound = 0;
|
|
113
145
|
let expiredClaimsReleased = 0;
|
|
114
146
|
let orphanedTasksRecovered = 0;
|
|
147
|
+
let orphanedClaimsReleased = 0;
|
|
115
148
|
let staleStatesFixed = 0;
|
|
116
149
|
// 1. Detect dead workers (missed 2+ heartbeats)
|
|
150
|
+
// Using 2 missed heartbeats to avoid false positives from transient
|
|
151
|
+
// delays (GC pauses, system load, SQLite contention). With a 30s
|
|
152
|
+
// heartbeat interval, detection occurs after ~60s of silence.
|
|
117
153
|
const deadWorkers = yield* workerService.findDead({
|
|
118
154
|
missedHeartbeats: 2
|
|
119
155
|
});
|
|
120
156
|
for (const worker of deadWorkers) {
|
|
121
|
-
yield* workerService.markDead(worker.id).pipe(Effect.catchAll(() => Effect.
|
|
157
|
+
yield* workerService.markDead(worker.id).pipe(Effect.catchAll((error) => Effect.log(`Reconciliation: failed to mark worker ${worker.id} as dead: ${error}`)));
|
|
122
158
|
// Release any claims held by this dead worker
|
|
123
|
-
yield* claimService.releaseByWorker(worker.id).pipe(Effect.catchAll(() => Effect.
|
|
159
|
+
yield* claimService.releaseByWorker(worker.id).pipe(Effect.catchAll((error) => Effect.log(`Reconciliation: failed to release claims for dead worker ${worker.id}: ${error}`).pipe(Effect.as(0))));
|
|
124
160
|
deadWorkersFound++;
|
|
125
161
|
}
|
|
126
162
|
// 2. Expire stale claims (past lease expiration)
|
|
127
163
|
const expiredClaims = yield* claimService.getExpired();
|
|
128
164
|
for (const claim of expiredClaims) {
|
|
129
|
-
yield* claimService.expire(claim.id).pipe(Effect.catchAll(() => Effect.
|
|
130
|
-
//
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
yield* taskRepo.update({
|
|
135
|
-
...task,
|
|
136
|
-
status: "ready",
|
|
137
|
-
updatedAt: now
|
|
138
|
-
});
|
|
139
|
-
}
|
|
165
|
+
yield* claimService.expire(claim.id).pipe(Effect.catchAll((error) => Effect.log(`Reconciliation: failed to expire claim ${claim.id}: ${error}`)));
|
|
166
|
+
// Atomically recover task status based on blocker states.
|
|
167
|
+
// Single UPDATE with subquery eliminates TOCTOU race between
|
|
168
|
+
// reading blocker statuses and writing the new task status.
|
|
169
|
+
yield* taskRepo.recoverTaskStatus(claim.taskId, "active");
|
|
140
170
|
expiredClaimsReleased++;
|
|
141
171
|
}
|
|
142
172
|
// 3. Find orphaned tasks (status='active' but no active claim)
|
|
@@ -144,21 +174,19 @@ export const OrchestratorServiceLive = Layer.effect(OrchestratorService, Effect.
|
|
|
144
174
|
for (const task of activeTasks) {
|
|
145
175
|
const activeClaim = yield* claimRepo.findActiveByTaskId(task.id);
|
|
146
176
|
if (!activeClaim) {
|
|
147
|
-
//
|
|
148
|
-
|
|
149
|
-
yield* taskRepo.
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
});
|
|
154
|
-
orphanedTasksRecovered++;
|
|
177
|
+
// Atomically recover orphaned task status based on blocker states.
|
|
178
|
+
// Single UPDATE with subquery eliminates TOCTOU race.
|
|
179
|
+
const updated = yield* taskRepo.recoverTaskStatus(task.id, "active");
|
|
180
|
+
if (updated) {
|
|
181
|
+
orphanedTasksRecovered++;
|
|
182
|
+
}
|
|
155
183
|
}
|
|
156
184
|
}
|
|
157
185
|
// 4. Fix workers marked busy but with no current_task_id
|
|
158
186
|
const busyWorkers = yield* workerService.list({ status: ["busy"] });
|
|
159
187
|
for (const worker of busyWorkers) {
|
|
160
188
|
if (worker.currentTaskId === null) {
|
|
161
|
-
yield* workerService.updateStatus(worker.id, "idle").pipe(Effect.catchAll(() => Effect.
|
|
189
|
+
yield* workerService.updateStatus(worker.id, "idle").pipe(Effect.catchAll((error) => Effect.log(`Reconciliation: failed to fix stale busy worker ${worker.id}: ${error}`)));
|
|
162
190
|
staleStatesFixed++;
|
|
163
191
|
}
|
|
164
192
|
}
|
|
@@ -167,11 +195,19 @@ export const OrchestratorServiceLive = Layer.effect(OrchestratorService, Effect.
|
|
|
167
195
|
if (worker.currentTaskId) {
|
|
168
196
|
const task = yield* taskRepo.findById(worker.currentTaskId);
|
|
169
197
|
if (!task || task.status !== "active") {
|
|
170
|
-
yield* workerService.updateStatus(worker.id, "idle").pipe(Effect.catchAll(() => Effect.
|
|
198
|
+
yield* workerService.updateStatus(worker.id, "idle").pipe(Effect.catchAll((error) => Effect.log(`Reconciliation: failed to fix stale worker ${worker.id} with task ${worker.currentTaskId}: ${error}`)));
|
|
171
199
|
staleStatesFixed++;
|
|
172
200
|
}
|
|
173
201
|
}
|
|
174
202
|
}
|
|
203
|
+
// 6. Find orphaned claims (active claims on non-active tasks)
|
|
204
|
+
// This catches claims that weren't released after task completion
|
|
205
|
+
// (e.g., if claim release failed after tx done)
|
|
206
|
+
const orphanedClaims = yield* claimService.getOrphanedClaims();
|
|
207
|
+
for (const claim of orphanedClaims) {
|
|
208
|
+
yield* claimService.expire(claim.id).pipe(Effect.catchAll((error) => Effect.log(`Reconciliation: failed to expire orphaned claim ${claim.id}: ${error}`)));
|
|
209
|
+
orphanedClaimsReleased++;
|
|
210
|
+
}
|
|
175
211
|
const reconcileTime = Date.now() - startTime;
|
|
176
212
|
// Update last reconcile timestamp
|
|
177
213
|
yield* stateRepo.update({
|
|
@@ -181,10 +217,12 @@ export const OrchestratorServiceLive = Layer.effect(OrchestratorService, Effect.
|
|
|
181
217
|
if (deadWorkersFound > 0 ||
|
|
182
218
|
expiredClaimsReleased > 0 ||
|
|
183
219
|
orphanedTasksRecovered > 0 ||
|
|
220
|
+
orphanedClaimsReleased > 0 ||
|
|
184
221
|
staleStatesFixed > 0) {
|
|
185
222
|
yield* Effect.log(`Reconciliation: ${deadWorkersFound} dead workers, ` +
|
|
186
223
|
`${expiredClaimsReleased} expired claims, ` +
|
|
187
224
|
`${orphanedTasksRecovered} orphaned tasks, ` +
|
|
225
|
+
`${orphanedClaimsReleased} orphaned claims, ` +
|
|
188
226
|
`${staleStatesFixed} stale states fixed ` +
|
|
189
227
|
`(${reconcileTime}ms)`);
|
|
190
228
|
}
|
|
@@ -193,11 +231,12 @@ export const OrchestratorServiceLive = Layer.effect(OrchestratorService, Effect.
|
|
|
193
231
|
deadWorkersFound,
|
|
194
232
|
expiredClaimsReleased,
|
|
195
233
|
orphanedTasksRecovered,
|
|
234
|
+
orphanedClaimsReleased,
|
|
196
235
|
staleStatesFixed,
|
|
197
236
|
reconcileTime
|
|
198
237
|
};
|
|
199
238
|
return result;
|
|
200
|
-
})
|
|
239
|
+
}))
|
|
201
240
|
};
|
|
202
241
|
}));
|
|
203
242
|
//# sourceMappingURL=orchestrator-service.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"orchestrator-service.js","sourceRoot":"","sources":["../../src/services/orchestrator-service.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAA;
|
|
1
|
+
{"version":3,"file":"orchestrator-service.js","sourceRoot":"","sources":["../../src/services/orchestrator-service.ts"],"names":[],"mappings":"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"}
|