Rhys Sullivanwip ui8f20d5b8 months agoHistory
241 lines · 6.7 KB · TypeScript
RawDownload
import * as Effect from "effect/Effect";import * as Schema from "effect/Schema"; import { createDiscoveryPrimitivesFromToolCatalog } from "./discovery";import { toTool } from "./tool-map";import type {  DiscoveryPrimitives,  ToolCatalog,  ToolMap,  ToolPath,} from "./types"; const asToolPath = (value: string): ToolPath => value as ToolPath; const catalogNamespacesInputSchema = Schema.standardSchemaV1(  Schema.Struct({    limit: Schema.optional(Schema.Number),  }),); const catalogNamespacesOutputSchema = Schema.standardSchemaV1(  Schema.Struct({    namespaces: Schema.Array(      Schema.Struct({        namespace: Schema.String,        displayName: Schema.optional(Schema.String),        toolCount: Schema.optional(Schema.Number),      }),    ),  }),); const catalogToolsInputSchema = Schema.standardSchemaV1(  Schema.Struct({    namespace: Schema.optional(Schema.String),    query: Schema.optional(Schema.String),    limit: Schema.optional(Schema.Number),    includeSchemas: Schema.optional(Schema.Boolean),  }),); const catalogToolsOutputSchema = Schema.standardSchemaV1(  Schema.Struct({    results: Schema.Array(      Schema.Struct({        path: Schema.String,        sourceKey: Schema.String,        description: Schema.optional(Schema.String),        interaction: Schema.optional(Schema.String),        inputType: Schema.optional(Schema.String),        outputType: Schema.optional(Schema.String),        inputSchemaJson: Schema.optional(Schema.String),        outputSchemaJson: Schema.optional(Schema.String),        exampleInputJson: Schema.optional(Schema.String),        exampleOutputJson: Schema.optional(Schema.String),        providerKind: Schema.optional(Schema.String),        providerDataJson: Schema.optional(Schema.String),      }),    ),  }),); const describeToolInputSchema = Schema.standardSchemaV1(  Schema.Struct({    path: Schema.String,    includeSchemas: Schema.optional(Schema.Boolean),  }),); const describeToolOutputSchema = Schema.standardSchemaV1(  Schema.NullOr(Schema.Unknown),); const discoverInputSchema = Schema.standardSchemaV1(  Schema.Struct({    query: Schema.String,    limit: Schema.optional(Schema.Number),    includeSchemas: Schema.optional(Schema.Boolean),  }),); const discoverResultItemSchema = Schema.Struct({  path: Schema.String,  score: Schema.Number,  description: Schema.optional(Schema.String),  interaction: Schema.optional(Schema.String),  inputType: Schema.optional(Schema.String),  outputType: Schema.optional(Schema.String),  inputSchemaJson: Schema.optional(Schema.String),  outputSchemaJson: Schema.optional(Schema.String),}); const discoverOutputSchema = Schema.standardSchemaV1(  Schema.Struct({    bestPath: Schema.NullOr(Schema.String),    results: Schema.Array(discoverResultItemSchema),    total: Schema.Number,  }),); export type CreateSystemToolMapInput = {  catalog: ToolCatalog;  sourceKey?: string;}; export const createSystemToolMap = (  input: CreateSystemToolMapInput,): ToolMap => {  const sourceKey = input.sourceKey ?? "system";  const primitives: DiscoveryPrimitives = createDiscoveryPrimitivesFromToolCatalog({    catalog: input.catalog,  });   const tools: ToolMap = {};   if (primitives.catalog) {    tools["catalog.namespaces"] = toTool({      tool: {        description: "List available namespaces with display names and tool counts",        inputSchema: catalogNamespacesInputSchema,        outputSchema: catalogNamespacesOutputSchema,        execute: ({ limit }: { limit?: number }) =>          Effect.runPromise(            primitives.catalog!.namespaces({              ...(limit !== undefined ? { limit } : {}),            }),          ),      },      metadata: {        sourceKey,        interaction: "auto",      },    });     tools["catalog.tools"] = toTool({      tool: {        description: "List tools with optional namespace and query filters",        inputSchema: catalogToolsInputSchema,        outputSchema: catalogToolsOutputSchema,        execute: (          input: {            namespace?: string;            query?: string;            limit?: number;            includeSchemas?: boolean;          },        ) =>          Effect.runPromise(            primitives.catalog!.tools({              ...(input.namespace !== undefined ? { namespace: input.namespace } : {}),              ...(input.query !== undefined ? { query: input.query } : {}),              ...(input.limit !== undefined ? { limit: input.limit } : {}),              ...(input.includeSchemas !== undefined                ? { includeSchemas: input.includeSchemas }                : {}),            }),          ),      },      metadata: {        sourceKey,        interaction: "auto",      },    });  }   if (primitives.describe) {    tools["describe.tool"] = toTool({      tool: {        description: "Get metadata and optional schemas for a tool path",        inputSchema: describeToolInputSchema,        outputSchema: describeToolOutputSchema,        execute: ({ path, includeSchemas }: { path: string; includeSchemas?: boolean }) =>          Effect.runPromise(            primitives.describe!.tool({              path: asToolPath(path),              ...(includeSchemas !== undefined ? { includeSchemas } : {}),            }),          ),      },      metadata: {        sourceKey,        interaction: "auto",      },    });  }   if (primitives.discover) {    tools.discover = toTool({      tool: {        description: "Search tools by intent and return ranked matches",        inputSchema: discoverInputSchema,        outputSchema: discoverOutputSchema,        execute: (          input: {            query: string;            limit?: number;            includeSchemas?: boolean;          },        ) =>          Effect.runPromise(            primitives.discover!({              query: input.query,              ...(input.limit !== undefined ? { limit: input.limit } : {}),              ...(input.includeSchemas !== undefined                ? { includeSchemas: input.includeSchemas }                : {}),            }),          ),      },      metadata: {        sourceKey,        interaction: "auto",      },    });  }   return tools;}; export type MergeToolMapsOptions = {  conflictMode?: "throw" | "override";}; export const mergeToolMaps = (  maps: ReadonlyArray<ToolMap>,  options: MergeToolMapsOptions = {},): ToolMap => {  const conflictMode = options.conflictMode ?? "throw";  const merged: ToolMap = {};   for (const map of maps) {    for (const [path, tool] of Object.entries(map)) {      if (conflictMode === "throw" && path in merged) {        throw new Error(`Tool path conflict: ${path}`);      }      merged[path] = tool;    }  }   return merged;};