Skip to content

Commit 9a5d50a

Browse files
jakedahnbfollington
authored andcommitted
adding a shared llm client wrapper that can be imported and used (#280)
1 parent 3684ab6 commit 9a5d50a

File tree

6 files changed

+63
-24
lines changed

6 files changed

+63
-24
lines changed
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import { AppType } from "@/app.ts";
2+
import { hc } from "hono/client";
3+
4+
// NOTE(jake): Ideally this would be exposed via the hono client, but I wasn't
5+
// able to get it all wired up. Importing the route definition is fine for now.
6+
import type { GetModelsRouteQueryParams } from "@/routes/ai/llm/llm.routes.ts";
7+
8+
const client = hc<AppType>("http://localhost:8000/");
9+
10+
export async function listAvailableModels({
11+
capability,
12+
task,
13+
search,
14+
}: GetModelsRouteQueryParams) {
15+
const res = await client.api.ai.llm.models.$get({
16+
query: {
17+
search,
18+
capability,
19+
task,
20+
},
21+
});
22+
return res.json();
23+
}
24+
25+
export async function generateText(
26+
query: Parameters<typeof client.api.ai.llm.$post>[0]["json"],
27+
): Promise<string> {
28+
const res = await client.api.ai.llm.$post({ json: query });
29+
const data = await res.json();
30+
31+
if ("error" in data) {
32+
throw new Error(data.error);
33+
}
34+
35+
if ("type" in data && data.type === "json") {
36+
return data.body.content;
37+
}
38+
39+
throw new Error("Unexpected response format");
40+
}

typescript/packages/toolshed/routes/ai/llm/llm.routes.ts

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,12 @@ import { z } from "zod";
66
const tags = ["AI Language Models"];
77

88
export const MessageSchema = z.object({
9-
role: z.enum(["user", "assistant"]),
9+
role: z.string(),
1010
content: z.string(),
1111
});
1212

13+
export type LLMResponseMessage = z.infer<typeof MessageSchema>;
14+
1315
export const LLMRequestSchema = z.object({
1416
messages: z.array(MessageSchema),
1517
system: z.string().optional(),
@@ -55,16 +57,24 @@ const JsonResponse = z.object({
5557
}),
5658
});
5759

60+
export type LLMJSONResponse = z.infer<typeof JsonResponse>;
61+
62+
const GetModelsRouteQueryParams = z.object({
63+
search: z.string().optional(),
64+
capability: z.string().optional(),
65+
task: z.string().optional(),
66+
});
67+
68+
export type GetModelsRouteQueryParams = z.infer<
69+
typeof GetModelsRouteQueryParams
70+
>;
71+
5872
// Route definitions
5973
export const getModels = createRoute({
6074
path: "/api/ai/llm/models",
6175
method: "get",
6276
tags,
63-
query: z.object({
64-
search: z.string().optional(),
65-
capability: z.string().optional(),
66-
task: z.string().optional(),
67-
}),
77+
query: GetModelsRouteQueryParams,
6878
responses: {
6979
[HttpStatusCodes.OK]: jsonContent(
7080
ModelsResponseSchema.openapi({

typescript/packages/toolshed/routes/ai/spell/behavior/effects.ts

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,6 @@ import { handleResponse } from "@/lib/response.ts";
44

55
const client = hc<AppType>("http://localhost:8000/");
66

7-
export async function generateText(
8-
query: Parameters<typeof client.api.ai.llm.$post>[0]["json"],
9-
) {
10-
const res = await client.api.ai.llm.$post({ json: query });
11-
// cheating
12-
// deno-lint-ignore no-explicit-any
13-
const data = (await res.json() as any) as {
14-
role: "assistant";
15-
content: string;
16-
};
17-
18-
return data.content;
19-
}
20-
217
export async function getAllBlobs(): Promise<string[]> {
228
const res = await client.api.storage.blobby.$get({ query: { all: "true" } });
239
const data = await res.json();

typescript/packages/toolshed/routes/ai/spell/behavior/strategies/scanByCollections.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { SearchResult } from "../search.ts";
22
import { Logger, PrefixedLogger } from "@/lib/prefixed-logger.ts";
3-
import { generateText, getBlob } from "../effects.ts";
3+
import { getBlob } from "../effects.ts";
4+
import { generateText } from "@/lib/llm.ts";
45

56
async function generateKeywords(
67
query: string,
@@ -11,7 +12,7 @@ async function generateKeywords(
1112
model: "claude-3-5-sonnet",
1213
messages: [
1314
{
14-
role: "user" as const,
15+
role: "user",
1516
content: query,
1617
},
1718
],

typescript/packages/toolshed/routes/ai/spell/behavior/strategies/scanBySchema.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ import { checkSchemaMatch } from "@/lib/schema-match.ts";
22
import { SearchResult } from "../search.ts";
33
import { Logger, PrefixedLogger } from "@/lib/prefixed-logger.ts";
44
import type { RedisClientType } from "redis";
5-
import { generateText, getAllBlobs, getBlob } from "../effects.ts";
5+
import { generateText } from "@/lib/llm.ts";
6+
import { getAllBlobs, getBlob } from "../effects.ts";
67
import { Schema } from "jsonschema";
78

89
export async function generateSchema(

typescript/packages/toolshed/routes/ai/spell/spell.handlers.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import * as HttpStatusCodes from "stoker/http-status-codes";
22
import { z } from "zod";
3-
import { generateText, getAllBlobs, getBlob } from "./behavior/effects.ts";
3+
import { getAllBlobs, getBlob } from "./behavior/effects.ts";
4+
import { generateText } from "@/lib/llm.ts";
45

56
import type { AppRouteHandler } from "@/lib/types.ts";
67
import type { ProcessSchemaRoute, SearchSchemaRoute } from "./spell.routes.ts";

0 commit comments

Comments
 (0)