Telygent

SDK Registry

Connection with your data

The Model Registry serves as the client-side declarative schema that the SDK uses to validate and constrain tool calls. It acts as a metadata bridge between your database collections/tables and the Telygent AI SDK. Rather than hard-coding data access patterns, the Registry allows you to define a declarative blueprint for every entity in your system. It governs everything from security whitelisting and type enforcement to complex relational lookups and automated link generation. By configuring a ModelConfig, you provide the SDK with the intelligence it needs to transform raw database documents into structured, navigable, and context-aware objects for your frontend and AI services.

Core Identification & Security

collectionName

The direct mapping to your underlying database collection/table. This tells the SDK exactly where the physical data resides.

allowedFields

The security "whitelist". Only fields listed here are exposed to the SDK. This prevents sensitive internal data from leaking into the client layer or to the AI while ensuring the SDK only interacts with verified properties.

fieldAliases

Optional
An abstraction layer for your data. This allows you to map internal database keys/fields/column names (e.g., u_id_01) to ergonomic, developer-friendly names (e.g., userId) within the SDK.

instructions

Optional

This is the contextual compass for the AI when using this model. While the schema defines what the data is, the instructions define how it should be handled or prioritized. Think of this as a model-specific system prompt. It allows you to pass business rules or "hints" directly to the AI to influence its reasoning.

Example: For a Ticket model, an instruction might be: "When a user asks for 'urgent' tickets, always filter for priority > 3 and status: 'open'."

Example:

registry.ts
1const registry = { 2 Ticket: { 3 collectionName: "support_tickets", 4 allowedFields: ["ticketId", "status", "priority", "createdAt"], 5 fieldAliases: { 6 ticketId: ["ticket_id", "t_id", "case_id"], 7 createdAt: ["created_at", "created_date"], 8 }, 9 instructions: "When a user asks for 'urgent' tickets, always filter for priority > 3 and status: 'open'" 10 ... 11 }, 12 };

Data Typing

fieldTypes

Optional
Field types are used to coerce filter values (and requiredFilters) into the correct shape before queries run. This helps with dates and ObjectIds in particular. If you don’t supply fieldTypes, the SDK does not infer types — it passes values through as provided.

requiredFilters

Optional

Mandatory "guardrails" for your data access. They ensures that every query made through the SDK is scoped correctly, usually for security, ownership, or multi-tenancy purposes. If a query is attempted without these parameters, or if the SDK cannot resolve the necessary values from the application context, the request will be blocked.

The requiredFilters need the following fields:

  • field: The specific field in the table/collection that must be filtered (e.g., userId).
  • contextKey: This is the "Source of Truth." It tells the SDK to look into the Active Session/Application Context for a specific key (like the logged-in user's ID). The SDK then injects this value into the database query automatically.
  • type: The expected data type for the filter value (e.g., string, objectId). This ensures that the injected context value matches the database schema.
Note: You do not need to manually add these filters to every SDK call. The Registry handles the injection of contextKey values into the field query at the middleware level, ensuring data isolation is enforced by default.

Example:

registry.ts
1const registry = { 2 Ticket: { 3 collectionName: "support_tickets", 4 allowedFields: ["ticketId", "status", "priority","userId", "createdAt"], 5 fieldTypes: { 6 ticketId: "objectId", 7 createdAt: "date", 8 priority: "number", 9 status: "string", 10 }, 11 requiredFilters: [ 12 { field: "userId", contextKey: "userId", type: "string" }, 13 ], 14 ... 15 }, 16 };

Relations & Joins

relations

Optional

Defines the entity graph, how this model connects to other collections. The SDK uses these to perform lookups.

  • path: The attribute name in the resulting object where the associated data is merged.
  • target: The name of the related Model Configuration collection/table name
  • singleResult: A cardinality flag. If true, the SDK treats the relationship as a 1:1 or Many:1 and returns a single object. If false, it treats it as 1:Many and returns a list.
  • localField / foreignField: The matching keys used to link the two entities (e.g., Primary and Foreign keys).
  • select (optional) : to limit fields pulled from the related collection.
  • description (optional) : This allows you to describe the type of connection this is and give the AI a sense of what to expect

Example:

registry.ts
1const registry = { 2 Ticket: { 3 collectionName: "support_tickets", 4 allowedFields: ["ticketId", "status", "priority", "createdAt", "customerId"], 5 relations: [ 6 { 7 path: "customer", 8 target: "customers", 9 localField: "customerId", 10 foreignField: "_id", 11 select: ["_id", "name", "email", "tier"], 12 singleResult: true, 13 description: "Attach the customer for each ticket", 14 }, 15 ], 16 ... 17 }, 18 };

Custom services

By design, the AI is restricted to read-only access to your data stores. To enable actions such as updating a status, sending a notification, or performing a complex analytical summary, you must define a Custom Service. This architecture ensures the AI cannot perform "Write" operations directly to your database, forcing all actions through your verified business logic.

Each service in the customServices array acts as a Function Contract that the AI discovers and understands.

name

The unique identifier for the service. This must match the key used in your SDK implementation block (the "Handshake").

description

A detailed, natural-language explanation. The AI uses this to decide when it should call this specific service versus a standard database query.

inputSchema

A standard JSON Schema defining the parameters the AI must provide.

  • properties: Defines the variables (e.g., timeRangeDays or query).
  • required: Lists the fields the AI must collect from the user before it is allowed to trigger the function.

Custom Services aren't just for writing data; they are also used for System Functions that replace standard lookups.

If your application uses a specialized search engine (like Elasticsearch or a Vector store for AI embeddings), or if you need to perform cross-entity summaries that a standard SQL/NoSQL query cannot handle efficiently, you can define a custom_search service. The AI will then defer to your function instead of trying to build its own database query.

Key Benefits for Developers:

  • Database Agnostic Execution: Your service can pull data from a MongoDB collection, a PostgreSQL table, and a 3rd-party API simultaneously and return a unified result to the AI
  • Input Validation: The inputSchema ensures the AI never sends malformed data to your backend.
  • Encapsulation: Your core database remains protected. The AI only sees the "Input" and "Output," never the raw connection strings or internal logic.

Example:

registry.ts
1const registry = { 2 Ticket: { 3 collectionName: "support_tickets", 4 allowedFields: ["ticketId", "status", "priority", "createdAt", "assigneeId"], 5 customServices: [ 6 { 7 name: "ticket_search", 8 description: "Search tickets by keyword and filters.", 9 inputSchema: { 10 type: "object", 11 properties: { 12 query: { type: "string" }, 13 status: { type: "string" }, 14 priority: { type: "string" }, 15 limit: { type: "number" }, 16 }, 17 required: ["query"], 18 }, 19 }, 20 { 21 name: "ticket_summary", 22 description: "Summarize ticket patterns over a time range.", 23 inputSchema: { 24 type: "object", 25 properties: { 26 timeRangeDays: { type: "number" }, 27 tags: { type: "array", items: { type: "string" } }, 28 }, 29 required: ["timeRangeDays"], 30 }, 31 }, 32 ], 33 }, 34 }; 35 36 const client = createAiClient({ 37 apiKey: process.env.TELYGENT_API_KEY, 38 registry, 39 customServices: { 40 Ticket: { 41 ticket_search: async (input) => ticketService.search(input), 42 ticket_summary: async (input) => ticketService.summary(input), 43 }, 44 }, 45 });

Next steps