@deepagents/text2sql 0.3.0 → 0.3.1
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 +7 -10
- package/dist/index.js.map +2 -2
- package/dist/lib/adapters/adapter.d.ts +5 -0
- package/dist/lib/adapters/adapter.d.ts.map +1 -1
- package/dist/lib/adapters/postgres/index.js +6 -0
- package/dist/lib/adapters/postgres/index.js.map +2 -2
- package/dist/lib/adapters/postgres/postgres.d.ts +1 -0
- package/dist/lib/adapters/postgres/postgres.d.ts.map +1 -1
- package/dist/lib/adapters/sqlite/index.js +4 -0
- package/dist/lib/adapters/sqlite/index.js.map +2 -2
- package/dist/lib/adapters/sqlite/sqlite.d.ts +1 -0
- package/dist/lib/adapters/sqlite/sqlite.d.ts.map +1 -1
- package/dist/lib/adapters/sqlserver/index.js +6 -0
- package/dist/lib/adapters/sqlserver/index.js.map +2 -2
- package/dist/lib/adapters/sqlserver/sqlserver.d.ts +1 -0
- package/dist/lib/adapters/sqlserver/sqlserver.d.ts.map +1 -1
- package/dist/lib/agents/text2sql.agent.d.ts.map +1 -1
- package/dist/lib/teach/teachings.d.ts.map +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -566,14 +566,14 @@ var tools = {
|
|
|
566
566
|
limit: z2.number().min(1).max(10).default(3).optional().describe("Number of rows to sample (1-10, default 3).")
|
|
567
567
|
}),
|
|
568
568
|
execute: ({ tableName, columns, limit = 3 }, options) => {
|
|
569
|
-
const sanitize = (name) => name.replace(/[^a-zA-Z0-9_.]/g, "");
|
|
570
|
-
const safeTable = sanitize(tableName);
|
|
571
|
-
const columnList = columns?.length ? columns.map(sanitize).join(", ") : "*";
|
|
572
569
|
const safeLimit = Math.min(Math.max(1, limit), 10);
|
|
573
570
|
const state = toState(options);
|
|
574
|
-
|
|
575
|
-
|
|
571
|
+
const sql = state.adapter.buildSampleRowsQuery(
|
|
572
|
+
tableName,
|
|
573
|
+
columns,
|
|
574
|
+
safeLimit
|
|
576
575
|
);
|
|
576
|
+
return state.adapter.execute(sql);
|
|
577
577
|
}
|
|
578
578
|
}),
|
|
579
579
|
db_query: tool({
|
|
@@ -1011,7 +1011,8 @@ var teachings_default = [
|
|
|
1011
1011
|
}),
|
|
1012
1012
|
guardrail({
|
|
1013
1013
|
rule: "Do not return oversized raw result sets.",
|
|
1014
|
-
action: "Keep raw
|
|
1014
|
+
action: "Keep raw limit strictly to ~100 rows even if users request more or coearced by hints.",
|
|
1015
|
+
reason: "Browser will time out or crash on huge datasets. Data overload harms usability."
|
|
1015
1016
|
}),
|
|
1016
1017
|
guardrail({
|
|
1017
1018
|
rule: "Prevent cartesian or guesswork joins.",
|
|
@@ -1042,10 +1043,6 @@ var teachings_default = [
|
|
|
1042
1043
|
prefer: "Summaries should be concise, business-friendly, highlight key comparisons, and add a short helpful follow-up when useful."
|
|
1043
1044
|
}),
|
|
1044
1045
|
// Tool usage constraints
|
|
1045
|
-
guardrail({
|
|
1046
|
-
rule: "Never output more than 100 rows of raw data.",
|
|
1047
|
-
action: "Use aggregation or pagination otherwise."
|
|
1048
|
-
}),
|
|
1049
1046
|
guardrail({
|
|
1050
1047
|
rule: "You must validate your query before final execution.",
|
|
1051
1048
|
action: "Follow the pattern: Draft Query \u2192 `validate_query` \u2192 Fix (if needed) \u2192 `db_query`."
|
package/dist/index.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/lib/agents/suggestions.agents.ts", "../src/lib/agents/text2sql.agent.ts", "../src/lib/teach/xml.ts", "../src/lib/teach/teachables.ts", "../src/lib/memory/memory.prompt.ts", "../src/lib/file-cache.ts", "../src/lib/history/history.ts", "../src/lib/history/sqlite.history.ts", "../src/lib/history/history.sqlite.sql", "../src/lib/history/memory.history.ts", "../src/lib/memory/sqlite.store.ts", "../src/lib/memory/store.sqlite.sql", "../src/lib/memory/store.ts", "../src/lib/memory/memory.store.ts", "../src/lib/sql.ts", "../src/lib/agents/explainer.agent.ts", "../src/lib/teach/teachings.ts", "../src/index.ts"],
|
|
4
|
-
"sourcesContent": ["import { groq } from '@ai-sdk/groq';\nimport dedent from 'dedent';\nimport z from 'zod';\n\nimport { agent, thirdPersonPrompt } from '@deepagents/agent';\n\nimport type { Introspection } from '../adapters/adapter.ts';\nimport { databaseSchemaPrompt } from '../prompt.ts';\n\ntype SuggestionsAgentContext = {\n context?: string;\n adapterInfo?: string;\n};\ntype SuggestionsAgentOutput = {\n suggestions: {\n question: string;\n sql: string;\n businessValue: string;\n }[];\n};\n\nexport const suggestionsAgent = agent<\n SuggestionsAgentOutput,\n SuggestionsAgentContext\n>({\n name: 'text2sql-suggestions',\n model: groq('openai/gpt-oss-20b'),\n output: z.object({\n suggestions: z\n .array(\n z.object({\n question: z\n .string()\n .describe('A complex, high-impact business question.'),\n sql: z\n .string()\n .describe('The SQL statement needed to answer the question.'),\n businessValue: z\n .string()\n .describe('Why the question matters to stakeholders.'),\n }),\n )\n .min(1)\n .max(5)\n .describe('A set of up to two advanced question + SQL pairs.'),\n }),\n prompt: (state) => {\n return dedent`\n ${thirdPersonPrompt()}\n\n <identity>\n You are a senior analytics strategist who proposes ambitious business questions\n and drafts the SQL needed to answer them. You specialize in identifying ideas\n that combine multiple tables, apply segmentation or time analysis, and surface\n metrics that drive executive decisions.\n </identity>\n\n\n <instructions>\n - Recommend one or two UNIQUE questions that go beyond simple counts or listings.\n - Favor questions that require joins, aggregates, time comparisons, cohort analysis,\n or window functions.\n - For each question, explain the business reason stakeholders care about it.\n - Provide the complete SQL query that could answer the question in the given schema.\n - Keep result sets scoped with LIMIT clauses (max 50 rows) when returning raw rows.\n - Ensure table/column names match the provided schema exactly.\n - Use columns marked [LowCardinality: ...] to identify meaningful categorical filters or segmentations.\n - Leverage table [rows / size] hints to determine whether to aggregate (large tables) or inspect detailed data (tiny tables).\n - Reference PK/Indexed annotations and the Indexes list to recommend queries that use efficient join/filter paths.\n - Column annotations may expose ranges/null percentages\u2014use them to suggest realistic thresholds or quality checks.\n - Consult <relationship_examples> to anchor your recommendations in the actual join paths between tables.\n - Output only information grounded in the schema/context provided.\n </instructions>\n\n <response-format>\n Return valid JSON that satisfies the defined output schema.\n </response-format>\n `;\n },\n});\n", "import { groq } from '@ai-sdk/groq';\nimport { type Tool, tool } from 'ai';\nimport z from 'zod';\n\nimport {\n type StepBackExample,\n agent,\n stepBackPrompt,\n toState,\n} from '@deepagents/agent';\nimport { scratchpad_tool } from '@deepagents/toolbox';\n\nimport type { Adapter } from '../adapters/adapter.ts';\nimport memoryPrompt from '../memory/memory.prompt.ts';\nimport type { TeachablesStore } from '../memory/store.ts';\nimport type { GeneratedTeachable } from '../teach/teachables.ts';\n\nexport type RenderingTools = Record<string, Tool<unknown, never>>;\n\nconst tools = {\n validate_query: tool({\n description: `Validate SQL query syntax before execution. Use this to check if your SQL is valid before running db_query. This helps catch errors early and allows you to correct the query if needed.`,\n inputSchema: z.object({\n sql: z.string().describe('The SQL query to validate.'),\n }),\n execute: async ({ sql }, options) => {\n const state = toState<{ adapter: Adapter }>(options);\n const result = await state.adapter.validate(sql);\n if (typeof result === 'string') {\n return `Validation Error: ${result}`;\n }\n return 'Query is valid.';\n },\n }),\n get_sample_rows: tool({\n description: `Sample rows from a table to understand data formatting, codes, and value patterns. Use BEFORE writing queries when:\n- Column types in schema don't reveal format (e.g., \"status\" could be 'active'/'inactive' or 1/0)\n- Date/time formats are unclear (ISO, Unix timestamp, locale-specific)\n- You need to understand lookup table codes or enum values\n- Column names are ambiguous (e.g., \"type\", \"category\", \"code\")`,\n inputSchema: z.object({\n tableName: z.string().describe('The name of the table to sample.'),\n columns: z\n .array(z.string())\n .optional()\n .describe(\n 'Specific columns to sample. If omitted, samples all columns.',\n ),\n limit: z\n .number()\n .min(1)\n .max(10)\n .default(3)\n .optional()\n .describe('Number of rows to sample (1-10, default 3).'),\n }),\n execute: ({ tableName, columns, limit = 3 }, options) => {\n const sanitize = (name: string) => name.replace(/[^a-zA-Z0-9_.]/g, '');\n const safeTable = sanitize(tableName);\n const columnList = columns?.length\n ? columns.map(sanitize).join(', ')\n : '*';\n const safeLimit = Math.min(Math.max(1, limit), 10);\n\n const state = toState<{ adapter: Adapter }>(options);\n return state.adapter.execute(\n `SELECT ${columnList} FROM ${safeTable} LIMIT ${safeLimit}`,\n );\n },\n }),\n db_query: tool({\n description: `Internal tool to fetch data from the store's database. Write a SQL query to retrieve the information needed to answer the user's question. The results will be returned as data that you can then present to the user in natural language.`,\n inputSchema: z.object({\n reasoning: z\n .string()\n .describe(\n 'Your reasoning for why this SQL query is relevant to the user request.',\n ),\n sql: z\n .string()\n .min(1, { message: 'SQL query cannot be empty.' })\n .refine(\n (sql) =>\n sql.trim().toUpperCase().startsWith('SELECT') ||\n sql.trim().toUpperCase().startsWith('WITH'),\n {\n message: 'Only read-only SELECT or WITH queries are allowed.',\n },\n )\n .describe('The SQL query to execute against the database.'),\n }),\n execute: ({ sql }, options) => {\n const state = toState<{ adapter: Adapter }>(options);\n return state.adapter.execute(sql);\n },\n }),\n scratchpad: scratchpad_tool,\n};\n\nconst userMemoryTypes = [\n 'identity',\n 'alias',\n 'preference',\n 'context',\n 'correction',\n] as const;\n\nconst userMemorySchema = z.discriminatedUnion('type', [\n z.object({\n type: z.literal('identity'),\n description: z.string().describe(\"The user's identity: role or/and name\"),\n }),\n z.object({\n type: z.literal('alias'),\n term: z.string().describe('The term the user uses'),\n meaning: z.string().describe('What the user means by this term'),\n }),\n z.object({\n type: z.literal('preference'),\n aspect: z\n .string()\n .describe('What aspect of output this preference applies to'),\n value: z.string().describe(\"The user's preference\"),\n }),\n z.object({\n type: z.literal('context'),\n description: z.string().describe('What the user is currently working on'),\n }),\n z.object({\n type: z.literal('correction'),\n subject: z.string().describe('What was misunderstood'),\n clarification: z.string().describe('The correct understanding'),\n }),\n]);\n\nexport const memoryTools = {\n remember_memory: tool({\n description:\n 'Store something about the user for future conversations. Use silently when user shares facts, preferences, vocabulary, corrections, or context.',\n inputSchema: z.object({ memory: userMemorySchema }),\n execute: async ({ memory }, options) => {\n const state = toState<{ memory: TeachablesStore; userId: string }>(\n options,\n );\n await state.memory.remember(state.userId, memory as GeneratedTeachable);\n return 'Remembered.';\n },\n }),\n forget_memory: tool({\n description:\n 'Forget a specific memory. Use when user asks to remove something.',\n inputSchema: z.object({\n id: z.string().describe('The ID of the teachable to forget'),\n }),\n execute: async ({ id }, options) => {\n const state = toState<{ memory: TeachablesStore }>(options);\n await state.memory.forget(id);\n return 'Forgotten.';\n },\n }),\n recall_memory: tool({\n description:\n 'List stored memories for the current user. Use when user asks what you remember about them or wants to see their stored preferences.',\n inputSchema: z.object({\n type: z\n .enum(userMemoryTypes)\n .optional()\n .catch(undefined)\n .describe('Optional: filter by memory type'),\n }),\n execute: async ({ type }, options) => {\n const state = toState<{ memory: TeachablesStore; userId: string }>(\n options,\n );\n const memories = await state.memory.recall(state.userId, type);\n if (memories.length === 0) {\n return type ? `No ${type} memories stored.` : 'No memories stored.';\n }\n return memories.map((m) => ({\n id: m.id,\n type: m.type,\n data: m.data,\n createdAt: m.createdAt,\n }));\n },\n }),\n update_memory: tool({\n description:\n 'Update an existing memory. Use when user wants to modify something you previously stored.',\n inputSchema: z.object({\n memory: userMemorySchema,\n id: z.string().describe('The ID of the memory to update'),\n }),\n execute: async ({ id, memory }, options) => {\n const state = toState<{ memory: TeachablesStore }>(options);\n await state.memory.update(id, memory as GeneratedTeachable);\n return 'Updated.';\n },\n }),\n};\n\nconst SQL_STEP_BACK_EXAMPLES: StepBackExample[] = [\n {\n originalQuestion: 'Who are our top 5 customers by spending?',\n stepBackQuestion:\n 'What are the SQL principles for ranking and aggregation queries?',\n stepBackAnswer:\n 'Ranking queries require: 1) Aggregation functions (SUM, COUNT, AVG) grouped by the entity to rank, 2) JOINs to connect related data across tables (e.g., Customer to Invoice), 3) ORDER BY to sort by the aggregated metric, 4) LIMIT to restrict to top N results. For customer spending, join Customer and Invoice tables, sum invoice totals, group by customer identifier, order by total descending.',\n finalAnswer:\n 'SELECT c.FirstName, c.LastName, SUM(i.Total) as total_spent FROM Customer c JOIN Invoice i ON c.CustomerId = i.CustomerId GROUP BY c.CustomerId ORDER BY total_spent DESC LIMIT 5',\n },\n {\n originalQuestion: 'Show me sales by month for 2013',\n stepBackQuestion:\n 'What are the principles of time-based grouping and aggregation in SQL?',\n stepBackAnswer:\n 'Time-based queries require: 1) Date extraction functions (e.g., DATE_TRUNC, strftime, YEAR/FORMAT) to bucket timestamps, 2) WHERE clauses to filter the date range, 3) GROUP BY the derived period, 4) Aggregations such as SUM for revenue and COUNT for transactions, 5) ORDER BY the period chronologically.',\n finalAnswer:\n \"SELECT date_trunc('month', InvoiceDate) as month, COUNT(*) as sales_count, SUM(Total) as revenue FROM Invoice WHERE EXTRACT(year FROM InvoiceDate) = 2013 GROUP BY month ORDER BY month -- replace date_trunc/EXTRACT with your dialect's month/year helpers\",\n },\n {\n originalQuestion: 'What are the best-selling tracks by genre?',\n stepBackQuestion:\n 'What are the SQL principles for multi-dimensional aggregation with categories?',\n stepBackAnswer:\n 'Multi-dimensional queries require: 1) Multiple JOINs to connect entities through foreign key relationships (Genre \u2192 Track \u2192 InvoiceLine), 2) GROUP BY all categorical dimensions you want to analyze (GenreId, TrackId), 3) Aggregation at the intersection of these dimensions (COUNT of sales per track per genre), 4) Proper table aliasing for query readability, 5) Understanding the data model relationships (which tables link to which).',\n finalAnswer:\n 'SELECT g.Name as genre, t.Name as track, COUNT(*) as times_sold FROM Genre g JOIN Track t ON g.GenreId = t.GenreId JOIN InvoiceLine il ON t.TrackId = il.TrackId GROUP BY g.GenreId, t.TrackId ORDER BY times_sold DESC LIMIT 10',\n },\n];\n\nexport const sqlQueryAgent = agent({\n name: 'text2sql',\n model: groq('openai/gpt-oss-20b'),\n tools,\n // output: z.object({\n // sql: z\n // .string()\n // .describe('The SQL query generated to answer the user question.'),\n // }),\n prompt: (state) => {\n return `\n <agent>\n <name>Freya</name>\n <role>You are an expert SQL query generator, answering business questions with accurate queries.</role>\n <tone>Your tone should be concise and business-friendly.</tone>\n </agent>\n ${state?.teachings || ''}\n ${state?.introspection || ''}\n <output>SQL query that can run directly without prose whatsoever</output>\n `;\n },\n});\n\n/**\n * An agent that does Table Augmented Generation for Text-to-SQL tasks.\n */\nexport const t_a_g = agent<\n { sql: string },\n {\n // FIXME: this should not be here after creating the context package\n introspection: string;\n teachings: string;\n memory?: TeachablesStore;\n userId?: string;\n }\n>({\n model: groq('openai/gpt-oss-20b'),\n tools,\n name: 'text2sql',\n prompt: (state) => {\n const hasMemory = !!state?.memory;\n\n return `\n\n ${state?.teachings || ''}\n ${state?.introspection || ''}\n\n ${hasMemory ? memoryPrompt : ''}\n `;\n },\n});\n", "export function wrapBlock(tag: string, children: string[]): string {\n const content = children\n .filter((child): child is string => Boolean(child))\n .join('\\n');\n if (!content) {\n return '';\n }\n return `<${tag}>\\n${indentBlock(content, 2)}\\n</${tag}>`;\n}\n\nexport function list(tag: string, values: string[], childTag: string): string {\n if (!values.length) {\n return '';\n }\n const children = values.map((value) => leaf(childTag, value)).join('\\n');\n return `<${tag}>\\n${indentBlock(children, 2)}\\n</${tag}>`;\n}\n\nexport function leaf(tag: string, value: string): string {\n const safe = escapeXml(value);\n if (safe.includes('\\n')) {\n return `<${tag}>\\n${indentBlock(safe, 2)}\\n</${tag}>`;\n }\n return `<${tag}>${safe}</${tag}>`;\n}\n\nexport function indentBlock(text: string, spaces: number): string {\n if (!text.trim()) {\n return '';\n }\n const padding = ' '.repeat(spaces);\n return text\n .split('\\n')\n .map((line) => (line.length ? padding + line : padding))\n .join('\\n');\n}\n\nexport function escapeXml(value: string): string {\n if (value == null) {\n return '';\n }\n return value\n .replaceAll(/&/g, '&')\n .replaceAll(/</g, '<')\n .replaceAll(/>/g, '>')\n .replaceAll(/\"/g, '"')\n .replaceAll(/'/g, ''');\n}\n", "import { indentBlock, leaf, list, wrapBlock } from './xml.ts';\n\nexport interface Teachables {\n type:\n | 'term'\n | 'hint'\n | 'guardrail'\n | 'explain'\n | 'example'\n | 'clarification'\n | 'workflow'\n | 'quirk'\n | 'styleGuide'\n | 'analogy'\n | 'glossary'\n | 'user_profile'\n // User-specific teachable types\n | 'identity'\n | 'persona'\n | 'alias'\n | 'preference'\n | 'context'\n | 'correction';\n format: () => string;\n}\nexport type GeneratedTeachable =\n | { type: 'term'; name: string; definition: string }\n | { type: 'hint'; text: string }\n | { type: 'guardrail'; rule: string; reason?: string; action?: string }\n | {\n type: 'explain';\n concept: string;\n explanation: string;\n therefore?: string;\n }\n | { type: 'example'; question: string; answer: string; note?: string }\n | { type: 'clarification'; when: string; ask: string; reason: string }\n | {\n type: 'workflow';\n task: string;\n steps: string[];\n triggers?: string[];\n notes?: string;\n }\n | { type: 'quirk'; issue: string; workaround: string }\n | { type: 'styleGuide'; prefer: string; never?: string; always?: string }\n | {\n type: 'analogy';\n concept: string[];\n relationship: string;\n insight?: string;\n therefore?: string;\n pitfall?: string;\n }\n | { type: 'glossary'; entries: Record<string, string> }\n // User-specific teachable types\n | { type: 'identity'; name?: string; role?: string }\n | { type: 'persona'; name: string; role: string; tone: string }\n | { type: 'alias'; term: string; meaning: string }\n | { type: 'preference'; aspect: string; value: string }\n | { type: 'context'; description: string }\n | { type: 'correction'; subject: string; clarification: string };\n\n/**\n * Teach the system domain-specific vocabulary and business terminology.\n *\n * Use this to define simple, direct mappings between business terms and their meanings.\n * The system will understand these terms when users mention them in queries.\n *\n * @param name - The business term or acronym to define\n * @param definition - What the term means in your domain\n *\n * @example\n * // Logistics/Transportation dataset\n * term(\"deadhead miles\", \"distance driven with empty truck between deliveries\")\n * term(\"dwell time\", \"total time a truck spends at a loading dock or warehouse\")\n * term(\"LTL\", \"less than truckload - shipment that doesn't fill entire truck\")\n *\n * @example\n * // Education/University dataset\n * term(\"matriculation\", \"students who completed enrollment and started classes\")\n * term(\"DFW rate\", \"percentage of students receiving D, F, or Withdrawal in a course\")\n * term(\"cohort\", \"group of students who entered the same semester or academic year\")\n *\n * @example\n * // Finance/Banking dataset\n * term(\"NPL\", \"non-performing loan - loan past due 90+ days\")\n * term(\"basis points\", \"one hundredth of a percentage point (1% = 100 bps)\")\n * term(\"AUM\", \"assets under management - total market value of client investments\")\n */\nexport function term(name: string, definition: string): Teachables {\n return {\n type: 'term',\n format: () =>\n wrapBlock('term', [leaf('name', name), leaf('definition', definition)]),\n };\n}\n\n/**\n * Teach the system behavioral rules and constraints that should always apply.\n *\n * Use this for business logic, data quality rules, or query preferences that should\n * be automatically applied to all relevant queries. Hints are injected as constraints\n * in the system prompt.\n *\n * @param text - The rule or constraint to follow (use imperative language)\n *\n * @example\n * // Manufacturing/Supply Chain dataset\n * hint(\"Always exclude work orders with status = 'simulation' from production metrics\")\n * hint(\"When calculating OEE (overall equipment effectiveness), only count scheduled production time\")\n * hint(\"Defect rates should be calculated per batch, not per individual unit, for consistency\")\n *\n * @example\n * // Real Estate/Property dataset\n * hint(\"Never include properties with listing_status = 'draft' in market analysis\")\n * hint(\"Always filter out duplicate MLS listings - use the earliest listing_date for each property_id\")\n * hint(\"Square footage comparisons must specify if including or excluding basement/garage\")\n *\n * @example\n * // Social Media/Content Platform dataset\n * hint(\"Engagement metrics should exclude bot accounts identified by is_verified_human = false\")\n * hint(\"View counts reset daily - always use cumulative_views for historical analysis\")\n * hint(\"Default content filters to published_status = 'public' unless analyzing drafts\")\n */\nexport function hint(text: string): Teachables {\n return {\n type: 'hint',\n format: () => leaf('hint', text),\n };\n}\n\n/**\n * Define hard guardrails, safety rules, and compliance boundaries the system must enforce.\n *\n * Use this for \"never do\" rules, sensitive data handling, and required behaviors when\n * certain conditions occur. Guardrails should be explicit and action oriented.\n *\n * @param input.rule - The guardrail or restriction to enforce\n * @param input.reason - Why this guardrail exists (compliance, security, performance)\n * @param input.action - What to do when this guardrail is triggered (block, ask, sanitize)\n *\n * @example\n * // Healthcare dataset\n * guardrail({\n * rule: \"Never return PHI like SSN, MRN, or full address in query results\",\n * reason: \"HIPAA compliance\",\n * action: \"If asked, state that identifiable patient data cannot be shared; offer de-identified aggregates instead\"\n * })\n *\n * @example\n * // Finance dataset\n * guardrail({\n * rule: \"Block any query exposing employee-level compensation by name\",\n * reason: \"Confidential payroll data\",\n * action: \"Provide ranges grouped by department or level instead of individual salaries\"\n * })\n *\n * @example\n * // E-commerce dataset\n * guardrail({\n * rule: \"Warn when a query would scan more than 10 million rows; require a narrower date range\",\n * reason: \"Performance and cost control\",\n * action: \"Ask the user to add filters (recent timeframe, specific categories) before proceeding\"\n * })\n */\nexport function guardrail(input: {\n rule: string;\n reason?: string;\n action?: string;\n}): Teachables {\n const { rule, reason, action } = input;\n return {\n type: 'guardrail',\n format: () =>\n wrapBlock('guardrail', [\n leaf('rule', rule),\n reason ? leaf('reason', reason) : '',\n action ? leaf('action', action) : '',\n ]),\n };\n}\n\n/**\n * Teach the system a rich understanding of a single concept using metaphors and explanations.\n *\n * Use this when a simple term definition isn't enough - when you need to convey deeper\n * understanding about how to think about and calculate a metric or concept.\n *\n * @param input.concept - The concept being explained\n * @param input.explanation - A metaphor or detailed explanation (often using real-world comparisons)\n * @param input.therefore - Optional actionable instruction based on this understanding\n *\n * @example\n * // Gaming/Entertainment dataset\n * explain({\n * concept: \"daily active users to monthly active users ratio\",\n * explanation: \"like measuring how many club members visit daily vs just once a month - shows stickiness\",\n * therefore: \"Calculate as DAU / MAU, where higher ratio (closer to 1) means more engaged user base\"\n * })\n *\n * @example\n * // HR/Employee Management dataset\n * explain({\n * concept: \"time to fill\",\n * explanation: \"like measuring how long a house sits on the market - from posting job to accepting offer\",\n * therefore: \"Calculate as days between job_posted_date and offer_accepted_date, exclude cancelled requisitions\"\n * })\n *\n * @example\n * // Telecommunications dataset\n * explain({\n * concept: \"network congestion ratio\",\n * explanation: \"like rush hour traffic density - measures actual usage vs total capacity at peak times\",\n * therefore: \"Calculate as (peak_hour_bandwidth_used / total_bandwidth_capacity) during busiest hour of day\"\n * })\n */\nexport function explain(input: {\n concept: string;\n explanation: string;\n therefore?: string;\n}): Teachables {\n const { concept, explanation, therefore } = input;\n return {\n type: 'explain',\n format: () =>\n wrapBlock('explanation', [\n leaf('concept', concept),\n leaf('details', explanation),\n therefore ? leaf('therefore', therefore) : '',\n ]),\n };\n}\n\n/**\n * Teach the system through concrete examples of question \u2192 SQL pairs.\n *\n * Use this for few-shot learning - show the system exactly how to translate\n * specific types of questions into SQL queries. Great for establishing patterns\n * and handling domain-specific query structures.\n *\n * @param input.question - The natural language question or request\n * @param input.answer - The correct answer that responds to the question\n * @param input.note - Optional note or explanation about the example\n *\n * @example\n * // Energy/Utilities dataset\n * example({\n * question: \"show me peak demand hours for the last week\",\n * answer: \"SELECT DATE_TRUNC('hour', reading_timestamp) as hour, MAX(consumption_kwh) as peak_demand FROM meter_readings WHERE reading_timestamp >= CURRENT_DATE - INTERVAL '7 days' GROUP BY hour ORDER BY peak_demand DESC LIMIT 10\"\n * })\n *\n * @example\n * // Agriculture/Farm Management dataset\n * example({\n * question: \"what is the average yield per acre by crop type this season\",\n * answer: \"SELECT crop_type, AVG(harvest_quantity / field_acres) as yield_per_acre FROM harvests WHERE harvest_date >= '2024-01-01' GROUP BY crop_type ORDER BY yield_per_acre DESC\"\n * })\n *\n * @example\n * // Travel/Hospitality dataset\n * example({\n * question: \"show me hotel occupancy rate for this month\",\n * answer: \"SELECT hotel_name, (SUM(occupied_rooms) / SUM(total_rooms)) * 100 as occupancy_rate FROM daily_occupancy WHERE date >= DATE_TRUNC('month', CURRENT_DATE) GROUP BY hotel_id, hotel_name ORDER BY occupancy_rate DESC\",\n * note: \"Occupancy rate is a percentage - multiply by 100 for readable output\"\n * })\n */\nexport function example(input: {\n question: string;\n answer: string;\n note?: string;\n}): Teachables {\n const { question, answer, note } = input;\n return {\n type: 'example',\n format: () =>\n wrapBlock('example', [\n leaf('question', question),\n leaf('answer', answer),\n note ? leaf('note', note) : '',\n ]),\n };\n}\n\n/**\n * Teach the system when and what to ask for clarification.\n *\n * Use this to handle ambiguous terms or situations where the system should\n * proactively ask the user for more information before generating a query.\n * Makes the system more conversational and precise.\n *\n * @param input.when - The condition or trigger that should prompt clarification\n * @param input.ask - The question to ask the user\n * @param input.reason - Why this clarification is necessary (helps system understand importance)\n *\n * @example\n * // Marketing/Advertising dataset\n * clarification({\n * when: \"user asks for 'conversion rate'\",\n * ask: \"Which conversion: click-to-lead, lead-to-opportunity, or opportunity-to-customer?\",\n * reason: \"Conversion rate means different things at each funnel stage - need to specify which metric\"\n * })\n *\n * @example\n * // Food Delivery dataset\n * clarification({\n * when: \"user asks about 'delivery time'\",\n * ask: \"Do you mean estimated time at order, actual delivery time, or time from kitchen to door?\",\n * reason: \"Multiple time metrics exist - estimated vs actual impacts customer satisfaction differently\"\n * })\n *\n * @example\n * // Fitness/Gym Management dataset\n * clarification({\n * when: \"user mentions 'active members'\",\n * ask: \"Do you mean paid memberships or members who actually visited in last 30 days?\",\n * reason: \"Many paid members don't use facilities - different metrics for revenue vs utilization\"\n * })\n */\nexport function clarification(input: {\n when: string;\n ask: string;\n reason: string;\n}): Teachables {\n const { when, ask, reason } = input;\n return {\n type: 'clarification',\n format: () =>\n wrapBlock('clarification', [\n leaf('when', when),\n leaf('ask', ask),\n leaf('reason', reason),\n ]),\n };\n}\n\n/**\n * Teach the system multi-step analytical processes that can't be solved with a single query.\n *\n * Use this for complex analytical tasks that require multiple CTEs, sequential logic,\n * or specific methodologies. Workflows teach the system HOW to approach a type of analysis.\n *\n * @param input.task - Name of the analytical task\n * @param input.steps - Sequential steps to execute (can include SQL snippets or descriptions)\n * @param input.triggers - Optional phrases that should activate this workflow\n * @param input.notes - Optional additional context, warnings, or guidance\n *\n * @example\n * // Insurance dataset\n * workflow({\n * task: \"Claims Loss Ratio Analysis\",\n * triggers: [\"loss ratio\", \"claims ratio\", \"underwriting performance\"],\n * steps: [\n * \"Calculate total claims paid for each policy period\",\n * \"Calculate total premiums earned for same period\",\n * \"Compute loss ratio as (claims_paid / premiums_earned) * 100\",\n * \"Segment by policy type, geography, and underwriter\",\n * \"Identify policies with loss ratio > 100% (losing money)\",\n * \"Calculate trend over time using rolling 12-month windows\"\n * ],\n * notes: \"Use incurred date for claims, not paid date. Exclude reinsurance recoveries from claims total.\"\n * })\n *\n * @example\n * // Media/Publishing dataset\n * workflow({\n * task: \"Content Performance Funnel\",\n * triggers: [\"content funnel\", \"engagement funnel\", \"content performance\"],\n * steps: [\n * \"Count total impressions (articles shown) per content piece\",\n * \"Count click-throughs (articles opened)\",\n * \"Count scroll depth > 50% (meaningful engagement)\",\n * \"Count shares, comments, or saves (viral actions)\",\n * \"Calculate conversion rate at each funnel stage\",\n * \"Identify top-performing content by final conversion rate\"\n * ],\n * notes: \"Requires multiple event types. Join events table multiple times or use conditional aggregation.\"\n * })\n *\n * @example\n * // Sports Analytics dataset\n * workflow({\n * task: \"Player Performance Rating Calculation\",\n * triggers: [\"player rating\", \"performance score\", \"player analytics\"],\n * steps: [\n * \"Aggregate per-game stats: points, assists, rebounds, turnovers\",\n * \"Calculate efficiency metrics: shooting percentage, plus/minus\",\n * \"Normalize each metric using z-scores vs league average\",\n * \"Apply position-specific weights to each metric\",\n * \"Combine weighted scores into overall performance rating (0-100)\",\n * \"Rank players within position group and overall\"\n * ],\n * notes: \"Requires league-wide statistics for normalization. Update weights each season based on game trends.\"\n * })\n */\nexport function workflow(input: {\n task: string;\n steps: string[];\n triggers?: string[];\n notes?: string;\n}): Teachables {\n const { task, steps, triggers, notes } = input;\n return {\n type: 'workflow',\n format: () =>\n wrapBlock('workflow', [\n leaf('task', task),\n triggers?.length ? list('triggers', triggers, 'trigger') : '',\n list('steps', steps, 'step'),\n notes ? leaf('notes', notes) : '',\n ]),\n };\n}\n\n/**\n * Teach the system about data quirks, edge cases, or database-specific issues and their workarounds.\n *\n * Use this to document weird data patterns, database limitations, or special handling\n * required for specific scenarios. Helps the system navigate real-world messiness.\n *\n * @param input.issue - Description of the quirk, edge case, or problem\n * @param input.workaround - How to handle or work around this issue\n *\n * @example\n * // Government/Public Services dataset\n * quirk({\n * issue: \"Citizen IDs contain leading zeros but are stored as integers, losing the zeros\",\n * workaround: \"Always cast to VARCHAR and use LPAD(citizen_id::VARCHAR, 10, '0') to restore leading zeros\"\n * })\n *\n * @example\n * // Aviation dataset\n * quirk({\n * issue: \"Flight times crossing midnight show as negative duration (landing before takeoff)\",\n * workaround: \"Add 24 hours when calculated duration < 0: CASE WHEN duration < 0 THEN duration + INTERVAL '24 hours' ELSE duration END\"\n * })\n *\n * @example\n * // Automotive/Dealership dataset\n * quirk({\n * issue: \"VIN numbers with letter 'O' were incorrectly entered as zero '0' in legacy data\",\n * workaround: \"When searching by VIN, use REPLACE(vin, '0', 'O') or fuzzy matching to handle both cases\"\n * })\n */\nexport function quirk(input: {\n issue: string;\n workaround: string;\n}): Teachables {\n const { issue, workaround } = input;\n return {\n type: 'quirk',\n format: () =>\n wrapBlock('quirk', [\n leaf('issue', issue),\n leaf('workaround', workaround),\n ]),\n };\n}\n\n/**\n * Teach the system SQL style preferences and coding standards for generated queries.\n *\n * Use this to enforce consistent SQL formatting, naming conventions, and best practices\n * specific to your team or organization. Improves readability and maintainability.\n *\n * @param input.prefer - Preferred SQL style or pattern\n * @param input.never - Optional anti-pattern to avoid\n * @param input.always - Optional rule that must always be followed\n *\n * @example\n * // Non-profit/Charity dataset\n * styleGuide({\n * prefer: \"Use donor-centric language in column aliases: 'donor_name' not 'customer_name'\",\n * never: \"Never expose internal donor IDs in external reports - use public gift IDs\",\n * always: \"Always include fiscal year in date-based aggregations (FY starts July 1)\"\n * })\n *\n * @example\n * // Legal/Law Firm dataset\n * styleGuide({\n * prefer: \"Use billable_hours with 2 decimal precision for accurate client billing\",\n * never: \"Never include attorney_rate in queries visible to paralegals - confidential data\",\n * always: \"Always filter by matter_status = 'open' unless specifically analyzing closed cases\"\n * })\n *\n * @example\n * // Inventory/Warehouse dataset\n * styleGuide({\n * prefer: \"Use location_id in joins rather than location_name (duplicates exist across warehouses)\",\n * never: \"Never aggregate inventory without grouping by warehouse_id first\",\n * always: \"Always use inventory_on_hand - inventory_reserved for available stock calculations\"\n * })\n */\nexport function styleGuide(input: {\n prefer: string;\n never?: string;\n always?: string;\n}): Teachables {\n const { prefer, never, always } = input;\n return {\n type: 'styleGuide',\n format: () =>\n wrapBlock('style_guide', [\n leaf('prefer', prefer),\n always ? leaf('always', always) : '',\n never ? leaf('never', never) : '',\n ]),\n };\n}\n\n/**\n * Teach the system by comparing related concepts through real-world analogies.\n *\n * Use this to teach relational understanding between two concepts by drawing comparisons\n * to familiar real-world scenarios. Helps the system understand WHY concepts differ and\n * when to use each one appropriately.\n *\n * @param input.concept - Array of two related concepts to compare\n * @param input.relationship - The comparison/analogy using real-world examples\n * @param input.insight - Optional key insight the analogy reveals\n * @param input.therefore - Optional actionable instruction based on this understanding\n * @param input.pitfall - Optional common mistake to avoid\n *\n * @example\n * // E-commerce dataset\n * analogy({\n * concept: [\"cart abandonment\", \"browse abandonment\"],\n * relationship: \"Cart abandonment is like leaving items at a checkout counter, browse abandonment is like window shopping without picking anything up\",\n * insight: \"Cart abandonment shows purchase intent (added to cart), browse abandonment shows only interest\",\n * therefore: \"Prioritize cart abandonment recovery campaigns - higher conversion potential than browse\",\n * pitfall: \"Don't combine both into generic 'abandonment rate' - they need different marketing strategies\"\n * })\n *\n * @example\n * // SaaS dataset\n * analogy({\n * concept: [\"logo churn\", \"revenue churn\"],\n * relationship: \"Logo churn is like counting how many customers left the store, revenue churn is how much money walked out\",\n * insight: \"Losing 10 small customers (high logo churn) might hurt less than losing 1 enterprise customer (high revenue churn)\",\n * therefore: \"Always report both metrics - logo churn for customer satisfaction, revenue churn for financial health\",\n * pitfall: \"Don't use logo churn to predict revenue impact - customer size distribution matters\"\n * })\n *\n * @example\n * // Healthcare dataset\n * analogy({\n * concept: [\"incident\", \"prevalence\"],\n * relationship: \"Incidence is like new house sales this month, prevalence is total houses currently occupied\",\n * insight: \"Incidence measures new cases over time, prevalence measures all existing cases at a point in time\",\n * therefore: \"For tracking disease outbreaks use incidence rate, for resource planning use prevalence\",\n * pitfall: \"Don't sum incidence rates across time periods - it's a rate not a count\"\n * })\n */\nexport function analogy(input: {\n concept: string[];\n relationship: string;\n insight?: string;\n therefore?: string;\n pitfall?: string;\n}): Teachables {\n const { concept, relationship, insight, therefore, pitfall } = input;\n return {\n type: 'analogy',\n format: () =>\n wrapBlock('analogy', [\n list('concepts', concept, 'concept'),\n leaf('relationship', relationship),\n insight ? leaf('insight', insight) : '',\n therefore ? leaf('therefore', therefore) : '',\n pitfall ? leaf('pitfall', pitfall) : '',\n ]),\n };\n}\n\n/**\n * Map business terms directly to SQL expressions or fragments.\n *\n * Use this to teach the system how to CALCULATE or QUERY specific business concepts.\n * The system will substitute these SQL patterns when users mention the term.\n *\n * **Glossary vs Alias:**\n * - `alias` = user vocabulary \u2192 table/column name (\"the big table\" \u2192 \"orders table\")\n * - `glossary` = business term \u2192 SQL expression (\"revenue\" \u2192 \"SUM(orders.total_amount)\")\n *\n * In short: alias renames, glossary computes.\n *\n * @param entries - Record mapping business terms to their SQL expressions\n *\n * @example\n * glossary({\n * \"revenue\": \"SUM(orders.total_amount)\",\n * \"average order value\": \"AVG(orders.total_amount)\",\n * \"active user\": \"last_login > NOW() - INTERVAL '30 days'\",\n * \"churned\": \"status = 'churned'\",\n * \"power user\": \"order_count > 10\",\n * \"net revenue\": \"SUM(orders.total_amount) - SUM(refunds.amount)\",\n * })\n */\nexport function glossary(entries: Record<string, string>): Teachables {\n return {\n type: 'glossary',\n format: () =>\n wrapBlock(\n 'glossary',\n Object.entries(entries).map(([term, sql]) =>\n wrapBlock('entry', [leaf('term', term), leaf('sql', sql)]),\n ),\n ),\n };\n}\n\n// =============================================================================\n// User-Specific Teachable Types\n// =============================================================================\n\n/**\n * Define the user's identity including name and/or role.\n *\n * Use this to capture who the user is and what lens they view data through.\n * Helps tailor explanations, terminology, and focus areas.\n *\n * @param input.name - The user's name (optional)\n * @param input.role - The user's role or position (optional)\n *\n * @example\n * identity({ name: \"John\", role: \"VP of Sales\" })\n * identity({ role: \"Data analyst in the marketing team\" })\n * identity({ name: \"Sarah\" })\n * identity({ role: \"Finance manager focused on cost optimization\" })\n */\nexport function identity(input: { name?: string; role?: string }): Teachables {\n const { name, role } = input;\n return {\n type: 'identity',\n format: () =>\n wrapBlock('identity', [\n name ? leaf('name', name) : '',\n role ? leaf('role', role) : '',\n ]),\n };\n}\n\n/**\n * Define an AI persona with a name, role, and communication tone.\n *\n * Use this to customize the assistant's personality and how it communicates.\n * The persona influences the style and approach of responses.\n *\n * @param input.name - The persona's name\n * @param input.role - The persona's role or expertise\n * @param input.tone - The communication style (e.g., friendly, professional, concise)\n *\n * @example\n * persona({ name: \"DataBot\", role: \"SQL Expert\", tone: \"friendly and encouraging\" })\n * persona({ name: \"QueryMaster\", role: \"Database Analyst\", tone: \"professional and concise\" })\n * persona({ name: \"SQLHelper\", role: \"Data Assistant\", tone: \"casual and approachable\" })\n */\nexport function persona(input: {\n name: string;\n role: string;\n tone: string;\n}): Teachables {\n const { name, role, tone } = input;\n return {\n type: 'persona',\n format: () =>\n wrapBlock('persona', [\n leaf('name', name),\n leaf('role', role),\n leaf('tone', tone),\n ]),\n };\n}\n\n/**\n * Define user-specific term meanings and vocabulary.\n *\n * Use this when the user has their own definitions for terms that might\n * differ from standard or domain definitions. Like `term()` but personal.\n *\n * @param termName - The term the user uses\n * @param meaning - What the user means by this term\n *\n * @example\n * alias(\"revenue\", \"gross revenue before deductions, not net\")\n * alias(\"active users\", \"users who logged in within the last 30 days\")\n * alias(\"the big table\", \"the orders table\")\n * alias(\"Q4\", \"October through December, not fiscal Q4\")\n */\nexport function alias(termName: string, meaning: string): Teachables {\n return {\n type: 'alias',\n format: () =>\n wrapBlock('alias', [leaf('term', termName), leaf('meaning', meaning)]),\n };\n}\n\n/**\n * Define how the user prefers results presented.\n *\n * Use this to capture output formatting, style, and behavioral preferences\n * that should apply to all interactions with this user.\n *\n * @param aspect - What aspect of output this preference applies to\n * @param value - The user's preference\n *\n * @example\n * preference(\"date format\", \"YYYY-MM-DD\")\n * preference(\"output style\", \"tables over charts unless trend data\")\n * preference(\"detail level\", \"always show the SQL query in responses\")\n * preference(\"row limit\", \"default to 50 rows unless I ask for more\")\n * preference(\"explanation style\", \"brief and to the point\")\n */\nexport function preference(aspect: string, value: string): Teachables {\n return {\n type: 'preference',\n format: () =>\n wrapBlock('preference', [leaf('aspect', aspect), leaf('value', value)]),\n };\n}\n\n/**\n * Define the user's current working focus or project.\n *\n * Use this to capture temporary context that helps inform defaults,\n * assumptions, and suggestions. Should be updated as focus changes.\n *\n * @param description - What the user is currently working on\n *\n * @example\n * context(\"Preparing Q4 board presentation\")\n * context(\"Investigating drop in signups last week\")\n * context(\"Working on EMEA regional analysis for strategy meeting\")\n * context(\"Debugging discrepancy in revenue numbers\")\n */\nexport function context(description: string): Teachables {\n return {\n type: 'context',\n format: () => leaf('context', description),\n };\n}\n\n/**\n * Record a correction the user made to previous understanding.\n *\n * Use this when the user corrects a misunderstanding about data, columns,\n * or business logic. Prevents repeating the same mistake.\n *\n * @param subject - What was misunderstood\n * @param clarification - The correct understanding\n *\n * @example\n * correction(\"status column\", \"1 = active, 0 = inactive, not boolean true/false\")\n * correction(\"orders table\", \"Use orders_v2, not the deprecated legacy_orders table\")\n * correction(\"date field\", \"order_date is when order was placed, ship_date is when shipped\")\n * correction(\"revenue calculation\", \"Must exclude refunds and chargebacks\")\n */\nexport function correction(subject: string, clarification: string): Teachables {\n return {\n type: 'correction',\n format: () =>\n wrapBlock('correction', [\n leaf('subject', subject),\n leaf('clarification', clarification),\n ]),\n };\n}\n\nexport function teachable(\n tag: string,\n ...teachables: Teachables[]\n): Teachables {\n return {\n type: 'user_profile',\n format: () => toInstructions(tag, ...teachables),\n };\n}\n\nexport function toInstructions(\n tag: string,\n ...teachables: Teachables[]\n): string {\n if (!teachables.length) {\n return '';\n }\n\n const grouped = new Map<Teachables['type'], Teachables[]>();\n for (const teachable of teachables) {\n const existing = grouped.get(teachable.type) ?? [];\n existing.push(teachable);\n grouped.set(teachable.type, existing);\n }\n\n const definedTypes = new Set(SECTION_ORDER.map((s) => s.type));\n\n const sections = SECTION_ORDER.map(({ type, tag }) => {\n const items = grouped.get(type);\n if (!items?.length) {\n return '';\n }\n const renderedItems = items\n .map((item) => item.format().trim())\n .filter(Boolean)\n .map((item) => indentBlock(item, 2))\n .join('\\n');\n if (!renderedItems.length) {\n return '';\n }\n return `<${tag}>\\n${renderedItems}\\n</${tag}>`;\n }).filter((section): section is string => Boolean(section));\n\n // Render types not defined in SECTION_ORDER at the end\n for (const [type, items] of grouped) {\n if (definedTypes.has(type)) {\n continue;\n }\n const renderedItems = items\n .map((item) => item.format().trim())\n .filter(Boolean)\n .map((item) => indentBlock(item, 2))\n .join('\\n');\n if (renderedItems.length) {\n sections.push(renderedItems);\n }\n }\n\n if (!sections.length) {\n return '';\n }\n\n const content = indentBlock(sections.join('\\n'), 2);\n return `<${tag}>\\n${content}\\n</${tag}>`;\n}\n\nconst SECTION_ORDER: Array<{ type: Teachables['type']; tag: string }> = [\n // User context (render first - most important for personalization)\n { type: 'identity', tag: 'identity' },\n { type: 'persona', tag: 'persona' },\n { type: 'context', tag: 'user_context' },\n { type: 'preference', tag: 'user_preferences' },\n { type: 'alias', tag: 'user_vocabulary' },\n { type: 'correction', tag: 'user_corrections' },\n // Domain knowledge\n { type: 'guardrail', tag: 'guardrails' },\n { type: 'styleGuide', tag: 'style_guides' },\n { type: 'hint', tag: 'hints' },\n { type: 'clarification', tag: 'clarifications' },\n { type: 'workflow', tag: 'workflows' },\n { type: 'quirk', tag: 'quirks' },\n { type: 'term', tag: 'terminology' },\n { type: 'explain', tag: 'explanations' },\n { type: 'analogy', tag: 'analogies' },\n { type: 'glossary', tag: 'glossary' },\n { type: 'example', tag: 'examples' },\n];\n\nexport function toTeachables(generated: GeneratedTeachable[]): Teachables[] {\n return generated.map((item) => {\n switch (item.type) {\n case 'persona':\n return persona({ name: item.name, role: item.role, tone: item.tone });\n case 'term':\n return term(item.name, item.definition);\n case 'hint':\n return hint(item.text);\n case 'guardrail':\n return guardrail({\n rule: item.rule,\n reason: item.reason,\n action: item.action,\n });\n case 'explain':\n return explain({\n concept: item.concept,\n explanation: item.explanation,\n therefore: item.therefore,\n });\n case 'example':\n return example({\n question: item.question,\n answer: item.answer,\n note: item.note,\n });\n case 'clarification':\n return clarification({\n when: item.when,\n ask: item.ask,\n reason: item.reason,\n });\n case 'workflow':\n return workflow({\n task: item.task,\n steps: item.steps,\n triggers: item.triggers,\n notes: item.notes,\n });\n case 'quirk':\n return quirk({\n issue: item.issue,\n workaround: item.workaround,\n });\n case 'styleGuide':\n return styleGuide({\n prefer: item.prefer,\n never: item.never,\n always: item.always,\n });\n case 'analogy':\n return analogy({\n concept: item.concept,\n relationship: item.relationship,\n insight: item.insight,\n therefore: item.therefore,\n pitfall: item.pitfall,\n });\n case 'glossary':\n return glossary(item.entries);\n // User-specific teachable types\n case 'identity':\n return identity({ name: item.name, role: item.role });\n case 'alias':\n return alias(item.term, item.meaning);\n case 'preference':\n return preference(item.aspect, item.value);\n case 'context':\n return context(item.description);\n case 'correction':\n return correction(item.subject, item.clarification);\n }\n });\n}\n\n/**\n * Default export containing all system teachable factory functions.\n * Excludes user-specific teachables (identity, alias, preference, context, correction).\n */\nexport default {\n persona,\n term,\n hint,\n guardrail,\n explain,\n example,\n clarification,\n workflow,\n quirk,\n styleGuide,\n analogy,\n glossary,\n teachable,\n};\n", "import {\n clarification,\n example,\n explain,\n guardrail,\n hint,\n toInstructions,\n workflow,\n} from '../teach/teachables.ts';\n\nexport default toInstructions(\n 'memory_guidelines',\n\n // Section 1: Core behavior\n guardrail({\n rule: 'Silently store user information when revealed. Respond to memory-related requests.',\n reason: 'Memory enables personalized responses across conversations',\n action:\n 'Store silently on reveal. Respond explicitly when asked about memories.',\n }),\n\n // Section 2: Workflows for memory operations\n\n workflow({\n task: 'Store user identity silently',\n triggers: [\"I'm a\", 'I work as', 'my name is', 'my role is'],\n steps: [\n 'Extract name and/or role from the statement',\n 'Call remember_memory() with type: \"identity\" and name/role fields',\n 'Do NOT announce or confirm - continue conversation naturally',\n ],\n notes:\n 'This should happen silently without disrupting the conversation flow.',\n }),\n\n workflow({\n task: 'Store user preferences and context silently',\n triggers: ['When I say', 'I prefer', \"I'm working on\"],\n steps: [\n 'Identify the memory type (alias/preference/context/correction)',\n 'Extract the relevant information',\n 'Call remember_memory() with appropriate type and fields',\n 'Do NOT announce or confirm - continue conversation naturally',\n ],\n notes:\n 'This should happen silently without disrupting the conversation flow.',\n }),\n\n workflow({\n task: 'Forget a memory',\n triggers: ['forget that', 'remove my', 'delete the', \"don't remember that\"],\n steps: [\n 'Call recall_memory() to list relevant memories',\n 'Find the memory ID that matches user request',\n 'Call forget_memory({ id }) with the found ID',\n 'Confirm to user what was forgotten',\n ],\n }),\n\n workflow({\n task: 'Update a memory',\n triggers: ['actually now I', 'I changed', 'update my', 'no longer'],\n steps: [\n 'Call recall_memory() to find the existing memory',\n 'Get the memory ID from results',\n 'Call update_memory({ id, memory }) with new data',\n 'Confirm the update to user',\n ],\n }),\n\n // Section 3: Type disambiguation\n\n explain({\n concept: 'identity vs context',\n explanation:\n 'Identity = WHO the user is (name and/or role, permanent). Context = WHAT they are working on (temporary focus).',\n therefore: 'Identity rarely changes. Context changes per project/task.',\n }),\n\n explain({\n concept: 'alias vs correction',\n explanation:\n 'Alias = user defines their own term/shorthand. Correction = user fixes a misunderstanding about existing data/schema.',\n therefore: 'Alias is vocabulary. Correction is data clarification.',\n }),\n\n explain({\n concept: 'preference memory type',\n explanation:\n 'Stores output/style/format preferences. Fields: { aspect: string, value: string }',\n therefore: 'Use for formatting, limits, display style, data scope filters',\n }),\n\n // Section 4: Clarifications for ambiguous situations\n\n clarification({\n when: 'user says something like \"X actually means Y\" but unclear if defining their term or correcting data',\n ask: 'Are you defining your own shorthand for this term, or correcting how the data/schema actually works?',\n reason:\n 'Alias is personal vocabulary. Correction is a data/schema clarification that applies universally.',\n }),\n\n clarification({\n when: 'user mentions a project or task that could be their identity or current focus',\n ask: 'Is this your ongoing identity (name/role), or a specific project you are currently working on?',\n reason:\n 'Identity is permanent. Context is temporary focus that may change.',\n }),\n\n // Section 5: Examples\n\n // Identity - role\n example({\n question: \"I'm the VP of Sales\",\n answer: 'remember_memory({ memory: { type: \"identity\", role: \"VP of Sales\" }})',\n note: 'Identity stores role',\n }),\n\n // Identity - name\n example({\n question: 'My name is Sarah',\n answer: 'remember_memory({ memory: { type: \"identity\", name: \"Sarah\" }})',\n note: 'Identity stores name',\n }),\n\n // Context\n example({\n question: \"I'm analyzing Q4 performance\",\n answer: 'remember_memory({ memory: { type: \"context\", description: \"Analyzing Q4 performance\" }})',\n note: 'Current task = context',\n }),\n\n // Alias\n example({\n question: 'When I say \"big customers\", I mean revenue > $1M',\n answer: 'remember_memory({ memory: { type: \"alias\", term: \"big customers\", meaning: \"revenue > $1M\" }})',\n note: 'User defining their vocabulary = alias',\n }),\n\n // Correction\n example({\n question:\n 'No, the status column uses 1 for active, not the string \"active\"',\n answer: 'remember_memory({ memory: { type: \"correction\", subject: \"status column values\", clarification: \"Uses 1 for active, not string\" }})',\n note: 'Correcting schema/data assumption = correction',\n }),\n\n // Preference\n example({\n question: 'Always show dates as YYYY-MM-DD',\n answer: 'remember_memory({ memory: { type: \"preference\", aspect: \"date format\", value: \"YYYY-MM-DD\" }})',\n }),\n\n // Recall\n example({\n question: 'What do you remember about me?',\n answer: 'recall_memory({})',\n note: 'List all stored memories',\n }),\n\n // Section 6: What NOT to remember\n hint('Do NOT remember one-time query details like \"show last 10 orders\"'),\n hint(\n 'Do NOT remember information already stored - use recall_memory to check first',\n ),\n hint('Do NOT remember obvious or universal facts'),\n);\n", "import { createHash } from 'node:crypto';\nimport { existsSync } from 'node:fs';\nimport { readFile, writeFile } from 'node:fs/promises';\nimport { tmpdir } from 'node:os';\nimport path from 'node:path';\n\nexport class FileCache {\n public path: string;\n constructor(watermark: string, extension = '.txt') {\n const hash = createHash('md5').update(watermark).digest('hex');\n this.path = path.join(tmpdir(), `text2sql-${hash}${extension}`);\n }\n\n async get() {\n if (existsSync(this.path)) {\n return readFile(this.path, 'utf-8');\n }\n return null;\n }\n\n set(content: string) {\n return writeFile(this.path, content, 'utf-8');\n }\n}\n\nexport class JsonCache<T> extends FileCache {\n constructor(watermark: string) {\n super(watermark, '.json');\n }\n\n async read(): Promise<T | null> {\n const content = await this.get();\n if (content) {\n return JSON.parse(content) as T;\n }\n return null;\n }\n\n write(data: T) {\n return this.set(JSON.stringify(data));\n }\n}\n", "import type { UIMessage } from 'ai';\n\nexport interface Message {\n id: string;\n chatId: string;\n role: string;\n createdAt: string | Date;\n content: UIMessage;\n}\n\nexport interface Chat {\n id: string;\n userId: string;\n title?: string | null;\n messages: Message[];\n}\n\nexport interface CreateChatParams {\n id: string;\n userId: string;\n title?: string;\n}\n\nexport interface UpdateChatParams {\n title?: string;\n}\n\nexport interface CreateMessageParams {\n id: string;\n chatId: string;\n role: string;\n content: UIMessage;\n createdAt?: Date;\n}\n\nexport abstract class History {\n abstract listChats(userId: string): Promise<Chat[]>;\n abstract getChat(chatId: string): Promise<Chat | null>;\n abstract createChat(chat: CreateChatParams): Promise<Chat>;\n abstract upsertChat(chat: CreateChatParams): Promise<Chat>;\n abstract deleteChat(chatId: string): Promise<void>;\n abstract updateChat(chatId: string, updates: UpdateChatParams): Promise<void>;\n abstract addMessage(message: CreateMessageParams): Promise<void>;\n abstract upsertMessage(message: CreateMessageParams): Promise<Message>;\n abstract deleteMessage(messageId: string): Promise<void>;\n}\n", "import { DatabaseSync } from 'node:sqlite';\n\nimport historyDDL from './history.sqlite.sql';\nimport {\n type Chat,\n type CreateChatParams,\n type CreateMessageParams,\n History,\n type Message,\n type UpdateChatParams,\n} from './history.ts';\n\nexport class SqliteHistory extends History {\n #db: DatabaseSync;\n\n constructor(path: string) {\n super();\n this.#db = new DatabaseSync(path);\n this.#db.exec(historyDDL);\n }\n\n async listChats(userId: string): Promise<Chat[]> {\n return this.#db\n .prepare(`SELECT * FROM chats WHERE \"userId\" = ?`)\n .all(userId) as unknown as Chat[];\n }\n\n async getChat(chatId: string): Promise<Chat | null> {\n const rows = this.#db\n .prepare(\n `SELECT\n c.id as chatId, c.\"userId\", c.title,\n m.id as messageId, m.role, m.\"createdAt\", m.content\n FROM chats c\n LEFT JOIN messages m ON m.\"chatId\" = c.id\n WHERE c.id = ?\n ORDER BY m.\"createdAt\" ASC`,\n )\n .all(chatId) as unknown as Array<{\n chatId: string;\n userId: string;\n title: string | null;\n messageId: string | null;\n role: string;\n createdAt: string;\n content: string;\n }>;\n\n if (!rows.length) return null;\n\n const firstRow = rows[0];\n const chat: Chat = {\n id: firstRow.chatId,\n userId: firstRow.userId,\n title: firstRow.title,\n messages: [],\n };\n\n for (const row of rows) {\n if (row.messageId) {\n chat.messages.push({\n id: row.messageId,\n chatId: firstRow.chatId,\n role: row.role as string,\n createdAt: row.createdAt as string,\n content: JSON.parse(row.content),\n });\n }\n }\n\n return chat;\n }\n\n async createChat(chat: CreateChatParams): Promise<Chat> {\n this.#db\n .prepare(`INSERT INTO chats (id, \"userId\", title) VALUES (?, ?, ?)`)\n .run(chat.id, chat.userId, chat.title || null);\n return chat as Chat;\n }\n\n async upsertChat(chat: CreateChatParams) {\n this.#db\n .prepare(\n `INSERT INTO chats (id, \"userId\", title) VALUES (?, ?, ?)\n ON CONFLICT(id) DO UPDATE SET title = excluded.title, \"userId\" = excluded.\"userId\"`,\n )\n .run(chat.id, chat.userId, chat.title || null);\n return this.getChat(chat.id) as Promise<Chat>;\n }\n\n async deleteChat(chatId: string): Promise<void> {\n this.#db.prepare(`DELETE FROM chats WHERE id = ?`).run(chatId);\n }\n\n async updateChat(chatId: string, updates: UpdateChatParams): Promise<void> {\n if (updates.title !== undefined) {\n this.#db\n .prepare(`UPDATE chats SET title = ? WHERE id = ?`)\n .run(updates.title, chatId);\n }\n }\n\n async addMessage(message: CreateMessageParams): Promise<void> {\n const createdAt = message.createdAt\n ? message.createdAt.toISOString()\n : new Date().toISOString();\n this.#db\n .prepare(\n `INSERT INTO messages (id, \"chatId\", role, \"createdAt\", content) VALUES (?, ?, ?, ?, ?)`,\n )\n .run(\n message.id,\n message.chatId,\n message.role,\n createdAt,\n JSON.stringify(message.content),\n );\n }\n\n async upsertMessage(message: CreateMessageParams): Promise<Message> {\n const createdAt = message.createdAt\n ? message.createdAt.toISOString()\n : new Date().toISOString();\n this.#db\n .prepare(\n `INSERT INTO messages (id, \"chatId\", role, \"createdAt\", content) VALUES (?, ?, ?, ?, ?)\n ON CONFLICT(id) DO UPDATE SET \"chatId\" = excluded.\"chatId\", role = excluded.role, \"createdAt\" = excluded.\"createdAt\", content = excluded.content`,\n )\n .run(\n message.id,\n message.chatId,\n message.role,\n createdAt,\n JSON.stringify(message.content),\n );\n return {\n ...message,\n createdAt,\n };\n }\n\n async deleteMessage(messageId: string): Promise<void> {\n this.#db.prepare(`DELETE FROM messages WHERE id = ?`).run(messageId);\n }\n}\n", "CREATE TABLE IF NOT EXISTS \"chats\" (\n\t\"id\" VARCHAR PRIMARY KEY,\n\t\"title\" VARCHAR,\n\t\"userId\" VARCHAR\n);\n\nCREATE TABLE IF NOT EXISTS \"messages\" (\n\t\"id\" VARCHAR PRIMARY KEY,\n\t\"chatId\" VARCHAR NOT NULL REFERENCES \"chats\" (\"id\") ON DELETE CASCADE,\n\t\"createdAt\" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\n\t\"role\" VARCHAR NOT NULL,\n\t\"content\" TEXT NOT NULL\n);\n\nCREATE INDEX IF NOT EXISTS \"messages_chat_id_idx\" ON \"messages\" (\"chatId\");\n\nCREATE INDEX IF NOT EXISTS \"messages_chat_id_created_at_idx\" ON \"messages\" (\"chatId\", \"createdAt\");\n", "import { SqliteHistory } from './sqlite.history.ts';\n\nexport class InMemoryHistory extends SqliteHistory {\n constructor() {\n super(':memory:');\n }\n}\n", "import { DatabaseSync } from 'node:sqlite';\nimport { v7 } from 'uuid';\n\nimport {\n type GeneratedTeachable,\n type Teachables,\n toTeachables,\n} from '../teach/teachables.ts';\nimport storeDDL from './store.sqlite.sql';\nimport { type StoredTeachable, TeachablesStore } from './store.ts';\n\ninterface TeachableRow {\n id: string;\n userId: string;\n type: string;\n data: string;\n createdAt: string;\n updatedAt: string;\n}\n\nfunction rowToStoredTeachable(row: TeachableRow): StoredTeachable {\n return {\n id: row.id,\n userId: row.userId,\n type: row.type as GeneratedTeachable['type'],\n data: JSON.parse(row.data),\n createdAt: row.createdAt,\n updatedAt: row.updatedAt,\n };\n}\n\nexport class SqliteTeachablesStore extends TeachablesStore {\n #db: DatabaseSync;\n\n constructor(path: string) {\n super();\n this.#db = new DatabaseSync(path);\n this.#db.exec(storeDDL);\n }\n\n async remember(\n userId: string,\n data: GeneratedTeachable,\n ): Promise<StoredTeachable> {\n const id = v7();\n const now = new Date().toISOString();\n\n this.#db\n .prepare(\n 'INSERT INTO teachables (id, userId, type, data, createdAt, updatedAt) VALUES (?, ?, ?, ?, ?, ?)',\n )\n .run(id, userId, data.type, JSON.stringify(data), now, now);\n\n return (await this.get(id))!;\n }\n\n async recall(\n userId: string,\n type?: GeneratedTeachable['type'],\n ): Promise<StoredTeachable[]> {\n let rows: TeachableRow[];\n\n if (type === undefined) {\n rows = this.#db\n .prepare('SELECT * FROM teachables WHERE userId = ? ORDER BY createdAt')\n .all(userId) as unknown as TeachableRow[];\n } else {\n rows = this.#db\n .prepare(\n 'SELECT * FROM teachables WHERE userId = ? AND type = ? ORDER BY createdAt',\n )\n .all(userId, type) as unknown as TeachableRow[];\n }\n\n return rows.map(rowToStoredTeachable);\n }\n\n async get(id: string): Promise<StoredTeachable | null> {\n const row = this.#db\n .prepare('SELECT * FROM teachables WHERE id = ?')\n .get(id) as TeachableRow | undefined;\n\n if (!row) return null;\n return rowToStoredTeachable(row);\n }\n\n async update(id: string, data: GeneratedTeachable): Promise<StoredTeachable> {\n const now = new Date().toISOString();\n\n this.#db\n .prepare(\n 'UPDATE teachables SET data = ?, type = ?, updatedAt = ? WHERE id = ?',\n )\n .run(JSON.stringify(data), data.type, now, id);\n\n return (await this.get(id))!;\n }\n\n async forget(id: string): Promise<void> {\n this.#db.prepare('DELETE FROM teachables WHERE id = ?').run(id);\n }\n\n async forgetAll(userId: string): Promise<void> {\n this.#db.prepare('DELETE FROM teachables WHERE userId = ?').run(userId);\n }\n\n async toTeachables(userId: string): Promise<Teachables[]> {\n const stored = await this.recall(userId);\n return toTeachables(stored.map((s) => s.data));\n }\n}\n", "CREATE TABLE IF NOT EXISTS \"teachables\" (\n\t\"id\" VARCHAR PRIMARY KEY,\n\t\"userId\" VARCHAR,\n\t\"type\" VARCHAR NOT NULL,\n\t\"data\" TEXT NOT NULL,\n\t\"createdAt\" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\n\t\"updatedAt\" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP\n);\n\nCREATE INDEX IF NOT EXISTS \"teachables_user_id_idx\" ON \"teachables\" (\"userId\");\n\nCREATE INDEX IF NOT EXISTS \"teachables_type_idx\" ON \"teachables\" (\"type\");\n\nCREATE INDEX IF NOT EXISTS \"teachables_user_type_idx\" ON \"teachables\" (\"userId\", \"type\");\n", "import type { GeneratedTeachable, Teachables } from '../teach/teachables.ts';\n\nexport interface StoredTeachable {\n id: string;\n userId: string;\n type: GeneratedTeachable['type'];\n data: GeneratedTeachable;\n createdAt: string;\n updatedAt: string;\n}\n\nexport abstract class TeachablesStore {\n /**\n * Remember a teachable for a user.\n */\n abstract remember(\n userId: string,\n data: GeneratedTeachable,\n ): Promise<StoredTeachable>;\n\n /**\n * Recall teachables for a user, optionally filtered by type.\n */\n abstract recall(\n userId: string,\n type?: GeneratedTeachable['type'],\n ): Promise<StoredTeachable[]>;\n\n /**\n * Get a specific teachable by ID.\n */\n abstract get(id: string): Promise<StoredTeachable | null>;\n\n /**\n * Update an existing teachable.\n */\n abstract update(\n id: string,\n data: GeneratedTeachable,\n ): Promise<StoredTeachable>;\n\n /**\n * Forget (remove) a specific teachable by ID.\n */\n abstract forget(id: string): Promise<void>;\n\n /**\n * Forget all teachables for a user.\n */\n abstract forgetAll(userId: string): Promise<void>;\n\n /**\n * Convert stored teachables to Teachables array for use with toInstructions().\n */\n abstract toTeachables(userId: string): Promise<Teachables[]>;\n}\n", "import { SqliteTeachablesStore } from './sqlite.store.ts';\n\nexport class InMemoryTeachablesStore extends SqliteTeachablesStore {\n constructor() {\n super(':memory:');\n }\n}\n", "import {\n InvalidToolInputError,\n NoSuchToolError,\n ToolCallRepairError,\n type UIMessage,\n generateId,\n} from 'ai';\nimport { v7 } from 'uuid';\n\nimport {\n type Agent,\n type AgentModel,\n generate,\n stream,\n user,\n} from '@deepagents/agent';\n\nimport type { Adapter, IntrospectOptions } from './adapters/adapter.ts';\nimport { explainerAgent } from './agents/explainer.agent.ts';\nimport {\n type RenderingTools,\n memoryTools,\n sqlQueryAgent,\n t_a_g,\n} from './agents/text2sql.agent.ts';\nimport { FileCache } from './file-cache.ts';\nimport { History } from './history/history.ts';\nimport type { TeachablesStore } from './memory/store.ts';\nimport {\n type Teachables,\n hint,\n persona,\n styleGuide,\n teachable,\n toInstructions,\n} from './teach/teachables.ts';\nimport teachings from './teach/teachings.ts';\n\nexport interface InspectionResult {\n /** The grounding/introspection data (database schema context as XML) */\n grounding: string;\n\n /** The full instructions XML that would be sent to the agent */\n instructions: string;\n\n /** User-specific teachables that were loaded */\n userTeachables: Teachables[];\n\n /** System teachings configured */\n systemTeachings: Teachables[];\n\n /** Tool names available to the agent */\n tools: string[];\n}\n\nexport class Text2Sql {\n #config: {\n model?: AgentModel;\n adapter: Adapter;\n briefCache: FileCache;\n history: History;\n tools?: RenderingTools;\n instructions: Teachables[];\n memory?: TeachablesStore;\n introspection: FileCache;\n };\n\n constructor(config: {\n adapter: Adapter;\n history: History;\n version: string;\n tools?: RenderingTools;\n instructions?: Teachables[];\n model?: AgentModel;\n memory?: TeachablesStore;\n }) {\n this.#config = {\n adapter: config.adapter,\n briefCache: new FileCache('brief-' + config.version),\n history: config.history,\n instructions: [...teachings, ...(config.instructions ?? [])],\n tools: config.tools ?? {},\n model: config.model,\n memory: config.memory,\n introspection: new FileCache('introspection-' + config.version),\n };\n }\n\n public async explain(sql: string) {\n const { experimental_output } = await generate(\n explainerAgent,\n [user('Explain this SQL.')],\n { sql },\n );\n return experimental_output.explanation;\n }\n\n public async toSql(\n query: string,\n options?: { tools?: RenderingTools },\n ): Promise<string> {\n const introspection = await this.index();\n\n const { text } = await generate(\n sqlQueryAgent.clone({\n model: this.#config.model,\n tools: {\n ...t_a_g.handoff.tools,\n ...(options?.tools ?? this.#config.tools),\n },\n }),\n [user(query)],\n {\n teachings: toInstructions(\n 'instructions',\n persona({\n name: 'Freya',\n role: 'You are an expert SQL query generator, answering business questions with accurate queries.',\n tone: 'Your tone should be concise and business-friendly.',\n }),\n ...this.#config.instructions,\n ),\n adapter: this.#config.adapter,\n introspection,\n },\n );\n\n return text;\n }\n\n public instruct(...dataset: Teachables[]) {\n this.#config.instructions.push(...dataset);\n }\n\n public async inspect(agent: Agent) {\n const [grounding] = await Promise.all([this.index() as Promise<string>]);\n\n const renderToolNames = Object.keys(this.#config.tools ?? {}).filter(\n (name) => name.startsWith('render_'),\n );\n const allInstructions = [\n ...this.#config.instructions,\n ...(renderToolNames.length\n ? [\n hint(`Rendering tools available: ${renderToolNames.join(', ')}.`),\n styleGuide({\n prefer:\n 'Use render_* tools for trend/over time/monthly requests or chart asks',\n always:\n 'Include text insight alongside visualizations. Prefer line charts for time-based data.',\n }),\n ]\n : []),\n ];\n\n const tools = Object.keys({\n ...agent.handoff.tools,\n ...(this.#config.memory ? memoryTools : {}),\n ...this.#config.tools,\n });\n\n return {\n tools,\n prompt: agent.instructions({\n introspection: grounding,\n teachings: toInstructions(\n 'instructions',\n persona({\n name: 'Freya',\n role: 'You are an expert SQL query generator, answering business questions with accurate queries.',\n tone: 'Your tone should be concise and business-friendly.',\n }),\n ...allInstructions,\n ),\n }),\n };\n }\n\n public async index(options?: IntrospectOptions) {\n const cached = await this.#config.introspection.get();\n if (cached) {\n return cached;\n }\n const introspection = await this.#config.adapter.introspect();\n await this.#config.introspection.set(introspection);\n return introspection;\n }\n\n // public async suggest() {\n // const [introspection, adapterInfo] = await Promise.all([\n // this.index(),\n // this.#config.adapter.introspect(),\n // ]);\n // const { experimental_output: output } = await generate(\n // suggestionsAgent,\n // [\n // user(\n // 'Suggest high-impact business questions and matching SQL queries for this database.',\n // ),\n // ],\n // {\n // },\n // );\n // return output.suggestions;\n // }\n\n public async chat(\n messages: UIMessage[],\n params: {\n chatId: string;\n userId: string;\n },\n ) {\n const [introspection, userTeachables] = await Promise.all([\n this.index({ onProgress: console.log }),\n this.#config.memory\n ? this.#config.memory.toTeachables(params.userId)\n : [],\n ]);\n const chat = await this.#config.history.upsertChat({\n id: params.chatId,\n userId: params.userId,\n title: 'Chat ' + params.chatId,\n });\n\n // Build instructions with conditional rendering hint\n const renderToolNames = Object.keys(this.#config.tools ?? {}).filter(\n (name) => name.startsWith('render_'),\n );\n const instructions = [\n ...this.#config.instructions,\n ...(renderToolNames.length\n ? [\n hint(`Rendering tools available: ${renderToolNames.join(', ')}.`),\n styleGuide({\n prefer:\n 'Use render_* tools for trend/over time/monthly requests or chart asks',\n always:\n 'Include text insight alongside visualizations. Prefer line charts for time-based data.',\n }),\n ]\n : []),\n ];\n\n const result = stream(\n t_a_g.clone({\n model: this.#config.model,\n tools: {\n ...t_a_g.handoff.tools,\n ...(this.#config.memory ? memoryTools : {}),\n ...this.#config.tools,\n },\n }),\n [...chat.messages.map((it) => it.content), ...messages],\n {\n teachings: toInstructions(\n 'instructions',\n persona({\n name: 'Freya',\n role: 'You are an expert SQL query generator, answering business questions with accurate queries.',\n tone: 'Your tone should be concise and business-friendly.',\n }),\n ...instructions,\n teachable('user_profile', ...userTeachables),\n ),\n adapter: this.#config.adapter,\n introspection,\n memory: this.#config.memory,\n userId: params.userId,\n },\n );\n\n return result.toUIMessageStream({\n onError: (error) => {\n if (NoSuchToolError.isInstance(error)) {\n return 'The model tried to call a unknown tool.';\n } else if (InvalidToolInputError.isInstance(error)) {\n return 'The model called a tool with invalid arguments.';\n } else if (ToolCallRepairError.isInstance(error)) {\n return 'The model tried to call a tool with invalid arguments, but it was repaired.';\n } else {\n return 'An unknown error occurred.';\n }\n },\n sendStart: true,\n sendFinish: true,\n sendReasoning: true,\n sendSources: true,\n originalMessages: messages,\n generateMessageId: generateId,\n onFinish: async ({ messages }) => {\n const userMessage = messages.at(-2);\n const botMessage = messages.at(-1);\n if (!userMessage || !botMessage) {\n throw new Error('Not implemented yet');\n }\n await this.#config.history.addMessage({\n id: v7(),\n chatId: params.chatId,\n role: userMessage.role,\n content: userMessage,\n });\n await this.#config.history.addMessage({\n id: v7(),\n chatId: params.chatId,\n role: botMessage.role,\n content: botMessage,\n });\n },\n });\n }\n}\n", "import { groq } from '@ai-sdk/groq';\nimport dedent from 'dedent';\nimport z from 'zod';\n\nimport { agent } from '@deepagents/agent';\n\nexport const explainerAgent = agent<{ explanation: string }, { sql: string }>({\n name: 'explainer',\n model: groq('openai/gpt-oss-20b'),\n prompt: (state) => dedent`\n You are an expert SQL tutor.\n Explain the following SQL query in plain English to a non-technical user.\n Focus on the intent and logic, not the syntax.\n\n <sql>\n ${state?.sql}\n </sql>\n `,\n output: z.object({\n explanation: z.string().describe('The explanation of the SQL query.'),\n }),\n});\n", "import {\n type Teachables,\n clarification,\n guardrail,\n hint,\n styleGuide,\n workflow,\n} from './teachables.ts';\n\nexport default [\n hint(\n 'If the user asks to show a table or entity without specifying columns, use SELECT *.',\n ),\n hint(\n 'When showing items associated with another entity, include the item ID and the related details requested.',\n ),\n hint(\n 'When asked to \"show\" items, list them unless the user explicitly asks to count or total.',\n ),\n hint(\n 'Use canonical/LowCardinality values verbatim for filtering; [rows/size] hints suggest when to aggregate instead of listing.',\n ),\n hint(\n 'Favor PK/indexed columns for joins and filters; follow relationship metadata for join direction and cardinality.',\n ),\n guardrail({\n rule: 'Avoid unbounded scans on large/time-based tables.',\n action:\n 'Ask for or apply a reasonable recent date range before querying broad fact tables.',\n }),\n guardrail({\n rule: 'Do not return oversized raw result sets.',\n action:\n 'Keep raw outputs to ~100 rows; aggregate or paginate unless the user explicitly confirms a larger pull.',\n }),\n guardrail({\n rule: 'Prevent cartesian or guesswork joins.',\n reason: 'Protect correctness and performance.',\n action:\n 'If join keys are missing or unclear, inspect relationships and ask for the intended join path before executing.',\n }),\n clarification({\n when: 'The request targets time-based data without a date range.',\n ask: 'Confirm the intended timeframe (e.g., last 30/90 days, YTD, specific year).',\n reason: 'Prevents large scans and irrelevant results.',\n }),\n clarification({\n when: 'The request uses ambiguous scoring or ranking language (e.g., \"top\", \"best\", \"active\") without a metric.',\n ask: 'Clarify the ranking metric or definition before writing the query.',\n reason: 'Ensures the correct aggregation/ordering is used.',\n }),\n workflow({\n task: 'SQL generation plan',\n steps: [\n 'Translate the question into SQL patterns (aggregation, segmentation, time range, ranking).',\n 'Choose tables/relations that satisfy those patterns; note lookup tables and filter values implied by schema hints.',\n \"Inspect samples with 'get_sample_rows' for any column you'll use in WHERE/JOIN conditions - target just those columns (e.g., get_sample_rows('orders', ['status', 'order_type'])).\",\n 'Sketch join/filter/aggregation order considering table sizes, indexes, and stats.',\n \"Draft SQL, validate via 'validate_query', then execute via 'db_query' with a short reasoning note.\",\n ],\n }),\n styleGuide({\n prefer:\n 'Summaries should be concise, business-friendly, highlight key comparisons, and add a short helpful follow-up when useful.',\n }),\n // Tool usage constraints\n guardrail({\n rule: 'Never output more than 100 rows of raw data.',\n action: 'Use aggregation or pagination otherwise.',\n }),\n guardrail({\n rule: 'You must validate your query before final execution.',\n action:\n \"Follow the pattern: Draft Query \u2192 `validate_query` \u2192 Fix (if needed) \u2192 `db_query`.\",\n }),\n guardrail({\n rule: 'ALWAYS use `get_sample_rows` before writing queries that filter or compare against string columns.',\n reason: 'Prevents SQL errors from wrong value formats.',\n action:\n \"Target specific columns (e.g., get_sample_rows('table', ['status', 'type'])).\",\n }),\n guardrail({\n rule: 'Do not call `db_query` without first producing and validating a SQL snippet.',\n action: 'First produce the query string, then validate.',\n }),\n hint(\n 'Use the `scratchpad` tool for strategic reflection during SQL query generation.',\n ),\n] as Teachables[];\n", "export * from './lib/agents/suggestions.agents.ts';\nexport * from './lib/agents/text2sql.agent.ts';\nexport * from './lib/file-cache.ts';\nexport * from './lib/history/history.ts';\nexport * from './lib/history/memory.history.ts';\nexport * from './lib/history/sqlite.history.ts';\nexport * from './lib/memory/memory.store.ts';\nexport * from './lib/memory/sqlite.store.ts';\nexport * from './lib/memory/store.ts';\nexport * from './lib/sql.ts';\n\nif (import.meta.main) {\n // const { DatabaseSync } = await import('node:sqlite');\n // const sqliteClient = new DatabaseSync(\n // '/Users/ezzabuzaid/Downloads/Chinook.db',\n // );\n // const text2sql = new Text2Sql({\n // version: 'v2',\n // history: new InMemoryHistory(),\n // adapter: new Sqlite({\n // grounding: [],\n // execute: (sql) => sqliteClient.prepare(sql).all(),\n // }),\n // });\n // console.dir(await text2sql.inspect(sqlQueryAgent), { depth: null });\n // const sql = await text2sql.toSql(\n // 'The top-selling products or categories each month last year given last record stored?. if the questions is wrong, show me full correct question I can ask.',\n // );\n // console.log('Generated SQL:');\n // console.log(sql);\n // await printer.readableStream(sql);\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["import { groq } from '@ai-sdk/groq';\nimport dedent from 'dedent';\nimport z from 'zod';\n\nimport { agent, thirdPersonPrompt } from '@deepagents/agent';\n\nimport type { Introspection } from '../adapters/adapter.ts';\nimport { databaseSchemaPrompt } from '../prompt.ts';\n\ntype SuggestionsAgentContext = {\n context?: string;\n adapterInfo?: string;\n};\ntype SuggestionsAgentOutput = {\n suggestions: {\n question: string;\n sql: string;\n businessValue: string;\n }[];\n};\n\nexport const suggestionsAgent = agent<\n SuggestionsAgentOutput,\n SuggestionsAgentContext\n>({\n name: 'text2sql-suggestions',\n model: groq('openai/gpt-oss-20b'),\n output: z.object({\n suggestions: z\n .array(\n z.object({\n question: z\n .string()\n .describe('A complex, high-impact business question.'),\n sql: z\n .string()\n .describe('The SQL statement needed to answer the question.'),\n businessValue: z\n .string()\n .describe('Why the question matters to stakeholders.'),\n }),\n )\n .min(1)\n .max(5)\n .describe('A set of up to two advanced question + SQL pairs.'),\n }),\n prompt: (state) => {\n return dedent`\n ${thirdPersonPrompt()}\n\n <identity>\n You are a senior analytics strategist who proposes ambitious business questions\n and drafts the SQL needed to answer them. You specialize in identifying ideas\n that combine multiple tables, apply segmentation or time analysis, and surface\n metrics that drive executive decisions.\n </identity>\n\n\n <instructions>\n - Recommend one or two UNIQUE questions that go beyond simple counts or listings.\n - Favor questions that require joins, aggregates, time comparisons, cohort analysis,\n or window functions.\n - For each question, explain the business reason stakeholders care about it.\n - Provide the complete SQL query that could answer the question in the given schema.\n - Keep result sets scoped with LIMIT clauses (max 50 rows) when returning raw rows.\n - Ensure table/column names match the provided schema exactly.\n - Use columns marked [LowCardinality: ...] to identify meaningful categorical filters or segmentations.\n - Leverage table [rows / size] hints to determine whether to aggregate (large tables) or inspect detailed data (tiny tables).\n - Reference PK/Indexed annotations and the Indexes list to recommend queries that use efficient join/filter paths.\n - Column annotations may expose ranges/null percentages\u2014use them to suggest realistic thresholds or quality checks.\n - Consult <relationship_examples> to anchor your recommendations in the actual join paths between tables.\n - Output only information grounded in the schema/context provided.\n </instructions>\n\n <response-format>\n Return valid JSON that satisfies the defined output schema.\n </response-format>\n `;\n },\n});\n", "import { groq } from '@ai-sdk/groq';\nimport { type Tool, tool } from 'ai';\nimport z from 'zod';\n\nimport {\n type StepBackExample,\n agent,\n stepBackPrompt,\n toState,\n} from '@deepagents/agent';\nimport { scratchpad_tool } from '@deepagents/toolbox';\n\nimport type { Adapter } from '../adapters/adapter.ts';\nimport memoryPrompt from '../memory/memory.prompt.ts';\nimport type { TeachablesStore } from '../memory/store.ts';\nimport type { GeneratedTeachable } from '../teach/teachables.ts';\n\nexport type RenderingTools = Record<string, Tool<unknown, never>>;\n\nconst tools = {\n validate_query: tool({\n description: `Validate SQL query syntax before execution. Use this to check if your SQL is valid before running db_query. This helps catch errors early and allows you to correct the query if needed.`,\n inputSchema: z.object({\n sql: z.string().describe('The SQL query to validate.'),\n }),\n execute: async ({ sql }, options) => {\n const state = toState<{ adapter: Adapter }>(options);\n const result = await state.adapter.validate(sql);\n if (typeof result === 'string') {\n return `Validation Error: ${result}`;\n }\n return 'Query is valid.';\n },\n }),\n get_sample_rows: tool({\n description: `Sample rows from a table to understand data formatting, codes, and value patterns. Use BEFORE writing queries when:\n- Column types in schema don't reveal format (e.g., \"status\" could be 'active'/'inactive' or 1/0)\n- Date/time formats are unclear (ISO, Unix timestamp, locale-specific)\n- You need to understand lookup table codes or enum values\n- Column names are ambiguous (e.g., \"type\", \"category\", \"code\")`,\n inputSchema: z.object({\n tableName: z.string().describe('The name of the table to sample.'),\n columns: z\n .array(z.string())\n .optional()\n .describe(\n 'Specific columns to sample. If omitted, samples all columns.',\n ),\n limit: z\n .number()\n .min(1)\n .max(10)\n .default(3)\n .optional()\n .describe('Number of rows to sample (1-10, default 3).'),\n }),\n execute: ({ tableName, columns, limit = 3 }, options) => {\n const safeLimit = Math.min(Math.max(1, limit), 10);\n const state = toState<{ adapter: Adapter }>(options);\n const sql = state.adapter.buildSampleRowsQuery(\n tableName,\n columns,\n safeLimit,\n );\n return state.adapter.execute(sql);\n },\n }),\n db_query: tool({\n description: `Internal tool to fetch data from the store's database. Write a SQL query to retrieve the information needed to answer the user's question. The results will be returned as data that you can then present to the user in natural language.`,\n inputSchema: z.object({\n reasoning: z\n .string()\n .describe(\n 'Your reasoning for why this SQL query is relevant to the user request.',\n ),\n sql: z\n .string()\n .min(1, { message: 'SQL query cannot be empty.' })\n .refine(\n (sql) =>\n sql.trim().toUpperCase().startsWith('SELECT') ||\n sql.trim().toUpperCase().startsWith('WITH'),\n {\n message: 'Only read-only SELECT or WITH queries are allowed.',\n },\n )\n .describe('The SQL query to execute against the database.'),\n }),\n execute: ({ sql }, options) => {\n const state = toState<{ adapter: Adapter }>(options);\n return state.adapter.execute(sql);\n },\n }),\n scratchpad: scratchpad_tool,\n};\n\nconst userMemoryTypes = [\n 'identity',\n 'alias',\n 'preference',\n 'context',\n 'correction',\n] as const;\n\nconst userMemorySchema = z.discriminatedUnion('type', [\n z.object({\n type: z.literal('identity'),\n description: z.string().describe(\"The user's identity: role or/and name\"),\n }),\n z.object({\n type: z.literal('alias'),\n term: z.string().describe('The term the user uses'),\n meaning: z.string().describe('What the user means by this term'),\n }),\n z.object({\n type: z.literal('preference'),\n aspect: z\n .string()\n .describe('What aspect of output this preference applies to'),\n value: z.string().describe(\"The user's preference\"),\n }),\n z.object({\n type: z.literal('context'),\n description: z.string().describe('What the user is currently working on'),\n }),\n z.object({\n type: z.literal('correction'),\n subject: z.string().describe('What was misunderstood'),\n clarification: z.string().describe('The correct understanding'),\n }),\n]);\n\nexport const memoryTools = {\n remember_memory: tool({\n description:\n 'Store something about the user for future conversations. Use silently when user shares facts, preferences, vocabulary, corrections, or context.',\n inputSchema: z.object({ memory: userMemorySchema }),\n execute: async ({ memory }, options) => {\n const state = toState<{ memory: TeachablesStore; userId: string }>(\n options,\n );\n await state.memory.remember(state.userId, memory as GeneratedTeachable);\n return 'Remembered.';\n },\n }),\n forget_memory: tool({\n description:\n 'Forget a specific memory. Use when user asks to remove something.',\n inputSchema: z.object({\n id: z.string().describe('The ID of the teachable to forget'),\n }),\n execute: async ({ id }, options) => {\n const state = toState<{ memory: TeachablesStore }>(options);\n await state.memory.forget(id);\n return 'Forgotten.';\n },\n }),\n recall_memory: tool({\n description:\n 'List stored memories for the current user. Use when user asks what you remember about them or wants to see their stored preferences.',\n inputSchema: z.object({\n type: z\n .enum(userMemoryTypes)\n .optional()\n .catch(undefined)\n .describe('Optional: filter by memory type'),\n }),\n execute: async ({ type }, options) => {\n const state = toState<{ memory: TeachablesStore; userId: string }>(\n options,\n );\n const memories = await state.memory.recall(state.userId, type);\n if (memories.length === 0) {\n return type ? `No ${type} memories stored.` : 'No memories stored.';\n }\n return memories.map((m) => ({\n id: m.id,\n type: m.type,\n data: m.data,\n createdAt: m.createdAt,\n }));\n },\n }),\n update_memory: tool({\n description:\n 'Update an existing memory. Use when user wants to modify something you previously stored.',\n inputSchema: z.object({\n memory: userMemorySchema,\n id: z.string().describe('The ID of the memory to update'),\n }),\n execute: async ({ id, memory }, options) => {\n const state = toState<{ memory: TeachablesStore }>(options);\n await state.memory.update(id, memory as GeneratedTeachable);\n return 'Updated.';\n },\n }),\n};\n\nconst SQL_STEP_BACK_EXAMPLES: StepBackExample[] = [\n {\n originalQuestion: 'Who are our top 5 customers by spending?',\n stepBackQuestion:\n 'What are the SQL principles for ranking and aggregation queries?',\n stepBackAnswer:\n 'Ranking queries require: 1) Aggregation functions (SUM, COUNT, AVG) grouped by the entity to rank, 2) JOINs to connect related data across tables (e.g., Customer to Invoice), 3) ORDER BY to sort by the aggregated metric, 4) LIMIT to restrict to top N results. For customer spending, join Customer and Invoice tables, sum invoice totals, group by customer identifier, order by total descending.',\n finalAnswer:\n 'SELECT c.FirstName, c.LastName, SUM(i.Total) as total_spent FROM Customer c JOIN Invoice i ON c.CustomerId = i.CustomerId GROUP BY c.CustomerId ORDER BY total_spent DESC LIMIT 5',\n },\n {\n originalQuestion: 'Show me sales by month for 2013',\n stepBackQuestion:\n 'What are the principles of time-based grouping and aggregation in SQL?',\n stepBackAnswer:\n 'Time-based queries require: 1) Date extraction functions (e.g., DATE_TRUNC, strftime, YEAR/FORMAT) to bucket timestamps, 2) WHERE clauses to filter the date range, 3) GROUP BY the derived period, 4) Aggregations such as SUM for revenue and COUNT for transactions, 5) ORDER BY the period chronologically.',\n finalAnswer:\n \"SELECT date_trunc('month', InvoiceDate) as month, COUNT(*) as sales_count, SUM(Total) as revenue FROM Invoice WHERE EXTRACT(year FROM InvoiceDate) = 2013 GROUP BY month ORDER BY month -- replace date_trunc/EXTRACT with your dialect's month/year helpers\",\n },\n {\n originalQuestion: 'What are the best-selling tracks by genre?',\n stepBackQuestion:\n 'What are the SQL principles for multi-dimensional aggregation with categories?',\n stepBackAnswer:\n 'Multi-dimensional queries require: 1) Multiple JOINs to connect entities through foreign key relationships (Genre \u2192 Track \u2192 InvoiceLine), 2) GROUP BY all categorical dimensions you want to analyze (GenreId, TrackId), 3) Aggregation at the intersection of these dimensions (COUNT of sales per track per genre), 4) Proper table aliasing for query readability, 5) Understanding the data model relationships (which tables link to which).',\n finalAnswer:\n 'SELECT g.Name as genre, t.Name as track, COUNT(*) as times_sold FROM Genre g JOIN Track t ON g.GenreId = t.GenreId JOIN InvoiceLine il ON t.TrackId = il.TrackId GROUP BY g.GenreId, t.TrackId ORDER BY times_sold DESC LIMIT 10',\n },\n];\n\nexport const sqlQueryAgent = agent({\n name: 'text2sql',\n model: groq('openai/gpt-oss-20b'),\n tools,\n // output: z.object({\n // sql: z\n // .string()\n // .describe('The SQL query generated to answer the user question.'),\n // }),\n prompt: (state) => {\n return `\n <agent>\n <name>Freya</name>\n <role>You are an expert SQL query generator, answering business questions with accurate queries.</role>\n <tone>Your tone should be concise and business-friendly.</tone>\n </agent>\n ${state?.teachings || ''}\n ${state?.introspection || ''}\n <output>SQL query that can run directly without prose whatsoever</output>\n `;\n },\n});\n\n/**\n * An agent that does Table Augmented Generation for Text-to-SQL tasks.\n */\nexport const t_a_g = agent<\n { sql: string },\n {\n // FIXME: this should not be here after creating the context package\n introspection: string;\n teachings: string;\n memory?: TeachablesStore;\n userId?: string;\n }\n>({\n model: groq('openai/gpt-oss-20b'),\n tools,\n name: 'text2sql',\n prompt: (state) => {\n const hasMemory = !!state?.memory;\n\n return `\n\n ${state?.teachings || ''}\n ${state?.introspection || ''}\n\n ${hasMemory ? memoryPrompt : ''}\n `;\n },\n});\n", "export function wrapBlock(tag: string, children: string[]): string {\n const content = children\n .filter((child): child is string => Boolean(child))\n .join('\\n');\n if (!content) {\n return '';\n }\n return `<${tag}>\\n${indentBlock(content, 2)}\\n</${tag}>`;\n}\n\nexport function list(tag: string, values: string[], childTag: string): string {\n if (!values.length) {\n return '';\n }\n const children = values.map((value) => leaf(childTag, value)).join('\\n');\n return `<${tag}>\\n${indentBlock(children, 2)}\\n</${tag}>`;\n}\n\nexport function leaf(tag: string, value: string): string {\n const safe = escapeXml(value);\n if (safe.includes('\\n')) {\n return `<${tag}>\\n${indentBlock(safe, 2)}\\n</${tag}>`;\n }\n return `<${tag}>${safe}</${tag}>`;\n}\n\nexport function indentBlock(text: string, spaces: number): string {\n if (!text.trim()) {\n return '';\n }\n const padding = ' '.repeat(spaces);\n return text\n .split('\\n')\n .map((line) => (line.length ? padding + line : padding))\n .join('\\n');\n}\n\nexport function escapeXml(value: string): string {\n if (value == null) {\n return '';\n }\n return value\n .replaceAll(/&/g, '&')\n .replaceAll(/</g, '<')\n .replaceAll(/>/g, '>')\n .replaceAll(/\"/g, '"')\n .replaceAll(/'/g, ''');\n}\n", "import { indentBlock, leaf, list, wrapBlock } from './xml.ts';\n\nexport interface Teachables {\n type:\n | 'term'\n | 'hint'\n | 'guardrail'\n | 'explain'\n | 'example'\n | 'clarification'\n | 'workflow'\n | 'quirk'\n | 'styleGuide'\n | 'analogy'\n | 'glossary'\n | 'user_profile'\n // User-specific teachable types\n | 'identity'\n | 'persona'\n | 'alias'\n | 'preference'\n | 'context'\n | 'correction';\n format: () => string;\n}\nexport type GeneratedTeachable =\n | { type: 'term'; name: string; definition: string }\n | { type: 'hint'; text: string }\n | { type: 'guardrail'; rule: string; reason?: string; action?: string }\n | {\n type: 'explain';\n concept: string;\n explanation: string;\n therefore?: string;\n }\n | { type: 'example'; question: string; answer: string; note?: string }\n | { type: 'clarification'; when: string; ask: string; reason: string }\n | {\n type: 'workflow';\n task: string;\n steps: string[];\n triggers?: string[];\n notes?: string;\n }\n | { type: 'quirk'; issue: string; workaround: string }\n | { type: 'styleGuide'; prefer: string; never?: string; always?: string }\n | {\n type: 'analogy';\n concept: string[];\n relationship: string;\n insight?: string;\n therefore?: string;\n pitfall?: string;\n }\n | { type: 'glossary'; entries: Record<string, string> }\n // User-specific teachable types\n | { type: 'identity'; name?: string; role?: string }\n | { type: 'persona'; name: string; role: string; tone: string }\n | { type: 'alias'; term: string; meaning: string }\n | { type: 'preference'; aspect: string; value: string }\n | { type: 'context'; description: string }\n | { type: 'correction'; subject: string; clarification: string };\n\n/**\n * Teach the system domain-specific vocabulary and business terminology.\n *\n * Use this to define simple, direct mappings between business terms and their meanings.\n * The system will understand these terms when users mention them in queries.\n *\n * @param name - The business term or acronym to define\n * @param definition - What the term means in your domain\n *\n * @example\n * // Logistics/Transportation dataset\n * term(\"deadhead miles\", \"distance driven with empty truck between deliveries\")\n * term(\"dwell time\", \"total time a truck spends at a loading dock or warehouse\")\n * term(\"LTL\", \"less than truckload - shipment that doesn't fill entire truck\")\n *\n * @example\n * // Education/University dataset\n * term(\"matriculation\", \"students who completed enrollment and started classes\")\n * term(\"DFW rate\", \"percentage of students receiving D, F, or Withdrawal in a course\")\n * term(\"cohort\", \"group of students who entered the same semester or academic year\")\n *\n * @example\n * // Finance/Banking dataset\n * term(\"NPL\", \"non-performing loan - loan past due 90+ days\")\n * term(\"basis points\", \"one hundredth of a percentage point (1% = 100 bps)\")\n * term(\"AUM\", \"assets under management - total market value of client investments\")\n */\nexport function term(name: string, definition: string): Teachables {\n return {\n type: 'term',\n format: () =>\n wrapBlock('term', [leaf('name', name), leaf('definition', definition)]),\n };\n}\n\n/**\n * Teach the system behavioral rules and constraints that should always apply.\n *\n * Use this for business logic, data quality rules, or query preferences that should\n * be automatically applied to all relevant queries. Hints are injected as constraints\n * in the system prompt.\n *\n * @param text - The rule or constraint to follow (use imperative language)\n *\n * @example\n * // Manufacturing/Supply Chain dataset\n * hint(\"Always exclude work orders with status = 'simulation' from production metrics\")\n * hint(\"When calculating OEE (overall equipment effectiveness), only count scheduled production time\")\n * hint(\"Defect rates should be calculated per batch, not per individual unit, for consistency\")\n *\n * @example\n * // Real Estate/Property dataset\n * hint(\"Never include properties with listing_status = 'draft' in market analysis\")\n * hint(\"Always filter out duplicate MLS listings - use the earliest listing_date for each property_id\")\n * hint(\"Square footage comparisons must specify if including or excluding basement/garage\")\n *\n * @example\n * // Social Media/Content Platform dataset\n * hint(\"Engagement metrics should exclude bot accounts identified by is_verified_human = false\")\n * hint(\"View counts reset daily - always use cumulative_views for historical analysis\")\n * hint(\"Default content filters to published_status = 'public' unless analyzing drafts\")\n */\nexport function hint(text: string): Teachables {\n return {\n type: 'hint',\n format: () => leaf('hint', text),\n };\n}\n\n/**\n * Define hard guardrails, safety rules, and compliance boundaries the system must enforce.\n *\n * Use this for \"never do\" rules, sensitive data handling, and required behaviors when\n * certain conditions occur. Guardrails should be explicit and action oriented.\n *\n * @param input.rule - The guardrail or restriction to enforce\n * @param input.reason - Why this guardrail exists (compliance, security, performance)\n * @param input.action - What to do when this guardrail is triggered (block, ask, sanitize)\n *\n * @example\n * // Healthcare dataset\n * guardrail({\n * rule: \"Never return PHI like SSN, MRN, or full address in query results\",\n * reason: \"HIPAA compliance\",\n * action: \"If asked, state that identifiable patient data cannot be shared; offer de-identified aggregates instead\"\n * })\n *\n * @example\n * // Finance dataset\n * guardrail({\n * rule: \"Block any query exposing employee-level compensation by name\",\n * reason: \"Confidential payroll data\",\n * action: \"Provide ranges grouped by department or level instead of individual salaries\"\n * })\n *\n * @example\n * // E-commerce dataset\n * guardrail({\n * rule: \"Warn when a query would scan more than 10 million rows; require a narrower date range\",\n * reason: \"Performance and cost control\",\n * action: \"Ask the user to add filters (recent timeframe, specific categories) before proceeding\"\n * })\n */\nexport function guardrail(input: {\n rule: string;\n reason?: string;\n action?: string;\n}): Teachables {\n const { rule, reason, action } = input;\n return {\n type: 'guardrail',\n format: () =>\n wrapBlock('guardrail', [\n leaf('rule', rule),\n reason ? leaf('reason', reason) : '',\n action ? leaf('action', action) : '',\n ]),\n };\n}\n\n/**\n * Teach the system a rich understanding of a single concept using metaphors and explanations.\n *\n * Use this when a simple term definition isn't enough - when you need to convey deeper\n * understanding about how to think about and calculate a metric or concept.\n *\n * @param input.concept - The concept being explained\n * @param input.explanation - A metaphor or detailed explanation (often using real-world comparisons)\n * @param input.therefore - Optional actionable instruction based on this understanding\n *\n * @example\n * // Gaming/Entertainment dataset\n * explain({\n * concept: \"daily active users to monthly active users ratio\",\n * explanation: \"like measuring how many club members visit daily vs just once a month - shows stickiness\",\n * therefore: \"Calculate as DAU / MAU, where higher ratio (closer to 1) means more engaged user base\"\n * })\n *\n * @example\n * // HR/Employee Management dataset\n * explain({\n * concept: \"time to fill\",\n * explanation: \"like measuring how long a house sits on the market - from posting job to accepting offer\",\n * therefore: \"Calculate as days between job_posted_date and offer_accepted_date, exclude cancelled requisitions\"\n * })\n *\n * @example\n * // Telecommunications dataset\n * explain({\n * concept: \"network congestion ratio\",\n * explanation: \"like rush hour traffic density - measures actual usage vs total capacity at peak times\",\n * therefore: \"Calculate as (peak_hour_bandwidth_used / total_bandwidth_capacity) during busiest hour of day\"\n * })\n */\nexport function explain(input: {\n concept: string;\n explanation: string;\n therefore?: string;\n}): Teachables {\n const { concept, explanation, therefore } = input;\n return {\n type: 'explain',\n format: () =>\n wrapBlock('explanation', [\n leaf('concept', concept),\n leaf('details', explanation),\n therefore ? leaf('therefore', therefore) : '',\n ]),\n };\n}\n\n/**\n * Teach the system through concrete examples of question \u2192 SQL pairs.\n *\n * Use this for few-shot learning - show the system exactly how to translate\n * specific types of questions into SQL queries. Great for establishing patterns\n * and handling domain-specific query structures.\n *\n * @param input.question - The natural language question or request\n * @param input.answer - The correct answer that responds to the question\n * @param input.note - Optional note or explanation about the example\n *\n * @example\n * // Energy/Utilities dataset\n * example({\n * question: \"show me peak demand hours for the last week\",\n * answer: \"SELECT DATE_TRUNC('hour', reading_timestamp) as hour, MAX(consumption_kwh) as peak_demand FROM meter_readings WHERE reading_timestamp >= CURRENT_DATE - INTERVAL '7 days' GROUP BY hour ORDER BY peak_demand DESC LIMIT 10\"\n * })\n *\n * @example\n * // Agriculture/Farm Management dataset\n * example({\n * question: \"what is the average yield per acre by crop type this season\",\n * answer: \"SELECT crop_type, AVG(harvest_quantity / field_acres) as yield_per_acre FROM harvests WHERE harvest_date >= '2024-01-01' GROUP BY crop_type ORDER BY yield_per_acre DESC\"\n * })\n *\n * @example\n * // Travel/Hospitality dataset\n * example({\n * question: \"show me hotel occupancy rate for this month\",\n * answer: \"SELECT hotel_name, (SUM(occupied_rooms) / SUM(total_rooms)) * 100 as occupancy_rate FROM daily_occupancy WHERE date >= DATE_TRUNC('month', CURRENT_DATE) GROUP BY hotel_id, hotel_name ORDER BY occupancy_rate DESC\",\n * note: \"Occupancy rate is a percentage - multiply by 100 for readable output\"\n * })\n */\nexport function example(input: {\n question: string;\n answer: string;\n note?: string;\n}): Teachables {\n const { question, answer, note } = input;\n return {\n type: 'example',\n format: () =>\n wrapBlock('example', [\n leaf('question', question),\n leaf('answer', answer),\n note ? leaf('note', note) : '',\n ]),\n };\n}\n\n/**\n * Teach the system when and what to ask for clarification.\n *\n * Use this to handle ambiguous terms or situations where the system should\n * proactively ask the user for more information before generating a query.\n * Makes the system more conversational and precise.\n *\n * @param input.when - The condition or trigger that should prompt clarification\n * @param input.ask - The question to ask the user\n * @param input.reason - Why this clarification is necessary (helps system understand importance)\n *\n * @example\n * // Marketing/Advertising dataset\n * clarification({\n * when: \"user asks for 'conversion rate'\",\n * ask: \"Which conversion: click-to-lead, lead-to-opportunity, or opportunity-to-customer?\",\n * reason: \"Conversion rate means different things at each funnel stage - need to specify which metric\"\n * })\n *\n * @example\n * // Food Delivery dataset\n * clarification({\n * when: \"user asks about 'delivery time'\",\n * ask: \"Do you mean estimated time at order, actual delivery time, or time from kitchen to door?\",\n * reason: \"Multiple time metrics exist - estimated vs actual impacts customer satisfaction differently\"\n * })\n *\n * @example\n * // Fitness/Gym Management dataset\n * clarification({\n * when: \"user mentions 'active members'\",\n * ask: \"Do you mean paid memberships or members who actually visited in last 30 days?\",\n * reason: \"Many paid members don't use facilities - different metrics for revenue vs utilization\"\n * })\n */\nexport function clarification(input: {\n when: string;\n ask: string;\n reason: string;\n}): Teachables {\n const { when, ask, reason } = input;\n return {\n type: 'clarification',\n format: () =>\n wrapBlock('clarification', [\n leaf('when', when),\n leaf('ask', ask),\n leaf('reason', reason),\n ]),\n };\n}\n\n/**\n * Teach the system multi-step analytical processes that can't be solved with a single query.\n *\n * Use this for complex analytical tasks that require multiple CTEs, sequential logic,\n * or specific methodologies. Workflows teach the system HOW to approach a type of analysis.\n *\n * @param input.task - Name of the analytical task\n * @param input.steps - Sequential steps to execute (can include SQL snippets or descriptions)\n * @param input.triggers - Optional phrases that should activate this workflow\n * @param input.notes - Optional additional context, warnings, or guidance\n *\n * @example\n * // Insurance dataset\n * workflow({\n * task: \"Claims Loss Ratio Analysis\",\n * triggers: [\"loss ratio\", \"claims ratio\", \"underwriting performance\"],\n * steps: [\n * \"Calculate total claims paid for each policy period\",\n * \"Calculate total premiums earned for same period\",\n * \"Compute loss ratio as (claims_paid / premiums_earned) * 100\",\n * \"Segment by policy type, geography, and underwriter\",\n * \"Identify policies with loss ratio > 100% (losing money)\",\n * \"Calculate trend over time using rolling 12-month windows\"\n * ],\n * notes: \"Use incurred date for claims, not paid date. Exclude reinsurance recoveries from claims total.\"\n * })\n *\n * @example\n * // Media/Publishing dataset\n * workflow({\n * task: \"Content Performance Funnel\",\n * triggers: [\"content funnel\", \"engagement funnel\", \"content performance\"],\n * steps: [\n * \"Count total impressions (articles shown) per content piece\",\n * \"Count click-throughs (articles opened)\",\n * \"Count scroll depth > 50% (meaningful engagement)\",\n * \"Count shares, comments, or saves (viral actions)\",\n * \"Calculate conversion rate at each funnel stage\",\n * \"Identify top-performing content by final conversion rate\"\n * ],\n * notes: \"Requires multiple event types. Join events table multiple times or use conditional aggregation.\"\n * })\n *\n * @example\n * // Sports Analytics dataset\n * workflow({\n * task: \"Player Performance Rating Calculation\",\n * triggers: [\"player rating\", \"performance score\", \"player analytics\"],\n * steps: [\n * \"Aggregate per-game stats: points, assists, rebounds, turnovers\",\n * \"Calculate efficiency metrics: shooting percentage, plus/minus\",\n * \"Normalize each metric using z-scores vs league average\",\n * \"Apply position-specific weights to each metric\",\n * \"Combine weighted scores into overall performance rating (0-100)\",\n * \"Rank players within position group and overall\"\n * ],\n * notes: \"Requires league-wide statistics for normalization. Update weights each season based on game trends.\"\n * })\n */\nexport function workflow(input: {\n task: string;\n steps: string[];\n triggers?: string[];\n notes?: string;\n}): Teachables {\n const { task, steps, triggers, notes } = input;\n return {\n type: 'workflow',\n format: () =>\n wrapBlock('workflow', [\n leaf('task', task),\n triggers?.length ? list('triggers', triggers, 'trigger') : '',\n list('steps', steps, 'step'),\n notes ? leaf('notes', notes) : '',\n ]),\n };\n}\n\n/**\n * Teach the system about data quirks, edge cases, or database-specific issues and their workarounds.\n *\n * Use this to document weird data patterns, database limitations, or special handling\n * required for specific scenarios. Helps the system navigate real-world messiness.\n *\n * @param input.issue - Description of the quirk, edge case, or problem\n * @param input.workaround - How to handle or work around this issue\n *\n * @example\n * // Government/Public Services dataset\n * quirk({\n * issue: \"Citizen IDs contain leading zeros but are stored as integers, losing the zeros\",\n * workaround: \"Always cast to VARCHAR and use LPAD(citizen_id::VARCHAR, 10, '0') to restore leading zeros\"\n * })\n *\n * @example\n * // Aviation dataset\n * quirk({\n * issue: \"Flight times crossing midnight show as negative duration (landing before takeoff)\",\n * workaround: \"Add 24 hours when calculated duration < 0: CASE WHEN duration < 0 THEN duration + INTERVAL '24 hours' ELSE duration END\"\n * })\n *\n * @example\n * // Automotive/Dealership dataset\n * quirk({\n * issue: \"VIN numbers with letter 'O' were incorrectly entered as zero '0' in legacy data\",\n * workaround: \"When searching by VIN, use REPLACE(vin, '0', 'O') or fuzzy matching to handle both cases\"\n * })\n */\nexport function quirk(input: {\n issue: string;\n workaround: string;\n}): Teachables {\n const { issue, workaround } = input;\n return {\n type: 'quirk',\n format: () =>\n wrapBlock('quirk', [\n leaf('issue', issue),\n leaf('workaround', workaround),\n ]),\n };\n}\n\n/**\n * Teach the system SQL style preferences and coding standards for generated queries.\n *\n * Use this to enforce consistent SQL formatting, naming conventions, and best practices\n * specific to your team or organization. Improves readability and maintainability.\n *\n * @param input.prefer - Preferred SQL style or pattern\n * @param input.never - Optional anti-pattern to avoid\n * @param input.always - Optional rule that must always be followed\n *\n * @example\n * // Non-profit/Charity dataset\n * styleGuide({\n * prefer: \"Use donor-centric language in column aliases: 'donor_name' not 'customer_name'\",\n * never: \"Never expose internal donor IDs in external reports - use public gift IDs\",\n * always: \"Always include fiscal year in date-based aggregations (FY starts July 1)\"\n * })\n *\n * @example\n * // Legal/Law Firm dataset\n * styleGuide({\n * prefer: \"Use billable_hours with 2 decimal precision for accurate client billing\",\n * never: \"Never include attorney_rate in queries visible to paralegals - confidential data\",\n * always: \"Always filter by matter_status = 'open' unless specifically analyzing closed cases\"\n * })\n *\n * @example\n * // Inventory/Warehouse dataset\n * styleGuide({\n * prefer: \"Use location_id in joins rather than location_name (duplicates exist across warehouses)\",\n * never: \"Never aggregate inventory without grouping by warehouse_id first\",\n * always: \"Always use inventory_on_hand - inventory_reserved for available stock calculations\"\n * })\n */\nexport function styleGuide(input: {\n prefer: string;\n never?: string;\n always?: string;\n}): Teachables {\n const { prefer, never, always } = input;\n return {\n type: 'styleGuide',\n format: () =>\n wrapBlock('style_guide', [\n leaf('prefer', prefer),\n always ? leaf('always', always) : '',\n never ? leaf('never', never) : '',\n ]),\n };\n}\n\n/**\n * Teach the system by comparing related concepts through real-world analogies.\n *\n * Use this to teach relational understanding between two concepts by drawing comparisons\n * to familiar real-world scenarios. Helps the system understand WHY concepts differ and\n * when to use each one appropriately.\n *\n * @param input.concept - Array of two related concepts to compare\n * @param input.relationship - The comparison/analogy using real-world examples\n * @param input.insight - Optional key insight the analogy reveals\n * @param input.therefore - Optional actionable instruction based on this understanding\n * @param input.pitfall - Optional common mistake to avoid\n *\n * @example\n * // E-commerce dataset\n * analogy({\n * concept: [\"cart abandonment\", \"browse abandonment\"],\n * relationship: \"Cart abandonment is like leaving items at a checkout counter, browse abandonment is like window shopping without picking anything up\",\n * insight: \"Cart abandonment shows purchase intent (added to cart), browse abandonment shows only interest\",\n * therefore: \"Prioritize cart abandonment recovery campaigns - higher conversion potential than browse\",\n * pitfall: \"Don't combine both into generic 'abandonment rate' - they need different marketing strategies\"\n * })\n *\n * @example\n * // SaaS dataset\n * analogy({\n * concept: [\"logo churn\", \"revenue churn\"],\n * relationship: \"Logo churn is like counting how many customers left the store, revenue churn is how much money walked out\",\n * insight: \"Losing 10 small customers (high logo churn) might hurt less than losing 1 enterprise customer (high revenue churn)\",\n * therefore: \"Always report both metrics - logo churn for customer satisfaction, revenue churn for financial health\",\n * pitfall: \"Don't use logo churn to predict revenue impact - customer size distribution matters\"\n * })\n *\n * @example\n * // Healthcare dataset\n * analogy({\n * concept: [\"incident\", \"prevalence\"],\n * relationship: \"Incidence is like new house sales this month, prevalence is total houses currently occupied\",\n * insight: \"Incidence measures new cases over time, prevalence measures all existing cases at a point in time\",\n * therefore: \"For tracking disease outbreaks use incidence rate, for resource planning use prevalence\",\n * pitfall: \"Don't sum incidence rates across time periods - it's a rate not a count\"\n * })\n */\nexport function analogy(input: {\n concept: string[];\n relationship: string;\n insight?: string;\n therefore?: string;\n pitfall?: string;\n}): Teachables {\n const { concept, relationship, insight, therefore, pitfall } = input;\n return {\n type: 'analogy',\n format: () =>\n wrapBlock('analogy', [\n list('concepts', concept, 'concept'),\n leaf('relationship', relationship),\n insight ? leaf('insight', insight) : '',\n therefore ? leaf('therefore', therefore) : '',\n pitfall ? leaf('pitfall', pitfall) : '',\n ]),\n };\n}\n\n/**\n * Map business terms directly to SQL expressions or fragments.\n *\n * Use this to teach the system how to CALCULATE or QUERY specific business concepts.\n * The system will substitute these SQL patterns when users mention the term.\n *\n * **Glossary vs Alias:**\n * - `alias` = user vocabulary \u2192 table/column name (\"the big table\" \u2192 \"orders table\")\n * - `glossary` = business term \u2192 SQL expression (\"revenue\" \u2192 \"SUM(orders.total_amount)\")\n *\n * In short: alias renames, glossary computes.\n *\n * @param entries - Record mapping business terms to their SQL expressions\n *\n * @example\n * glossary({\n * \"revenue\": \"SUM(orders.total_amount)\",\n * \"average order value\": \"AVG(orders.total_amount)\",\n * \"active user\": \"last_login > NOW() - INTERVAL '30 days'\",\n * \"churned\": \"status = 'churned'\",\n * \"power user\": \"order_count > 10\",\n * \"net revenue\": \"SUM(orders.total_amount) - SUM(refunds.amount)\",\n * })\n */\nexport function glossary(entries: Record<string, string>): Teachables {\n return {\n type: 'glossary',\n format: () =>\n wrapBlock(\n 'glossary',\n Object.entries(entries).map(([term, sql]) =>\n wrapBlock('entry', [leaf('term', term), leaf('sql', sql)]),\n ),\n ),\n };\n}\n\n// =============================================================================\n// User-Specific Teachable Types\n// =============================================================================\n\n/**\n * Define the user's identity including name and/or role.\n *\n * Use this to capture who the user is and what lens they view data through.\n * Helps tailor explanations, terminology, and focus areas.\n *\n * @param input.name - The user's name (optional)\n * @param input.role - The user's role or position (optional)\n *\n * @example\n * identity({ name: \"John\", role: \"VP of Sales\" })\n * identity({ role: \"Data analyst in the marketing team\" })\n * identity({ name: \"Sarah\" })\n * identity({ role: \"Finance manager focused on cost optimization\" })\n */\nexport function identity(input: { name?: string; role?: string }): Teachables {\n const { name, role } = input;\n return {\n type: 'identity',\n format: () =>\n wrapBlock('identity', [\n name ? leaf('name', name) : '',\n role ? leaf('role', role) : '',\n ]),\n };\n}\n\n/**\n * Define an AI persona with a name, role, and communication tone.\n *\n * Use this to customize the assistant's personality and how it communicates.\n * The persona influences the style and approach of responses.\n *\n * @param input.name - The persona's name\n * @param input.role - The persona's role or expertise\n * @param input.tone - The communication style (e.g., friendly, professional, concise)\n *\n * @example\n * persona({ name: \"DataBot\", role: \"SQL Expert\", tone: \"friendly and encouraging\" })\n * persona({ name: \"QueryMaster\", role: \"Database Analyst\", tone: \"professional and concise\" })\n * persona({ name: \"SQLHelper\", role: \"Data Assistant\", tone: \"casual and approachable\" })\n */\nexport function persona(input: {\n name: string;\n role: string;\n tone: string;\n}): Teachables {\n const { name, role, tone } = input;\n return {\n type: 'persona',\n format: () =>\n wrapBlock('persona', [\n leaf('name', name),\n leaf('role', role),\n leaf('tone', tone),\n ]),\n };\n}\n\n/**\n * Define user-specific term meanings and vocabulary.\n *\n * Use this when the user has their own definitions for terms that might\n * differ from standard or domain definitions. Like `term()` but personal.\n *\n * @param termName - The term the user uses\n * @param meaning - What the user means by this term\n *\n * @example\n * alias(\"revenue\", \"gross revenue before deductions, not net\")\n * alias(\"active users\", \"users who logged in within the last 30 days\")\n * alias(\"the big table\", \"the orders table\")\n * alias(\"Q4\", \"October through December, not fiscal Q4\")\n */\nexport function alias(termName: string, meaning: string): Teachables {\n return {\n type: 'alias',\n format: () =>\n wrapBlock('alias', [leaf('term', termName), leaf('meaning', meaning)]),\n };\n}\n\n/**\n * Define how the user prefers results presented.\n *\n * Use this to capture output formatting, style, and behavioral preferences\n * that should apply to all interactions with this user.\n *\n * @param aspect - What aspect of output this preference applies to\n * @param value - The user's preference\n *\n * @example\n * preference(\"date format\", \"YYYY-MM-DD\")\n * preference(\"output style\", \"tables over charts unless trend data\")\n * preference(\"detail level\", \"always show the SQL query in responses\")\n * preference(\"row limit\", \"default to 50 rows unless I ask for more\")\n * preference(\"explanation style\", \"brief and to the point\")\n */\nexport function preference(aspect: string, value: string): Teachables {\n return {\n type: 'preference',\n format: () =>\n wrapBlock('preference', [leaf('aspect', aspect), leaf('value', value)]),\n };\n}\n\n/**\n * Define the user's current working focus or project.\n *\n * Use this to capture temporary context that helps inform defaults,\n * assumptions, and suggestions. Should be updated as focus changes.\n *\n * @param description - What the user is currently working on\n *\n * @example\n * context(\"Preparing Q4 board presentation\")\n * context(\"Investigating drop in signups last week\")\n * context(\"Working on EMEA regional analysis for strategy meeting\")\n * context(\"Debugging discrepancy in revenue numbers\")\n */\nexport function context(description: string): Teachables {\n return {\n type: 'context',\n format: () => leaf('context', description),\n };\n}\n\n/**\n * Record a correction the user made to previous understanding.\n *\n * Use this when the user corrects a misunderstanding about data, columns,\n * or business logic. Prevents repeating the same mistake.\n *\n * @param subject - What was misunderstood\n * @param clarification - The correct understanding\n *\n * @example\n * correction(\"status column\", \"1 = active, 0 = inactive, not boolean true/false\")\n * correction(\"orders table\", \"Use orders_v2, not the deprecated legacy_orders table\")\n * correction(\"date field\", \"order_date is when order was placed, ship_date is when shipped\")\n * correction(\"revenue calculation\", \"Must exclude refunds and chargebacks\")\n */\nexport function correction(subject: string, clarification: string): Teachables {\n return {\n type: 'correction',\n format: () =>\n wrapBlock('correction', [\n leaf('subject', subject),\n leaf('clarification', clarification),\n ]),\n };\n}\n\nexport function teachable(\n tag: string,\n ...teachables: Teachables[]\n): Teachables {\n return {\n type: 'user_profile',\n format: () => toInstructions(tag, ...teachables),\n };\n}\n\nexport function toInstructions(\n tag: string,\n ...teachables: Teachables[]\n): string {\n if (!teachables.length) {\n return '';\n }\n\n const grouped = new Map<Teachables['type'], Teachables[]>();\n for (const teachable of teachables) {\n const existing = grouped.get(teachable.type) ?? [];\n existing.push(teachable);\n grouped.set(teachable.type, existing);\n }\n\n const definedTypes = new Set(SECTION_ORDER.map((s) => s.type));\n\n const sections = SECTION_ORDER.map(({ type, tag }) => {\n const items = grouped.get(type);\n if (!items?.length) {\n return '';\n }\n const renderedItems = items\n .map((item) => item.format().trim())\n .filter(Boolean)\n .map((item) => indentBlock(item, 2))\n .join('\\n');\n if (!renderedItems.length) {\n return '';\n }\n return `<${tag}>\\n${renderedItems}\\n</${tag}>`;\n }).filter((section): section is string => Boolean(section));\n\n // Render types not defined in SECTION_ORDER at the end\n for (const [type, items] of grouped) {\n if (definedTypes.has(type)) {\n continue;\n }\n const renderedItems = items\n .map((item) => item.format().trim())\n .filter(Boolean)\n .map((item) => indentBlock(item, 2))\n .join('\\n');\n if (renderedItems.length) {\n sections.push(renderedItems);\n }\n }\n\n if (!sections.length) {\n return '';\n }\n\n const content = indentBlock(sections.join('\\n'), 2);\n return `<${tag}>\\n${content}\\n</${tag}>`;\n}\n\nconst SECTION_ORDER: Array<{ type: Teachables['type']; tag: string }> = [\n // User context (render first - most important for personalization)\n { type: 'identity', tag: 'identity' },\n { type: 'persona', tag: 'persona' },\n { type: 'context', tag: 'user_context' },\n { type: 'preference', tag: 'user_preferences' },\n { type: 'alias', tag: 'user_vocabulary' },\n { type: 'correction', tag: 'user_corrections' },\n // Domain knowledge\n { type: 'guardrail', tag: 'guardrails' },\n { type: 'styleGuide', tag: 'style_guides' },\n { type: 'hint', tag: 'hints' },\n { type: 'clarification', tag: 'clarifications' },\n { type: 'workflow', tag: 'workflows' },\n { type: 'quirk', tag: 'quirks' },\n { type: 'term', tag: 'terminology' },\n { type: 'explain', tag: 'explanations' },\n { type: 'analogy', tag: 'analogies' },\n { type: 'glossary', tag: 'glossary' },\n { type: 'example', tag: 'examples' },\n];\n\nexport function toTeachables(generated: GeneratedTeachable[]): Teachables[] {\n return generated.map((item) => {\n switch (item.type) {\n case 'persona':\n return persona({ name: item.name, role: item.role, tone: item.tone });\n case 'term':\n return term(item.name, item.definition);\n case 'hint':\n return hint(item.text);\n case 'guardrail':\n return guardrail({\n rule: item.rule,\n reason: item.reason,\n action: item.action,\n });\n case 'explain':\n return explain({\n concept: item.concept,\n explanation: item.explanation,\n therefore: item.therefore,\n });\n case 'example':\n return example({\n question: item.question,\n answer: item.answer,\n note: item.note,\n });\n case 'clarification':\n return clarification({\n when: item.when,\n ask: item.ask,\n reason: item.reason,\n });\n case 'workflow':\n return workflow({\n task: item.task,\n steps: item.steps,\n triggers: item.triggers,\n notes: item.notes,\n });\n case 'quirk':\n return quirk({\n issue: item.issue,\n workaround: item.workaround,\n });\n case 'styleGuide':\n return styleGuide({\n prefer: item.prefer,\n never: item.never,\n always: item.always,\n });\n case 'analogy':\n return analogy({\n concept: item.concept,\n relationship: item.relationship,\n insight: item.insight,\n therefore: item.therefore,\n pitfall: item.pitfall,\n });\n case 'glossary':\n return glossary(item.entries);\n // User-specific teachable types\n case 'identity':\n return identity({ name: item.name, role: item.role });\n case 'alias':\n return alias(item.term, item.meaning);\n case 'preference':\n return preference(item.aspect, item.value);\n case 'context':\n return context(item.description);\n case 'correction':\n return correction(item.subject, item.clarification);\n }\n });\n}\n\n/**\n * Default export containing all system teachable factory functions.\n * Excludes user-specific teachables (identity, alias, preference, context, correction).\n */\nexport default {\n persona,\n term,\n hint,\n guardrail,\n explain,\n example,\n clarification,\n workflow,\n quirk,\n styleGuide,\n analogy,\n glossary,\n teachable,\n};\n", "import {\n clarification,\n example,\n explain,\n guardrail,\n hint,\n toInstructions,\n workflow,\n} from '../teach/teachables.ts';\n\nexport default toInstructions(\n 'memory_guidelines',\n\n // Section 1: Core behavior\n guardrail({\n rule: 'Silently store user information when revealed. Respond to memory-related requests.',\n reason: 'Memory enables personalized responses across conversations',\n action:\n 'Store silently on reveal. Respond explicitly when asked about memories.',\n }),\n\n // Section 2: Workflows for memory operations\n\n workflow({\n task: 'Store user identity silently',\n triggers: [\"I'm a\", 'I work as', 'my name is', 'my role is'],\n steps: [\n 'Extract name and/or role from the statement',\n 'Call remember_memory() with type: \"identity\" and name/role fields',\n 'Do NOT announce or confirm - continue conversation naturally',\n ],\n notes:\n 'This should happen silently without disrupting the conversation flow.',\n }),\n\n workflow({\n task: 'Store user preferences and context silently',\n triggers: ['When I say', 'I prefer', \"I'm working on\"],\n steps: [\n 'Identify the memory type (alias/preference/context/correction)',\n 'Extract the relevant information',\n 'Call remember_memory() with appropriate type and fields',\n 'Do NOT announce or confirm - continue conversation naturally',\n ],\n notes:\n 'This should happen silently without disrupting the conversation flow.',\n }),\n\n workflow({\n task: 'Forget a memory',\n triggers: ['forget that', 'remove my', 'delete the', \"don't remember that\"],\n steps: [\n 'Call recall_memory() to list relevant memories',\n 'Find the memory ID that matches user request',\n 'Call forget_memory({ id }) with the found ID',\n 'Confirm to user what was forgotten',\n ],\n }),\n\n workflow({\n task: 'Update a memory',\n triggers: ['actually now I', 'I changed', 'update my', 'no longer'],\n steps: [\n 'Call recall_memory() to find the existing memory',\n 'Get the memory ID from results',\n 'Call update_memory({ id, memory }) with new data',\n 'Confirm the update to user',\n ],\n }),\n\n // Section 3: Type disambiguation\n\n explain({\n concept: 'identity vs context',\n explanation:\n 'Identity = WHO the user is (name and/or role, permanent). Context = WHAT they are working on (temporary focus).',\n therefore: 'Identity rarely changes. Context changes per project/task.',\n }),\n\n explain({\n concept: 'alias vs correction',\n explanation:\n 'Alias = user defines their own term/shorthand. Correction = user fixes a misunderstanding about existing data/schema.',\n therefore: 'Alias is vocabulary. Correction is data clarification.',\n }),\n\n explain({\n concept: 'preference memory type',\n explanation:\n 'Stores output/style/format preferences. Fields: { aspect: string, value: string }',\n therefore: 'Use for formatting, limits, display style, data scope filters',\n }),\n\n // Section 4: Clarifications for ambiguous situations\n\n clarification({\n when: 'user says something like \"X actually means Y\" but unclear if defining their term or correcting data',\n ask: 'Are you defining your own shorthand for this term, or correcting how the data/schema actually works?',\n reason:\n 'Alias is personal vocabulary. Correction is a data/schema clarification that applies universally.',\n }),\n\n clarification({\n when: 'user mentions a project or task that could be their identity or current focus',\n ask: 'Is this your ongoing identity (name/role), or a specific project you are currently working on?',\n reason:\n 'Identity is permanent. Context is temporary focus that may change.',\n }),\n\n // Section 5: Examples\n\n // Identity - role\n example({\n question: \"I'm the VP of Sales\",\n answer: 'remember_memory({ memory: { type: \"identity\", role: \"VP of Sales\" }})',\n note: 'Identity stores role',\n }),\n\n // Identity - name\n example({\n question: 'My name is Sarah',\n answer: 'remember_memory({ memory: { type: \"identity\", name: \"Sarah\" }})',\n note: 'Identity stores name',\n }),\n\n // Context\n example({\n question: \"I'm analyzing Q4 performance\",\n answer: 'remember_memory({ memory: { type: \"context\", description: \"Analyzing Q4 performance\" }})',\n note: 'Current task = context',\n }),\n\n // Alias\n example({\n question: 'When I say \"big customers\", I mean revenue > $1M',\n answer: 'remember_memory({ memory: { type: \"alias\", term: \"big customers\", meaning: \"revenue > $1M\" }})',\n note: 'User defining their vocabulary = alias',\n }),\n\n // Correction\n example({\n question:\n 'No, the status column uses 1 for active, not the string \"active\"',\n answer: 'remember_memory({ memory: { type: \"correction\", subject: \"status column values\", clarification: \"Uses 1 for active, not string\" }})',\n note: 'Correcting schema/data assumption = correction',\n }),\n\n // Preference\n example({\n question: 'Always show dates as YYYY-MM-DD',\n answer: 'remember_memory({ memory: { type: \"preference\", aspect: \"date format\", value: \"YYYY-MM-DD\" }})',\n }),\n\n // Recall\n example({\n question: 'What do you remember about me?',\n answer: 'recall_memory({})',\n note: 'List all stored memories',\n }),\n\n // Section 6: What NOT to remember\n hint('Do NOT remember one-time query details like \"show last 10 orders\"'),\n hint(\n 'Do NOT remember information already stored - use recall_memory to check first',\n ),\n hint('Do NOT remember obvious or universal facts'),\n);\n", "import { createHash } from 'node:crypto';\nimport { existsSync } from 'node:fs';\nimport { readFile, writeFile } from 'node:fs/promises';\nimport { tmpdir } from 'node:os';\nimport path from 'node:path';\n\nexport class FileCache {\n public path: string;\n constructor(watermark: string, extension = '.txt') {\n const hash = createHash('md5').update(watermark).digest('hex');\n this.path = path.join(tmpdir(), `text2sql-${hash}${extension}`);\n }\n\n async get() {\n if (existsSync(this.path)) {\n return readFile(this.path, 'utf-8');\n }\n return null;\n }\n\n set(content: string) {\n return writeFile(this.path, content, 'utf-8');\n }\n}\n\nexport class JsonCache<T> extends FileCache {\n constructor(watermark: string) {\n super(watermark, '.json');\n }\n\n async read(): Promise<T | null> {\n const content = await this.get();\n if (content) {\n return JSON.parse(content) as T;\n }\n return null;\n }\n\n write(data: T) {\n return this.set(JSON.stringify(data));\n }\n}\n", "import type { UIMessage } from 'ai';\n\nexport interface Message {\n id: string;\n chatId: string;\n role: string;\n createdAt: string | Date;\n content: UIMessage;\n}\n\nexport interface Chat {\n id: string;\n userId: string;\n title?: string | null;\n messages: Message[];\n}\n\nexport interface CreateChatParams {\n id: string;\n userId: string;\n title?: string;\n}\n\nexport interface UpdateChatParams {\n title?: string;\n}\n\nexport interface CreateMessageParams {\n id: string;\n chatId: string;\n role: string;\n content: UIMessage;\n createdAt?: Date;\n}\n\nexport abstract class History {\n abstract listChats(userId: string): Promise<Chat[]>;\n abstract getChat(chatId: string): Promise<Chat | null>;\n abstract createChat(chat: CreateChatParams): Promise<Chat>;\n abstract upsertChat(chat: CreateChatParams): Promise<Chat>;\n abstract deleteChat(chatId: string): Promise<void>;\n abstract updateChat(chatId: string, updates: UpdateChatParams): Promise<void>;\n abstract addMessage(message: CreateMessageParams): Promise<void>;\n abstract upsertMessage(message: CreateMessageParams): Promise<Message>;\n abstract deleteMessage(messageId: string): Promise<void>;\n}\n", "import { DatabaseSync } from 'node:sqlite';\n\nimport historyDDL from './history.sqlite.sql';\nimport {\n type Chat,\n type CreateChatParams,\n type CreateMessageParams,\n History,\n type Message,\n type UpdateChatParams,\n} from './history.ts';\n\nexport class SqliteHistory extends History {\n #db: DatabaseSync;\n\n constructor(path: string) {\n super();\n this.#db = new DatabaseSync(path);\n this.#db.exec(historyDDL);\n }\n\n async listChats(userId: string): Promise<Chat[]> {\n return this.#db\n .prepare(`SELECT * FROM chats WHERE \"userId\" = ?`)\n .all(userId) as unknown as Chat[];\n }\n\n async getChat(chatId: string): Promise<Chat | null> {\n const rows = this.#db\n .prepare(\n `SELECT\n c.id as chatId, c.\"userId\", c.title,\n m.id as messageId, m.role, m.\"createdAt\", m.content\n FROM chats c\n LEFT JOIN messages m ON m.\"chatId\" = c.id\n WHERE c.id = ?\n ORDER BY m.\"createdAt\" ASC`,\n )\n .all(chatId) as unknown as Array<{\n chatId: string;\n userId: string;\n title: string | null;\n messageId: string | null;\n role: string;\n createdAt: string;\n content: string;\n }>;\n\n if (!rows.length) return null;\n\n const firstRow = rows[0];\n const chat: Chat = {\n id: firstRow.chatId,\n userId: firstRow.userId,\n title: firstRow.title,\n messages: [],\n };\n\n for (const row of rows) {\n if (row.messageId) {\n chat.messages.push({\n id: row.messageId,\n chatId: firstRow.chatId,\n role: row.role as string,\n createdAt: row.createdAt as string,\n content: JSON.parse(row.content),\n });\n }\n }\n\n return chat;\n }\n\n async createChat(chat: CreateChatParams): Promise<Chat> {\n this.#db\n .prepare(`INSERT INTO chats (id, \"userId\", title) VALUES (?, ?, ?)`)\n .run(chat.id, chat.userId, chat.title || null);\n return chat as Chat;\n }\n\n async upsertChat(chat: CreateChatParams) {\n this.#db\n .prepare(\n `INSERT INTO chats (id, \"userId\", title) VALUES (?, ?, ?)\n ON CONFLICT(id) DO UPDATE SET title = excluded.title, \"userId\" = excluded.\"userId\"`,\n )\n .run(chat.id, chat.userId, chat.title || null);\n return this.getChat(chat.id) as Promise<Chat>;\n }\n\n async deleteChat(chatId: string): Promise<void> {\n this.#db.prepare(`DELETE FROM chats WHERE id = ?`).run(chatId);\n }\n\n async updateChat(chatId: string, updates: UpdateChatParams): Promise<void> {\n if (updates.title !== undefined) {\n this.#db\n .prepare(`UPDATE chats SET title = ? WHERE id = ?`)\n .run(updates.title, chatId);\n }\n }\n\n async addMessage(message: CreateMessageParams): Promise<void> {\n const createdAt = message.createdAt\n ? message.createdAt.toISOString()\n : new Date().toISOString();\n this.#db\n .prepare(\n `INSERT INTO messages (id, \"chatId\", role, \"createdAt\", content) VALUES (?, ?, ?, ?, ?)`,\n )\n .run(\n message.id,\n message.chatId,\n message.role,\n createdAt,\n JSON.stringify(message.content),\n );\n }\n\n async upsertMessage(message: CreateMessageParams): Promise<Message> {\n const createdAt = message.createdAt\n ? message.createdAt.toISOString()\n : new Date().toISOString();\n this.#db\n .prepare(\n `INSERT INTO messages (id, \"chatId\", role, \"createdAt\", content) VALUES (?, ?, ?, ?, ?)\n ON CONFLICT(id) DO UPDATE SET \"chatId\" = excluded.\"chatId\", role = excluded.role, \"createdAt\" = excluded.\"createdAt\", content = excluded.content`,\n )\n .run(\n message.id,\n message.chatId,\n message.role,\n createdAt,\n JSON.stringify(message.content),\n );\n return {\n ...message,\n createdAt,\n };\n }\n\n async deleteMessage(messageId: string): Promise<void> {\n this.#db.prepare(`DELETE FROM messages WHERE id = ?`).run(messageId);\n }\n}\n", "CREATE TABLE IF NOT EXISTS \"chats\" (\n\t\"id\" VARCHAR PRIMARY KEY,\n\t\"title\" VARCHAR,\n\t\"userId\" VARCHAR\n);\n\nCREATE TABLE IF NOT EXISTS \"messages\" (\n\t\"id\" VARCHAR PRIMARY KEY,\n\t\"chatId\" VARCHAR NOT NULL REFERENCES \"chats\" (\"id\") ON DELETE CASCADE,\n\t\"createdAt\" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\n\t\"role\" VARCHAR NOT NULL,\n\t\"content\" TEXT NOT NULL\n);\n\nCREATE INDEX IF NOT EXISTS \"messages_chat_id_idx\" ON \"messages\" (\"chatId\");\n\nCREATE INDEX IF NOT EXISTS \"messages_chat_id_created_at_idx\" ON \"messages\" (\"chatId\", \"createdAt\");\n", "import { SqliteHistory } from './sqlite.history.ts';\n\nexport class InMemoryHistory extends SqliteHistory {\n constructor() {\n super(':memory:');\n }\n}\n", "import { DatabaseSync } from 'node:sqlite';\nimport { v7 } from 'uuid';\n\nimport {\n type GeneratedTeachable,\n type Teachables,\n toTeachables,\n} from '../teach/teachables.ts';\nimport storeDDL from './store.sqlite.sql';\nimport { type StoredTeachable, TeachablesStore } from './store.ts';\n\ninterface TeachableRow {\n id: string;\n userId: string;\n type: string;\n data: string;\n createdAt: string;\n updatedAt: string;\n}\n\nfunction rowToStoredTeachable(row: TeachableRow): StoredTeachable {\n return {\n id: row.id,\n userId: row.userId,\n type: row.type as GeneratedTeachable['type'],\n data: JSON.parse(row.data),\n createdAt: row.createdAt,\n updatedAt: row.updatedAt,\n };\n}\n\nexport class SqliteTeachablesStore extends TeachablesStore {\n #db: DatabaseSync;\n\n constructor(path: string) {\n super();\n this.#db = new DatabaseSync(path);\n this.#db.exec(storeDDL);\n }\n\n async remember(\n userId: string,\n data: GeneratedTeachable,\n ): Promise<StoredTeachable> {\n const id = v7();\n const now = new Date().toISOString();\n\n this.#db\n .prepare(\n 'INSERT INTO teachables (id, userId, type, data, createdAt, updatedAt) VALUES (?, ?, ?, ?, ?, ?)',\n )\n .run(id, userId, data.type, JSON.stringify(data), now, now);\n\n return (await this.get(id))!;\n }\n\n async recall(\n userId: string,\n type?: GeneratedTeachable['type'],\n ): Promise<StoredTeachable[]> {\n let rows: TeachableRow[];\n\n if (type === undefined) {\n rows = this.#db\n .prepare('SELECT * FROM teachables WHERE userId = ? ORDER BY createdAt')\n .all(userId) as unknown as TeachableRow[];\n } else {\n rows = this.#db\n .prepare(\n 'SELECT * FROM teachables WHERE userId = ? AND type = ? ORDER BY createdAt',\n )\n .all(userId, type) as unknown as TeachableRow[];\n }\n\n return rows.map(rowToStoredTeachable);\n }\n\n async get(id: string): Promise<StoredTeachable | null> {\n const row = this.#db\n .prepare('SELECT * FROM teachables WHERE id = ?')\n .get(id) as TeachableRow | undefined;\n\n if (!row) return null;\n return rowToStoredTeachable(row);\n }\n\n async update(id: string, data: GeneratedTeachable): Promise<StoredTeachable> {\n const now = new Date().toISOString();\n\n this.#db\n .prepare(\n 'UPDATE teachables SET data = ?, type = ?, updatedAt = ? WHERE id = ?',\n )\n .run(JSON.stringify(data), data.type, now, id);\n\n return (await this.get(id))!;\n }\n\n async forget(id: string): Promise<void> {\n this.#db.prepare('DELETE FROM teachables WHERE id = ?').run(id);\n }\n\n async forgetAll(userId: string): Promise<void> {\n this.#db.prepare('DELETE FROM teachables WHERE userId = ?').run(userId);\n }\n\n async toTeachables(userId: string): Promise<Teachables[]> {\n const stored = await this.recall(userId);\n return toTeachables(stored.map((s) => s.data));\n }\n}\n", "CREATE TABLE IF NOT EXISTS \"teachables\" (\n\t\"id\" VARCHAR PRIMARY KEY,\n\t\"userId\" VARCHAR,\n\t\"type\" VARCHAR NOT NULL,\n\t\"data\" TEXT NOT NULL,\n\t\"createdAt\" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\n\t\"updatedAt\" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP\n);\n\nCREATE INDEX IF NOT EXISTS \"teachables_user_id_idx\" ON \"teachables\" (\"userId\");\n\nCREATE INDEX IF NOT EXISTS \"teachables_type_idx\" ON \"teachables\" (\"type\");\n\nCREATE INDEX IF NOT EXISTS \"teachables_user_type_idx\" ON \"teachables\" (\"userId\", \"type\");\n", "import type { GeneratedTeachable, Teachables } from '../teach/teachables.ts';\n\nexport interface StoredTeachable {\n id: string;\n userId: string;\n type: GeneratedTeachable['type'];\n data: GeneratedTeachable;\n createdAt: string;\n updatedAt: string;\n}\n\nexport abstract class TeachablesStore {\n /**\n * Remember a teachable for a user.\n */\n abstract remember(\n userId: string,\n data: GeneratedTeachable,\n ): Promise<StoredTeachable>;\n\n /**\n * Recall teachables for a user, optionally filtered by type.\n */\n abstract recall(\n userId: string,\n type?: GeneratedTeachable['type'],\n ): Promise<StoredTeachable[]>;\n\n /**\n * Get a specific teachable by ID.\n */\n abstract get(id: string): Promise<StoredTeachable | null>;\n\n /**\n * Update an existing teachable.\n */\n abstract update(\n id: string,\n data: GeneratedTeachable,\n ): Promise<StoredTeachable>;\n\n /**\n * Forget (remove) a specific teachable by ID.\n */\n abstract forget(id: string): Promise<void>;\n\n /**\n * Forget all teachables for a user.\n */\n abstract forgetAll(userId: string): Promise<void>;\n\n /**\n * Convert stored teachables to Teachables array for use with toInstructions().\n */\n abstract toTeachables(userId: string): Promise<Teachables[]>;\n}\n", "import { SqliteTeachablesStore } from './sqlite.store.ts';\n\nexport class InMemoryTeachablesStore extends SqliteTeachablesStore {\n constructor() {\n super(':memory:');\n }\n}\n", "import {\n InvalidToolInputError,\n NoSuchToolError,\n ToolCallRepairError,\n type UIMessage,\n generateId,\n} from 'ai';\nimport { v7 } from 'uuid';\n\nimport {\n type Agent,\n type AgentModel,\n generate,\n stream,\n user,\n} from '@deepagents/agent';\n\nimport type { Adapter, IntrospectOptions } from './adapters/adapter.ts';\nimport { explainerAgent } from './agents/explainer.agent.ts';\nimport {\n type RenderingTools,\n memoryTools,\n sqlQueryAgent,\n t_a_g,\n} from './agents/text2sql.agent.ts';\nimport { FileCache } from './file-cache.ts';\nimport { History } from './history/history.ts';\nimport type { TeachablesStore } from './memory/store.ts';\nimport {\n type Teachables,\n hint,\n persona,\n styleGuide,\n teachable,\n toInstructions,\n} from './teach/teachables.ts';\nimport teachings from './teach/teachings.ts';\n\nexport interface InspectionResult {\n /** The grounding/introspection data (database schema context as XML) */\n grounding: string;\n\n /** The full instructions XML that would be sent to the agent */\n instructions: string;\n\n /** User-specific teachables that were loaded */\n userTeachables: Teachables[];\n\n /** System teachings configured */\n systemTeachings: Teachables[];\n\n /** Tool names available to the agent */\n tools: string[];\n}\n\nexport class Text2Sql {\n #config: {\n model?: AgentModel;\n adapter: Adapter;\n briefCache: FileCache;\n history: History;\n tools?: RenderingTools;\n instructions: Teachables[];\n memory?: TeachablesStore;\n introspection: FileCache;\n };\n\n constructor(config: {\n adapter: Adapter;\n history: History;\n version: string;\n tools?: RenderingTools;\n instructions?: Teachables[];\n model?: AgentModel;\n memory?: TeachablesStore;\n }) {\n this.#config = {\n adapter: config.adapter,\n briefCache: new FileCache('brief-' + config.version),\n history: config.history,\n instructions: [...teachings, ...(config.instructions ?? [])],\n tools: config.tools ?? {},\n model: config.model,\n memory: config.memory,\n introspection: new FileCache('introspection-' + config.version),\n };\n }\n\n public async explain(sql: string) {\n const { experimental_output } = await generate(\n explainerAgent,\n [user('Explain this SQL.')],\n { sql },\n );\n return experimental_output.explanation;\n }\n\n public async toSql(\n query: string,\n options?: { tools?: RenderingTools },\n ): Promise<string> {\n const introspection = await this.index();\n\n const { text } = await generate(\n sqlQueryAgent.clone({\n model: this.#config.model,\n tools: {\n ...t_a_g.handoff.tools,\n ...(options?.tools ?? this.#config.tools),\n },\n }),\n [user(query)],\n {\n teachings: toInstructions(\n 'instructions',\n persona({\n name: 'Freya',\n role: 'You are an expert SQL query generator, answering business questions with accurate queries.',\n tone: 'Your tone should be concise and business-friendly.',\n }),\n ...this.#config.instructions,\n ),\n adapter: this.#config.adapter,\n introspection,\n },\n );\n\n return text;\n }\n\n public instruct(...dataset: Teachables[]) {\n this.#config.instructions.push(...dataset);\n }\n\n public async inspect(agent: Agent) {\n const [grounding] = await Promise.all([this.index() as Promise<string>]);\n\n const renderToolNames = Object.keys(this.#config.tools ?? {}).filter(\n (name) => name.startsWith('render_'),\n );\n const allInstructions = [\n ...this.#config.instructions,\n ...(renderToolNames.length\n ? [\n hint(`Rendering tools available: ${renderToolNames.join(', ')}.`),\n styleGuide({\n prefer:\n 'Use render_* tools for trend/over time/monthly requests or chart asks',\n always:\n 'Include text insight alongside visualizations. Prefer line charts for time-based data.',\n }),\n ]\n : []),\n ];\n\n const tools = Object.keys({\n ...agent.handoff.tools,\n ...(this.#config.memory ? memoryTools : {}),\n ...this.#config.tools,\n });\n\n return {\n tools,\n prompt: agent.instructions({\n introspection: grounding,\n teachings: toInstructions(\n 'instructions',\n persona({\n name: 'Freya',\n role: 'You are an expert SQL query generator, answering business questions with accurate queries.',\n tone: 'Your tone should be concise and business-friendly.',\n }),\n ...allInstructions,\n ),\n }),\n };\n }\n\n public async index(options?: IntrospectOptions) {\n const cached = await this.#config.introspection.get();\n if (cached) {\n return cached;\n }\n const introspection = await this.#config.adapter.introspect();\n await this.#config.introspection.set(introspection);\n return introspection;\n }\n\n // public async suggest() {\n // const [introspection, adapterInfo] = await Promise.all([\n // this.index(),\n // this.#config.adapter.introspect(),\n // ]);\n // const { experimental_output: output } = await generate(\n // suggestionsAgent,\n // [\n // user(\n // 'Suggest high-impact business questions and matching SQL queries for this database.',\n // ),\n // ],\n // {\n // },\n // );\n // return output.suggestions;\n // }\n\n public async chat(\n messages: UIMessage[],\n params: {\n chatId: string;\n userId: string;\n },\n ) {\n const [introspection, userTeachables] = await Promise.all([\n this.index({ onProgress: console.log }),\n this.#config.memory\n ? this.#config.memory.toTeachables(params.userId)\n : [],\n ]);\n const chat = await this.#config.history.upsertChat({\n id: params.chatId,\n userId: params.userId,\n title: 'Chat ' + params.chatId,\n });\n\n // Build instructions with conditional rendering hint\n const renderToolNames = Object.keys(this.#config.tools ?? {}).filter(\n (name) => name.startsWith('render_'),\n );\n const instructions = [\n ...this.#config.instructions,\n ...(renderToolNames.length\n ? [\n hint(`Rendering tools available: ${renderToolNames.join(', ')}.`),\n styleGuide({\n prefer:\n 'Use render_* tools for trend/over time/monthly requests or chart asks',\n always:\n 'Include text insight alongside visualizations. Prefer line charts for time-based data.',\n }),\n ]\n : []),\n ];\n\n const result = stream(\n t_a_g.clone({\n model: this.#config.model,\n tools: {\n ...t_a_g.handoff.tools,\n ...(this.#config.memory ? memoryTools : {}),\n ...this.#config.tools,\n },\n }),\n [...chat.messages.map((it) => it.content), ...messages],\n {\n teachings: toInstructions(\n 'instructions',\n persona({\n name: 'Freya',\n role: 'You are an expert SQL query generator, answering business questions with accurate queries.',\n tone: 'Your tone should be concise and business-friendly.',\n }),\n ...instructions,\n teachable('user_profile', ...userTeachables),\n ),\n adapter: this.#config.adapter,\n introspection,\n memory: this.#config.memory,\n userId: params.userId,\n },\n );\n\n return result.toUIMessageStream({\n onError: (error) => {\n if (NoSuchToolError.isInstance(error)) {\n return 'The model tried to call a unknown tool.';\n } else if (InvalidToolInputError.isInstance(error)) {\n return 'The model called a tool with invalid arguments.';\n } else if (ToolCallRepairError.isInstance(error)) {\n return 'The model tried to call a tool with invalid arguments, but it was repaired.';\n } else {\n return 'An unknown error occurred.';\n }\n },\n sendStart: true,\n sendFinish: true,\n sendReasoning: true,\n sendSources: true,\n originalMessages: messages,\n generateMessageId: generateId,\n onFinish: async ({ messages }) => {\n const userMessage = messages.at(-2);\n const botMessage = messages.at(-1);\n if (!userMessage || !botMessage) {\n throw new Error('Not implemented yet');\n }\n await this.#config.history.addMessage({\n id: v7(),\n chatId: params.chatId,\n role: userMessage.role,\n content: userMessage,\n });\n await this.#config.history.addMessage({\n id: v7(),\n chatId: params.chatId,\n role: botMessage.role,\n content: botMessage,\n });\n },\n });\n }\n}\n", "import { groq } from '@ai-sdk/groq';\nimport dedent from 'dedent';\nimport z from 'zod';\n\nimport { agent } from '@deepagents/agent';\n\nexport const explainerAgent = agent<{ explanation: string }, { sql: string }>({\n name: 'explainer',\n model: groq('openai/gpt-oss-20b'),\n prompt: (state) => dedent`\n You are an expert SQL tutor.\n Explain the following SQL query in plain English to a non-technical user.\n Focus on the intent and logic, not the syntax.\n\n <sql>\n ${state?.sql}\n </sql>\n `,\n output: z.object({\n explanation: z.string().describe('The explanation of the SQL query.'),\n }),\n});\n", "import {\n type Teachables,\n clarification,\n guardrail,\n hint,\n styleGuide,\n workflow,\n} from './teachables.ts';\n\nexport default [\n hint(\n 'If the user asks to show a table or entity without specifying columns, use SELECT *.',\n ),\n hint(\n 'When showing items associated with another entity, include the item ID and the related details requested.',\n ),\n hint(\n 'When asked to \"show\" items, list them unless the user explicitly asks to count or total.',\n ),\n hint(\n 'Use canonical/LowCardinality values verbatim for filtering; [rows/size] hints suggest when to aggregate instead of listing.',\n ),\n hint(\n 'Favor PK/indexed columns for joins and filters; follow relationship metadata for join direction and cardinality.',\n ),\n guardrail({\n rule: 'Avoid unbounded scans on large/time-based tables.',\n action:\n 'Ask for or apply a reasonable recent date range before querying broad fact tables.',\n }),\n guardrail({\n rule: 'Do not return oversized raw result sets.',\n action:\n 'Keep raw limit strictly to ~100 rows even if users request more or coearced by hints.',\n reason:\n 'Browser will time out or crash on huge datasets. Data overload harms usability.',\n }),\n guardrail({\n rule: 'Prevent cartesian or guesswork joins.',\n reason: 'Protect correctness and performance.',\n action:\n 'If join keys are missing or unclear, inspect relationships and ask for the intended join path before executing.',\n }),\n clarification({\n when: 'The request targets time-based data without a date range.',\n ask: 'Confirm the intended timeframe (e.g., last 30/90 days, YTD, specific year).',\n reason: 'Prevents large scans and irrelevant results.',\n }),\n clarification({\n when: 'The request uses ambiguous scoring or ranking language (e.g., \"top\", \"best\", \"active\") without a metric.',\n ask: 'Clarify the ranking metric or definition before writing the query.',\n reason: 'Ensures the correct aggregation/ordering is used.',\n }),\n workflow({\n task: 'SQL generation plan',\n steps: [\n 'Translate the question into SQL patterns (aggregation, segmentation, time range, ranking).',\n 'Choose tables/relations that satisfy those patterns; note lookup tables and filter values implied by schema hints.',\n \"Inspect samples with 'get_sample_rows' for any column you'll use in WHERE/JOIN conditions - target just those columns (e.g., get_sample_rows('orders', ['status', 'order_type'])).\",\n 'Sketch join/filter/aggregation order considering table sizes, indexes, and stats.',\n \"Draft SQL, validate via 'validate_query', then execute via 'db_query' with a short reasoning note.\",\n ],\n }),\n styleGuide({\n prefer:\n 'Summaries should be concise, business-friendly, highlight key comparisons, and add a short helpful follow-up when useful.',\n }),\n // Tool usage constraints\n guardrail({\n rule: 'You must validate your query before final execution.',\n action:\n 'Follow the pattern: Draft Query \u2192 `validate_query` \u2192 Fix (if needed) \u2192 `db_query`.',\n }),\n guardrail({\n rule: 'ALWAYS use `get_sample_rows` before writing queries that filter or compare against string columns.',\n reason: 'Prevents SQL errors from wrong value formats.',\n action:\n \"Target specific columns (e.g., get_sample_rows('table', ['status', 'type'])).\",\n }),\n guardrail({\n rule: 'Do not call `db_query` without first producing and validating a SQL snippet.',\n action: 'First produce the query string, then validate.',\n }),\n hint(\n 'Use the `scratchpad` tool for strategic reflection during SQL query generation.',\n ),\n] as Teachables[];\n", "export * from './lib/agents/suggestions.agents.ts';\nexport * from './lib/agents/text2sql.agent.ts';\nexport * from './lib/file-cache.ts';\nexport * from './lib/history/history.ts';\nexport * from './lib/history/memory.history.ts';\nexport * from './lib/history/sqlite.history.ts';\nexport * from './lib/memory/memory.store.ts';\nexport * from './lib/memory/sqlite.store.ts';\nexport * from './lib/memory/store.ts';\nexport * from './lib/sql.ts';\n\nif (import.meta.main) {\n // const { DatabaseSync } = await import('node:sqlite');\n // const sqliteClient = new DatabaseSync(\n // '/Users/ezzabuzaid/Downloads/Chinook.db',\n // );\n // const text2sql = new Text2Sql({\n // version: 'v2',\n // history: new InMemoryHistory(),\n // adapter: new Sqlite({\n // grounding: [],\n // execute: (sql) => sqliteClient.prepare(sql).all(),\n // }),\n // });\n // console.dir(await text2sql.inspect(sqlQueryAgent), { depth: null });\n // const sql = await text2sql.toSql(\n // 'The top-selling products or categories each month last year given last record stored?. if the questions is wrong, show me full correct question I can ask.',\n // );\n // console.log('Generated SQL:');\n // console.log(sql);\n // await printer.readableStream(sql);\n}\n"],
|
|
5
|
+
"mappings": ";AAAA,SAAS,YAAY;AACrB,OAAO,YAAY;AACnB,OAAO,OAAO;AAEd,SAAS,OAAO,yBAAyB;AAiBlC,IAAM,mBAAmB,MAG9B;AAAA,EACA,MAAM;AAAA,EACN,OAAO,KAAK,oBAAoB;AAAA,EAChC,QAAQ,EAAE,OAAO;AAAA,IACf,aAAa,EACV;AAAA,MACC,EAAE,OAAO;AAAA,QACP,UAAU,EACP,OAAO,EACP,SAAS,2CAA2C;AAAA,QACvD,KAAK,EACF,OAAO,EACP,SAAS,kDAAkD;AAAA,QAC9D,eAAe,EACZ,OAAO,EACP,SAAS,2CAA2C;AAAA,MACzD,CAAC;AAAA,IACH,EACC,IAAI,CAAC,EACL,IAAI,CAAC,EACL,SAAS,mDAAmD;AAAA,EACjE,CAAC;AAAA,EACD,QAAQ,CAAC,UAAU;AACjB,WAAO;AAAA,QACH,kBAAkB,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA8BzB;AACF,CAAC;;;AC/ED,SAAS,QAAAA,aAAY;AACrB,SAAoB,YAAY;AAChC,OAAOC,QAAO;AAEd;AAAA,EAEE,SAAAC;AAAA,EAEA;AAAA,OACK;AACP,SAAS,uBAAuB;;;ACVzB,SAAS,UAAU,KAAa,UAA4B;AACjE,QAAM,UAAU,SACb,OAAO,CAAC,UAA2B,QAAQ,KAAK,CAAC,EACjD,KAAK,IAAI;AACZ,MAAI,CAAC,SAAS;AACZ,WAAO;AAAA,EACT;AACA,SAAO,IAAI,GAAG;AAAA,EAAM,YAAY,SAAS,CAAC,CAAC;AAAA,IAAO,GAAG;AACvD;AAEO,SAAS,KAAK,KAAa,QAAkB,UAA0B;AAC5E,MAAI,CAAC,OAAO,QAAQ;AAClB,WAAO;AAAA,EACT;AACA,QAAM,WAAW,OAAO,IAAI,CAAC,UAAU,KAAK,UAAU,KAAK,CAAC,EAAE,KAAK,IAAI;AACvE,SAAO,IAAI,GAAG;AAAA,EAAM,YAAY,UAAU,CAAC,CAAC;AAAA,IAAO,GAAG;AACxD;AAEO,SAAS,KAAK,KAAa,OAAuB;AACvD,QAAM,OAAO,UAAU,KAAK;AAC5B,MAAI,KAAK,SAAS,IAAI,GAAG;AACvB,WAAO,IAAI,GAAG;AAAA,EAAM,YAAY,MAAM,CAAC,CAAC;AAAA,IAAO,GAAG;AAAA,EACpD;AACA,SAAO,IAAI,GAAG,IAAI,IAAI,KAAK,GAAG;AAChC;AAEO,SAAS,YAAY,MAAc,QAAwB;AAChE,MAAI,CAAC,KAAK,KAAK,GAAG;AAChB,WAAO;AAAA,EACT;AACA,QAAM,UAAU,IAAI,OAAO,MAAM;AACjC,SAAO,KACJ,MAAM,IAAI,EACV,IAAI,CAAC,SAAU,KAAK,SAAS,UAAU,OAAO,OAAQ,EACtD,KAAK,IAAI;AACd;AAEO,SAAS,UAAU,OAAuB;AAC/C,MAAI,SAAS,MAAM;AACjB,WAAO;AAAA,EACT;AACA,SAAO,MACJ,WAAW,MAAM,OAAO,EACxB,WAAW,MAAM,MAAM,EACvB,WAAW,MAAM,MAAM,EACvB,WAAW,MAAM,QAAQ,EACzB,WAAW,MAAM,QAAQ;AAC9B;;;AC2CO,SAAS,KAAK,MAAc,YAAgC;AACjE,SAAO;AAAA,IACL,MAAM;AAAA,IACN,QAAQ,MACN,UAAU,QAAQ,CAAC,KAAK,QAAQ,IAAI,GAAG,KAAK,cAAc,UAAU,CAAC,CAAC;AAAA,EAC1E;AACF;AA6BO,SAAS,KAAK,MAA0B;AAC7C,SAAO;AAAA,IACL,MAAM;AAAA,IACN,QAAQ,MAAM,KAAK,QAAQ,IAAI;AAAA,EACjC;AACF;AAoCO,SAAS,UAAU,OAIX;AACb,QAAM,EAAE,MAAM,QAAQ,OAAO,IAAI;AACjC,SAAO;AAAA,IACL,MAAM;AAAA,IACN,QAAQ,MACN,UAAU,aAAa;AAAA,MACrB,KAAK,QAAQ,IAAI;AAAA,MACjB,SAAS,KAAK,UAAU,MAAM,IAAI;AAAA,MAClC,SAAS,KAAK,UAAU,MAAM,IAAI;AAAA,IACpC,CAAC;AAAA,EACL;AACF;AAoCO,SAAS,QAAQ,OAIT;AACb,QAAM,EAAE,SAAS,aAAa,UAAU,IAAI;AAC5C,SAAO;AAAA,IACL,MAAM;AAAA,IACN,QAAQ,MACN,UAAU,eAAe;AAAA,MACvB,KAAK,WAAW,OAAO;AAAA,MACvB,KAAK,WAAW,WAAW;AAAA,MAC3B,YAAY,KAAK,aAAa,SAAS,IAAI;AAAA,IAC7C,CAAC;AAAA,EACL;AACF;AAmCO,SAAS,QAAQ,OAIT;AACb,QAAM,EAAE,UAAU,QAAQ,KAAK,IAAI;AACnC,SAAO;AAAA,IACL,MAAM;AAAA,IACN,QAAQ,MACN,UAAU,WAAW;AAAA,MACnB,KAAK,YAAY,QAAQ;AAAA,MACzB,KAAK,UAAU,MAAM;AAAA,MACrB,OAAO,KAAK,QAAQ,IAAI,IAAI;AAAA,IAC9B,CAAC;AAAA,EACL;AACF;AAqCO,SAAS,cAAc,OAIf;AACb,QAAM,EAAE,MAAM,KAAK,OAAO,IAAI;AAC9B,SAAO;AAAA,IACL,MAAM;AAAA,IACN,QAAQ,MACN,UAAU,iBAAiB;AAAA,MACzB,KAAK,QAAQ,IAAI;AAAA,MACjB,KAAK,OAAO,GAAG;AAAA,MACf,KAAK,UAAU,MAAM;AAAA,IACvB,CAAC;AAAA,EACL;AACF;AA6DO,SAAS,SAAS,OAKV;AACb,QAAM,EAAE,MAAM,OAAO,UAAU,MAAM,IAAI;AACzC,SAAO;AAAA,IACL,MAAM;AAAA,IACN,QAAQ,MACN,UAAU,YAAY;AAAA,MACpB,KAAK,QAAQ,IAAI;AAAA,MACjB,UAAU,SAAS,KAAK,YAAY,UAAU,SAAS,IAAI;AAAA,MAC3D,KAAK,SAAS,OAAO,MAAM;AAAA,MAC3B,QAAQ,KAAK,SAAS,KAAK,IAAI;AAAA,IACjC,CAAC;AAAA,EACL;AACF;AAgCO,SAAS,MAAM,OAGP;AACb,QAAM,EAAE,OAAO,WAAW,IAAI;AAC9B,SAAO;AAAA,IACL,MAAM;AAAA,IACN,QAAQ,MACN,UAAU,SAAS;AAAA,MACjB,KAAK,SAAS,KAAK;AAAA,MACnB,KAAK,cAAc,UAAU;AAAA,IAC/B,CAAC;AAAA,EACL;AACF;AAoCO,SAAS,WAAW,OAIZ;AACb,QAAM,EAAE,QAAQ,OAAO,OAAO,IAAI;AAClC,SAAO;AAAA,IACL,MAAM;AAAA,IACN,QAAQ,MACN,UAAU,eAAe;AAAA,MACvB,KAAK,UAAU,MAAM;AAAA,MACrB,SAAS,KAAK,UAAU,MAAM,IAAI;AAAA,MAClC,QAAQ,KAAK,SAAS,KAAK,IAAI;AAAA,IACjC,CAAC;AAAA,EACL;AACF;AA6CO,SAAS,QAAQ,OAMT;AACb,QAAM,EAAE,SAAS,cAAc,SAAS,WAAW,QAAQ,IAAI;AAC/D,SAAO;AAAA,IACL,MAAM;AAAA,IACN,QAAQ,MACN,UAAU,WAAW;AAAA,MACnB,KAAK,YAAY,SAAS,SAAS;AAAA,MACnC,KAAK,gBAAgB,YAAY;AAAA,MACjC,UAAU,KAAK,WAAW,OAAO,IAAI;AAAA,MACrC,YAAY,KAAK,aAAa,SAAS,IAAI;AAAA,MAC3C,UAAU,KAAK,WAAW,OAAO,IAAI;AAAA,IACvC,CAAC;AAAA,EACL;AACF;AA0BO,SAAS,SAAS,SAA6C;AACpE,SAAO;AAAA,IACL,MAAM;AAAA,IACN,QAAQ,MACN;AAAA,MACE;AAAA,MACA,OAAO,QAAQ,OAAO,EAAE;AAAA,QAAI,CAAC,CAACC,OAAM,GAAG,MACrC,UAAU,SAAS,CAAC,KAAK,QAAQA,KAAI,GAAG,KAAK,OAAO,GAAG,CAAC,CAAC;AAAA,MAC3D;AAAA,IACF;AAAA,EACJ;AACF;AAqBO,SAAS,SAAS,OAAqD;AAC5E,QAAM,EAAE,MAAM,KAAK,IAAI;AACvB,SAAO;AAAA,IACL,MAAM;AAAA,IACN,QAAQ,MACN,UAAU,YAAY;AAAA,MACpB,OAAO,KAAK,QAAQ,IAAI,IAAI;AAAA,MAC5B,OAAO,KAAK,QAAQ,IAAI,IAAI;AAAA,IAC9B,CAAC;AAAA,EACL;AACF;AAiBO,SAAS,QAAQ,OAIT;AACb,QAAM,EAAE,MAAM,MAAM,KAAK,IAAI;AAC7B,SAAO;AAAA,IACL,MAAM;AAAA,IACN,QAAQ,MACN,UAAU,WAAW;AAAA,MACnB,KAAK,QAAQ,IAAI;AAAA,MACjB,KAAK,QAAQ,IAAI;AAAA,MACjB,KAAK,QAAQ,IAAI;AAAA,IACnB,CAAC;AAAA,EACL;AACF;AAiBO,SAAS,MAAM,UAAkB,SAA6B;AACnE,SAAO;AAAA,IACL,MAAM;AAAA,IACN,QAAQ,MACN,UAAU,SAAS,CAAC,KAAK,QAAQ,QAAQ,GAAG,KAAK,WAAW,OAAO,CAAC,CAAC;AAAA,EACzE;AACF;AAkBO,SAAS,WAAW,QAAgB,OAA2B;AACpE,SAAO;AAAA,IACL,MAAM;AAAA,IACN,QAAQ,MACN,UAAU,cAAc,CAAC,KAAK,UAAU,MAAM,GAAG,KAAK,SAAS,KAAK,CAAC,CAAC;AAAA,EAC1E;AACF;AAgBO,SAAS,QAAQ,aAAiC;AACvD,SAAO;AAAA,IACL,MAAM;AAAA,IACN,QAAQ,MAAM,KAAK,WAAW,WAAW;AAAA,EAC3C;AACF;AAiBO,SAAS,WAAW,SAAiBC,gBAAmC;AAC7E,SAAO;AAAA,IACL,MAAM;AAAA,IACN,QAAQ,MACN,UAAU,cAAc;AAAA,MACtB,KAAK,WAAW,OAAO;AAAA,MACvB,KAAK,iBAAiBA,cAAa;AAAA,IACrC,CAAC;AAAA,EACL;AACF;AAEO,SAAS,UACd,QACG,YACS;AACZ,SAAO;AAAA,IACL,MAAM;AAAA,IACN,QAAQ,MAAM,eAAe,KAAK,GAAG,UAAU;AAAA,EACjD;AACF;AAEO,SAAS,eACd,QACG,YACK;AACR,MAAI,CAAC,WAAW,QAAQ;AACtB,WAAO;AAAA,EACT;AAEA,QAAM,UAAU,oBAAI,IAAsC;AAC1D,aAAWC,cAAa,YAAY;AAClC,UAAM,WAAW,QAAQ,IAAIA,WAAU,IAAI,KAAK,CAAC;AACjD,aAAS,KAAKA,UAAS;AACvB,YAAQ,IAAIA,WAAU,MAAM,QAAQ;AAAA,EACtC;AAEA,QAAM,eAAe,IAAI,IAAI,cAAc,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC;AAE7D,QAAM,WAAW,cAAc,IAAI,CAAC,EAAE,MAAM,KAAAC,KAAI,MAAM;AACpD,UAAM,QAAQ,QAAQ,IAAI,IAAI;AAC9B,QAAI,CAAC,OAAO,QAAQ;AAClB,aAAO;AAAA,IACT;AACA,UAAM,gBAAgB,MACnB,IAAI,CAAC,SAAS,KAAK,OAAO,EAAE,KAAK,CAAC,EAClC,OAAO,OAAO,EACd,IAAI,CAAC,SAAS,YAAY,MAAM,CAAC,CAAC,EAClC,KAAK,IAAI;AACZ,QAAI,CAAC,cAAc,QAAQ;AACzB,aAAO;AAAA,IACT;AACA,WAAO,IAAIA,IAAG;AAAA,EAAM,aAAa;AAAA,IAAOA,IAAG;AAAA,EAC7C,CAAC,EAAE,OAAO,CAAC,YAA+B,QAAQ,OAAO,CAAC;AAG1D,aAAW,CAAC,MAAM,KAAK,KAAK,SAAS;AACnC,QAAI,aAAa,IAAI,IAAI,GAAG;AAC1B;AAAA,IACF;AACA,UAAM,gBAAgB,MACnB,IAAI,CAAC,SAAS,KAAK,OAAO,EAAE,KAAK,CAAC,EAClC,OAAO,OAAO,EACd,IAAI,CAAC,SAAS,YAAY,MAAM,CAAC,CAAC,EAClC,KAAK,IAAI;AACZ,QAAI,cAAc,QAAQ;AACxB,eAAS,KAAK,aAAa;AAAA,IAC7B;AAAA,EACF;AAEA,MAAI,CAAC,SAAS,QAAQ;AACpB,WAAO;AAAA,EACT;AAEA,QAAM,UAAU,YAAY,SAAS,KAAK,IAAI,GAAG,CAAC;AAClD,SAAO,IAAI,GAAG;AAAA,EAAM,OAAO;AAAA,IAAO,GAAG;AACvC;AAEA,IAAM,gBAAkE;AAAA;AAAA,EAEtE,EAAE,MAAM,YAAY,KAAK,WAAW;AAAA,EACpC,EAAE,MAAM,WAAW,KAAK,UAAU;AAAA,EAClC,EAAE,MAAM,WAAW,KAAK,eAAe;AAAA,EACvC,EAAE,MAAM,cAAc,KAAK,mBAAmB;AAAA,EAC9C,EAAE,MAAM,SAAS,KAAK,kBAAkB;AAAA,EACxC,EAAE,MAAM,cAAc,KAAK,mBAAmB;AAAA;AAAA,EAE9C,EAAE,MAAM,aAAa,KAAK,aAAa;AAAA,EACvC,EAAE,MAAM,cAAc,KAAK,eAAe;AAAA,EAC1C,EAAE,MAAM,QAAQ,KAAK,QAAQ;AAAA,EAC7B,EAAE,MAAM,iBAAiB,KAAK,iBAAiB;AAAA,EAC/C,EAAE,MAAM,YAAY,KAAK,YAAY;AAAA,EACrC,EAAE,MAAM,SAAS,KAAK,SAAS;AAAA,EAC/B,EAAE,MAAM,QAAQ,KAAK,cAAc;AAAA,EACnC,EAAE,MAAM,WAAW,KAAK,eAAe;AAAA,EACvC,EAAE,MAAM,WAAW,KAAK,YAAY;AAAA,EACpC,EAAE,MAAM,YAAY,KAAK,WAAW;AAAA,EACpC,EAAE,MAAM,WAAW,KAAK,WAAW;AACrC;AAEO,SAAS,aAAa,WAA+C;AAC1E,SAAO,UAAU,IAAI,CAAC,SAAS;AAC7B,YAAQ,KAAK,MAAM;AAAA,MACjB,KAAK;AACH,eAAO,QAAQ,EAAE,MAAM,KAAK,MAAM,MAAM,KAAK,MAAM,MAAM,KAAK,KAAK,CAAC;AAAA,MACtE,KAAK;AACH,eAAO,KAAK,KAAK,MAAM,KAAK,UAAU;AAAA,MACxC,KAAK;AACH,eAAO,KAAK,KAAK,IAAI;AAAA,MACvB,KAAK;AACH,eAAO,UAAU;AAAA,UACf,MAAM,KAAK;AAAA,UACX,QAAQ,KAAK;AAAA,UACb,QAAQ,KAAK;AAAA,QACf,CAAC;AAAA,MACH,KAAK;AACH,eAAO,QAAQ;AAAA,UACb,SAAS,KAAK;AAAA,UACd,aAAa,KAAK;AAAA,UAClB,WAAW,KAAK;AAAA,QAClB,CAAC;AAAA,MACH,KAAK;AACH,eAAO,QAAQ;AAAA,UACb,UAAU,KAAK;AAAA,UACf,QAAQ,KAAK;AAAA,UACb,MAAM,KAAK;AAAA,QACb,CAAC;AAAA,MACH,KAAK;AACH,eAAO,cAAc;AAAA,UACnB,MAAM,KAAK;AAAA,UACX,KAAK,KAAK;AAAA,UACV,QAAQ,KAAK;AAAA,QACf,CAAC;AAAA,MACH,KAAK;AACH,eAAO,SAAS;AAAA,UACd,MAAM,KAAK;AAAA,UACX,OAAO,KAAK;AAAA,UACZ,UAAU,KAAK;AAAA,UACf,OAAO,KAAK;AAAA,QACd,CAAC;AAAA,MACH,KAAK;AACH,eAAO,MAAM;AAAA,UACX,OAAO,KAAK;AAAA,UACZ,YAAY,KAAK;AAAA,QACnB,CAAC;AAAA,MACH,KAAK;AACH,eAAO,WAAW;AAAA,UAChB,QAAQ,KAAK;AAAA,UACb,OAAO,KAAK;AAAA,UACZ,QAAQ,KAAK;AAAA,QACf,CAAC;AAAA,MACH,KAAK;AACH,eAAO,QAAQ;AAAA,UACb,SAAS,KAAK;AAAA,UACd,cAAc,KAAK;AAAA,UACnB,SAAS,KAAK;AAAA,UACd,WAAW,KAAK;AAAA,UAChB,SAAS,KAAK;AAAA,QAChB,CAAC;AAAA,MACH,KAAK;AACH,eAAO,SAAS,KAAK,OAAO;AAAA;AAAA,MAE9B,KAAK;AACH,eAAO,SAAS,EAAE,MAAM,KAAK,MAAM,MAAM,KAAK,KAAK,CAAC;AAAA,MACtD,KAAK;AACH,eAAO,MAAM,KAAK,MAAM,KAAK,OAAO;AAAA,MACtC,KAAK;AACH,eAAO,WAAW,KAAK,QAAQ,KAAK,KAAK;AAAA,MAC3C,KAAK;AACH,eAAO,QAAQ,KAAK,WAAW;AAAA,MACjC,KAAK;AACH,eAAO,WAAW,KAAK,SAAS,KAAK,aAAa;AAAA,IACtD;AAAA,EACF,CAAC;AACH;;;ACx5BA,IAAO,wBAAQ;AAAA,EACb;AAAA;AAAA,EAGA,UAAU;AAAA,IACR,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,QACE;AAAA,EACJ,CAAC;AAAA;AAAA,EAID,SAAS;AAAA,IACP,MAAM;AAAA,IACN,UAAU,CAAC,SAAS,aAAa,cAAc,YAAY;AAAA,IAC3D,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,OACE;AAAA,EACJ,CAAC;AAAA,EAED,SAAS;AAAA,IACP,MAAM;AAAA,IACN,UAAU,CAAC,cAAc,YAAY,gBAAgB;AAAA,IACrD,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,OACE;AAAA,EACJ,CAAC;AAAA,EAED,SAAS;AAAA,IACP,MAAM;AAAA,IACN,UAAU,CAAC,eAAe,aAAa,cAAc,qBAAqB;AAAA,IAC1E,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF,CAAC;AAAA,EAED,SAAS;AAAA,IACP,MAAM;AAAA,IACN,UAAU,CAAC,kBAAkB,aAAa,aAAa,WAAW;AAAA,IAClE,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF,CAAC;AAAA;AAAA,EAID,QAAQ;AAAA,IACN,SAAS;AAAA,IACT,aACE;AAAA,IACF,WAAW;AAAA,EACb,CAAC;AAAA,EAED,QAAQ;AAAA,IACN,SAAS;AAAA,IACT,aACE;AAAA,IACF,WAAW;AAAA,EACb,CAAC;AAAA,EAED,QAAQ;AAAA,IACN,SAAS;AAAA,IACT,aACE;AAAA,IACF,WAAW;AAAA,EACb,CAAC;AAAA;AAAA,EAID,cAAc;AAAA,IACZ,MAAM;AAAA,IACN,KAAK;AAAA,IACL,QACE;AAAA,EACJ,CAAC;AAAA,EAED,cAAc;AAAA,IACZ,MAAM;AAAA,IACN,KAAK;AAAA,IACL,QACE;AAAA,EACJ,CAAC;AAAA;AAAA;AAAA,EAKD,QAAQ;AAAA,IACN,UAAU;AAAA,IACV,QAAQ;AAAA,IACR,MAAM;AAAA,EACR,CAAC;AAAA;AAAA,EAGD,QAAQ;AAAA,IACN,UAAU;AAAA,IACV,QAAQ;AAAA,IACR,MAAM;AAAA,EACR,CAAC;AAAA;AAAA,EAGD,QAAQ;AAAA,IACN,UAAU;AAAA,IACV,QAAQ;AAAA,IACR,MAAM;AAAA,EACR,CAAC;AAAA;AAAA,EAGD,QAAQ;AAAA,IACN,UAAU;AAAA,IACV,QAAQ;AAAA,IACR,MAAM;AAAA,EACR,CAAC;AAAA;AAAA,EAGD,QAAQ;AAAA,IACN,UACE;AAAA,IACF,QAAQ;AAAA,IACR,MAAM;AAAA,EACR,CAAC;AAAA;AAAA,EAGD,QAAQ;AAAA,IACN,UAAU;AAAA,IACV,QAAQ;AAAA,EACV,CAAC;AAAA;AAAA,EAGD,QAAQ;AAAA,IACN,UAAU;AAAA,IACV,QAAQ;AAAA,IACR,MAAM;AAAA,EACR,CAAC;AAAA;AAAA,EAGD,KAAK,mEAAmE;AAAA,EACxE;AAAA,IACE;AAAA,EACF;AAAA,EACA,KAAK,4CAA4C;AACnD;;;AHnJA,IAAM,QAAQ;AAAA,EACZ,gBAAgB,KAAK;AAAA,IACnB,aAAa;AAAA,IACb,aAAaC,GAAE,OAAO;AAAA,MACpB,KAAKA,GAAE,OAAO,EAAE,SAAS,4BAA4B;AAAA,IACvD,CAAC;AAAA,IACD,SAAS,OAAO,EAAE,IAAI,GAAG,YAAY;AACnC,YAAM,QAAQ,QAA8B,OAAO;AACnD,YAAM,SAAS,MAAM,MAAM,QAAQ,SAAS,GAAG;AAC/C,UAAI,OAAO,WAAW,UAAU;AAC9B,eAAO,qBAAqB,MAAM;AAAA,MACpC;AACA,aAAO;AAAA,IACT;AAAA,EACF,CAAC;AAAA,EACD,iBAAiB,KAAK;AAAA,IACpB,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA,IAKb,aAAaA,GAAE,OAAO;AAAA,MACpB,WAAWA,GAAE,OAAO,EAAE,SAAS,kCAAkC;AAAA,MACjE,SAASA,GACN,MAAMA,GAAE,OAAO,CAAC,EAChB,SAAS,EACT;AAAA,QACC;AAAA,MACF;AAAA,MACF,OAAOA,GACJ,OAAO,EACP,IAAI,CAAC,EACL,IAAI,EAAE,EACN,QAAQ,CAAC,EACT,SAAS,EACT,SAAS,6CAA6C;AAAA,IAC3D,CAAC;AAAA,IACD,SAAS,CAAC,EAAE,WAAW,SAAS,QAAQ,EAAE,GAAG,YAAY;AACvD,YAAM,YAAY,KAAK,IAAI,KAAK,IAAI,GAAG,KAAK,GAAG,EAAE;AACjD,YAAM,QAAQ,QAA8B,OAAO;AACnD,YAAM,MAAM,MAAM,QAAQ;AAAA,QACxB;AAAA,QACA;AAAA,QACA;AAAA,MACF;AACA,aAAO,MAAM,QAAQ,QAAQ,GAAG;AAAA,IAClC;AAAA,EACF,CAAC;AAAA,EACD,UAAU,KAAK;AAAA,IACb,aAAa;AAAA,IACb,aAAaA,GAAE,OAAO;AAAA,MACpB,WAAWA,GACR,OAAO,EACP;AAAA,QACC;AAAA,MACF;AAAA,MACF,KAAKA,GACF,OAAO,EACP,IAAI,GAAG,EAAE,SAAS,6BAA6B,CAAC,EAChD;AAAA,QACC,CAAC,QACC,IAAI,KAAK,EAAE,YAAY,EAAE,WAAW,QAAQ,KAC5C,IAAI,KAAK,EAAE,YAAY,EAAE,WAAW,MAAM;AAAA,QAC5C;AAAA,UACE,SAAS;AAAA,QACX;AAAA,MACF,EACC,SAAS,gDAAgD;AAAA,IAC9D,CAAC;AAAA,IACD,SAAS,CAAC,EAAE,IAAI,GAAG,YAAY;AAC7B,YAAM,QAAQ,QAA8B,OAAO;AACnD,aAAO,MAAM,QAAQ,QAAQ,GAAG;AAAA,IAClC;AAAA,EACF,CAAC;AAAA,EACD,YAAY;AACd;AAEA,IAAM,kBAAkB;AAAA,EACtB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,IAAM,mBAAmBA,GAAE,mBAAmB,QAAQ;AAAA,EACpDA,GAAE,OAAO;AAAA,IACP,MAAMA,GAAE,QAAQ,UAAU;AAAA,IAC1B,aAAaA,GAAE,OAAO,EAAE,SAAS,uCAAuC;AAAA,EAC1E,CAAC;AAAA,EACDA,GAAE,OAAO;AAAA,IACP,MAAMA,GAAE,QAAQ,OAAO;AAAA,IACvB,MAAMA,GAAE,OAAO,EAAE,SAAS,wBAAwB;AAAA,IAClD,SAASA,GAAE,OAAO,EAAE,SAAS,kCAAkC;AAAA,EACjE,CAAC;AAAA,EACDA,GAAE,OAAO;AAAA,IACP,MAAMA,GAAE,QAAQ,YAAY;AAAA,IAC5B,QAAQA,GACL,OAAO,EACP,SAAS,kDAAkD;AAAA,IAC9D,OAAOA,GAAE,OAAO,EAAE,SAAS,uBAAuB;AAAA,EACpD,CAAC;AAAA,EACDA,GAAE,OAAO;AAAA,IACP,MAAMA,GAAE,QAAQ,SAAS;AAAA,IACzB,aAAaA,GAAE,OAAO,EAAE,SAAS,uCAAuC;AAAA,EAC1E,CAAC;AAAA,EACDA,GAAE,OAAO;AAAA,IACP,MAAMA,GAAE,QAAQ,YAAY;AAAA,IAC5B,SAASA,GAAE,OAAO,EAAE,SAAS,wBAAwB;AAAA,IACrD,eAAeA,GAAE,OAAO,EAAE,SAAS,2BAA2B;AAAA,EAChE,CAAC;AACH,CAAC;AAEM,IAAM,cAAc;AAAA,EACzB,iBAAiB,KAAK;AAAA,IACpB,aACE;AAAA,IACF,aAAaA,GAAE,OAAO,EAAE,QAAQ,iBAAiB,CAAC;AAAA,IAClD,SAAS,OAAO,EAAE,OAAO,GAAG,YAAY;AACtC,YAAM,QAAQ;AAAA,QACZ;AAAA,MACF;AACA,YAAM,MAAM,OAAO,SAAS,MAAM,QAAQ,MAA4B;AACtE,aAAO;AAAA,IACT;AAAA,EACF,CAAC;AAAA,EACD,eAAe,KAAK;AAAA,IAClB,aACE;AAAA,IACF,aAAaA,GAAE,OAAO;AAAA,MACpB,IAAIA,GAAE,OAAO,EAAE,SAAS,mCAAmC;AAAA,IAC7D,CAAC;AAAA,IACD,SAAS,OAAO,EAAE,GAAG,GAAG,YAAY;AAClC,YAAM,QAAQ,QAAqC,OAAO;AAC1D,YAAM,MAAM,OAAO,OAAO,EAAE;AAC5B,aAAO;AAAA,IACT;AAAA,EACF,CAAC;AAAA,EACD,eAAe,KAAK;AAAA,IAClB,aACE;AAAA,IACF,aAAaA,GAAE,OAAO;AAAA,MACpB,MAAMA,GACH,KAAK,eAAe,EACpB,SAAS,EACT,MAAM,MAAS,EACf,SAAS,iCAAiC;AAAA,IAC/C,CAAC;AAAA,IACD,SAAS,OAAO,EAAE,KAAK,GAAG,YAAY;AACpC,YAAM,QAAQ;AAAA,QACZ;AAAA,MACF;AACA,YAAM,WAAW,MAAM,MAAM,OAAO,OAAO,MAAM,QAAQ,IAAI;AAC7D,UAAI,SAAS,WAAW,GAAG;AACzB,eAAO,OAAO,MAAM,IAAI,sBAAsB;AAAA,MAChD;AACA,aAAO,SAAS,IAAI,CAAC,OAAO;AAAA,QAC1B,IAAI,EAAE;AAAA,QACN,MAAM,EAAE;AAAA,QACR,MAAM,EAAE;AAAA,QACR,WAAW,EAAE;AAAA,MACf,EAAE;AAAA,IACJ;AAAA,EACF,CAAC;AAAA,EACD,eAAe,KAAK;AAAA,IAClB,aACE;AAAA,IACF,aAAaA,GAAE,OAAO;AAAA,MACpB,QAAQ;AAAA,MACR,IAAIA,GAAE,OAAO,EAAE,SAAS,gCAAgC;AAAA,IAC1D,CAAC;AAAA,IACD,SAAS,OAAO,EAAE,IAAI,OAAO,GAAG,YAAY;AAC1C,YAAM,QAAQ,QAAqC,OAAO;AAC1D,YAAM,MAAM,OAAO,OAAO,IAAI,MAA4B;AAC1D,aAAO;AAAA,IACT;AAAA,EACF,CAAC;AACH;AAgCO,IAAM,gBAAgBC,OAAM;AAAA,EACjC,MAAM;AAAA,EACN,OAAOC,MAAK,oBAAoB;AAAA,EAChC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,QAAQ,CAAC,UAAU;AACjB,WAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAML,OAAO,aAAa,EAAE;AAAA,MACtB,OAAO,iBAAiB,EAAE;AAAA;AAAA;AAAA,EAG9B;AACF,CAAC;AAKM,IAAM,QAAQD,OASnB;AAAA,EACA,OAAOC,MAAK,oBAAoB;AAAA,EAChC;AAAA,EACA,MAAM;AAAA,EACN,QAAQ,CAAC,UAAU;AACjB,UAAM,YAAY,CAAC,CAAC,OAAO;AAE3B,WAAO;AAAA;AAAA,MAEL,OAAO,aAAa,EAAE;AAAA,MACtB,OAAO,iBAAiB,EAAE;AAAA;AAAA,MAE1B,YAAY,wBAAe,EAAE;AAAA;AAAA,EAEjC;AACF,CAAC;;;AItRD,SAAS,kBAAkB;AAC3B,SAAS,kBAAkB;AAC3B,SAAS,UAAU,iBAAiB;AACpC,SAAS,cAAc;AACvB,OAAO,UAAU;AAEV,IAAM,YAAN,MAAgB;AAAA,EACd;AAAA,EACP,YAAY,WAAmB,YAAY,QAAQ;AACjD,UAAM,OAAO,WAAW,KAAK,EAAE,OAAO,SAAS,EAAE,OAAO,KAAK;AAC7D,SAAK,OAAO,KAAK,KAAK,OAAO,GAAG,YAAY,IAAI,GAAG,SAAS,EAAE;AAAA,EAChE;AAAA,EAEA,MAAM,MAAM;AACV,QAAI,WAAW,KAAK,IAAI,GAAG;AACzB,aAAO,SAAS,KAAK,MAAM,OAAO;AAAA,IACpC;AACA,WAAO;AAAA,EACT;AAAA,EAEA,IAAI,SAAiB;AACnB,WAAO,UAAU,KAAK,MAAM,SAAS,OAAO;AAAA,EAC9C;AACF;AAEO,IAAM,YAAN,cAA2B,UAAU;AAAA,EAC1C,YAAY,WAAmB;AAC7B,UAAM,WAAW,OAAO;AAAA,EAC1B;AAAA,EAEA,MAAM,OAA0B;AAC9B,UAAM,UAAU,MAAM,KAAK,IAAI;AAC/B,QAAI,SAAS;AACX,aAAO,KAAK,MAAM,OAAO;AAAA,IAC3B;AACA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,MAAS;AACb,WAAO,KAAK,IAAI,KAAK,UAAU,IAAI,CAAC;AAAA,EACtC;AACF;;;ACNO,IAAe,UAAf,MAAuB;AAU9B;;;AC7CA,SAAS,oBAAoB;;;ACA7B;;;ADYO,IAAM,gBAAN,cAA4B,QAAQ;AAAA,EACzC;AAAA,EAEA,YAAYC,OAAc;AACxB,UAAM;AACN,SAAK,MAAM,IAAI,aAAaA,KAAI;AAChC,SAAK,IAAI,KAAK,sBAAU;AAAA,EAC1B;AAAA,EAEA,MAAM,UAAU,QAAiC;AAC/C,WAAO,KAAK,IACT,QAAQ,wCAAwC,EAChD,IAAI,MAAM;AAAA,EACf;AAAA,EAEA,MAAM,QAAQ,QAAsC;AAClD,UAAM,OAAO,KAAK,IACf;AAAA,MACC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAOF,EACC,IAAI,MAAM;AAUb,QAAI,CAAC,KAAK,OAAQ,QAAO;AAEzB,UAAM,WAAW,KAAK,CAAC;AACvB,UAAM,OAAa;AAAA,MACjB,IAAI,SAAS;AAAA,MACb,QAAQ,SAAS;AAAA,MACjB,OAAO,SAAS;AAAA,MAChB,UAAU,CAAC;AAAA,IACb;AAEA,eAAW,OAAO,MAAM;AACtB,UAAI,IAAI,WAAW;AACjB,aAAK,SAAS,KAAK;AAAA,UACjB,IAAI,IAAI;AAAA,UACR,QAAQ,SAAS;AAAA,UACjB,MAAM,IAAI;AAAA,UACV,WAAW,IAAI;AAAA,UACf,SAAS,KAAK,MAAM,IAAI,OAAO;AAAA,QACjC,CAAC;AAAA,MACH;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,WAAW,MAAuC;AACtD,SAAK,IACF,QAAQ,0DAA0D,EAClE,IAAI,KAAK,IAAI,KAAK,QAAQ,KAAK,SAAS,IAAI;AAC/C,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,WAAW,MAAwB;AACvC,SAAK,IACF;AAAA,MACC;AAAA;AAAA,IAEF,EACC,IAAI,KAAK,IAAI,KAAK,QAAQ,KAAK,SAAS,IAAI;AAC/C,WAAO,KAAK,QAAQ,KAAK,EAAE;AAAA,EAC7B;AAAA,EAEA,MAAM,WAAW,QAA+B;AAC9C,SAAK,IAAI,QAAQ,gCAAgC,EAAE,IAAI,MAAM;AAAA,EAC/D;AAAA,EAEA,MAAM,WAAW,QAAgB,SAA0C;AACzE,QAAI,QAAQ,UAAU,QAAW;AAC/B,WAAK,IACF,QAAQ,yCAAyC,EACjD,IAAI,QAAQ,OAAO,MAAM;AAAA,IAC9B;AAAA,EACF;AAAA,EAEA,MAAM,WAAW,SAA6C;AAC5D,UAAM,YAAY,QAAQ,YACtB,QAAQ,UAAU,YAAY,KAC9B,oBAAI,KAAK,GAAE,YAAY;AAC3B,SAAK,IACF;AAAA,MACC;AAAA,IACF,EACC;AAAA,MACC,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR;AAAA,MACA,KAAK,UAAU,QAAQ,OAAO;AAAA,IAChC;AAAA,EACJ;AAAA,EAEA,MAAM,cAAc,SAAgD;AAClE,UAAM,YAAY,QAAQ,YACtB,QAAQ,UAAU,YAAY,KAC9B,oBAAI,KAAK,GAAE,YAAY;AAC3B,SAAK,IACF;AAAA,MACC;AAAA;AAAA,IAEF,EACC;AAAA,MACC,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR;AAAA,MACA,KAAK,UAAU,QAAQ,OAAO;AAAA,IAChC;AACF,WAAO;AAAA,MACL,GAAG;AAAA,MACH;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,cAAc,WAAkC;AACpD,SAAK,IAAI,QAAQ,mCAAmC,EAAE,IAAI,SAAS;AAAA,EACrE;AACF;;;AE9IO,IAAM,kBAAN,cAA8B,cAAc;AAAA,EACjD,cAAc;AACZ,UAAM,UAAU;AAAA,EAClB;AACF;;;ACNA,SAAS,gBAAAC,qBAAoB;AAC7B,SAAS,UAAU;;;ACDnB;;;ACWO,IAAe,kBAAf,MAA+B;AA4CtC;;;AFnCA,SAAS,qBAAqB,KAAoC;AAChE,SAAO;AAAA,IACL,IAAI,IAAI;AAAA,IACR,QAAQ,IAAI;AAAA,IACZ,MAAM,IAAI;AAAA,IACV,MAAM,KAAK,MAAM,IAAI,IAAI;AAAA,IACzB,WAAW,IAAI;AAAA,IACf,WAAW,IAAI;AAAA,EACjB;AACF;AAEO,IAAM,wBAAN,cAAoC,gBAAgB;AAAA,EACzD;AAAA,EAEA,YAAYC,OAAc;AACxB,UAAM;AACN,SAAK,MAAM,IAAIC,cAAaD,KAAI;AAChC,SAAK,IAAI,KAAK,oBAAQ;AAAA,EACxB;AAAA,EAEA,MAAM,SACJ,QACA,MAC0B;AAC1B,UAAM,KAAK,GAAG;AACd,UAAM,OAAM,oBAAI,KAAK,GAAE,YAAY;AAEnC,SAAK,IACF;AAAA,MACC;AAAA,IACF,EACC,IAAI,IAAI,QAAQ,KAAK,MAAM,KAAK,UAAU,IAAI,GAAG,KAAK,GAAG;AAE5D,WAAQ,MAAM,KAAK,IAAI,EAAE;AAAA,EAC3B;AAAA,EAEA,MAAM,OACJ,QACA,MAC4B;AAC5B,QAAI;AAEJ,QAAI,SAAS,QAAW;AACtB,aAAO,KAAK,IACT,QAAQ,8DAA8D,EACtE,IAAI,MAAM;AAAA,IACf,OAAO;AACL,aAAO,KAAK,IACT;AAAA,QACC;AAAA,MACF,EACC,IAAI,QAAQ,IAAI;AAAA,IACrB;AAEA,WAAO,KAAK,IAAI,oBAAoB;AAAA,EACtC;AAAA,EAEA,MAAM,IAAI,IAA6C;AACrD,UAAM,MAAM,KAAK,IACd,QAAQ,uCAAuC,EAC/C,IAAI,EAAE;AAET,QAAI,CAAC,IAAK,QAAO;AACjB,WAAO,qBAAqB,GAAG;AAAA,EACjC;AAAA,EAEA,MAAM,OAAO,IAAY,MAAoD;AAC3E,UAAM,OAAM,oBAAI,KAAK,GAAE,YAAY;AAEnC,SAAK,IACF;AAAA,MACC;AAAA,IACF,EACC,IAAI,KAAK,UAAU,IAAI,GAAG,KAAK,MAAM,KAAK,EAAE;AAE/C,WAAQ,MAAM,KAAK,IAAI,EAAE;AAAA,EAC3B;AAAA,EAEA,MAAM,OAAO,IAA2B;AACtC,SAAK,IAAI,QAAQ,qCAAqC,EAAE,IAAI,EAAE;AAAA,EAChE;AAAA,EAEA,MAAM,UAAU,QAA+B;AAC7C,SAAK,IAAI,QAAQ,yCAAyC,EAAE,IAAI,MAAM;AAAA,EACxE;AAAA,EAEA,MAAM,aAAa,QAAuC;AACxD,UAAM,SAAS,MAAM,KAAK,OAAO,MAAM;AACvC,WAAO,aAAa,OAAO,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC;AAAA,EAC/C;AACF;;;AG5GO,IAAM,0BAAN,cAAsC,sBAAsB;AAAA,EACjE,cAAc;AACZ,UAAM,UAAU;AAAA,EAClB;AACF;;;ACNA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EAEA;AAAA,OACK;AACP,SAAS,MAAAE,WAAU;AAEnB;AAAA,EAGE;AAAA,EACA;AAAA,EACA;AAAA,OACK;;;ACfP,SAAS,QAAAC,aAAY;AACrB,OAAOC,aAAY;AACnB,OAAOC,QAAO;AAEd,SAAS,SAAAC,cAAa;AAEf,IAAM,iBAAiBA,OAAgD;AAAA,EAC5E,MAAM;AAAA,EACN,OAAOH,MAAK,oBAAoB;AAAA,EAChC,QAAQ,CAAC,UAAUC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAMf,OAAO,GAAG;AAAA;AAAA;AAAA,EAGd,QAAQC,GAAE,OAAO;AAAA,IACf,aAAaA,GAAE,OAAO,EAAE,SAAS,mCAAmC;AAAA,EACtE,CAAC;AACH,CAAC;;;ACZD,IAAO,oBAAQ;AAAA,EACb;AAAA,IACE;AAAA,EACF;AAAA,EACA;AAAA,IACE;AAAA,EACF;AAAA,EACA;AAAA,IACE;AAAA,EACF;AAAA,EACA;AAAA,IACE;AAAA,EACF;AAAA,EACA;AAAA,IACE;AAAA,EACF;AAAA,EACA,UAAU;AAAA,IACR,MAAM;AAAA,IACN,QACE;AAAA,EACJ,CAAC;AAAA,EACD,UAAU;AAAA,IACR,MAAM;AAAA,IACN,QACE;AAAA,IACF,QACE;AAAA,EACJ,CAAC;AAAA,EACD,UAAU;AAAA,IACR,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,QACE;AAAA,EACJ,CAAC;AAAA,EACD,cAAc;AAAA,IACZ,MAAM;AAAA,IACN,KAAK;AAAA,IACL,QAAQ;AAAA,EACV,CAAC;AAAA,EACD,cAAc;AAAA,IACZ,MAAM;AAAA,IACN,KAAK;AAAA,IACL,QAAQ;AAAA,EACV,CAAC;AAAA,EACD,SAAS;AAAA,IACP,MAAM;AAAA,IACN,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF,CAAC;AAAA,EACD,WAAW;AAAA,IACT,QACE;AAAA,EACJ,CAAC;AAAA;AAAA,EAED,UAAU;AAAA,IACR,MAAM;AAAA,IACN,QACE;AAAA,EACJ,CAAC;AAAA,EACD,UAAU;AAAA,IACR,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,QACE;AAAA,EACJ,CAAC;AAAA,EACD,UAAU;AAAA,IACR,MAAM;AAAA,IACN,QAAQ;AAAA,EACV,CAAC;AAAA,EACD;AAAA,IACE;AAAA,EACF;AACF;;;AF/BO,IAAM,WAAN,MAAe;AAAA,EACpB;AAAA,EAWA,YAAY,QAQT;AACD,SAAK,UAAU;AAAA,MACb,SAAS,OAAO;AAAA,MAChB,YAAY,IAAI,UAAU,WAAW,OAAO,OAAO;AAAA,MACnD,SAAS,OAAO;AAAA,MAChB,cAAc,CAAC,GAAG,mBAAW,GAAI,OAAO,gBAAgB,CAAC,CAAE;AAAA,MAC3D,OAAO,OAAO,SAAS,CAAC;AAAA,MACxB,OAAO,OAAO;AAAA,MACd,QAAQ,OAAO;AAAA,MACf,eAAe,IAAI,UAAU,mBAAmB,OAAO,OAAO;AAAA,IAChE;AAAA,EACF;AAAA,EAEA,MAAa,QAAQ,KAAa;AAChC,UAAM,EAAE,oBAAoB,IAAI,MAAM;AAAA,MACpC;AAAA,MACA,CAAC,KAAK,mBAAmB,CAAC;AAAA,MAC1B,EAAE,IAAI;AAAA,IACR;AACA,WAAO,oBAAoB;AAAA,EAC7B;AAAA,EAEA,MAAa,MACX,OACA,SACiB;AACjB,UAAM,gBAAgB,MAAM,KAAK,MAAM;AAEvC,UAAM,EAAE,KAAK,IAAI,MAAM;AAAA,MACrB,cAAc,MAAM;AAAA,QAClB,OAAO,KAAK,QAAQ;AAAA,QACpB,OAAO;AAAA,UACL,GAAG,MAAM,QAAQ;AAAA,UACjB,GAAI,SAAS,SAAS,KAAK,QAAQ;AAAA,QACrC;AAAA,MACF,CAAC;AAAA,MACD,CAAC,KAAK,KAAK,CAAC;AAAA,MACZ;AAAA,QACE,WAAW;AAAA,UACT;AAAA,UACA,QAAQ;AAAA,YACN,MAAM;AAAA,YACN,MAAM;AAAA,YACN,MAAM;AAAA,UACR,CAAC;AAAA,UACD,GAAG,KAAK,QAAQ;AAAA,QAClB;AAAA,QACA,SAAS,KAAK,QAAQ;AAAA,QACtB;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA,EAEO,YAAY,SAAuB;AACxC,SAAK,QAAQ,aAAa,KAAK,GAAG,OAAO;AAAA,EAC3C;AAAA,EAEA,MAAa,QAAQE,QAAc;AACjC,UAAM,CAAC,SAAS,IAAI,MAAM,QAAQ,IAAI,CAAC,KAAK,MAAM,CAAoB,CAAC;AAEvE,UAAM,kBAAkB,OAAO,KAAK,KAAK,QAAQ,SAAS,CAAC,CAAC,EAAE;AAAA,MAC5D,CAAC,SAAS,KAAK,WAAW,SAAS;AAAA,IACrC;AACA,UAAM,kBAAkB;AAAA,MACtB,GAAG,KAAK,QAAQ;AAAA,MAChB,GAAI,gBAAgB,SAChB;AAAA,QACE,KAAK,8BAA8B,gBAAgB,KAAK,IAAI,CAAC,GAAG;AAAA,QAChE,WAAW;AAAA,UACT,QACE;AAAA,UACF,QACE;AAAA,QACJ,CAAC;AAAA,MACH,IACA,CAAC;AAAA,IACP;AAEA,UAAMC,SAAQ,OAAO,KAAK;AAAA,MACxB,GAAGD,OAAM,QAAQ;AAAA,MACjB,GAAI,KAAK,QAAQ,SAAS,cAAc,CAAC;AAAA,MACzC,GAAG,KAAK,QAAQ;AAAA,IAClB,CAAC;AAED,WAAO;AAAA,MACL,OAAAC;AAAA,MACA,QAAQD,OAAM,aAAa;AAAA,QACzB,eAAe;AAAA,QACf,WAAW;AAAA,UACT;AAAA,UACA,QAAQ;AAAA,YACN,MAAM;AAAA,YACN,MAAM;AAAA,YACN,MAAM;AAAA,UACR,CAAC;AAAA,UACD,GAAG;AAAA,QACL;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEA,MAAa,MAAM,SAA6B;AAC9C,UAAM,SAAS,MAAM,KAAK,QAAQ,cAAc,IAAI;AACpD,QAAI,QAAQ;AACV,aAAO;AAAA,IACT;AACA,UAAM,gBAAgB,MAAM,KAAK,QAAQ,QAAQ,WAAW;AAC5D,UAAM,KAAK,QAAQ,cAAc,IAAI,aAAa;AAClD,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAoBA,MAAa,KACX,UACA,QAIA;AACA,UAAM,CAAC,eAAe,cAAc,IAAI,MAAM,QAAQ,IAAI;AAAA,MACxD,KAAK,MAAM,EAAE,YAAY,QAAQ,IAAI,CAAC;AAAA,MACtC,KAAK,QAAQ,SACT,KAAK,QAAQ,OAAO,aAAa,OAAO,MAAM,IAC9C,CAAC;AAAA,IACP,CAAC;AACD,UAAM,OAAO,MAAM,KAAK,QAAQ,QAAQ,WAAW;AAAA,MACjD,IAAI,OAAO;AAAA,MACX,QAAQ,OAAO;AAAA,MACf,OAAO,UAAU,OAAO;AAAA,IAC1B,CAAC;AAGD,UAAM,kBAAkB,OAAO,KAAK,KAAK,QAAQ,SAAS,CAAC,CAAC,EAAE;AAAA,MAC5D,CAAC,SAAS,KAAK,WAAW,SAAS;AAAA,IACrC;AACA,UAAM,eAAe;AAAA,MACnB,GAAG,KAAK,QAAQ;AAAA,MAChB,GAAI,gBAAgB,SAChB;AAAA,QACE,KAAK,8BAA8B,gBAAgB,KAAK,IAAI,CAAC,GAAG;AAAA,QAChE,WAAW;AAAA,UACT,QACE;AAAA,UACF,QACE;AAAA,QACJ,CAAC;AAAA,MACH,IACA,CAAC;AAAA,IACP;AAEA,UAAM,SAAS;AAAA,MACb,MAAM,MAAM;AAAA,QACV,OAAO,KAAK,QAAQ;AAAA,QACpB,OAAO;AAAA,UACL,GAAG,MAAM,QAAQ;AAAA,UACjB,GAAI,KAAK,QAAQ,SAAS,cAAc,CAAC;AAAA,UACzC,GAAG,KAAK,QAAQ;AAAA,QAClB;AAAA,MACF,CAAC;AAAA,MACD,CAAC,GAAG,KAAK,SAAS,IAAI,CAAC,OAAO,GAAG,OAAO,GAAG,GAAG,QAAQ;AAAA,MACtD;AAAA,QACE,WAAW;AAAA,UACT;AAAA,UACA,QAAQ;AAAA,YACN,MAAM;AAAA,YACN,MAAM;AAAA,YACN,MAAM;AAAA,UACR,CAAC;AAAA,UACD,GAAG;AAAA,UACH,UAAU,gBAAgB,GAAG,cAAc;AAAA,QAC7C;AAAA,QACA,SAAS,KAAK,QAAQ;AAAA,QACtB;AAAA,QACA,QAAQ,KAAK,QAAQ;AAAA,QACrB,QAAQ,OAAO;AAAA,MACjB;AAAA,IACF;AAEA,WAAO,OAAO,kBAAkB;AAAA,MAC9B,SAAS,CAAC,UAAU;AAClB,YAAI,gBAAgB,WAAW,KAAK,GAAG;AACrC,iBAAO;AAAA,QACT,WAAW,sBAAsB,WAAW,KAAK,GAAG;AAClD,iBAAO;AAAA,QACT,WAAW,oBAAoB,WAAW,KAAK,GAAG;AAChD,iBAAO;AAAA,QACT,OAAO;AACL,iBAAO;AAAA,QACT;AAAA,MACF;AAAA,MACA,WAAW;AAAA,MACX,YAAY;AAAA,MACZ,eAAe;AAAA,MACf,aAAa;AAAA,MACb,kBAAkB;AAAA,MAClB,mBAAmB;AAAA,MACnB,UAAU,OAAO,EAAE,UAAAE,UAAS,MAAM;AAChC,cAAM,cAAcA,UAAS,GAAG,EAAE;AAClC,cAAM,aAAaA,UAAS,GAAG,EAAE;AACjC,YAAI,CAAC,eAAe,CAAC,YAAY;AAC/B,gBAAM,IAAI,MAAM,qBAAqB;AAAA,QACvC;AACA,cAAM,KAAK,QAAQ,QAAQ,WAAW;AAAA,UACpC,IAAIC,IAAG;AAAA,UACP,QAAQ,OAAO;AAAA,UACf,MAAM,YAAY;AAAA,UAClB,SAAS;AAAA,QACX,CAAC;AACD,cAAM,KAAK,QAAQ,QAAQ,WAAW;AAAA,UACpC,IAAIA,IAAG;AAAA,UACP,QAAQ,OAAO;AAAA,UACf,MAAM,WAAW;AAAA,UACjB,SAAS;AAAA,QACX,CAAC;AAAA,MACH;AAAA,IACF,CAAC;AAAA,EACH;AACF;;;AG5SA,IAAI,YAAY,MAAM;AAoBtB;",
|
|
6
6
|
"names": ["groq", "z", "agent", "term", "clarification", "teachable", "tag", "z", "agent", "groq", "path", "DatabaseSync", "path", "DatabaseSync", "v7", "groq", "dedent", "z", "agent", "agent", "tools", "messages", "v7"]
|
|
7
7
|
}
|