@decocms/bindings 0.1.3 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -36,7 +36,6 @@ function createBindingChecker(binderTools) {
36
36
  }
37
37
  const binderInputSchema = normalizeSchema(binderTool.inputSchema);
38
38
  const toolInputSchema = normalizeSchema(matchedTool.inputSchema);
39
- console.log(JSON.stringify(binderInputSchema, null, 2));
40
39
  if (binderInputSchema && toolInputSchema) {
41
40
  try {
42
41
  const inputDiff = await diffSchemas({
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/core/binder.ts"],"names":["jsonSchema"],"mappings":";;;;AAwEA,SAAS,gBAAgB,MAAA,EAAkD;AACzE,EAAA,IAAI,CAAC,QAAQ,OAAO,MAAA;AAGpB,EAAA,IAAI,OAAO,IAAA,EAAM;AACf,IAAA,MAAMA,WAAAA,GAAa,gBAAgB,MAAA,EAAQ;AAAA;AAAA,MAEzC,YAAA,EAAc;AAAA,KACf,CAAA;AAGD,IAAA,IAAIA,WAAAA,CAAW,SAAS,QAAA,EAAU;AAChC,MAAA,OAAOA,WAAAA,CAAW,oBAAA;AAAA,IACpB;AAEA,IAAA,OAAOA,WAAAA;AAAA,EACT;AAGA,EAAA,MAAM,UAAA,GAAa,MAAA;AAGnB,EAAA,IAAI,UAAA,CAAW,IAAA,KAAS,QAAA,IAAY,sBAAA,IAA0B,UAAA,EAAY;AACxE,IAAA,MAAM,IAAA,GAAO,EAAE,GAAG,UAAA,EAAW;AAC7B,IAAA,OAAO,IAAA,CAAK,oBAAA;AACZ,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,OAAO,UAAA;AACT;AAoCO,SAAS,qBACd,WAAA,EACgB;AAChB,EAAA,OAAO;AAAA,IACL,eAAA,EAAiB,OAAO,KAAA,KAA6B;AACnD,MAAA,KAAA,MAAW,cAAc,WAAA,EAAa;AAEpC,QAAA,MAAM,OAAA,GAAU,OAAO,UAAA,CAAW,IAAA,KAAS,QAAA,GACvC,IAAI,MAAA,CAAO,CAAA,CAAA,EAAI,UAAA,CAAW,IAAI,CAAA,CAAA,CAAG,CAAA,GACjC,UAAA,CAAW,IAAA;AAEf,QAAA,MAAM,WAAA,GAAc,MAAM,IAAA,CAAK,CAAC,MAAM,OAAA,CAAQ,IAAA,CAAK,CAAA,CAAE,IAAI,CAAC,CAAA;AAG1D,QAAA,IAAI,CAAC,WAAA,IAAe,UAAA,CAAW,GAAA,EAAK;AAClC,UAAA;AAAA,QACF;AAGA,QAAA,IAAI,CAAC,WAAA,EAAa;AAChB,UAAA,OAAO,KAAA;AAAA,QACT;AAMA,QAAA,MAAM,iBAAA,GAAoB,eAAA,CAAgB,UAAA,CAAW,WAAW,CAAA;AAChE,QAAA,MAAM,eAAA,GAAkB,eAAA,CAAgB,WAAA,CAAY,WAAW,CAAA;AAE/D,QAAA,OAAA,CAAQ,IAAI,IAAA,CAAK,SAAA,CAAU,iBAAA,EAAmB,IAAA,EAAM,CAAC,CAAC,CAAA;AAEtD,QAAA,IAAI,qBAAqB,eAAA,EAAiB;AACxC,UAAA,IAAI;AACF,YAAA,MAAM,SAAA,GAAY,MAAM,WAAA,CAAY;AAAA,cAClC,YAAA,EAAc,iBAAA;AAAA,cACd,iBAAA,EAAmB;AAAA,aACpB,CAAA;AAGD,YAAA,IAAI,UAAU,aAAA,EAAe;AAC3B,cAAA,OAAO,KAAA;AAAA,YACT;AAAA,UACF,SAAS,KAAA,EAAO;AACd,YAAA,OAAA,CAAQ,KAAA,CAAM,sBAAsB,KAAK,CAAA;AAEzC,YAAA,OAAO,KAAA;AAAA,UACT;AAAA,QACF,CAAA,MAAA,IAAW,iBAAA,IAAqB,CAAC,eAAA,EAAiB;AAEhD,UAAA,OAAO,KAAA;AAAA,QACT;AAMA,QAAA,MAAM,kBAAA,GAAqB,eAAA,CAAgB,UAAA,CAAW,YAAY,CAAA;AAClE,QAAA,MAAM,gBAAA,GAAmB,eAAA,CAAgB,WAAA,CAAY,YAAY,CAAA;AAEjE,QAAA,IAAI,sBAAsB,gBAAA,EAAkB;AAC1C,UAAA,IAAI;AACF,YAAA,MAAM,UAAA,GAAa,MAAM,WAAA,CAAY;AAAA,cACnC,YAAA,EAAc,kBAAA;AAAA,cACd,iBAAA,EAAmB;AAAA,aACpB,CAAA;AAGD,YAAA,IAAI,WAAW,aAAA,EAAe;AAC5B,cAAA,OAAO,KAAA;AAAA,YACT;AAAA,UACF,SAAS,KAAA,EAAO;AACd,YAAA,OAAA,CAAQ,KAAA,CAAM,sBAAsB,KAAK,CAAA;AAEzC,YAAA,OAAO,KAAA;AAAA,UACT;AAAA,QACF,CAAA,MAAA,IAAW,kBAAA,IAAsB,CAAC,gBAAA,EAAkB;AAElD,UAAA,OAAO,KAAA;AAAA,QACT;AAAA,MACF;AAEA,MAAA,OAAO,IAAA;AAAA,IACT;AAAA,GACF;AACF","file":"index.js","sourcesContent":["/**\n * Core Binder Types and Utilities\n *\n * This module provides the core types and utilities for the bindings system.\n * Bindings define standardized interfaces that integrations (MCPs) can implement.\n */\n\nimport type { ZodType } from \"zod\";\nimport { zodToJsonSchema } from \"zod-to-json-schema\";\nimport { diffSchemas } from \"json-schema-diff\";\n\n/**\n * ToolBinder defines a single tool within a binding.\n * It specifies the tool name, input/output schemas, and whether it's optional.\n *\n * @template TName - The tool name (can be a string or RegExp for pattern matching)\n * @template TInput - The input type (inferred from inputSchema)\n * @template TReturn - The return type (inferred from outputSchema)\n */\nexport interface ToolBinder<\n TName extends string | RegExp = string,\n // biome-ignore lint/suspicious/noExplicitAny: Generic type parameter\n TInput = any,\n TReturn extends object | null | boolean = object,\n> {\n /** The name of the tool (e.g., \"DECO_CHAT_CHANNELS_JOIN\") */\n name: TName;\n\n /** Zod schema for validating tool input */\n inputSchema: ZodType<TInput>;\n\n /** Optional Zod schema for validating tool output */\n outputSchema?: ZodType<TReturn>;\n\n /**\n * Whether this tool is optional in the binding.\n * If true, an implementation doesn't need to provide this tool.\n */\n opt?: true;\n}\n\n/**\n * Binder represents a collection of tool definitions that form a binding.\n * A binding is like a TypeScript interface - it defines what tools must be implemented.\n *\n * @template TDefinition - Array of ToolBinder definitions\n *\n * @example\n * ```ts\n * const MY_BINDING = [{\n * name: \"MY_TOOL\" as const,\n * inputSchema: z.object({ id: z.string() }),\n * outputSchema: z.object({ success: z.boolean() }),\n * }] as const satisfies Binder;\n * ```\n */\nexport type Binder<\n TDefinition extends readonly ToolBinder[] = readonly ToolBinder[],\n> = TDefinition;\n\n/**\n * Tool with schemas for validation\n */\nexport interface ToolWithSchemas {\n name: string;\n inputSchema?: ZodType<any> | Record<string, unknown>;\n outputSchema?: ZodType<any> | Record<string, unknown>;\n}\n\n/**\n * Converts a schema to JSON Schema format if it's a Zod schema\n */\nfunction normalizeSchema(schema: any): Record<string, unknown> | undefined {\n if (!schema) return undefined;\n\n // If it's a Zod schema (has _def property), convert it\n if (schema._def) {\n const jsonSchema = zodToJsonSchema(schema, {\n // Don't add additionalProperties: false to allow structural compatibility\n $refStrategy: \"none\",\n }) as Record<string, unknown>;\n\n // Remove additionalProperties constraint to allow subtyping\n if (jsonSchema.type === \"object\") {\n delete jsonSchema.additionalProperties;\n }\n\n return jsonSchema;\n }\n\n // Otherwise assume it's already a JSON Schema\n const jsonSchema = schema as Record<string, unknown>;\n\n // Remove additionalProperties constraint if present\n if (jsonSchema.type === \"object\" && \"additionalProperties\" in jsonSchema) {\n const copy = { ...jsonSchema };\n delete copy.additionalProperties;\n return copy;\n }\n\n return jsonSchema;\n}\n\n/**\n * Binding checker interface\n */\nexport interface BindingChecker {\n /**\n * Check if a set of tools implements the binding with full schema validation.\n *\n * Validates:\n * - Tool name matches (exact or regex)\n * - Input schema: Tool accepts what binder requires (no removals from binder to tool)\n * - Output schema: Tool provides what binder expects (no removals from tool to binder)\n *\n * @param tools - Array of tools with names and schemas\n * @returns Promise<boolean> - true if all tools implement the binding correctly\n */\n isImplementedBy: (tools: ToolWithSchemas[]) => Promise<boolean>;\n}\n\n/**\n * Creates a binding checker with full schema validation using json-schema-diff.\n *\n * This performs strict compatibility checking:\n * - For input schemas: Validates that the tool can accept what the binder requires\n * - For output schemas: Validates that the tool provides what the binder expects\n *\n * @param binderTools - The binding definition to check against\n * @returns A binding checker with an async isImplementedBy method\n *\n * @example\n * ```ts\n * const checker = createBindingChecker(MY_BINDING);\n * const isCompatible = await checker.isImplementedBy(availableTools);\n * ```\n */\nexport function createBindingChecker<TDefinition extends readonly ToolBinder[]>(\n binderTools: TDefinition,\n): BindingChecker {\n return {\n isImplementedBy: async (tools: ToolWithSchemas[]) => {\n for (const binderTool of binderTools) {\n // Find matching tool by name (exact or regex)\n const pattern = typeof binderTool.name === \"string\"\n ? new RegExp(`^${binderTool.name}$`)\n : binderTool.name;\n\n const matchedTool = tools.find((t) => pattern.test(t.name));\n\n // Skip optional tools that aren't present\n if (!matchedTool && binderTool.opt) {\n continue;\n }\n\n // Required tool not found\n if (!matchedTool) {\n return false;\n }\n\n // === INPUT SCHEMA VALIDATION ===\n // Tool must accept what binder requires\n // Check: binder (source) -> tool (destination)\n // If removals found, tool doesn't accept something binder requires\n const binderInputSchema = normalizeSchema(binderTool.inputSchema);\n const toolInputSchema = normalizeSchema(matchedTool.inputSchema);\n\n console.log(JSON.stringify(binderInputSchema, null, 2));\n\n if (binderInputSchema && toolInputSchema) {\n try {\n const inputDiff = await diffSchemas({\n sourceSchema: binderInputSchema,\n destinationSchema: toolInputSchema,\n });\n\n // If something was removed from binder to tool, tool can't accept it\n if (inputDiff.removalsFound) {\n return false;\n }\n } catch (error) {\n console.error(\"Schema diff failed\", error);\n // Schema diff failed - consider incompatible\n return false;\n }\n } else if (binderInputSchema && !toolInputSchema) {\n // Binder requires input schema but tool doesn't have one\n return false;\n }\n\n // === OUTPUT SCHEMA VALIDATION ===\n // Tool must provide what binder expects (but can provide more)\n // Check: binder (source) -> tool (destination)\n // If removals found, tool doesn't provide something binder expects\n const binderOutputSchema = normalizeSchema(binderTool.outputSchema);\n const toolOutputSchema = normalizeSchema(matchedTool.outputSchema);\n\n if (binderOutputSchema && toolOutputSchema) {\n try {\n const outputDiff = await diffSchemas({\n sourceSchema: binderOutputSchema,\n destinationSchema: toolOutputSchema,\n });\n\n // If something was removed from binder to tool, tool doesn't provide it\n if (outputDiff.removalsFound) {\n return false;\n }\n } catch (error) {\n console.error(\"Schema diff failed\", error);\n // Schema diff failed - consider incompatible\n return false;\n }\n } else if (binderOutputSchema && !toolOutputSchema) {\n // Binder expects output schema but tool doesn't have one\n return false;\n }\n }\n\n return true;\n },\n };\n}\n"]}
1
+ {"version":3,"sources":["../src/core/binder.ts"],"names":["jsonSchema"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Core Binder Types and Utilities\n *\n * This module provides the core types and utilities for the bindings system.\n * Bindings define standardized interfaces that integrations (MCPs) can implement.\n */\n\nimport type { ZodType } from \"zod\";\nimport { zodToJsonSchema } from \"zod-to-json-schema\";\nimport { diffSchemas } from \"json-schema-diff\";\n\n/**\n * ToolBinder defines a single tool within a binding.\n * It specifies the tool name, input/output schemas, and whether it's optional.\n *\n * @template TName - The tool name (can be a string or RegExp for pattern matching)\n * @template TInput - The input type (inferred from inputSchema)\n * @template TReturn - The return type (inferred from outputSchema)\n */\nexport interface ToolBinder<\n TName extends string | RegExp = string,\n // biome-ignore lint/suspicious/noExplicitAny: Generic type parameter\n TInput = any,\n TReturn extends object | null | boolean = object,\n> {\n /** The name of the tool (e.g., \"DECO_CHAT_CHANNELS_JOIN\") */\n name: TName;\n\n /** Zod schema for validating tool input */\n inputSchema: ZodType<TInput>;\n\n /** Optional Zod schema for validating tool output */\n outputSchema?: ZodType<TReturn>;\n\n /**\n * Whether this tool is optional in the binding.\n * If true, an implementation doesn't need to provide this tool.\n */\n opt?: true;\n}\n\n/**\n * Binder represents a collection of tool definitions that form a binding.\n * A binding is like a TypeScript interface - it defines what tools must be implemented.\n *\n * @template TDefinition - Array of ToolBinder definitions\n *\n * @example\n * ```ts\n * const MY_BINDING = [{\n * name: \"MY_TOOL\" as const,\n * inputSchema: z.object({ id: z.string() }),\n * outputSchema: z.object({ success: z.boolean() }),\n * }] as const satisfies Binder;\n * ```\n */\nexport type Binder<\n TDefinition extends readonly ToolBinder[] = readonly ToolBinder[],\n> = TDefinition;\n\n/**\n * Tool with schemas for validation\n */\nexport interface ToolWithSchemas {\n name: string;\n inputSchema?: ZodType<any> | Record<string, unknown>;\n outputSchema?: ZodType<any> | Record<string, unknown>;\n}\n\n/**\n * Converts a schema to JSON Schema format if it's a Zod schema\n */\nfunction normalizeSchema(schema: any): Record<string, unknown> | undefined {\n if (!schema) return undefined;\n\n // If it's a Zod schema (has _def property), convert it\n if (schema._def) {\n const jsonSchema = zodToJsonSchema(schema, {\n // Don't add additionalProperties: false to allow structural compatibility\n $refStrategy: \"none\",\n }) as Record<string, unknown>;\n\n // Remove additionalProperties constraint to allow subtyping\n if (jsonSchema.type === \"object\") {\n delete jsonSchema.additionalProperties;\n }\n\n return jsonSchema;\n }\n\n // Otherwise assume it's already a JSON Schema\n const jsonSchema = schema as Record<string, unknown>;\n\n // Remove additionalProperties constraint if present\n if (jsonSchema.type === \"object\" && \"additionalProperties\" in jsonSchema) {\n const copy = { ...jsonSchema };\n delete copy.additionalProperties;\n return copy;\n }\n\n return jsonSchema;\n}\n\n/**\n * Binding checker interface\n */\nexport interface BindingChecker {\n /**\n * Check if a set of tools implements the binding with full schema validation.\n *\n * Validates:\n * - Tool name matches (exact or regex)\n * - Input schema: Tool accepts what binder requires (no removals from binder to tool)\n * - Output schema: Tool provides what binder expects (no removals from tool to binder)\n *\n * @param tools - Array of tools with names and schemas\n * @returns Promise<boolean> - true if all tools implement the binding correctly\n */\n isImplementedBy: (tools: ToolWithSchemas[]) => Promise<boolean>;\n}\n\n/**\n * Creates a binding checker with full schema validation using json-schema-diff.\n *\n * This performs strict compatibility checking:\n * - For input schemas: Validates that the tool can accept what the binder requires\n * - For output schemas: Validates that the tool provides what the binder expects\n *\n * @param binderTools - The binding definition to check against\n * @returns A binding checker with an async isImplementedBy method\n *\n * @example\n * ```ts\n * const checker = createBindingChecker(MY_BINDING);\n * const isCompatible = await checker.isImplementedBy(availableTools);\n * ```\n */\nexport function createBindingChecker<TDefinition extends readonly ToolBinder[]>(\n binderTools: TDefinition,\n): BindingChecker {\n return {\n isImplementedBy: async (tools: ToolWithSchemas[]) => {\n for (const binderTool of binderTools) {\n // Find matching tool by name (exact or regex)\n const pattern = typeof binderTool.name === \"string\"\n ? new RegExp(`^${binderTool.name}$`)\n : binderTool.name;\n\n const matchedTool = tools.find((t) => pattern.test(t.name));\n\n // Skip optional tools that aren't present\n if (!matchedTool && binderTool.opt) {\n continue;\n }\n\n // Required tool not found\n if (!matchedTool) {\n return false;\n }\n\n // === INPUT SCHEMA VALIDATION ===\n // Tool must accept what binder requires\n // Check: binder (source) -> tool (destination)\n // If removals found, tool doesn't accept something binder requires\n const binderInputSchema = normalizeSchema(binderTool.inputSchema);\n const toolInputSchema = normalizeSchema(matchedTool.inputSchema);\n\n if (binderInputSchema && toolInputSchema) {\n try {\n const inputDiff = await diffSchemas({\n sourceSchema: binderInputSchema,\n destinationSchema: toolInputSchema,\n });\n\n // If something was removed from binder to tool, tool can't accept it\n if (inputDiff.removalsFound) {\n return false;\n }\n } catch (error) {\n console.error(\"Schema diff failed\", error);\n // Schema diff failed - consider incompatible\n return false;\n }\n } else if (binderInputSchema && !toolInputSchema) {\n // Binder requires input schema but tool doesn't have one\n return false;\n }\n\n // === OUTPUT SCHEMA VALIDATION ===\n // Tool must provide what binder expects (but can provide more)\n // Check: binder (source) -> tool (destination)\n // If removals found, tool doesn't provide something binder expects\n const binderOutputSchema = normalizeSchema(binderTool.outputSchema);\n const toolOutputSchema = normalizeSchema(matchedTool.outputSchema);\n\n if (binderOutputSchema && toolOutputSchema) {\n try {\n const outputDiff = await diffSchemas({\n sourceSchema: binderOutputSchema,\n destinationSchema: toolOutputSchema,\n });\n\n // If something was removed from binder to tool, tool doesn't provide it\n if (outputDiff.removalsFound) {\n return false;\n }\n } catch (error) {\n console.error(\"Schema diff failed\", error);\n // Schema diff failed - consider incompatible\n return false;\n }\n } else if (binderOutputSchema && !toolOutputSchema) {\n // Binder expects output schema but tool doesn't have one\n return false;\n }\n }\n\n return true;\n },\n };\n}\n"]}
@@ -1,15 +1,107 @@
1
1
  import { ToolBinder } from '../index.js';
2
- import 'zod';
2
+ import { z } from 'zod';
3
3
 
4
4
  /**
5
- * Models Well-Known Binding
6
- *
7
- * Defines the interface for AI model providers.
8
- * Any MCP that implements this binding can provide AI models and streaming endpoints.
9
- *
10
- * This binding uses collection bindings for LIST and GET operations (read-only).
11
- * Streaming endpoint information is included directly in the model entity schema.
5
+ * Model entity schema for AI models
6
+ * Extends BaseCollectionEntitySchema with model-specific fields
7
+ * Base schema already includes: id, title, created_at, updated_at, created_by, updated_by
12
8
  */
9
+ declare const ModelSchema: z.ZodObject<{
10
+ id: z.ZodString;
11
+ title: z.ZodString;
12
+ created_at: z.ZodString;
13
+ updated_at: z.ZodString;
14
+ created_by: z.ZodOptional<z.ZodString>;
15
+ updated_by: z.ZodOptional<z.ZodString>;
16
+ } & {
17
+ logo: z.ZodNullable<z.ZodString>;
18
+ description: z.ZodNullable<z.ZodString>;
19
+ capabilities: z.ZodArray<z.ZodString, "many">;
20
+ limits: z.ZodNullable<z.ZodObject<{
21
+ contextWindow: z.ZodNumber;
22
+ maxOutputTokens: z.ZodNumber;
23
+ }, "strip", z.ZodTypeAny, {
24
+ contextWindow: number;
25
+ maxOutputTokens: number;
26
+ }, {
27
+ contextWindow: number;
28
+ maxOutputTokens: number;
29
+ }>>;
30
+ costs: z.ZodNullable<z.ZodObject<{
31
+ input: z.ZodNumber;
32
+ output: z.ZodNumber;
33
+ }, "strip", z.ZodTypeAny, {
34
+ input: number;
35
+ output: number;
36
+ }, {
37
+ input: number;
38
+ output: number;
39
+ }>>;
40
+ endpoint: z.ZodNullable<z.ZodObject<{
41
+ url: z.ZodString;
42
+ method: z.ZodDefault<z.ZodString>;
43
+ contentType: z.ZodDefault<z.ZodString>;
44
+ stream: z.ZodDefault<z.ZodBoolean>;
45
+ }, "strip", z.ZodTypeAny, {
46
+ url: string;
47
+ method: string;
48
+ contentType: string;
49
+ stream: boolean;
50
+ }, {
51
+ url: string;
52
+ method?: string | undefined;
53
+ contentType?: string | undefined;
54
+ stream?: boolean | undefined;
55
+ }>>;
56
+ }, "strip", z.ZodTypeAny, {
57
+ id: string;
58
+ title: string;
59
+ created_at: string;
60
+ updated_at: string;
61
+ logo: string | null;
62
+ description: string | null;
63
+ capabilities: string[];
64
+ limits: {
65
+ contextWindow: number;
66
+ maxOutputTokens: number;
67
+ } | null;
68
+ costs: {
69
+ input: number;
70
+ output: number;
71
+ } | null;
72
+ endpoint: {
73
+ url: string;
74
+ method: string;
75
+ contentType: string;
76
+ stream: boolean;
77
+ } | null;
78
+ created_by?: string | undefined;
79
+ updated_by?: string | undefined;
80
+ }, {
81
+ id: string;
82
+ title: string;
83
+ created_at: string;
84
+ updated_at: string;
85
+ logo: string | null;
86
+ description: string | null;
87
+ capabilities: string[];
88
+ limits: {
89
+ contextWindow: number;
90
+ maxOutputTokens: number;
91
+ } | null;
92
+ costs: {
93
+ input: number;
94
+ output: number;
95
+ } | null;
96
+ endpoint: {
97
+ url: string;
98
+ method?: string | undefined;
99
+ contentType?: string | undefined;
100
+ stream?: boolean | undefined;
101
+ } | null;
102
+ created_by?: string | undefined;
103
+ updated_by?: string | undefined;
104
+ }>;
13
105
  /**
14
106
  * MODELS Collection Binding
15
107
  *
@@ -29,4 +121,4 @@ declare const MODELS_COLLECTION_BINDING: ToolBinder<string, any, object>[];
29
121
  */
30
122
  declare const MODELS_BINDING: readonly ToolBinder<string, any, object>[];
31
123
 
32
- export { MODELS_BINDING, MODELS_COLLECTION_BINDING };
124
+ export { MODELS_BINDING, MODELS_COLLECTION_BINDING, ModelSchema };
@@ -31,6 +31,6 @@ var MODELS_BINDING = [
31
31
  ...MODELS_COLLECTION_BINDING
32
32
  ];
33
33
 
34
- export { MODELS_BINDING, MODELS_COLLECTION_BINDING };
34
+ export { MODELS_BINDING, MODELS_COLLECTION_BINDING, ModelSchema };
35
35
  //# sourceMappingURL=models.js.map
36
36
  //# sourceMappingURL=models.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/well-known/models.ts"],"names":[],"mappings":";;;AAsBA,IAAM,WAAA,GAAc,2BAA2B,MAAA,CAAO;AAAA;AAAA,EAEpD,IAAA,EAAM,CAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS;AAAA,EAC1B,WAAA,EAAa,CAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS;AAAA,EACjC,YAAA,EAAc,CAAA,CAAE,KAAA,CAAM,CAAA,CAAE,QAAQ,CAAA;AAAA,EAChC,MAAA,EAAQ,EAAE,MAAA,CAAO;AAAA,IACf,aAAA,EAAe,EAAE,MAAA,EAAO;AAAA,IACxB,eAAA,EAAiB,EAAE,MAAA;AAAO,GAC3B,EAAE,QAAA,EAAS;AAAA,EACZ,KAAA,EAAO,EAAE,MAAA,CAAO;AAAA,IACd,KAAA,EAAO,EAAE,MAAA,EAAO;AAAA,IAChB,MAAA,EAAQ,EAAE,MAAA;AAAO,GAClB,EAAE,QAAA,EAAS;AAAA;AAAA,EAEZ,QAAA,EAAU,EAAE,MAAA,CAAO;AAAA,IACjB,GAAA,EAAK,CAAA,CAAE,MAAA,EAAO,CAAE,GAAA,EAAI;AAAA,IACpB,MAAA,EAAQ,CAAA,CAAE,MAAA,EAAO,CAAE,QAAQ,MAAM,CAAA;AAAA,IACjC,WAAA,EAAa,CAAA,CAAE,MAAA,EAAO,CAAE,QAAQ,kBAAkB,CAAA;AAAA,IAClD,MAAA,EAAQ,CAAA,CAAE,OAAA,EAAQ,CAAE,QAAQ,IAAI;AAAA,GACjC,EAAE,QAAA;AACL,CAAC,CAAA;AAQM,IAAM,yBAAA,GAA4B,wBAAA;AAAA,EACvC,QAAA;AAAA,EACA,WAAA;AAAA,EACA,EAAE,UAAU,IAAA;AACd;AAYO,IAAM,cAAA,GAAiB;AAAA,EAC5B,GAAG;AACL","file":"models.js","sourcesContent":["/**\n * Models Well-Known Binding\n *\n * Defines the interface for AI model providers.\n * Any MCP that implements this binding can provide AI models and streaming endpoints.\n *\n * This binding uses collection bindings for LIST and GET operations (read-only).\n * Streaming endpoint information is included directly in the model entity schema.\n */\n\nimport { z } from \"zod\";\nimport type { Binder } from \"../core/binder\";\nimport {\n BaseCollectionEntitySchema,\n createCollectionBindings,\n} from \"./collections\";\n\n/**\n * Model entity schema for AI models\n * Extends BaseCollectionEntitySchema with model-specific fields\n * Base schema already includes: id, title, created_at, updated_at, created_by, updated_by\n */\nconst ModelSchema = BaseCollectionEntitySchema.extend({\n // Model-specific fields\n logo: z.string().nullable(),\n description: z.string().nullable(),\n capabilities: z.array(z.string()),\n limits: z.object({\n contextWindow: z.number(),\n maxOutputTokens: z.number(),\n }).nullable(),\n costs: z.object({\n input: z.number(),\n output: z.number(),\n }).nullable(),\n // Streaming endpoint information\n endpoint: z.object({\n url: z.string().url(),\n method: z.string().default(\"POST\"),\n contentType: z.string().default(\"application/json\"),\n stream: z.boolean().default(true),\n }).nullable(),\n});\n\n/**\n * MODELS Collection Binding\n *\n * Collection bindings for models (read-only).\n * Provides LIST and GET operations for AI models.\n */\nexport const MODELS_COLLECTION_BINDING = createCollectionBindings(\n \"models\",\n ModelSchema,\n { readOnly: true },\n);\n\n/**\n * MODELS Binding\n *\n * Defines the interface for AI model providers.\n * Any MCP that implements this binding can provide AI models and streaming endpoints.\n *\n * Required tools:\n * - DECO_COLLECTION_MODELS_LIST: List available AI models with their capabilities\n * - DECO_COLLECTION_MODELS_GET: Get a single model by ID (includes streaming endpoint info)\n */\nexport const MODELS_BINDING = [\n ...MODELS_COLLECTION_BINDING,\n] as const satisfies Binder;\n"]}
1
+ {"version":3,"sources":["../../src/well-known/models.ts"],"names":[],"mappings":";;;AAsBO,IAAM,WAAA,GAAc,2BAA2B,MAAA,CAAO;AAAA;AAAA,EAE3D,IAAA,EAAM,CAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS;AAAA,EAC1B,WAAA,EAAa,CAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS;AAAA,EACjC,YAAA,EAAc,CAAA,CAAE,KAAA,CAAM,CAAA,CAAE,QAAQ,CAAA;AAAA,EAChC,MAAA,EAAQ,EAAE,MAAA,CAAO;AAAA,IACf,aAAA,EAAe,EAAE,MAAA,EAAO;AAAA,IACxB,eAAA,EAAiB,EAAE,MAAA;AAAO,GAC3B,EAAE,QAAA,EAAS;AAAA,EACZ,KAAA,EAAO,EAAE,MAAA,CAAO;AAAA,IACd,KAAA,EAAO,EAAE,MAAA,EAAO;AAAA,IAChB,MAAA,EAAQ,EAAE,MAAA;AAAO,GAClB,EAAE,QAAA,EAAS;AAAA;AAAA,EAEZ,QAAA,EAAU,EAAE,MAAA,CAAO;AAAA,IACjB,GAAA,EAAK,CAAA,CAAE,MAAA,EAAO,CAAE,GAAA,EAAI;AAAA,IACpB,MAAA,EAAQ,CAAA,CAAE,MAAA,EAAO,CAAE,QAAQ,MAAM,CAAA;AAAA,IACjC,WAAA,EAAa,CAAA,CAAE,MAAA,EAAO,CAAE,QAAQ,kBAAkB,CAAA;AAAA,IAClD,MAAA,EAAQ,CAAA,CAAE,OAAA,EAAQ,CAAE,QAAQ,IAAI;AAAA,GACjC,EAAE,QAAA;AACL,CAAC;AAQM,IAAM,yBAAA,GAA4B,wBAAA;AAAA,EACvC,QAAA;AAAA,EACA,WAAA;AAAA,EACA,EAAE,UAAU,IAAA;AACd;AAYO,IAAM,cAAA,GAAiB;AAAA,EAC5B,GAAG;AACL","file":"models.js","sourcesContent":["/**\n * Models Well-Known Binding\n *\n * Defines the interface for AI model providers.\n * Any MCP that implements this binding can provide AI models and streaming endpoints.\n *\n * This binding uses collection bindings for LIST and GET operations (read-only).\n * Streaming endpoint information is included directly in the model entity schema.\n */\n\nimport { z } from \"zod\";\nimport type { Binder } from \"../core/binder\";\nimport {\n BaseCollectionEntitySchema,\n createCollectionBindings,\n} from \"./collections\";\n\n/**\n * Model entity schema for AI models\n * Extends BaseCollectionEntitySchema with model-specific fields\n * Base schema already includes: id, title, created_at, updated_at, created_by, updated_by\n */\nexport const ModelSchema = BaseCollectionEntitySchema.extend({\n // Model-specific fields\n logo: z.string().nullable(),\n description: z.string().nullable(),\n capabilities: z.array(z.string()),\n limits: z.object({\n contextWindow: z.number(),\n maxOutputTokens: z.number(),\n }).nullable(),\n costs: z.object({\n input: z.number(),\n output: z.number(),\n }).nullable(),\n // Streaming endpoint information\n endpoint: z.object({\n url: z.string().url(),\n method: z.string().default(\"POST\"),\n contentType: z.string().default(\"application/json\"),\n stream: z.boolean().default(true),\n }).nullable(),\n});\n\n/**\n * MODELS Collection Binding\n *\n * Collection bindings for models (read-only).\n * Provides LIST and GET operations for AI models.\n */\nexport const MODELS_COLLECTION_BINDING = createCollectionBindings(\n \"models\",\n ModelSchema,\n { readOnly: true },\n);\n\n/**\n * MODELS Binding\n *\n * Defines the interface for AI model providers.\n * Any MCP that implements this binding can provide AI models and streaming endpoints.\n *\n * Required tools:\n * - DECO_COLLECTION_MODELS_LIST: List available AI models with their capabilities\n * - DECO_COLLECTION_MODELS_GET: Get a single model by ID (includes streaming endpoint info)\n */\nexport const MODELS_BINDING = [\n ...MODELS_COLLECTION_BINDING,\n] as const satisfies Binder;\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@decocms/bindings",
3
- "version": "0.1.3",
3
+ "version": "0.1.4",
4
4
  "type": "module",
5
5
  "scripts": {
6
6
  "build": "tsup",
@@ -165,8 +165,6 @@ export function createBindingChecker<TDefinition extends readonly ToolBinder[]>(
165
165
  const binderInputSchema = normalizeSchema(binderTool.inputSchema);
166
166
  const toolInputSchema = normalizeSchema(matchedTool.inputSchema);
167
167
 
168
- console.log(JSON.stringify(binderInputSchema, null, 2));
169
-
170
168
  if (binderInputSchema && toolInputSchema) {
171
169
  try {
172
170
  const inputDiff = await diffSchemas({
@@ -20,7 +20,7 @@ import {
20
20
  * Extends BaseCollectionEntitySchema with model-specific fields
21
21
  * Base schema already includes: id, title, created_at, updated_at, created_by, updated_by
22
22
  */
23
- const ModelSchema = BaseCollectionEntitySchema.extend({
23
+ export const ModelSchema = BaseCollectionEntitySchema.extend({
24
24
  // Model-specific fields
25
25
  logo: z.string().nullable(),
26
26
  description: z.string().nullable(),