Skip to content

Commit c9b58d7

Browse files
committed
Prompt data interpolation functions
1 parent 1b22670 commit c9b58d7

File tree

7 files changed

+163
-1
lines changed

7 files changed

+163
-1
lines changed

packages/llm_manager/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,13 @@
1919
"@latitude-data/source-manager": "workspace:*",
2020
"@latitude-data/sql-compiler": "workspace:^",
2121
"dotenv": "^16.4.5",
22+
"json-2-csv": "^5.5.1",
2223
"openai": "^4.52.0",
2324
"yaml": "^2.3.4"
2425
},
2526
"devDependencies": {
2627
"@latitude-data/eslint-config": "workspace:*",
28+
"@latitude-data/query_result": "workspace:*",
2729
"@latitude-data/typescript": "workspace:*",
2830
"@rollup/plugin-typescript": "^11.1.6",
2931
"@types/mock-fs": "^4.13.4",
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import { BuildSupportedMethodsArgs } from '$/types'
2+
import {
3+
emptyMetadata,
4+
type SupportedMethod,
5+
} from '@latitude-data/sql-compiler'
6+
import { QueryResultArray } from '@latitude-data/query_result'
7+
import { json2csv } from 'json-2-csv'
8+
9+
const buildCastMethod = (_: BuildSupportedMethodsArgs): SupportedMethod => ({
10+
requirements: {
11+
interpolationPolicy: 'require', // Results can be interpolated
12+
interpolationMethod: 'raw', // When interpolating, use the raw value
13+
requireStaticArguments: false, // Can be used with variables or logic expressions
14+
},
15+
16+
resolve: async (value: QueryResultArray) => {
17+
// Check value is the correct type (array of objects)
18+
if (!Array.isArray(value) || !value.every((v) => typeof v === 'object')) {
19+
throw new Error('Value must be a query result.')
20+
}
21+
22+
return json2csv(value, {
23+
keys: value[0] ? Object.keys(value[0]) : [],
24+
expandArrayObjects: false,
25+
expandNestedObjects: false,
26+
})
27+
},
28+
29+
readMetadata: async () => {
30+
return emptyMetadata()
31+
},
32+
})
33+
34+
export default buildCastMethod

packages/llm_manager/src/model/supportedMethods/index.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ import { default as buildParam } from './param'
66
import { default as buildRef } from './ref'
77
import { default as buildRunQuery } from './runQuery'
88
import { default as buildReadQuery } from './readQuery'
9+
import { default as table } from './table'
10+
import { default as json } from './json'
11+
import { default as csv } from './csv'
912

1013
export default function buildSupportedMethods(
1114
args: BuildSupportedMethodsArgs,
@@ -16,5 +19,8 @@ export default function buildSupportedMethods(
1619
runQuery: buildRunQuery(args),
1720
cast: buildCast(args),
1821
readQuery: buildReadQuery(args),
22+
table: table(args),
23+
json: json(args),
24+
csv: csv(args),
1925
}
2026
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import { BuildSupportedMethodsArgs } from '$/types'
2+
import {
3+
emptyMetadata,
4+
type SupportedMethod,
5+
} from '@latitude-data/sql-compiler'
6+
import { QueryResultArray } from '@latitude-data/query_result'
7+
8+
function removeBigInts(results: QueryResultArray) {
9+
results.forEach((row, i) => {
10+
Object.entries(row).forEach(([key, value]) => {
11+
if (typeof value === 'bigint') {
12+
results[i]![key] = Number(value)
13+
}
14+
})
15+
})
16+
}
17+
18+
const buildCastMethod = (_: BuildSupportedMethodsArgs): SupportedMethod => ({
19+
requirements: {
20+
interpolationPolicy: 'require', // Results can be interpolated
21+
interpolationMethod: 'raw', // When interpolating, use the raw value
22+
requireStaticArguments: false, // Can be used with variables or logic expressions
23+
},
24+
25+
resolve: async (value: QueryResultArray) => {
26+
// Check value is the correct type (array of objects)
27+
if (!Array.isArray(value) || !value.every((v) => typeof v === 'object')) {
28+
throw new Error('Value must be a query result.')
29+
}
30+
31+
removeBigInts(value)
32+
return JSON.stringify(value)
33+
},
34+
35+
readMetadata: async () => {
36+
return emptyMetadata()
37+
},
38+
})
39+
40+
export default buildCastMethod

packages/llm_manager/src/model/supportedMethods/ref.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ const buildRefMethod = ({
4343
refContext,
4444
)
4545

46-
return `(${compiledSubPrompt.prompt})`
46+
return compiledSubPrompt.prompt
4747
},
4848

4949
readMetadata: async () => {
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import { BuildSupportedMethodsArgs } from '$/types'
2+
import {
3+
emptyMetadata,
4+
type SupportedMethod,
5+
} from '@latitude-data/sql-compiler'
6+
import { QueryResultArray } from '@latitude-data/query_result'
7+
8+
type Col = {
9+
name: string
10+
values: string[]
11+
maxLength: number
12+
}
13+
14+
function padSpaces(str: string, length: number) {
15+
return str + ' '.repeat(Math.max(0, length - str.length))
16+
}
17+
18+
const buildCastMethod = (_: BuildSupportedMethodsArgs): SupportedMethod => ({
19+
requirements: {
20+
interpolationPolicy: 'require', // Results can be interpolated
21+
interpolationMethod: 'raw', // When interpolating, use the raw value
22+
requireStaticArguments: false, // Can be used with variables or logic expressions
23+
},
24+
25+
resolve: async (value: QueryResultArray) => {
26+
// Check value is the correct type (array of objects)
27+
if (!Array.isArray(value) || !value.every((v) => typeof v === 'object')) {
28+
throw new Error('Value must be a query result.')
29+
}
30+
31+
const cols: Col[] = []
32+
33+
value.forEach((row, i) => {
34+
Object.entries(row).forEach(([col, val]) => {
35+
let colIndex = cols.findIndex((c) => c.name === col)
36+
if (colIndex === -1) {
37+
colIndex = cols.length
38+
cols.push({
39+
name: col,
40+
values: Array(value.length).fill(''), // Fill with empty strings
41+
maxLength: 0,
42+
})
43+
}
44+
45+
const valStr = String(val).replace(/\n/g, '\\n')
46+
cols[colIndex]!.values[i] = valStr
47+
48+
if (valStr.length > cols[colIndex]!.maxLength) {
49+
cols[colIndex]!.maxLength = valStr.length
50+
}
51+
})
52+
})
53+
54+
let table = ''
55+
56+
// Add header row
57+
table += '| ' + cols.map(c => padSpaces(c.name, c.maxLength)).join(' | ') + ' |\n'
58+
table += '|-' + cols.map(c => '-'.repeat(c.maxLength)).join('-|-') + '-|\n'
59+
60+
// Add data rows
61+
value.forEach((_, i) => {
62+
const cells = cols.map((c) => padSpaces(c.values[i]!, c.maxLength))
63+
table += '| ' + cells.join(' | ') + ' |\n'
64+
})
65+
66+
return table
67+
},
68+
69+
readMetadata: async () => {
70+
return emptyMetadata()
71+
},
72+
})
73+
74+
export default buildCastMethod

pnpm-lock.yaml

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)