kopia lustrzana https://github.com/transitive-bullshit/chatgpt-api
pull/643/head^2
rodzic
4b4e7e0510
commit
65e2e73a00
|
@ -18,40 +18,46 @@ async function main() {
|
|||
{ role: 'user', content: 'What is the weather in San Francisco?' }
|
||||
]
|
||||
|
||||
const res0 = await openai.chat.completions.create({
|
||||
messages,
|
||||
model: 'gpt-4o',
|
||||
temperature: 0,
|
||||
tools: weather.tools.specs,
|
||||
tool_choice: 'required'
|
||||
})
|
||||
const message0 = res0.choices[0]?.message!
|
||||
console.log(JSON.stringify(message0, null, 2))
|
||||
assert(message0.role === 'assistant')
|
||||
assert(message0.tool_calls?.[0]?.function?.name === 'get_current_weather')
|
||||
const tools = weather.tools
|
||||
|
||||
const getCurrentWeather = weather.tools.get('get_current_weather')!.function
|
||||
assert(getCurrentWeather)
|
||||
{
|
||||
// First call to OpenAI to invoke the weather tool
|
||||
const res = await openai.chat.completions.create({
|
||||
messages,
|
||||
model: 'gpt-4o',
|
||||
temperature: 0,
|
||||
tools: tools.specs,
|
||||
tool_choice: 'required'
|
||||
})
|
||||
const message = res.choices[0]?.message!
|
||||
console.log(JSON.stringify(message, null, 2))
|
||||
assert(message.tool_calls?.[0]?.function?.name === 'get_current_weather')
|
||||
|
||||
const toolParams = message0.tool_calls[0].function.arguments
|
||||
assert(typeof toolParams === 'string')
|
||||
const toolResult = await getCurrentWeather(toolParams)
|
||||
const fn = tools.get('get_current_weather')!.function
|
||||
assert(fn)
|
||||
|
||||
messages.push(message0)
|
||||
messages.push({
|
||||
role: 'tool',
|
||||
tool_call_id: message0.tool_calls[0].id,
|
||||
content: JSON.stringify(toolResult)
|
||||
})
|
||||
const toolParams = message.tool_calls[0].function.arguments
|
||||
const toolResult = await fn(toolParams)
|
||||
|
||||
const res1 = await openai.chat.completions.create({
|
||||
messages,
|
||||
model: 'gpt-4o',
|
||||
temperature: 0,
|
||||
tools: weather.tools.specs
|
||||
})
|
||||
const message1 = res1.choices[0].message
|
||||
console.log(JSON.stringify(message1, null, 2))
|
||||
messages.push(message)
|
||||
messages.push({
|
||||
role: 'tool',
|
||||
tool_call_id: message.tool_calls[0].id,
|
||||
content: JSON.stringify(toolResult)
|
||||
})
|
||||
}
|
||||
|
||||
{
|
||||
// Second call to OpenAI to generate a text response
|
||||
const res = await openai.chat.completions.create({
|
||||
messages,
|
||||
model: 'gpt-4o',
|
||||
temperature: 0,
|
||||
tools: tools.specs
|
||||
})
|
||||
const message = res.choices[0].message
|
||||
console.log(JSON.stringify(message, null, 2))
|
||||
}
|
||||
}
|
||||
|
||||
await main()
|
||||
|
|
|
@ -26,12 +26,15 @@ export function createAIFunction<InputSchema extends z.ZodObject<any>, Return>(
|
|||
/** Implementation of the function to call with the parsed arguments. */
|
||||
implementation: (params: z.infer<InputSchema>) => types.MaybePromise<Return>
|
||||
): types.AIFunction<InputSchema, Return> {
|
||||
assert(spec.name, 'Missing required AIFunction "spec.name"')
|
||||
assert(spec.inputSchema, 'Missing required AIFunction "spec.inputSchema"')
|
||||
assert(implementation, 'Missing required AIFunction "implementation"')
|
||||
assert(spec.name, 'createAIFunction missing required "spec.name"')
|
||||
assert(
|
||||
spec.inputSchema,
|
||||
'createAIFunction missing required "spec.inputSchema"'
|
||||
)
|
||||
assert(implementation, 'createAIFunction missing required "implementation"')
|
||||
assert(
|
||||
typeof implementation === 'function',
|
||||
'Required AIFunction "implementation" must be a function'
|
||||
'createAIFunction "implementation" must be a function'
|
||||
)
|
||||
|
||||
/** Parse the arguments string, optionally reading from a message. */
|
11
src/fns.ts
11
src/fns.ts
|
@ -3,9 +3,9 @@ import './symbol-polyfill.js'
|
|||
import type { z } from 'zod'
|
||||
|
||||
import type * as types from './types.js'
|
||||
import { createAIFunction } from './ai-function.js'
|
||||
import { AIFunctionSet } from './ai-function-set.js'
|
||||
import { AIToolSet } from './ai-tool-set.js'
|
||||
import { createAIFunction } from './create-ai-function.js'
|
||||
import { assert } from './utils.js'
|
||||
|
||||
export interface Invocable {
|
||||
|
@ -35,7 +35,7 @@ export abstract class AIToolsProvider {
|
|||
// console.log({ metadata, invocables })
|
||||
|
||||
const aiFunctions = invocables.map((invocable) => {
|
||||
const impl = (this as any)[invocable.methodName]?.bind(this)
|
||||
const impl = (this as any)[invocable.methodName]
|
||||
assert(impl)
|
||||
|
||||
return createAIFunction(invocable, impl)
|
||||
|
@ -87,14 +87,15 @@ export function aiFunction<
|
|||
inputSchema,
|
||||
methodName
|
||||
})
|
||||
|
||||
// console.log({
|
||||
// name,
|
||||
// methodName,
|
||||
// context
|
||||
// })
|
||||
|
||||
// context.addInitializer(function () {
|
||||
// ;(this as any)[methodName] = (this as any)[methodName].bind(this)
|
||||
// })
|
||||
context.addInitializer(function () {
|
||||
;(this as any)[methodName] = (this as any)[methodName].bind(this)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
export * from './ai-function.js'
|
||||
export * from './ai-function-set.js'
|
||||
export * from './ai-tool-set.js'
|
||||
export * from './create-ai-function.js'
|
||||
export * from './errors.js'
|
||||
export * from './fns.js'
|
||||
export * from './parse-structured-output.js'
|
||||
|
|
Ładowanie…
Reference in New Issue