Skip to content

Commit 873918d

Browse files
committed
🚧 WIP
1 parent 33ca232 commit 873918d

8 files changed

Lines changed: 137 additions & 19 deletions

File tree

examples/ai/prompt.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import {prompt} from '@github/models'
2+
import {generateText} from 'ai'
3+
import 'dotenv/config'
4+
5+
async function main() {
6+
const call = await prompt('./teacher.prompt.yml', {
7+
subject: 'balloon popping',
8+
})
9+
const result = await generateText(call)
10+
11+
console.log('Text:')
12+
console.log(result.text)
13+
console.log()
14+
15+
console.log('Token usage:', result.usage)
16+
console.log('Finish reason:', result.finishReason)
17+
}
18+
19+
main().catch(console.error)

examples/ai/teacher.prompt.yml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
name: teacher
2+
model: openai/gpt-4o-mini
3+
modelParameters:
4+
temperature: 0.7
5+
maxTokens: 300
6+
messages:
7+
- role: system
8+
content: You're an elementary school teacher who loves to make learning fun.
9+
- role: user
10+
content: Please explain {{subject}} in as little as 5 sentences.

package-lock.json

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

package.json

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,16 +32,19 @@
3232
"dependencies": {
3333
"@ai-sdk/openai-compatible": "beta",
3434
"@ai-sdk/provider": "beta",
35-
"@ai-sdk/provider-utils": "beta"
35+
"@ai-sdk/provider-utils": "beta",
36+
"confbox": "^0.2.2",
37+
"templite": "^1.2.0",
38+
"zod": "^3 || ^4"
3639
},
3740
"devDependencies": {
38-
"eslint-plugin-simple-import-sort": "12.1.1",
39-
"tsup": "^8.3.0",
4041
"@github/prettier-config": "0.0.6",
4142
"@types/node": "^24",
4243
"eslint": "^9",
4344
"eslint-plugin-github": "^6",
45+
"eslint-plugin-simple-import-sort": "12.1.1",
4446
"prettier": "^3",
47+
"tsup": "^8.3.0",
4548
"typescript": "^5.7.2",
4649
"vitest": "^3"
4750
},

readme.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,10 @@ You can use the following optional settings to customize the GitHub Models provi
7474
You can use it as a middleware to intercept requests,
7575
or to provide a custom fetch implementation for e.g. testing.
7676

77+
## Prompt.yaml
78+
79+
TODO
80+
7781
## License
7882

7983
Distributed under the MIT license. See [LICENSE](./license.txt) for details.

src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
export type {GitHubModelsChatModelId} from './options'
2+
export {getPrompt, prompt} from './prompt'
23
export {
34
createGitHubModels,
45
githubModels,

src/prompt.ts

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
import {readFile} from 'node:fs/promises'
2+
3+
import {type LanguageModelV2} from '@ai-sdk/provider'
4+
// eslint-disable-next-line import/no-unresolved
5+
import {parseYAML} from 'confbox/yaml'
6+
import templite from 'templite'
7+
import {z} from 'zod/v4'
8+
9+
import {createGitHubModels, type GitHubModelsProviderSettings} from './provider'
10+
11+
const message = z.discriminatedUnion('role', [
12+
z.object({role: z.literal('user'), content: z.string()}),
13+
z.object({role: z.literal('system'), content: z.string()}),
14+
])
15+
16+
type Message = z.infer<typeof message>
17+
18+
const schema = z.object({
19+
name: z.string().optional(),
20+
description: z.string().optional(),
21+
model: z.string(),
22+
modelParameters: z
23+
.object({
24+
maxTokens: z.number().positive().optional(),
25+
temperature: z.number().min(0).max(1).optional(),
26+
topP: z.number().min(0).max(1).optional(),
27+
})
28+
.optional(),
29+
messages: z.array(message),
30+
responseFormat: z.enum(['text']).optional(),
31+
})
32+
33+
type PromptConfig = z.infer<typeof schema>
34+
type Variables = Record<string, string | number | boolean>
35+
36+
export async function getPrompt(filename: string | URL, variables: Variables = {}): Promise<PromptConfig> {
37+
const file = await readFile(filename, 'utf8')
38+
const yml = parseYAML(file, {
39+
filename: filename.toString(),
40+
})
41+
const p = schema.parse(yml)
42+
for (const msg of p.messages) msg.content = templite(msg.content, variables)
43+
return p
44+
}
45+
46+
export async function prompt(
47+
filename: string | URL,
48+
variables: Variables = {},
49+
options: GitHubModelsProviderSettings = {},
50+
): Promise<{
51+
model: LanguageModelV2
52+
messages: Message[]
53+
temperature?: number
54+
maxOutputTokens?: number
55+
topP?: number
56+
}> {
57+
const p = await getPrompt(filename, variables)
58+
const provider = createGitHubModels(options)
59+
60+
return {
61+
model: provider(p.model),
62+
messages: p.messages,
63+
temperature: p.modelParameters?.temperature,
64+
maxOutputTokens: p.modelParameters?.maxTokens,
65+
topP: p.modelParameters?.topP,
66+
}
67+
}

tsconfig.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
"declaration": true,
88
"outDir": "dist",
99
"preserveConstEnums": true,
10-
"moduleResolution": "node",
10+
"moduleResolution": "bundler",
1111
"allowJs": true,
1212
"allowSyntheticDefaultImports": true,
1313
"allowUnreachableCode": false,

0 commit comments

Comments
 (0)