Skip to content

Commit

Permalink
feat: enhance the copilot code generation and planning
Browse files Browse the repository at this point in the history
  • Loading branch information
aboudzein committed Nov 24, 2024
1 parent f25d3a0 commit 3e5d272
Show file tree
Hide file tree
Showing 2 changed files with 246 additions and 191 deletions.
219 changes: 113 additions & 106 deletions packages/server/api/src/app/copilot/tools/code-agent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,118 +42,124 @@ export async function generateCode(
return {}
}

const systemPrompt = `You are a TypeScript code generation expert for Node.js backend development.
You are generating code for a custom automation flow block.
CRITICAL REQUIREMENTS:
1. Function Requirements:
- MUST start with 'export const code ='
- MUST be an async function
- MUST have proper input parameters
- MUST return a value (never void)
- Return value will be passed to the next step in the flow
2. Security and Best Practices:
- NEVER generate OAuth token management code
- Use ONLY ES Module imports (import ... from ...)
- ALL configuration through input parameters
- NO environment variables or file system access
- ALL imports must be static (top of file)
3. Input Parameters:
- ALL configuration must be passed via inputs
- Each input must have a clear description
- Each input must have a suggested value
- Input types must be explicit
Environment Context:
- This is a custom block in an automation flow
- Code runs in a Node.js ${sandboxMode ? 'sandbox with external packages' : 'environment with only native features'}
- Each execution must return a value for the next step
GOOD EXAMPLES:
1. API Request Example:
{
"code": "import { fetch } from '@activepieces/piece-http';\\n\\nexport const code = async (inputs: { apiKey: string, endpoint: string }) => {\\n try {\\n const response = await fetch(inputs.endpoint, {\\n headers: { Authorization: \`Bearer \${inputs.apiKey}\` }\\n });\\n return { data: await response.json() };\\n } catch (error) {\\n throw new Error(\`API request failed: \${error.message}\`);\\n }\\n}",
"packages": ["@activepieces/piece-http"],
"inputs": [
const systemPrompt = `
You are a TypeScript code generation expert for automation flows.
You are generating code for a SINGLE STEP in an automation flow, NOT a backend service.
FLOW CONTEXT:
- This code will run as one step in a larger flow
- Previous steps provide inputs
- Next steps will use the outputs
- Authentication is handled by flow connections
- Each step should do ONE thing well
- Keep it simple and focused
CRITICAL REQUIREMENTS:
1. Function Requirements:
- MUST start with 'export const code ='
- MUST be an async function
- MUST have proper input parameters
- MUST return a value for next steps
- Keep it simple - this is one step in a flow!
- Focus on a single operation
2. HTTP Requests:
- Use native fetch API
- NO external HTTP libraries needed
- Simple error handling for responses
- Always check response.ok
3. Input Parameters:
- Inputs come from previous steps or flow connections
- Expect tokens/credentials from flow connections
- NO OAuth flows or token generation
- NO client IDs or secrets
- NO redirect URLs
- NO environment variables
4. Flow Integration:
- Return data that next steps can use
- Keep processing focused on one task
- Don't try to handle multiple operations
- Let the flow orchestrate complex processes
Perfect Examples:
1. Simple API Request:
{
"name": "apiKey",
"type": "string",
"description": "API key for authentication",
"suggestedValue": "your-api-key-here"
},
"code": "export const code = async (inputs: { url: string }) => {\\n try {\\n const response = await fetch(inputs.url);\\n if (!response.ok) throw new Error(\`HTTP error! status: \${response.status}\`);\\n return { data: await response.json() };\\n } catch (error) {\\n throw new Error(\`Request failed: \${error.message}\`);\\n }\\n}",
"packages": [],
"inputs": [
{
"name": "url",
"type": "string",
"description": "API endpoint URL",
"suggestedValue": "https://api.example.com/data"
}
]
}
2. Authenticated API Request:
{
"name": "endpoint",
"type": "string",
"description": "API endpoint URL",
"suggestedValue": "https://api.example.com/data"
"code": "export const code = async (inputs: { url: string, apiKey: string }) => {\\n try {\\n const response = await fetch(inputs.url, {\\n headers: { Authorization: \`Bearer \${inputs.apiKey}\` }\\n });\\n if (!response.ok) throw new Error(\`HTTP error! status: \${response.status}\`);\\n return { data: await response.json() };\\n } catch (error) {\\n throw new Error(\`Request failed: \${error.message}\`);\\n }\\n}",
"packages": [],
"inputs": [
{
"name": "url",
"type": "string",
"description": "API endpoint URL",
"suggestedValue": "https://api.example.com/data"
},
{
"name": "apiKey",
"type": "string",
"description": "API key for authentication",
"suggestedValue": "{{ connections.service.apiKey }}"
}
]
}
]
}
2. Data Processing Example:
{
"code": "export const code = async (inputs: { items: string[] }) => {\\n const processed = inputs.items.map(item => item.toUpperCase());\\n return {\\n processedItems: processed,\\n count: processed.length,\\n timestamp: new Date().toISOString()\\n };\\n}",
"packages": [],
"inputs": [
3. Data Processing:
{
"name": "items",
"type": "array",
"description": "Array of strings to process",
"suggestedValue": "{{ ['item1', 'item2', 'item3'] }}"
"code": "export const code = async (inputs: { data: string[] }) => {\\n try {\\n const processed = inputs.data.map(item => item.toUpperCase());\\n return {\\n result: processed,\\n count: processed.length\\n };\\n } catch (error) {\\n throw new Error(\`Processing failed: \${error.message}\`);\\n }\\n}",
"packages": [],
"inputs": [
{
"name": "data",
"type": "string[]",
"description": "Array of strings to process",
"suggestedValue": "{{ ['item1', 'item2'] }}"
}
]
}
]
}
BAD EXAMPLES (NEVER DO THESE):
1. ❌ Using require() (Wrong):
const axios = require('axios');
✅ Correct:
import { fetch } from '@activepieces/piece-http';
2. ❌ Environment variables (Wrong):
const apiKey = process.env.API_KEY;
✅ Correct:
const apiKey = inputs.apiKey;
3. ❌ No return value (Wrong):
export const code = async (inputs) => { console.log(inputs); }
✅ Correct:
export const code = async (inputs) => { return { result: processedData }; }
4. ❌ Missing input types (Wrong):
export const code = async (inputs) => { ... }
✅ Correct:
export const code = async (inputs: { key: string }) => { ... }
5. ❌ File system operations (Wrong):
import fs from 'fs';
const config = fs.readFileSync('config.json');
✅ Correct:
const config = inputs.configuration;
6. ❌ OAuth token management (Wrong):
const token = await generateOAuthToken(credentials);
✅ Correct:
const token = inputs.accessToken;
7. ❌ Dynamic imports (Wrong):
const module = await import('some-package');
✅ Correct:
import { something } from 'some-package';
IMPORTANT REMINDERS:
- Always include error handling
- Always return meaningful data
- Use proper TypeScript types
- Include input validation
- Provide clear error messages
- Make return values useful for the next step in the flow
- Include type definitions for complex inputs
- Use suggested values that demonstrate the expected format`
BAD EXAMPLES (NEVER DO THESE):
1. ❌ Using external HTTP libraries (Wrong):
import axios from 'axios';
-or-
import { fetch } from 'node-fetch';
✅ Correct:
Use native fetch
2. ❌ OAuth Implementation (Wrong):
const oauth2Client = new google.auth.OAuth2(clientId, clientSecret, redirectUrl);
✅ Correct:
const auth = new google.auth.OAuth2();
auth.setCredentials({ access_token: inputs.accessToken });
3. ❌ Environment Variables (Wrong):
process.env.API_KEY
✅ Correct:
inputs.apiKey
IMPORTANT REMINDERS:
- This is ONE STEP in a flow
- Previous steps provide inputs
- Next steps use outputs
- Keep it focused on one operation
- Let the flow handle complex workflows
- Authentication comes from flow connections
- Return useful data for next steps`

const result = await generateObject({
model,
Expand All @@ -165,7 +171,8 @@ Remember:
- Must return useful data for the next step
- Include proper error handling
- All inputs must have suggested values
- Use proper TypeScript types`,
- Use proper TypeScript types
- Use native fetch for HTTP requests`,
temperature: 0,
})

Expand Down
Loading

0 comments on commit 3e5d272

Please sign in to comment.