mirror of
https://github.com/trustgraph-ai/trustgraph.git
synced 2026-07-02 02:58:10 +02:00
refactor(ts): remove non-client effect run boundaries
This commit is contained in:
parent
be2370ee7b
commit
174d636178
20 changed files with 126 additions and 106 deletions
|
|
@ -337,16 +337,13 @@ export const makeMcpToolConfigHandlers = (): ReadonlyArray<
|
|||
export type McpToolService = FlowProcessorRuntime<McpToolRuntime>;
|
||||
|
||||
export function makeMcpToolService(config: ProcessorConfig): McpToolService {
|
||||
const runtime = Effect.runSync(makeMcpToolRuntime);
|
||||
const service = makeFlowProcessor(config, {
|
||||
specifications: makeMcpToolSpecs(),
|
||||
provide: (effect) => effect.pipe(Effect.provideService(McpToolRuntime, runtime)),
|
||||
});
|
||||
service.registerConfigHandler((pushedConfig, version) =>
|
||||
onMcpConfig(pushedConfig, version).pipe(
|
||||
Effect.provideService(McpToolRuntime, runtime),
|
||||
provide: (effect) => effect.pipe(
|
||||
Effect.provideServiceEffect(McpToolRuntime, makeMcpToolRuntime),
|
||||
),
|
||||
);
|
||||
});
|
||||
service.registerConfigHandler(onMcpConfig);
|
||||
return service;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -507,17 +507,13 @@ export const makeAgentConfigHandlers = (): ReadonlyArray<
|
|||
export type AgentService = FlowProcessorRuntime<AgentRuntime>;
|
||||
|
||||
export function makeAgentService(config: ProcessorConfig): AgentService {
|
||||
const runtime = Effect.runSync(makeAgentRuntime);
|
||||
const service = makeFlowProcessor(config, {
|
||||
specifications: makeAgentSpecs(),
|
||||
provide: (effect) => effect.pipe(Effect.provideService(AgentRuntime, runtime)),
|
||||
});
|
||||
service.registerConfigHandler((pushedConfig, version) =>
|
||||
onToolsConfig(pushedConfig, version).pipe(
|
||||
Effect.provideService(AgentRuntime, runtime),
|
||||
provide: (effect) => effect.pipe(
|
||||
Effect.provideServiceEffect(AgentRuntime, makeAgentRuntime),
|
||||
),
|
||||
);
|
||||
Effect.runSync(Effect.log("[AgentService] Service initialized"));
|
||||
});
|
||||
service.registerConfigHandler(onToolsConfig);
|
||||
return service;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -96,11 +96,9 @@ export const makeChunkingSpecs = (): ReadonlyArray<
|
|||
export type ChunkingService = FlowProcessorRuntime;
|
||||
|
||||
export function makeChunkingService(config: ProcessorConfig): ChunkingService {
|
||||
const service = makeFlowProcessor(config, {
|
||||
return makeFlowProcessor(config, {
|
||||
specifications: makeChunkingSpecs(),
|
||||
});
|
||||
Effect.runSync(Effect.log("[ChunkingService] Service initialized"));
|
||||
return service;
|
||||
}
|
||||
|
||||
export const ChunkingService = makeChunkingService;
|
||||
|
|
|
|||
|
|
@ -237,11 +237,9 @@ export const makePdfDecoderSpecs = (): ReadonlyArray<Spec> => [
|
|||
export type PdfDecoderService = FlowProcessorRuntime;
|
||||
|
||||
export function makePdfDecoderService(config: ProcessorConfig): PdfDecoderService {
|
||||
const service = makeFlowProcessor(config, {
|
||||
return makeFlowProcessor(config, {
|
||||
specifications: makePdfDecoderSpecs(),
|
||||
});
|
||||
Effect.runSync(Effect.log("[PdfDecoder] Service initialized"));
|
||||
return service;
|
||||
}
|
||||
|
||||
export const PdfDecoderService = makePdfDecoderService;
|
||||
|
|
|
|||
|
|
@ -138,7 +138,11 @@ export const makeOllamaEmbeddingsEffect = Effect.fn("makeOllamaEmbeddingsEffect"
|
|||
});
|
||||
|
||||
export function makeOllamaEmbeddings(config: OllamaEmbeddingsConfig): EmbeddingsServiceShape {
|
||||
return Effect.runSync(makeOllamaEmbeddingsEffect(config));
|
||||
return makeOllamaEmbeddingsFromConfig({
|
||||
defaultModel: config.model ?? "mxbai-embed-large",
|
||||
ollamaHost: config.ollamaHost ?? "http://localhost:11434",
|
||||
fetchImpl: config.fetch ?? globalThis.fetch,
|
||||
});
|
||||
}
|
||||
|
||||
export function OllamaEmbeddingsLive(config: OllamaEmbeddingsConfig): Layer.Layer<Embeddings, EmbeddingsError> {
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ import type {
|
|||
Spec,
|
||||
} from "@trustgraph/base";
|
||||
import {
|
||||
errorMessage,
|
||||
makeFlowProcessor,
|
||||
makeConsumerSpec,
|
||||
makeProducerSpec,
|
||||
|
|
@ -179,7 +180,7 @@ const onKnowledgeExtractMessage = Effect.fn("KnowledgeExtractService.onMessage")
|
|||
const relationships = yield* extractRelationships(promptClient, llmClient, text).pipe(
|
||||
Effect.catch((error: unknown) =>
|
||||
Effect.logError("[KnowledgeExtract] Relationship extraction failed", {
|
||||
error: error instanceof Error ? error.message : String(error),
|
||||
error: errorMessage(error),
|
||||
}).pipe(Effect.as(null)),
|
||||
),
|
||||
);
|
||||
|
|
@ -233,7 +234,7 @@ const onKnowledgeExtractMessage = Effect.fn("KnowledgeExtractService.onMessage")
|
|||
const definitions = yield* extractDefinitions(promptClient, llmClient, text).pipe(
|
||||
Effect.catch((error: unknown) =>
|
||||
Effect.logError("[KnowledgeExtract] Definition extraction failed", {
|
||||
error: error instanceof Error ? error.message : String(error),
|
||||
error: errorMessage(error),
|
||||
}).pipe(Effect.as(null)),
|
||||
),
|
||||
);
|
||||
|
|
@ -294,11 +295,9 @@ export const makeKnowledgeExtractSpecs = (): ReadonlyArray<Spec> => [
|
|||
export type KnowledgeExtractService = FlowProcessorRuntime;
|
||||
|
||||
export function makeKnowledgeExtractService(config: ProcessorConfig): KnowledgeExtractService {
|
||||
const service = makeFlowProcessor(config, {
|
||||
return makeFlowProcessor(config, {
|
||||
specifications: makeKnowledgeExtractSpecs(),
|
||||
});
|
||||
Effect.runSync(Effect.log("[KnowledgeExtract] Service initialized"));
|
||||
return service;
|
||||
}
|
||||
|
||||
export const KnowledgeExtractService = makeKnowledgeExtractService;
|
||||
|
|
@ -332,9 +331,6 @@ export function parseJsonResponse<T>(raw: string): T | null {
|
|||
if (O.isSome(decoded)) return decoded.value as T;
|
||||
}
|
||||
|
||||
Effect.runSync(Effect.logWarning("[KnowledgeExtract] Failed to parse JSON from LLM response", {
|
||||
response: raw.slice(0, 300),
|
||||
}));
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
@ -343,9 +339,6 @@ function parseRelationshipsResponse(raw: string): ReadonlyArray<ExtractedRelatio
|
|||
const decoded = decodeExtractedRelationships(candidate);
|
||||
if (O.isSome(decoded)) return decoded.value;
|
||||
}
|
||||
Effect.runSync(Effect.logWarning("[KnowledgeExtract] Failed to parse relationships from LLM response", {
|
||||
response: raw.slice(0, 300),
|
||||
}));
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
@ -354,9 +347,6 @@ function parseDefinitionsResponse(raw: string): ReadonlyArray<ExtractedDefinitio
|
|||
const decoded = decodeExtractedDefinitions(candidate);
|
||||
if (O.isSome(decoded)) return decoded.value;
|
||||
}
|
||||
Effect.runSync(Effect.logWarning("[KnowledgeExtract] Failed to parse definitions from LLM response", {
|
||||
response: raw.slice(0, 300),
|
||||
}));
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ import {
|
|||
errorMessage,
|
||||
makeAsyncProcessor,
|
||||
makeProcessorProgram,
|
||||
loadProcessorRuntimeConfig,
|
||||
topics,
|
||||
DocumentMetadata as DocumentMetadataSchema,
|
||||
ProcessingMetadata as ProcessingMetadataSchema,
|
||||
|
|
@ -88,11 +89,20 @@ const librarianServiceError = (operation: string, cause: unknown): LibrarianServ
|
|||
});
|
||||
|
||||
function resolveDataDir(config: LibrarianServiceConfig): string {
|
||||
return config.dataDir ?? Effect.runSync(
|
||||
Config.string("LIBRARIAN_DATA_DIR").pipe(Config.withDefault("./data/librarian")),
|
||||
);
|
||||
return config.dataDir ?? "./data/librarian";
|
||||
}
|
||||
|
||||
const loadLibrarianServiceConfig = Effect.gen(function* () {
|
||||
const config = yield* loadProcessorRuntimeConfig("librarian-svc", {
|
||||
manageProcessSignals: false,
|
||||
});
|
||||
const dataDir = Option.getOrUndefined(yield* Config.string("LIBRARIAN_DATA_DIR").pipe(Config.option));
|
||||
return {
|
||||
...config,
|
||||
...(dataDir === undefined ? {} : { dataDir }),
|
||||
} satisfies LibrarianServiceConfig;
|
||||
});
|
||||
|
||||
const currentEpochSeconds: Effect.Effect<number> = Clock.currentTimeMillis.pipe(
|
||||
Effect.map((millis) => Math.floor(millis / 1000)),
|
||||
);
|
||||
|
|
@ -1504,6 +1514,7 @@ export const LibrarianService = makeLibrarianService;
|
|||
|
||||
export const program = makeProcessorProgram({
|
||||
id: "librarian-svc",
|
||||
loadConfig: loadLibrarianServiceConfig,
|
||||
make: (config) => makeLibrarianService(config),
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -176,7 +176,22 @@ const makeAzureOpenAIProviderFromClient = (
|
|||
export function makeAzureOpenAIProvider(
|
||||
config: AzureOpenAIProcessorConfig,
|
||||
): LlmProvider<TextCompletionRuntimeError> {
|
||||
return Effect.runSync(makeAzureOpenAIProviderEffect(config));
|
||||
const resolved = {
|
||||
defaultModel: config.model ?? "gpt-4o",
|
||||
defaultTemperature: config.temperature ?? 0.0,
|
||||
maxOutput: config.maxOutput ?? 4096,
|
||||
apiKey: config.apiKey ?? "",
|
||||
endpoint: config.endpoint ?? "",
|
||||
apiVersion: config.apiVersion ?? "2024-12-01-preview",
|
||||
} satisfies ResolvedAzureOpenAIConfig;
|
||||
return makeAzureOpenAIProviderFromClient(
|
||||
resolved,
|
||||
new AzureOpenAI({
|
||||
apiKey: resolved.apiKey,
|
||||
apiVersion: resolved.apiVersion,
|
||||
endpoint: resolved.endpoint,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
export const makeAzureOpenAIProviderEffect = Effect.fn("makeAzureOpenAIProvider")(function*(
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ import {
|
|||
makeFlowProcessorProgram,
|
||||
makeLlmSpecs,
|
||||
} from "@trustgraph/base";
|
||||
import { Effect, Layer, Redacted } from "effect";
|
||||
import { Context, Effect, Layer, Redacted } from "effect";
|
||||
import { FetchHttpClient } from "effect/unstable/http";
|
||||
import type {
|
||||
TextCompletionConfigError,
|
||||
|
|
@ -69,7 +69,32 @@ const makeClaudeLayer = (apiKey: string) =>
|
|||
export function makeClaudeProvider(
|
||||
config: ClaudeProcessorConfig,
|
||||
): LlmProvider<TextCompletionRuntimeError> {
|
||||
return Effect.runSync(Effect.scoped(makeClaudeProviderEffect(config)));
|
||||
const resolved = {
|
||||
defaultModel: config.model ?? "claude-sonnet-4-20250514",
|
||||
defaultTemperature: config.temperature ?? 0.0,
|
||||
maxOutput: config.maxOutput ?? 8192,
|
||||
apiKey: config.apiKey ?? "",
|
||||
} satisfies ResolvedClaudeConfig;
|
||||
return makeLanguageModelProvider({
|
||||
provider: "Claude",
|
||||
defaultModel: resolved.defaultModel,
|
||||
defaultTemperature: resolved.defaultTemperature,
|
||||
context: Context.empty(),
|
||||
makeLanguageModel: ({ model, temperature }) =>
|
||||
Effect.scoped(
|
||||
Layer.build(makeClaudeLayer(resolved.apiKey)).pipe(
|
||||
Effect.flatMap((context) =>
|
||||
AnthropicLanguageModel.make({
|
||||
model,
|
||||
config: {
|
||||
max_tokens: resolved.maxOutput,
|
||||
temperature,
|
||||
},
|
||||
}).pipe(Effect.provideContext(context))
|
||||
),
|
||||
),
|
||||
),
|
||||
});
|
||||
}
|
||||
|
||||
export const makeClaudeProviderEffect = Effect.fn("makeClaudeProvider")(function* (
|
||||
|
|
|
|||
|
|
@ -156,7 +156,16 @@ const makeMistralProviderFromClient = (
|
|||
export function makeMistralProvider(
|
||||
config: MistralProcessorConfig,
|
||||
): LlmProvider<TextCompletionRuntimeError> {
|
||||
return Effect.runSync(makeMistralProviderEffect(config));
|
||||
const resolved = {
|
||||
defaultModel: config.model ?? "ministral-8b-latest",
|
||||
defaultTemperature: config.temperature ?? 0.0,
|
||||
maxOutput: config.maxOutput ?? 4096,
|
||||
apiKey: config.apiKey ?? "",
|
||||
} satisfies ResolvedMistralConfig;
|
||||
return makeMistralProviderFromClient(
|
||||
resolved,
|
||||
new Mistral({ apiKey: resolved.apiKey }),
|
||||
);
|
||||
}
|
||||
|
||||
export const makeMistralProviderEffect = Effect.fn("makeMistralProvider")(function*(
|
||||
|
|
|
|||
|
|
@ -132,7 +132,14 @@ const makeOllamaProviderFromClient = (
|
|||
export function makeOllamaProvider(
|
||||
config: OllamaProcessorConfig,
|
||||
): LlmProvider<TextCompletionRuntimeError> {
|
||||
return Effect.runSync(makeOllamaProviderEffect(config));
|
||||
const resolved = {
|
||||
defaultModel: config.model ?? "qwen2.5:0.5b",
|
||||
host: config.ollamaUrl ?? "http://localhost:11434",
|
||||
} satisfies ResolvedOllamaConfig;
|
||||
return makeOllamaProviderFromClient(
|
||||
resolved,
|
||||
new Ollama({ host: resolved.host }),
|
||||
);
|
||||
}
|
||||
|
||||
export const makeOllamaProviderEffect = Effect.fn("makeOllamaProvider")(function*(
|
||||
|
|
|
|||
|
|
@ -165,7 +165,17 @@ const makeOpenAICompatibleProviderFromClient = (
|
|||
export function makeOpenAICompatibleProvider(
|
||||
config: OpenAICompatibleProcessorConfig,
|
||||
): LlmProvider<TextCompletionRuntimeError> {
|
||||
return Effect.runSync(makeOpenAICompatibleProviderEffect(config));
|
||||
const resolved = {
|
||||
defaultModel: config.model ?? "default",
|
||||
defaultTemperature: config.temperature ?? 0.0,
|
||||
maxOutput: config.maxOutput ?? 4096,
|
||||
apiKey: config.apiKey ?? "sk-no-key-required",
|
||||
baseURL: config.baseUrl ?? "http://localhost:1234/v1",
|
||||
} satisfies ResolvedOpenAICompatibleConfig;
|
||||
return makeOpenAICompatibleProviderFromClient(
|
||||
resolved,
|
||||
new OpenAI({ baseURL: resolved.baseURL, apiKey: resolved.apiKey }),
|
||||
);
|
||||
}
|
||||
|
||||
export const makeOpenAICompatibleProviderEffect = Effect.fn("makeOpenAICompatibleProvider")(function*(
|
||||
|
|
|
|||
|
|
@ -155,7 +155,20 @@ const makeOpenAIProviderFromClient = (
|
|||
export function makeOpenAIProvider(
|
||||
config: OpenAIProcessorConfig,
|
||||
): LlmProvider<TextCompletionRuntimeError> {
|
||||
return Effect.runSync(makeOpenAIProviderEffect(config));
|
||||
const resolved = {
|
||||
defaultModel: config.model ?? "gpt-4o",
|
||||
defaultTemperature: config.temperature ?? 0.0,
|
||||
maxOutput: config.maxOutput ?? 4096,
|
||||
apiKey: config.apiKey ?? "",
|
||||
baseURL: config.baseUrl,
|
||||
} satisfies ResolvedOpenAIConfig;
|
||||
return makeOpenAIProviderFromClient(
|
||||
resolved,
|
||||
new OpenAI({
|
||||
apiKey: resolved.apiKey,
|
||||
baseURL: resolved.baseURL,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
export const makeOpenAIProviderEffect = Effect.fn("makeOpenAIProvider")(function*(
|
||||
|
|
|
|||
|
|
@ -171,7 +171,6 @@ export function makePromptTemplateService(config: PromptTemplateConfig): PromptT
|
|||
for (const handler of runtime.configHandlers) {
|
||||
service.registerConfigHandler(handler);
|
||||
}
|
||||
Effect.runSync(Effect.log("[PromptTemplate] Service initialized"));
|
||||
return service;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue