|
1 | 1 | import { anthropic } from '@ai-sdk/anthropic'; |
2 | | -import { streamText } from 'ai'; |
| 2 | +import { streamText, tool } from 'ai'; |
| 3 | +import { getInstalledDataSources } from '@/lib/tinybird'; |
| 4 | +import { z } from 'zod'; |
3 | 5 |
|
4 | 6 | // Allow streaming responses up to 30 seconds |
5 | 7 | export const maxDuration = 30; |
6 | 8 |
|
7 | 9 | export async function POST(req: Request) { |
| 10 | + const token = req.headers.get('token') ?? ''; |
8 | 11 | const { messages } = await req.json(); |
| 12 | + console.log('token: ' + token) |
9 | 13 |
|
10 | 14 | const result = streamText({ |
11 | 15 | model: anthropic('claude-3-5-sonnet-latest'), |
| 16 | + maxSteps: 5, |
| 17 | + tools: { |
| 18 | + getAvailableDataSources: tool({ |
| 19 | + description: 'Get available data sources. ' + |
| 20 | + 'This returns the names of data sources that the user currently has data available.' + |
| 21 | + 'Only the data sources returned by the this tools should be used in future tools to query data.' + |
| 22 | + 'This tool must always be used before analysing data.', |
| 23 | + parameters: z.object({ |
| 24 | + // token: z.string().describe('Tinybird Admin Token used to authenticate calls to the Tinybird API'), |
| 25 | + }), |
| 26 | + execute: async () => { |
| 27 | + const dataSources = await getInstalledDataSources(token); |
| 28 | + return dataSources; |
| 29 | + }, |
| 30 | + }), |
| 31 | + queryDataSource: tool({ |
| 32 | + description: 'Query a data source. ' + |
| 33 | + 'This tool should be used to query data sources that the user has data available.' + |
| 34 | + 'Only the data sources returned by the getAvailableDataSources tool should be used as sources of data for this tool.' + |
| 35 | + 'This tool should generate Tinybird SQL queries, which are based on a subset of ClickHouse SQL.' + |
| 36 | + 'Every query MUST follow these rules:' + |
| 37 | + '1. The query must be a valid Tinybird SQL query' + |
| 38 | + '2. The query must be a SELECT query' + |
| 39 | + '3. The query must be a single query' + |
| 40 | + '4. The query must be a single table' + |
| 41 | + '5. The query must not end with a semicolon (;)' + |
| 42 | + '6. The query must end with the text FORMAT JSON' + |
| 43 | + '7. The query must not contains new lines' + |
| 44 | + 'The schema of all data sources is as follows: event_time DATETIME, event_type STRING, event JSON.' + |
| 45 | + 'The event column contains a JSON object using the ClickHouse JSON type. The fields should be accessed using dot notation, e.g. event.data.field_name.', |
| 46 | + parameters: z.object({ |
| 47 | + // token: z.string().describe('Tinybird Admin Token used to authenticate calls to the Tinybird API'), |
| 48 | + query: z.string().describe('The SQL query to execute'), |
| 49 | + response: z.string().describe('An analysis of the data returned by the query which is shown to the user. The analysis must include the result of the query at the start.'), |
| 50 | + }), |
| 51 | + execute: async ({ query }) => { |
| 52 | + const response = await fetch(`/api/query?token=${token}&query=${encodeURIComponent(query)}`, { |
| 53 | + method: 'GET', |
| 54 | + }); |
| 55 | + const data = await response.json(); |
| 56 | + return data; |
| 57 | + }, |
| 58 | + }), |
| 59 | + }, |
| 60 | + system: 'You are the founder of a SaaS business. ' + |
| 61 | + 'You want to understand your customers and their usage of your SaaS. ' + |
| 62 | + 'Your product is built using various other SaaS products as building blocks. ' + |
| 63 | + 'You have configured those SaaS products to push data to Tinybird. ' + |
| 64 | + 'Tinybird is a data platform that allows you to query that data using SQL.' + |
| 65 | + 'You can use the getAvailableDataSources tool to get the names of the data sources that you have available. ' + |
| 66 | + 'You can use the queryDataSource tool to query the data sources that you have available. ', |
12 | 67 | messages, |
13 | 68 | }); |
14 | 69 |
|
|
0 commit comments