From a59fec88888909e2c9eb6b2945862102f3d66666 Mon Sep 17 00:00:00 2001 From: Alex Whiteside Date: Thu, 26 Sep 2024 19:24:20 -0400 Subject: [PATCH] Agents --- packages/agents/src/Agent.spec.ts | 22 ++++++++------- packages/agents/src/Agent.ts | 43 +++++++++--------------------- packages/agents/src/md/pipeline.ts | 5 ++-- packages/agents/vite.config.ts | 7 ++++- 4 files changed, 33 insertions(+), 44 deletions(-) diff --git a/packages/agents/src/Agent.spec.ts b/packages/agents/src/Agent.spec.ts index 06d58e6..f0840ed 100644 --- a/packages/agents/src/Agent.spec.ts +++ b/packages/agents/src/Agent.spec.ts @@ -1,26 +1,28 @@ import { HelloAgent, Task } from "./Agent"; -import { Effect, Layer, pipe } from "effect"; +import { Effect } from "effect"; import { Schema } from "@effect/schema"; -import { AppLayer, LLMServiceLive } from "./services"; +import { AppLayer } from "./services"; describe("Agent", () => { - it("should ", {timeout:100000},async () => { - const program = Effect.gen(function* () { + it("should ", { timeout: 100000 }, async () => { + const program = Effect.gen(function* (_) { const agent = new HelloAgent(); const createTask = Effect.succeed( new Task( "Create a greeting for Alex Whiteside, a software architect who enjoys sarcasm and XKCD", ["Be Positive", "Be Creative"], - Schema.Struct({greeting: Schema.String}), + Schema.Struct({ greeting: Schema.String }), ), ); - const result = yield* agent.process(createTask); - console.log(result); + return yield* agent.process(createTask); }); - const ollamaLayer = LLMServiceLive(); - const runnable = Effect.provide(program, ollamaLayer); + // const ollamaLayer = LLMServiceLive(); + const runnable = Effect.provide(program, AppLayer); - await Effect.runPromiseExit(runnable).then(console.log); + const output = await Effect.runPromise(runnable); + expect(output.data).toMatchObject( + expect.objectContaining({ greeting: expect.stringContaining("Alex") }), + ); }); }); diff --git a/packages/agents/src/Agent.ts b/packages/agents/src/Agent.ts index 588d4f4..5ef940e 100644 --- a/packages/agents/src/Agent.ts +++ b/packages/agents/src/Agent.ts @@ -1,12 +1,11 @@ import { JSONSchema, Schema } from "@effect/schema"; import { LLMService } from "./services"; -import { Effect, pipe, Either } from "effect"; +import { Effect, Match, pipe } from "effect"; import { extractJSON, getMdast, stringifyMdast } from "./md"; -import { Match } from "effect"; import { get, isArray, unique } from "radash"; -import { isSchema, transform } from "@effect/schema/Schema"; +import { isSchema } from "@effect/schema/Schema"; import { getSectionByHeading } from "./md/getSection"; -import { Root } from "mdast"; +import { isRight } from "effect/Either"; export class Task { constructor( @@ -116,11 +115,17 @@ export abstract class Agent { const llm = yield* LLMService; const taskReal = yield* task; - console.log(taskReal); const prompt = generatePrompt(taskReal); - console.log(prompt); const response = yield* llm.generateText(prompt, "mistral-small"); - return parseTaskResponse(taskReal, response); + + const mdast = yield* getMdast(response); + const data = Schema.decodeEither(taskReal.format)( + extractJSON(getSectionByHeading(mdast, sections.data.heading)), + ); + if (isRight(data)) { + return new TaskResult(data.right, ""); + } + return new TaskResult(null, "null"); }); } } @@ -130,27 +135,3 @@ export class HelloAgent extends Agent { description = "Welcomes people to the project"; } -const parseTaskResponse = (task: Task, response: string) => { - const root = getMdast(response); - - const getSection = >( - heading: string, - transform?: T, - ) => { - return pipe( - Effect.try({ - try: () => getSectionByHeading(root, heading), - catch: (err) => err, - }), - Effect.map(transform ?? stringifyMdast), - ); - }; - - const data = getSection(sections.data.heading, (node) => - Schema.decodeEither(task.format)(extractJSON(node)), - ); - - if (task.format && data && Either.isLeft(data)) throw new Error("Failed"); - const unstructured = getSection(sections.unstructured.heading); - return new TaskResult(data, unstructured); -}; diff --git a/packages/agents/src/md/pipeline.ts b/packages/agents/src/md/pipeline.ts index c8796df..934a583 100644 --- a/packages/agents/src/md/pipeline.ts +++ b/packages/agents/src/md/pipeline.ts @@ -1,11 +1,12 @@ import { remark } from "remark"; import remarkGfm from "remark-gfm"; import { Root } from "mdast"; +import { Effect } from "effect"; const markdownPipeline = remark().use(remarkGfm); export const getMdast = (md: string) => { - return markdownPipeline.parse(md); + return Effect.succeed(markdownPipeline.parse(md)); }; -export const stringifyMdast = (node: Root)=> markdownPipeline.stringify(node) \ No newline at end of file +export const stringifyMdast = (node: Root)=> Effect.succeed(markdownPipeline.stringify(node)) \ No newline at end of file diff --git a/packages/agents/vite.config.ts b/packages/agents/vite.config.ts index bf50159..24e5995 100644 --- a/packages/agents/vite.config.ts +++ b/packages/agents/vite.config.ts @@ -1,11 +1,16 @@ -/// import { defineConfig } from "vitest/config"; import tsconfigPaths from "vite-tsconfig-paths"; export default defineConfig({ plugins: [tsconfigPaths()], + build:{ + sourcemap:'inline' + + }, + test: { + globals: true, }, });