Skip to content

Commit

Permalink
Merge pull request #10 from picahq/feature/form-multipart-support
Browse files Browse the repository at this point in the history
feat: add support to form-multipart
  • Loading branch information
paulkr authored Feb 25, 2025
2 parents 78527af + e5e555d commit ad626e0
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 7 deletions.
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@picahq/ai",
"version": "2.0.9",
"version": "2.1.0",
"description": "Pica AI SDK for Vercel AI SDK integration",
"main": "dist/index.js",
"types": "dist/index.d.ts",
Expand Down
37 changes: 33 additions & 4 deletions src/pica.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import axios from "axios";
import { z } from "zod";
import FormData from 'form-data';

import {
AvailableActions,
Expand Down Expand Up @@ -186,6 +187,7 @@ Your capabilities must be used in this exact sequence FOR EACH EXECUTION:
* data: The request payload (optional)
* pathVariables: Values for path variables (if needed)
* queryParams: Query parameters (if needed)
* isFormData: Set to true to send data as multipart/form-data
WORKFLOW (MUST FOLLOW THIS ORDER FOR EACH PLATFORM):
1. For ANY user request:
Expand Down Expand Up @@ -341,7 +343,9 @@ ${availablePlatformsInfo}
data: any,
path: string,
method?: string,
queryParams?: Record<string, string | number | boolean>
queryParams?: Record<string, string | number | boolean>,
headers?: Record<string, string | number | boolean>,
isFormData?: boolean
): Promise<{
responseData: unknown;
requestConfig: RequestConfig;
Expand All @@ -350,7 +354,8 @@ ${availablePlatformsInfo}
const headers = {
...this.generateHeaders(),
'x-pica-connection-key': connectionKey,
'x-pica-action-id': actionId
'x-pica-action-id': actionId,
...(isFormData ? { 'Content-Type': 'multipart/form-data' } : {})
};

const url = `${this.baseUrl}/v1/passthrough${path.startsWith('/') ? path : '/' + path}`;
Expand All @@ -363,7 +368,25 @@ ${availablePlatformsInfo}
};

if (method?.toLowerCase() !== 'get') {
requestConfig.data = data;
if (isFormData) {
const formData = new FormData();

if (data && typeof data === 'object' && !Array.isArray(data)) {
Object.entries(data).forEach(([key, value]) => {
if (typeof value === 'object') {
formData.append(key, JSON.stringify(value));
} else {
formData.append(key, value);
}
});
}

requestConfig.data = formData;

Object.assign(requestConfig.headers, formData.getHeaders());
} else {
requestConfig.data = data;
}
}

const response = await axios(requestConfig);
Expand Down Expand Up @@ -467,6 +490,8 @@ ${availablePlatformsInfo}
data: z.any(),
pathVariables: z.record(z.union([z.string(), z.number(), z.boolean()])).optional(),
queryParams: z.record(z.union([z.string(), z.number(), z.boolean()])).optional(),
headers: z.record(z.union([z.string(), z.number(), z.boolean()])).optional(),
isFormData: z.boolean().optional(),
}),
execute: async (params: {
platform: string;
Expand All @@ -479,6 +504,8 @@ ${availablePlatformsInfo}
data?: any;
pathVariables?: Record<string, string | number | boolean>;
queryParams?: Record<string, string | number | boolean>;
headers?: Record<string, string | number | boolean>;
isFormData?: boolean;
}) => {
try {
const fullAction = await this.getSingleAction(params.action._id);
Expand Down Expand Up @@ -524,7 +551,9 @@ ${availablePlatformsInfo}
params.data,
resolvedPath,
params.method,
params.queryParams
params.queryParams,
params.headers,
params.isFormData
);

return {
Expand Down

0 comments on commit ad626e0

Please sign in to comment.