listSources
कभी निष्पादित नहीं होताडिस्कवरी। टाइप्ड फ़ील्ड वाले कनेक्टेड सोर्स, कैपेबिलिटी मॉड्यूल, फ़ंक्शन सिग्नेचर — एक इनपुट से तीन मोड, ताकि specs सटीक नाम उपयोग करें।
एजेंट्स के लिए — नियंत्रित डेटा टूल
SQAI एक टूल-कॉलिंग मॉडल को तीन नियंत्रित टूल के माध्यम से संरचित डेटा तक रीड-ओनली पहुँच देता है। मॉडल टाइप्ड इंटेंट लिखता है। एक कॉन्ट्रैक्ट और आपकी पॉलिसी उसे जाँचती है। एक निर्धारक इंजन उसे निष्पादित करता है। हर उत्तर एक हैश के साथ लौटता है जो उसे दोबारा चला सकता है।
Iलूप का एक चक्र
“किस क्षेत्र में कुल राजस्व सर्वाधिक था?”चरण योजना बनाता है। इंटेंट लिखता है। डेटा को कभी नहीं छूता।
{ version:"1", kind:"query", spec:{ metric:"revenue", aggregation:"sum", group_by:"region", source:"sales" } }contractहैश-पिन्ड कैपेबिलिटी कॉन्ट्रैक्टpolicyआपकी अनुमति सूचियाँ, एक्ज़ीक्यूशन से पहले जाँची गईंengineनिर्धारक, रीड-ओनली एक्ज़ीक्यूशनstatus: ok · needs_clarification · rejected · erroreast — 2,130.50 · plan_hash f87610d8afeb…okलूप से बाहर। पंक्तियाँ या मान — और वह हैश जो उन्हें दोबारा चला सकता है।
needs_clarification ↺लूप में पुनः प्रवेश। एक प्रश्न और उसके मिले उम्मीदवार — मॉडल स्पेक परिष्कृत करता है और फिर से कॉल करता है। यह कभी कोई कॉलम अनुमान नहीं लगाता।
रिजेक्टेड और एरर एक ही रिटर्न लेन से आते हैं — टाइप्ड परिणाम जो मॉडल पढ़ सकता है, न कि अपवाद जो रन को बाधित करें।
IIटूलसेट
sqai.tools() ठीक तीन टूल लौटाता है — एक जानबूझकर छोटी सतह। डिस्कवरी और ड्राई रन कभी निष्पादित नहीं होते; निष्पादन ठीक एक स्थान पर होता है।
listSourcesडिस्कवरी। टाइप्ड फ़ील्ड वाले कनेक्टेड सोर्स, कैपेबिलिटी मॉड्यूल, फ़ंक्शन सिग्नेचर — एक इनपुट से तीन मोड, ताकि specs सटीक नाम उपयोग करें।
queryDataएक versioned इनपुट — kind पर discriminated union: एक query या computation। चार outcomes, हमेशा typed, कभी throw नहीं।
explainQueryकिसी intent को बिना चलाए resolve और validate करता है। मॉडल इसे clarifications debug करने के लिए उपयोग करता है; आप इसे plan preview करने के लिए।
यह सेट सीधे generateText या streamText में जाता है — typed, बिना किसी cast के assignable। Vercel AI SDK सेटअप →
IIIएरर कॉन्ट्रैक्ट
एक exception एजेंट रन को रोक देता है। इसलिए यहाँ कुछ भी throw नहीं होता: अस्पष्टता, अस्वीकृति, और विफलता — सब typed statuses के रूप में वापस आते हैं जिन्हें मॉडल अपने step budget के भीतर पढ़ और सुधार सकता है।
retryable transient वाले चिह्नित करता है — network_error · timeout · rate_limited · service_unavailable
queryData — चार outcomes
okपरिणाम: rows या value, provenance hashes, घोषित truncation।plan_hash · invocation_hash · computation_hash · truncatedneeds_clarificationintent अस्पष्ट था। एक प्रश्न और candidates — कभी अनुमान नहीं।question · candidates · explanationrejectedresolver ने intent अस्वीकार किया। कुछ execute नहीं हुआ।rejection_reason · candidates · explanationerrorएक stable code के साथ structured विफलता — मॉडल इसे पढ़कर समायोजन करता है।code · message · retryable · nearest_matches?हर branch डेटा है। लूप अपनी बारी बनाए रखता है।
सिद्धांत
नीति कोड में · किसी tool इनपुट में policy फ़ील्ड नहीं · केवल संकुचन
IVसिद्धांत, व्यवहार में
उद्योग ने यह production में सीखा — एक autonomous coding agent ने एक live database कुख्यात रूप से हटा दिया। SQAI का उत्तर structural है, behavioral नहीं: exposed surface निर्माण से ही read-only है। Write और non-deterministic श्रेणियाँ कभी इसमें generate नहीं होतीं, और कोई flag, policy, या मॉडल इनपुट उन्हें वापस चालू नहीं करता।
Vवायरिंग
एक package client को tools में wrap करता है। Sources पहली call पर lazily connect होते हैं; पहला computation runtime एक बार provision करता है, फिर warm रहता है — 0.83 ms मापा गया।
import { generateText } from "ai";
import { createSQAI } from "@thyn-ai/sqai-ai-sdk";
const sqai = createSQAI({
sources: [{ data: "./data/sales.csv", name: "sales" }],
});
const { text, steps } = await generateText({
model, // any AI SDK model
tools: sqai.tools(), // listSources · queryData · explainQuery
prompt: "Which region had the highest total revenue?",
});केवल server-side — Next.js पर Node runtime रखें, Edge नहीं।
मॉडल तक क्या पहुँचता है
Truncation हमेशा घोषित होती है — truncated: true, returned_rows < total_rows। कभी मौन नहीं। पूर्ण परिणाम application code में result_id द्वारा retrievable रहते हैं।
VIएजेंटिक विश्लेषण
Agentic analytics ज्ञात तरीकों से विफल होता है: malformed tool calls, मॉडल का स्वयं अंकगणित करना, प्रशंसनीय संख्याएँ जिन्हें कोई सत्यापित नहीं कर सकता। हर एक का उत्तर structural है, बेहतर prompt से नहीं।
एक versioned इनपुट, कुछ भी चलने से पहले validated। Malformed या अस्पष्ट intent एक typed status लौटाता है — loop crash होने की बजाय जारी रहता है।
यहाँ नहीं। engine compute करता है। 16 quantitative प्रश्नों के सेट पर, वही मॉडल 0/16 से 16/16 हो गया जब engine ने computing की।
हर उत्तर अपना hash लेकर आता है। उसी intent को उसी data पर replay करें और hash मेल खाता है — TypeScript और Python में byte-identical।
एक loop latency को गुणित करता है। Query plane in-process sub-millisecond पर चलता है; warm compute 0.83 ms मापा गया।
VIIप्रश्न
SQL फ़िल्टर न करें — generate ही न करें। Sources को createSQAI() से connect करें और मॉडल को sqai.tools() दें: वह जिस surface तक पहुँचता है वह निर्माण से ही 4,574 read-only capabilities और आपके sources हैं, कोई write path नहीं। ब्लॉक करने के लिए कोई write category नहीं है, और कोई मॉडल इनपुट नहीं जो उसे पुनः सक्षम करे।
queryData, needs_clarification के साथ एक प्रश्न और उसे मिले संभावित फ़ील्ड लौटाता है। यह कभी कोई कॉलम अनुमान नहीं लगाता। मॉडल प्रश्न का उत्तर देता है और पुनः कॉल करता है — लूप का एक और चक्र।
नहीं। हर विफलता एक संरचित परिणाम है — एक स्थिर कोड, एक संदेश, और एक retryable फ़्लैग के साथ। अस्पष्टता, अस्वीकृति, नीति-निषेध, और क्षणिक त्रुटियाँ — सभी डेटा के रूप में लौटती हैं जिसे मॉडल पढ़ सकता है।
नहीं। allowedSources, allowedFields और allowedFunctions कोड में रहते हैं — createSQAI() के समय निर्धारित और निष्पादन से पहले जाँचे जाते हैं। किसी भी टूल के input schema में कोई policy फ़ील्ड नहीं है; किसी निषिद्ध क्षमता का नाम लेने पर एक संरचित policy_denied त्रुटि मिलती है।
हाँ — @thyn-ai/sqai-ai-sdk तीनों टूल को generateText और streamText के लिए एक typed tool set के रूप में प्रदान करता है, जिसमें ai ^7.0.0 और zod ^4.0.0 peer dependencies हैं, Node 20 या उससे नया, server-side। अंतर्निहित क्लाइंट वही SDK है जिसे आप किसी भी एजेंट लूप में जोड़ सकते हैं।