mirror of
https://github.com/trustgraph-ai/trustgraph.git
synced 2026-07-03 15:01:00 +02:00
refactor(ts): make port effect native
This commit is contained in:
parent
2868ced2d3
commit
b6759e75df
113 changed files with 4140 additions and 4554 deletions
|
|
@ -1 +1 @@
|
|||
export { McpToolService, run, runMain } from "./service.js";
|
||||
export { McpToolService, program, runMain } from "./service.js";
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ import {
|
|||
type MessagingDeliveryError,
|
||||
type Spec,
|
||||
} from "@trustgraph/base";
|
||||
import { Context, Effect, Layer, ManagedRuntime, Ref } from "effect";
|
||||
import { Context, Effect, Layer, Ref } from "effect";
|
||||
import * as O from "effect/Option";
|
||||
import * as S from "effect/Schema";
|
||||
|
||||
|
|
@ -342,9 +342,9 @@ export function makeMcpToolService(config: ProcessorConfig): McpToolService {
|
|||
provide: (effect) => effect.pipe(Effect.provideService(McpToolRuntime, runtime)),
|
||||
});
|
||||
service.registerConfigHandler((pushedConfig, version) =>
|
||||
Effect.runPromise(onMcpConfig(pushedConfig, version).pipe(
|
||||
onMcpConfig(pushedConfig, version).pipe(
|
||||
Effect.provideService(McpToolRuntime, runtime),
|
||||
)),
|
||||
),
|
||||
);
|
||||
return service;
|
||||
}
|
||||
|
|
@ -358,12 +358,6 @@ export const program = makeFlowProcessorProgram<ProcessorConfig, never, McpToolR
|
|||
layer: () => McpToolRuntimeLive,
|
||||
});
|
||||
|
||||
const mcpToolRuntime = ManagedRuntime.make(Layer.empty);
|
||||
|
||||
export function run(): Promise<void> {
|
||||
return mcpToolRuntime.runPromise(program);
|
||||
}
|
||||
|
||||
export function runMain(): void {
|
||||
NodeRuntime.runMain(program);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ import {
|
|||
type MessagingDeliveryError,
|
||||
type Spec,
|
||||
} from "@trustgraph/base";
|
||||
import {Context, Effect, Layer, ManagedRuntime, Match, Ref} from "effect";
|
||||
import {Context, Effect, Layer, Match, Ref} from "effect";
|
||||
import * as O from "effect/Option";
|
||||
import * as Predicate from "effect/Predicate";
|
||||
import * as S from "effect/Schema";
|
||||
|
|
@ -64,13 +64,6 @@ import type { AgentTool, ToolArg } from "./types.js";
|
|||
|
||||
const MAX_ITERATIONS = 10;
|
||||
|
||||
class AgentToolExecutionError extends S.TaggedErrorClass<AgentToolExecutionError>()(
|
||||
"AgentToolExecutionError",
|
||||
{
|
||||
message: S.String,
|
||||
},
|
||||
) {}
|
||||
|
||||
const AgentResponseProducer = makeProducerSpec<AgentResponse>("agent-response");
|
||||
const AgentLlmClient = makeRequestResponseSpec<TextCompletionRequest, TextCompletionResponse>(
|
||||
"llm",
|
||||
|
|
@ -157,7 +150,7 @@ const buildConfiguredTool = Effect.fn("AgentService.buildConfiguredTool")(functi
|
|||
: "Query the knowledge graph for information about entities and their relationships.",
|
||||
args: [{ name: "question", type: "string", description: "The question to ask" }],
|
||||
config,
|
||||
execute: () => Promise.resolve(""),
|
||||
execute: () => Effect.succeed(""),
|
||||
})
|
||||
),
|
||||
|
||||
|
|
@ -170,7 +163,7 @@ const buildConfiguredTool = Effect.fn("AgentService.buildConfiguredTool")(functi
|
|||
: "Search documents for relevant information.",
|
||||
args: [{ name: "question", type: "string", description: "The question to search for" }],
|
||||
config,
|
||||
execute: () => Promise.resolve(""),
|
||||
execute: () => Effect.succeed(""),
|
||||
})
|
||||
),
|
||||
|
||||
|
|
@ -187,7 +180,7 @@ const buildConfiguredTool = Effect.fn("AgentService.buildConfiguredTool")(functi
|
|||
{ name: "object", type: "string", description: "Object entity (optional)" },
|
||||
],
|
||||
config,
|
||||
execute: () => Promise.resolve(""),
|
||||
execute: () => Effect.succeed(""),
|
||||
})
|
||||
),
|
||||
|
||||
|
|
@ -203,7 +196,7 @@ const buildConfiguredTool = Effect.fn("AgentService.buildConfiguredTool")(functi
|
|||
description,
|
||||
args,
|
||||
config,
|
||||
execute: () => Promise.resolve(""),
|
||||
execute: () => Effect.succeed(""),
|
||||
});
|
||||
}),
|
||||
|
||||
|
|
@ -355,12 +348,9 @@ const executeTool = (
|
|||
tool: AgentTool,
|
||||
input: string,
|
||||
): Effect.Effect<string> =>
|
||||
Effect.tryPromise({
|
||||
try: () => tool.execute(input),
|
||||
catch: (cause) => AgentToolExecutionError.make({ message: errorMessage(cause) }),
|
||||
}).pipe(
|
||||
Effect.catch((error: AgentToolExecutionError) =>
|
||||
Effect.succeed(`Error executing tool: ${error.message}`),
|
||||
tool.execute(input).pipe(
|
||||
Effect.catch((cause) =>
|
||||
Effect.succeed(`Error executing tool: ${errorMessage(cause)}`),
|
||||
),
|
||||
);
|
||||
|
||||
|
|
@ -520,9 +510,9 @@ export function makeAgentService(config: ProcessorConfig): AgentService {
|
|||
provide: (effect) => effect.pipe(Effect.provideService(AgentRuntime, runtime)),
|
||||
});
|
||||
service.registerConfigHandler((pushedConfig, version) =>
|
||||
Effect.runPromise(onToolsConfig(pushedConfig, version).pipe(
|
||||
onToolsConfig(pushedConfig, version).pipe(
|
||||
Effect.provideService(AgentRuntime, runtime),
|
||||
)),
|
||||
),
|
||||
);
|
||||
Effect.runSync(Effect.log("[AgentService] Service initialized"));
|
||||
return service;
|
||||
|
|
@ -616,12 +606,6 @@ export const program = makeFlowProcessorProgram<ProcessorConfig, never, AgentRun
|
|||
layer: () => AgentRuntimeLive,
|
||||
});
|
||||
|
||||
const agentRuntime = ManagedRuntime.make(Layer.empty);
|
||||
|
||||
export function run(): Promise<void> {
|
||||
return agentRuntime.runPromise(program);
|
||||
}
|
||||
|
||||
export function runMain(): void {
|
||||
NodeRuntime.runMain(program);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ import * as O from "effect/Option";
|
|||
import * as Predicate from "effect/Predicate";
|
||||
import * as S from "effect/Schema";
|
||||
|
||||
import type { AgentTool, ToolArg } from "./types.js";
|
||||
import { agentToolError, type AgentTool, type ToolArg } from "./types.js";
|
||||
|
||||
const decodeJsonUnknown = S.decodeUnknownOption(S.UnknownFromJsonString);
|
||||
const decodeTerm = S.decodeUnknownOption(TermSchema);
|
||||
|
|
@ -88,14 +88,16 @@ export function createKnowledgeQueryTool(
|
|||
description: "The question to ask the knowledge graph",
|
||||
},
|
||||
],
|
||||
execute: (input: string): Promise<string> => Effect.runPromise(Effect.gen(function* () {
|
||||
execute: Effect.fn("KnowledgeQuery.execute")(function* (input: string) {
|
||||
const question = parseQuestion(input);
|
||||
yield* Effect.log(`[KnowledgeQuery] Executing: "${question.slice(0, 60)}..." collection=${collection}`);
|
||||
const request: GraphRagRequest = {
|
||||
query: question,
|
||||
...(collection !== undefined ? { collection } : {}),
|
||||
};
|
||||
const res = yield* client.request(request);
|
||||
const res = yield* client.request(request).pipe(
|
||||
Effect.mapError((cause) => agentToolError("knowledge-query", cause)),
|
||||
);
|
||||
yield* Effect.log(`[KnowledgeQuery] Response (${res.response?.length ?? 0} chars): ${res.error !== undefined ? `ERROR: ${res.error.message}` : `${res.response?.slice(0, 300)}...`}`);
|
||||
|
||||
const explainTriples = res.explain_triples;
|
||||
|
|
@ -108,7 +110,7 @@ export function createKnowledgeQueryTool(
|
|||
|
||||
if (res.error !== undefined) return `Error: ${res.error.message}`;
|
||||
return res.response;
|
||||
})),
|
||||
}),
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -130,16 +132,18 @@ export function createDocumentQueryTool(
|
|||
description: "The question to search documents for",
|
||||
},
|
||||
],
|
||||
execute: (input: string): Promise<string> => Effect.runPromise(Effect.gen(function* () {
|
||||
execute: Effect.fn("DocumentQuery.execute")(function* (input: string) {
|
||||
const question = parseQuestion(input);
|
||||
const request: DocumentRagRequest = {
|
||||
query: question,
|
||||
...(collection !== undefined ? { collection } : {}),
|
||||
};
|
||||
const res = yield* client.request(request);
|
||||
const res = yield* client.request(request).pipe(
|
||||
Effect.mapError((cause) => agentToolError("document-query", cause)),
|
||||
);
|
||||
if (res.error !== undefined) return `Error: ${res.error.message}`;
|
||||
return res.response;
|
||||
})),
|
||||
}),
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -221,7 +225,7 @@ export function createTriplesQueryTool(
|
|||
description: "The object entity to search for (optional)",
|
||||
},
|
||||
],
|
||||
execute: (input: string): Promise<string> => Effect.runPromise(Effect.gen(function* () {
|
||||
execute: Effect.fn("TriplesQuery.execute")(function* (input: string) {
|
||||
const { s, p, o, limit } = parseTriplesInput(input);
|
||||
const request: TriplesQueryRequest = {
|
||||
limit: limit ?? 20,
|
||||
|
|
@ -230,7 +234,9 @@ export function createTriplesQueryTool(
|
|||
...(o !== undefined ? { o } : {}),
|
||||
...(collection !== undefined ? { collection } : {}),
|
||||
};
|
||||
const res = yield* client.request(request);
|
||||
const res = yield* client.request(request).pipe(
|
||||
Effect.mapError((cause) => agentToolError("triples-query", cause)),
|
||||
);
|
||||
|
||||
if (res.error !== undefined) return `Error: ${res.error.message}`;
|
||||
|
||||
|
|
@ -243,7 +249,7 @@ export function createTriplesQueryTool(
|
|||
`(${termToString(t.s)}) -[${termToString(t.p)}]-> (${termToString(t.o)})`,
|
||||
);
|
||||
return lines.join("\n");
|
||||
})),
|
||||
}),
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -263,12 +269,14 @@ export function createMcpTool(
|
|||
name: toolName,
|
||||
description,
|
||||
args,
|
||||
execute: (input: string): Promise<string> => Effect.runPromise(Effect.gen(function* () {
|
||||
const res = yield* client.request({ name: toolName, parameters: input });
|
||||
execute: Effect.fn("McpTool.execute")(function* (input: string) {
|
||||
const res = yield* client.request({ name: toolName, parameters: input }).pipe(
|
||||
Effect.mapError((cause) => agentToolError("mcp-tool", cause)),
|
||||
);
|
||||
if (res.error !== undefined) return `Error: ${res.error.message}`;
|
||||
if (res.text !== undefined) return res.text;
|
||||
if (res.object !== undefined) return res.object;
|
||||
return "No content";
|
||||
})),
|
||||
}),
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,24 @@
|
|||
* Types for the ReAct agent service.
|
||||
*/
|
||||
|
||||
import type { Effect } from "effect";
|
||||
import * as S from "effect/Schema";
|
||||
import { errorMessage } from "@trustgraph/base";
|
||||
|
||||
export class AgentToolError extends S.TaggedErrorClass<AgentToolError>()(
|
||||
"AgentToolError",
|
||||
{
|
||||
message: S.String,
|
||||
operation: S.String,
|
||||
},
|
||||
) {}
|
||||
|
||||
export const agentToolError = (operation: string, cause: unknown): AgentToolError =>
|
||||
AgentToolError.make({
|
||||
operation,
|
||||
message: errorMessage(cause),
|
||||
});
|
||||
|
||||
export interface ToolArg {
|
||||
name: string;
|
||||
type: string;
|
||||
|
|
@ -12,7 +30,7 @@ export interface AgentTool {
|
|||
name: string;
|
||||
description: string;
|
||||
args: ToolArg[];
|
||||
execute: (input: string) => Promise<string>;
|
||||
execute: (input: string) => Effect.Effect<string, AgentToolError>;
|
||||
/** Full tool config from config-push (used by tool filtering). */
|
||||
config?: Record<string, unknown>;
|
||||
}
|
||||
|
|
@ -30,6 +48,6 @@ export interface ParsedEvent {
|
|||
content: string;
|
||||
}
|
||||
|
||||
export type OnThought = (text: string, isFinal: boolean) => Promise<void>;
|
||||
export type OnObservation = (text: string, isFinal: boolean) => Promise<void>;
|
||||
export type OnAnswer = (text: string) => Promise<void>;
|
||||
export type OnThought = (text: string, isFinal: boolean) => Effect.Effect<void, AgentToolError>;
|
||||
export type OnObservation = (text: string, isFinal: boolean) => Effect.Effect<void, AgentToolError>;
|
||||
export type OnAnswer = (text: string) => Effect.Effect<void, AgentToolError>;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue