Skip to content

Commit 5e4d44b

Browse files
Merge pull request #4 from aipotheosis-labs/more_code_example
create more code example
2 parents 13e5dc3 + b996b04 commit 5e4d44b

File tree

5 files changed

+447
-2
lines changed

5 files changed

+447
-2
lines changed

examples/ai-sdk.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import { generateText, tool } from 'ai';
2+
import { openai } from '@ai-sdk/openai';
3+
import { jsonSchema } from 'ai';
4+
import dotenv from 'dotenv';
5+
import { FunctionDefinitionFormat } from '@aci-sdk/aci';
6+
import { ACI } from '@aci-sdk/aci';
7+
import { OpenAIResponsesFunctionDefinition } from '@aci-sdk/aci';
8+
9+
dotenv.config();
10+
11+
async function main() {
12+
const aciClient = new ACI({
13+
apiKey: process.env.ACI_API_KEY as string
14+
});
15+
16+
const braveSearchFunctionDefinition = await aciClient.functions.getDefinition(
17+
'BRAVE_SEARCH__WEB_SEARCH',
18+
FunctionDefinitionFormat.OPENAI_RESPONSES
19+
) as OpenAIResponsesFunctionDefinition
20+
21+
const result = await generateText({
22+
model: openai('gpt-4o'),
23+
tools: {
24+
braveSearch: tool({
25+
description: 'Search the web for information',
26+
parameters: jsonSchema(braveSearchFunctionDefinition.parameters),
27+
}),
28+
},
29+
prompt: 'What is the weather in San Francisco?',
30+
});
31+
32+
for (const toolCall of result.toolCalls) {
33+
console.log(JSON.stringify(toolCall, null, 2));
34+
}
35+
}
36+
37+
main().catch(console.error);

examples/openai-dynamic-tool.ts

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
import OpenAI from 'openai';
2+
import { ACI } from '../src/client';
3+
import {
4+
ACISearchFunctions,
5+
ACIExecuteFunction
6+
} from '../src/meta_functions';
7+
import { FunctionDefinitionFormat } from '../src/types/functions';
8+
import dotenv from 'dotenv';
9+
10+
// Load environment variables
11+
dotenv.config();
12+
13+
async function main() {
14+
// Initialize clients
15+
const aciClient = new ACI({
16+
apiKey: process.env.ACI_API_KEY as string
17+
});
18+
19+
const openaiClient = new OpenAI({
20+
apiKey: process.env.OPENAI_API_KEY as string,
21+
});
22+
23+
// Get function schemas in OpenAI format
24+
const aciSearchFunctionsSchema = ACISearchFunctions.toJsonSchema(
25+
FunctionDefinitionFormat.OPENAI_RESPONSES
26+
);
27+
28+
const aciExecuteFunctionSchema = ACIExecuteFunction.toJsonSchema(
29+
FunctionDefinitionFormat.OPENAI_RESPONSES
30+
);
31+
32+
const systemPrompt = `You are a helpful assistant with access to an unlimited number of tools via some meta functions:
33+
- ACI_SEARCH_FUNCTIONS,
34+
- and ACI_EXECUTE_FUNCTION.
35+
You can use ACI_SEARCH_FUNCTIONS to find relevant functions across all apps.
36+
Try to limit the number of results per request to 10.
37+
Once you have identified the function you need to use,
38+
you can use ACI_EXECUTE_FUNCTION to execute the function provided you have the correct input arguments.
39+
`;
40+
41+
const userMessage = "Can you star aipotheosis-labs/aci github repo?"
42+
43+
// Step 1: Search for relevant functions
44+
const searchResponse = await openaiClient.responses.create({
45+
model: 'gpt-4',
46+
input: [
47+
{
48+
role: 'system',
49+
content: systemPrompt
50+
},
51+
{
52+
role: 'user',
53+
content: userMessage
54+
}
55+
],
56+
tools: [aciSearchFunctionsSchema, aciExecuteFunctionSchema] as any
57+
});
58+
59+
// Find the first function call in the response
60+
const searchToolCall = searchResponse.output.find(
61+
(item: any) => item.type === 'function_call'
62+
);
63+
64+
if (!searchToolCall || searchToolCall.type !== 'function_call') {
65+
throw new Error('No tool call returned from OpenAI');
66+
}
67+
68+
// Step 2: Handle the ACI search function call
69+
const searchArguments = JSON.parse(searchToolCall.arguments);
70+
const searchResults = await aciClient.handleFunctionCall({
71+
functionName: searchToolCall.name,
72+
functionArguments: searchArguments,
73+
linkedAccountOwnerId: 'your-user-id', // Replace with actual user ID
74+
allowedAppsOnly: false,
75+
format: FunctionDefinitionFormat.OPENAI_RESPONSES
76+
});
77+
78+
// Step 3: Execute the found function
79+
const executeResponse = await openaiClient.responses.create({
80+
model: 'gpt-4',
81+
input: [
82+
{
83+
role: 'system',
84+
content: systemPrompt
85+
},
86+
{
87+
role: 'user',
88+
content: userMessage
89+
},
90+
{
91+
...searchToolCall
92+
},
93+
{
94+
type: "function_call_output",
95+
call_id: searchToolCall.call_id,
96+
"output": JSON.stringify(searchResults)
97+
},
98+
],
99+
tools: [aciSearchFunctionsSchema, aciExecuteFunctionSchema] as any
100+
} as any);
101+
102+
// Extract the execution tool call
103+
const executeToolCall = executeResponse.output.find(
104+
(item: any) => item.type === 'function_call'
105+
);
106+
107+
if (!executeToolCall || executeToolCall.type !== 'function_call') {
108+
throw new Error('No execution tool call returned from OpenAI');
109+
}
110+
111+
// Step 4: Execute the function
112+
const executeArguments = JSON.parse(executeToolCall.arguments);
113+
const executionResult = await aciClient.handleFunctionCall({
114+
functionName: executeToolCall.name,
115+
functionArguments: executeArguments,
116+
linkedAccountOwnerId: process.env.LINKED_ACCOUNT_OWNER_ID as string,
117+
allowedAppsOnly: false,
118+
format: FunctionDefinitionFormat.OPENAI_RESPONSES
119+
});
120+
121+
console.log('Execution result:', executionResult);
122+
}
123+
124+
// Run the example
125+
main().catch(console.error);

examples/openai-static-tool.ts

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
import OpenAI from 'openai';
2+
import { ACI } from '@aci-sdk/aci';
3+
import { FunctionDefinitionFormat } from '@aci-sdk/aci';
4+
import dotenv from 'dotenv';
5+
import { OpenAIResponsesFunctionDefinition } from '@aci-sdk/aci';
6+
7+
// Load environment variables
8+
dotenv.config();
9+
10+
const LINKED_ACCOUNT_OWNER_ID = process.env.LINKED_ACCOUNT_OWNER_ID;
11+
if (!LINKED_ACCOUNT_OWNER_ID) {
12+
throw new Error('LINKED_ACCOUNT_OWNER_ID is not set');
13+
}
14+
15+
async function main() {
16+
// Initialize clients
17+
const aciClient = new ACI({
18+
apiKey: process.env.ACI_API_KEY as string
19+
});
20+
21+
const openaiClient = new OpenAI({
22+
apiKey: process.env.OPENAI_API_KEY as string,
23+
});
24+
25+
// Get Brave Search function definition in OpenAI format
26+
const braveSearchFunctionDefinition = await aciClient.functions.getDefinition(
27+
'BRAVE_SEARCH__WEB_SEARCH',
28+
FunctionDefinitionFormat.OPENAI_RESPONSES
29+
) as OpenAIResponsesFunctionDefinition
30+
31+
console.log('Brave search function definition:');
32+
console.log(braveSearchFunctionDefinition);
33+
34+
// Convert function definition to OpenAI format
35+
const openaiTool = braveSearchFunctionDefinition as any;
36+
37+
// Create chat completion with OpenAI
38+
const response = await openaiClient.responses.create({
39+
model: 'gpt-4o',
40+
input: [
41+
{
42+
role: 'system',
43+
content: 'You are a helpful assistant with access to a variety of tools.',
44+
},
45+
{
46+
role: 'user',
47+
content: 'What is aipolabs ACI?',
48+
},
49+
],
50+
tools: [openaiTool],
51+
tool_choice: 'required', // force the model to generate a tool call for demo purposes
52+
});
53+
54+
const toolCall = response.output[0] as any;
55+
56+
if (toolCall) {
57+
console.log('Tool call:', toolCall);
58+
59+
// Submit the selected function and its arguments to ACI backend for execution
60+
const result1 = await aciClient.handleFunctionCall({
61+
functionName: toolCall.name,
62+
functionArguments: JSON.parse(toolCall.arguments),
63+
linkedAccountOwnerId: LINKED_ACCOUNT_OWNER_ID,
64+
allowedAppsOnly: true,
65+
format: FunctionDefinitionFormat.OPENAI_RESPONSES
66+
});
67+
68+
console.log('ACI Function Call Result1:');
69+
console.log(JSON.stringify(result1, null, 2));
70+
71+
72+
// Alternatively, because this is a direct function execution you can use:
73+
// you just need one way to execute the function
74+
// const result2 = await aciClient.functions.execute({
75+
// function_name: toolCall.name,
76+
// function_parameters: JSON.parse(toolCall.arguments),
77+
// linked_account_owner_id: LINKED_ACCOUNT_OWNER_ID as string
78+
// });
79+
80+
81+
// console.log('ACI Function Call Result2:');
82+
// console.log(JSON.stringify(result2, null, 2));
83+
}
84+
}
85+
86+
// Run the example
87+
main().catch(console.error);

examples/package.json

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,16 @@
55
"private": true,
66
"scripts": {
77
"start": "pnpm tsx basic-usage.ts",
8-
"dev": "pnpm tsx watch basic-usage.ts"
8+
"dev": "pnpm tsx watch basic-usage.ts",
9+
"openai:static": "pnpm tsx openai-static-tool.ts",
10+
"openai:dynamic": "pnpm tsx openai-dynamic-tool.ts",
11+
"ai-sdk": "pnpm tsx ai-sdk.ts"
912
},
1013
"dependencies": {
11-
"@types/dotenv": "^8.2.3",
1214
"@aci-sdk/aci": "file:../",
15+
"@ai-sdk/openai": "^1.3.22",
16+
"@types/dotenv": "^8.2.3",
17+
"ai": "^4.3.15",
1318
"dotenv": "^16.5.0"
1419
},
1520
"devDependencies": {

0 commit comments

Comments
 (0)