kopia lustrzana https://github.com/transitive-bullshit/chatgpt-api
feat: add calculator tool
rodzic
cb6ea27d80
commit
c531872378
|
@ -43,6 +43,7 @@
|
||||||
"@inquirer/editor": "^1.2.0",
|
"@inquirer/editor": "^1.2.0",
|
||||||
"@inquirer/select": "^1.2.1",
|
"@inquirer/select": "^1.2.1",
|
||||||
"debug": "^4.3.4",
|
"debug": "^4.3.4",
|
||||||
|
"expr-eval": "^2.0.2",
|
||||||
"handlebars": "^4.7.7",
|
"handlebars": "^4.7.7",
|
||||||
"js-tiktoken": "^1.0.6",
|
"js-tiktoken": "^1.0.6",
|
||||||
"jsonrepair": "^3.1.0",
|
"jsonrepair": "^3.1.0",
|
||||||
|
|
|
@ -20,6 +20,9 @@ dependencies:
|
||||||
debug:
|
debug:
|
||||||
specifier: ^4.3.4
|
specifier: ^4.3.4
|
||||||
version: 4.3.4
|
version: 4.3.4
|
||||||
|
expr-eval:
|
||||||
|
specifier: ^2.0.2
|
||||||
|
version: 2.0.2
|
||||||
handlebars:
|
handlebars:
|
||||||
specifier: ^4.7.7
|
specifier: ^4.7.7
|
||||||
version: 4.7.7
|
version: 4.7.7
|
||||||
|
@ -1793,6 +1796,10 @@ packages:
|
||||||
engines: {node: '>=12.0.0'}
|
engines: {node: '>=12.0.0'}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/expr-eval@2.0.2:
|
||||||
|
resolution: {integrity: sha512-4EMSHGOPSwAfBiibw3ndnP0AvjDWLsMvGOvWEZ2F96IGk0bIVdjQisOHxReSkE13mHcfbuCiXw+G4y0zv6N8Eg==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/external-editor@3.1.0:
|
/external-editor@3.1.0:
|
||||||
resolution: {integrity: sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==}
|
resolution: {integrity: sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==}
|
||||||
engines: {node: '>=4'}
|
engines: {node: '>=4'}
|
||||||
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
import { Parser } from 'expr-eval'
|
||||||
|
import { z } from 'zod'
|
||||||
|
|
||||||
|
import * as types from '@/types'
|
||||||
|
import { BaseTask } from '@/task'
|
||||||
|
|
||||||
|
export const CalculatorInputSchema = z.string().describe('expression')
|
||||||
|
export const CalculatorOutputSchema = z
|
||||||
|
.number()
|
||||||
|
.describe('result of calculating the expression')
|
||||||
|
|
||||||
|
export type CalculatorInput = z.infer<typeof CalculatorInputSchema>
|
||||||
|
|
||||||
|
export type CalculatorOutput = z.infer<typeof CalculatorOutputSchema>
|
||||||
|
|
||||||
|
export class CalculatorTool extends BaseTask<
|
||||||
|
CalculatorInput,
|
||||||
|
CalculatorOutput
|
||||||
|
> {
|
||||||
|
constructor(opts: types.BaseTaskOptions) {
|
||||||
|
super(opts)
|
||||||
|
}
|
||||||
|
|
||||||
|
public override get inputSchema() {
|
||||||
|
return CalculatorInputSchema
|
||||||
|
}
|
||||||
|
|
||||||
|
public override get outputSchema() {
|
||||||
|
return CalculatorOutputSchema
|
||||||
|
}
|
||||||
|
|
||||||
|
public override get name(): string {
|
||||||
|
return 'calculator'
|
||||||
|
}
|
||||||
|
|
||||||
|
public get descriptionForModel(): string {
|
||||||
|
return 'Useful for getting the result of a math expression. The input to this tool should be a valid mathematical expression that could be executed by a simple calculator.'
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override async _call(
|
||||||
|
ctx: types.TaskCallContext<CalculatorInput>
|
||||||
|
): Promise<CalculatorOutput> {
|
||||||
|
const result = Parser.evaluate(ctx.input!)
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
import test from 'ava'
|
||||||
|
import { expectTypeOf } from 'expect-type'
|
||||||
|
|
||||||
|
import { CalculatorTool } from '@/tools/calculator'
|
||||||
|
|
||||||
|
import { createTestAgenticRuntime } from './_utils'
|
||||||
|
|
||||||
|
test('CalculatorTool', async (t) => {
|
||||||
|
const agentic = createTestAgenticRuntime()
|
||||||
|
const tool = new CalculatorTool({ agentic })
|
||||||
|
|
||||||
|
const res = await tool.call('1 + 1')
|
||||||
|
t.is(res, 2)
|
||||||
|
expectTypeOf(res).toMatchTypeOf<number>()
|
||||||
|
|
||||||
|
const res2 = await tool.callWithMetadata('cos(0)')
|
||||||
|
t.is(res2.result, 1)
|
||||||
|
expectTypeOf(res2.result).toMatchTypeOf<number>()
|
||||||
|
|
||||||
|
const { taskId, ...metadata } = res2.metadata
|
||||||
|
t.true(typeof taskId === 'string')
|
||||||
|
t.deepEqual(metadata, {
|
||||||
|
success: true,
|
||||||
|
taskName: 'calculator',
|
||||||
|
numRetries: 0,
|
||||||
|
error: undefined
|
||||||
|
})
|
||||||
|
})
|
Ładowanie…
Reference in New Issue