Skip to content

Commit

Permalink
fix: generate code prompt
Browse files Browse the repository at this point in the history
  • Loading branch information
rajatsandeepsen committed Dec 27, 2024
1 parent bd00852 commit 40288e1
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 30 deletions.
2 changes: 1 addition & 1 deletion packages/ai/core/generate-code/generate-code.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ describe('result.code', () => {

return {
...dummyResponseValues,
text: `\`\`\`ts
text: `\`\`\`js
let balance = listOfFunctions.getBalance({});
return balance
\`\`\`
Expand Down
33 changes: 20 additions & 13 deletions packages/ai/core/generate-code/prompt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,42 +3,49 @@ import { generateZodTypeString } from "./type-zod";

type AnyFunction = (...args: any[]) => any;

function isAsync(fn: AnyFunction): boolean {
function checkAsync(fn: AnyFunction): boolean {
return fn.constructor.name === 'AsyncFunction';
}

type TOOLS = Record<string, CoreTool>

const displayToolsToType = (tools: TOOLS) =>
Object.entries(tools)
.map(([key, value]) => {
const async = isAsync(value.execute)
return `type ${key} = (data:${generateZodTypeString(value.parameters, "data")}) => ${async ? "Promise<" : ""}${generateZodTypeString(value.returns, "returns")}${async ? ">" : ""}`
}
).join("\n")
const functionDefinition = (tool: TOOLS[string], isAsync:boolean) => {
const type = generateZodTypeString(tool.returns, "returns")

const returnType = isAsync ? `Promise<${type}>` : type
const paramType = generateZodTypeString(tool.parameters, "data")

return `${isAsync ? "async" : ""} (data:${paramType}): ${returnType} => {\n\t// ${tool?.description ?? "Does something"}\n\treturn // something\n}`
}

const displayToolsToCode = (tools: TOOLS) =>
Object.entries(tools)
.map(([key, value]) => `const ${key} = ${isAsync(value.execute) ? "async" : ""}(data:${generateZodTypeString(value.parameters, "data")}):${generateZodTypeString(value.returns, "returns")} => {\n // ${value?.description ?? "Does something"}\n return // something\n}`)
.map(([toolName, toolObject]) => {
if (!toolObject.execute)
throw new Error(`Execute function is required for tool ${toolName}`);

const isAsync = checkAsync(toolObject.execute)

return `const ${toolName} = ${functionDefinition(toolObject, isAsync)}`
})
.join("\n\n")

export const newSystemPrompt = (text: string, tools: TOOLS, thisKeyWord: string) => `Your Persona: ${text}
Instructions:
- write pure javascript code
- only use functions from the "Tools" list
- only use functions from the ${thisKeyWord} object
- functions are already defined
- don't imported or redifined
- don't imported any external libraries
- nested functions are allowed
- don't use any external libraries
- don't use console.log
- don't wrap code in a function
- use let to declare variables
- always end the code with return statement
- wrap the entire Javascript code in \`\`\`js ... \`\`\` code block
- also write the JSON schema for the return value of the code in \`\`\`json ... \`\`\` code block
if function name is build(), then use it as ${thisKeyWord}.build()
eg: if function name is build(), then use it as ${thisKeyWord}.build()
Tools:
Expand Down
33 changes: 17 additions & 16 deletions packages/ai/core/tool/tool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { ToolResultContent } from '../prompt/tool-result-content';
import { CoreMessage } from '../prompt/message';

type Parameters = z.ZodTypeAny | Schema<any>;
type Returns = Parameters;

export type inferParameters<PARAMETERS extends Parameters> =
PARAMETERS extends Schema<any>
Expand Down Expand Up @@ -36,20 +37,20 @@ This enables the language model to generate the input.
The tool can also contain an optional execute function for the actual execution function of the tool.
*/
export type CoreTool<PARAMETERS extends Parameters = any, RESULT extends Parameters = any> = {
export type CoreTool<PARAMETERS extends Parameters = any, RETURNS extends Returns = any, RESULT = any> = {
/**
The schema of the input that the tool expects. The language model will use this to generate the input.
It is also used to validate the output of the language model.
Use descriptions to make the input understandable for the language model.
*/
parameters: PARAMETERS;

returns: RESULT;
returns: RETURNS;

/**
An optional description of what the tool does. Will be used by the language model to decide whether to use the tool.
*/
description?: string;
description?: string;

/**
Optional conversion function that maps the tool result to multi-part tool content for LLMs.
Expand All @@ -63,10 +64,10 @@ If not provided, the tool will not be executed automatically.
@args is the input of the tool call.
@options.abortSignal is a signal that can be used to abort the tool call.
*/
execute: (
execute?: (
args: inferParameters<PARAMETERS>,
options: ToolExecutionOptions,
) => PromiseLike<inferParameters<RESULT>>;
) => PromiseLike<inferParameters<RETURNS>>;
} & (
| {
/**
Expand Down Expand Up @@ -96,28 +97,28 @@ The arguments for configuring the tool. Must match the expected arguments define
Helper function for inferring the execute args of a tool.
*/
// Note: special type inference is needed for the execute function args to make sure they are inferred correctly.
export function tool<PARAMETERS extends Parameters, RESULT extends Parameters>(
tool: CoreTool<PARAMETERS, RESULT> & {
export function tool<PARAMETERS extends Parameters, RETURNS extends Returns>(
tool: CoreTool<PARAMETERS, RETURNS> & {
execute: (
args: inferParameters<PARAMETERS>,
options: ToolExecutionOptions,
) => PromiseLike<inferParameters<RESULT>>;
) => PromiseLike<inferParameters<RETURNS>>;
},
): CoreTool<PARAMETERS, RESULT> & {
): CoreTool<PARAMETERS, RETURNS> & {
execute: (
args: inferParameters<PARAMETERS>,
options: ToolExecutionOptions,
) => PromiseLike<inferParameters<RESULT>>;
) => PromiseLike<inferParameters<RETURNS>>;
};
export function tool<PARAMETERS extends Parameters, RESULT extends Parameters>(
tool: CoreTool<PARAMETERS, RESULT> & {
export function tool<PARAMETERS extends Parameters>(
tool: CoreTool<PARAMETERS> & {
execute?: undefined;
},
): CoreTool<PARAMETERS, RESULT> & {
): CoreTool<PARAMETERS> & {
execute: undefined;
};
export function tool<PARAMETERS extends Parameters, RESULT extends Parameters = any>(
tool: CoreTool<PARAMETERS, RESULT>,
): CoreTool<PARAMETERS, RESULT> {
export function tool<PARAMETERS extends Parameters, RETURNS extends Returns>(
tool: CoreTool<PARAMETERS, RETURNS>,
): CoreTool<PARAMETERS, RETURNS> {
return tool;
}

0 comments on commit 40288e1

Please sign in to comment.