Big News: Socket raises $60M Series C at a $1B valuation to secure software supply chains for AI-driven development.Announcement
Sign In

@picahq/ai

Package Overview
Dependencies
Maintainers
4
Versions
57
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@picahq/ai - npm Package Compare versions

Comparing version
2.5.1
to
2.6.0
+25
dist/utils/index.d.ts
/**
* Paginate results from a fetch function
* @param fetchFn - The function to fetch the results
* @param limit - The number of results to fetch per page
* @returns An array of all results
*/
export declare function paginateResults<T>(fetchFn: (skip: number, limit: number) => Promise<{
rows: T[];
total: number;
skip: number;
limit: number;
}>, limit?: number): Promise<T[]>;
/**
* Normalize an action ID
* @param raw - The raw action ID
* @returns The normalized action ID
*/
export declare function normalizeActionId(raw: string): string;
/**
* Replace path variables in a path
* @param path - The path to replace variables in
* @param variables - The variables to replace in the path
* @returns The path with the variables replaced
*/
export declare function replacePathVariables(path: string, variables: Record<string, string | number | boolean>): string;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.paginateResults = paginateResults;
exports.normalizeActionId = normalizeActionId;
exports.replacePathVariables = replacePathVariables;
/**
* Paginate results from a fetch function
* @param fetchFn - The function to fetch the results
* @param limit - The number of results to fetch per page
* @returns An array of all results
*/
async function paginateResults(fetchFn, limit = 100) {
let skip = 0;
let allResults = [];
let total = 0;
try {
do {
const response = await fetchFn(skip, limit);
const { rows, total: totalCount } = response;
total = totalCount;
allResults = [...allResults, ...rows];
skip += limit;
} while (allResults.length < total);
return allResults;
}
catch (error) {
console.error("Error in pagination:", error);
throw error;
}
}
/**
* Normalize an action ID
* @param raw - The raw action ID
* @returns The normalized action ID
*/
function normalizeActionId(raw) {
if (raw.includes("::")) {
if (!raw.startsWith("conn_mod_def::")) {
return `conn_mod_def::${raw}`;
}
return raw;
}
return raw;
}
/**
* Replace path variables in a path
* @param path - The path to replace variables in
* @param variables - The variables to replace in the path
* @returns The path with the variables replaced
*/
function replacePathVariables(path, variables) {
return path.replace(/\{\{([^}]+)\}\}/g, (match, variable) => {
const value = variables[variable];
if (!value) {
throw new Error(`Missing value for path variable: ${variable}`);
}
return value.toString();
});
}
/**
* Paginate results from a fetch function
* @param fetchFn - The function to fetch the results
* @param limit - The number of results to fetch per page
* @returns An array of all results
*/
export async function paginateResults<T>(
fetchFn: (skip: number, limit: number) => Promise<{
rows: T[],
total: number,
skip: number,
limit: number
}>,
limit = 100
): Promise<T[]> {
let skip = 0;
let allResults: T[] = [];
let total = 0;
try {
do {
const response = await fetchFn(skip, limit);
const { rows, total: totalCount } = response;
total = totalCount;
allResults = [...allResults, ...rows];
skip += limit;
} while (allResults.length < total);
return allResults;
} catch (error) {
console.error("Error in pagination:", error);
throw error;
}
}
/**
* Normalize an action ID
* @param raw - The raw action ID
* @returns The normalized action ID
*/
export function normalizeActionId(raw: string): string {
if (raw.includes("::")) {
if (!raw.startsWith("conn_mod_def::")) {
return `conn_mod_def::${raw}`;
}
return raw;
}
return raw;
}
/**
* Replace path variables in a path
* @param path - The path to replace variables in
* @param variables - The variables to replace in the path
* @returns The path with the variables replaced
*/
export function replacePathVariables(path: string, variables: Record<string, string | number | boolean>): string {
return path.replace(/\{\{([^}]+)\}\}/g, (match, variable) => {
const value = variables[variable];
if (!value) {
throw new Error(`Missing value for path variable: ${variable}`);
}
return value.toString();
});
}
+15
-3
import { z } from "zod";
import { AvailableActions, RequestConfig, ConnectionDefinition, Connection } from "./types/connection";
interface PicaOptions {
/**
* The descriptor for the Pica client options.
* @property connectors - Array of connector IDs to filter available actions
* @property actions - Array of action IDs to filter available actions (default: all actions)
* @property permissions - Permissions for the Pica client: "read" (GET only), "write" (POST/PUT/PATCH), "admin" (all methods) (default: "admin")
* @property serverUrl - Custom server URL for Pica API (defaults to https://api.picaos.com)
* @property identity - Identity value for AuthKit token generation
* @property identityType - Type of identity for AuthKit ("user", "team", "organization", or "project")
* @property authkit - Whether to enable AuthKit integration
* @property knowledgeAgent - Whether to enable Knowledge Agent mode
* @property knowledgeAgentConfig - Configuration options for Knowledge Agent
*/
connectors?: string[];
actions?: string[];
permissions?: "read" | "write" | "admin";
serverUrl?: string;

@@ -26,2 +40,3 @@ identity?: string;

private knowledgeAgentConfig?;
private options?;
private baseUrl;

@@ -39,11 +54,8 @@ private getConnectionUrl;

private generateHeaders;
private paginateResults;
private getAllAvailableActions;
getAvailablePicaConnectors(): Promise<ConnectionDefinition[]>;
getAvailableConnectors(platform?: string): Promise<Connection[]>;
private normalizeActionId;
private getSingleAction;
private getAvailableActions;
private executePassthrough;
private replacePathVariables;
private getPromptToConnectPlatformTool;

@@ -50,0 +62,0 @@ get intelligenceTool(): {

+45
-54

@@ -14,2 +14,3 @@ "use strict";

const knowledgeAgentWithAuthkitSystem_1 = require("./prompts/knowledgeAgentWithAuthkitSystem");
const utils_1 = require("./utils");
class Pica {

@@ -29,2 +30,3 @@ constructor(secret, options) {

};
this.options = options;
if (options === null || options === void 0 ? void 0 : options.serverUrl) {

@@ -79,4 +81,4 @@ this.baseUrl = options.serverUrl;

const now = new Date();
const prompt = `${userSystemPrompt ? userSystemPrompt + '\n\n' : ''}=== PICA: INTEGRATION ASSISTANT ===
Everything below is for Pica (picaos.com), your integration assistant that can instantly connect your AI agents to 100+ APIs.
const prompt = `${userSystemPrompt ? userSystemPrompt + '\n\n' : ''}=== PICA: INTEGRATION ASSISTANT ===\n
Everything below is for Pica (picaos.com), your integration assistant that can instantly connect your AI agents to 100+ APIs.\n

@@ -103,3 +105,3 @@ Current Time: ${now.toLocaleString('en-US', { timeZone: 'GMT' })} (GMT)

const headers = this.generateHeaders();
let baseUrl = `${this.baseUrl}/v1/vault/connections`;
let baseUrl = this.getConnectionUrl;
let hasQueryParam = false;

@@ -119,3 +121,3 @@ if (platform) {

const fetchPage = (skip, limit) => axios_1.default.get(`${baseUrl}${hasQueryParam ? '&' : '?'}limit=${limit}&skip=${skip}`, { headers }).then(response => response.data);
this.connections = await this.paginateResults(fetchPage);
this.connections = await (0, utils_1.paginateResults)(fetchPage);
}

@@ -130,3 +132,3 @@ catch (error) {

const headers = this.generateHeaders();
let url = `${this.baseUrl}/v1/available-connectors`;
let url = this.getConnectionDefinitionsUrl;
let hasQueryParam = false;

@@ -138,3 +140,3 @@ if (this.useAuthkit) {

const fetchPage = (skip, limit) => axios_1.default.get(`${url}${hasQueryParam ? '&' : '?'}limit=${limit}&skip=${skip}`, { headers }).then(response => response.data);
this.connectionDefinitions = await this.paginateResults(fetchPage);
this.connectionDefinitions = await (0, utils_1.paginateResults)(fetchPage);
}

@@ -155,32 +157,38 @@ catch (error) {

}
async paginateResults(fetchFn, limit = 100) {
let skip = 0;
let allResults = [];
let total = 0;
async getAllAvailableActions(platform, actions) {
var _a;
try {
do {
const response = await fetchFn(skip, limit);
const { rows, total: totalCount } = response;
total = totalCount;
allResults = [...allResults, ...rows];
skip += limit;
} while (allResults.length < total);
return allResults;
}
catch (error) {
console.error("Error in pagination:", error);
throw error;
}
}
async getAllAvailableActions(platform) {
try {
const fetchPage = (skip, limit) => axios_1.default.get(`${this.availableActionsUrl}?supported=true&connectionPlatform=${platform}&skip=${skip}&limit=${limit}`, { headers: this.generateHeaders() }).then(response => response.data);
const results = await this.paginateResults(fetchPage);
const results = await (0, utils_1.paginateResults)(fetchPage);
// Normalize action IDs in the results
return results.map(action => {
const normalizedResults = results.map(action => {
if (action._id) {
action._id = this.normalizeActionId(action._id);
action._id = (0, utils_1.normalizeActionId)(action._id);
}
return action;
});
// Filter actions by permissions
let filteredByPermissions = normalizedResults;
const permissions = (_a = this.options) === null || _a === void 0 ? void 0 : _a.permissions;
if (permissions === "read") {
// Filter for GET methods only
filteredByPermissions = normalizedResults.filter(action => {
let method = action.method;
return (method === null || method === void 0 ? void 0 : method.toUpperCase()) === "GET";
});
}
else if (permissions === "write") {
// Filter for POST, PUT, PATCH methods
filteredByPermissions = normalizedResults.filter(action => {
var _a;
let method = (_a = action.method) === null || _a === void 0 ? void 0 : _a.toUpperCase();
return method === "POST" || method === "PUT" || method === "PATCH";
});
}
// For "admin" or no permissions set, return all actions (no filtering)
// Filter actions if actions array is provided
if (actions === null || actions === void 0 ? void 0 : actions.length) {
return filteredByPermissions.filter(action => actions.includes(action._id));
}
return filteredByPermissions;
}

@@ -200,14 +208,5 @@ catch (error) {

}
normalizeActionId(raw) {
if (raw.includes("::")) {
if (!raw.startsWith("conn_mod_def::")) {
return `conn_mod_def::${raw}`;
}
return raw;
}
return raw;
}
async getSingleAction(actionId) {
try {
const normalizedActionId = this.normalizeActionId(actionId);
const normalizedActionId = (0, utils_1.normalizeActionId)(actionId);
const response = await axios_1.default.get(`${this.availableActionsUrl}?_id=${normalizedActionId}`, { headers: this.generateHeaders() });

@@ -225,4 +224,5 @@ if (!response.data.rows || response.data.rows.length === 0) {

async getAvailableActions(platform) {
var _a;
try {
const allActions = await this.getAllAvailableActions(platform);
const allActions = await this.getAllAvailableActions(platform, (_a = this.options) === null || _a === void 0 ? void 0 : _a.actions);
return {

@@ -309,11 +309,2 @@ total: allActions.length,

}
replacePathVariables(path, variables) {
return path.replace(/\{\{([^}]+)\}\}/g, (match, variable) => {
const value = variables[variable];
if (!value) {
throw new Error(`Missing value for path variable: ${variable}`);
}
return value.toString();
});
}
getPromptToConnectPlatformTool() {

@@ -386,5 +377,5 @@ return {

}
resolvedPath = this.replacePathVariables(params.action.path, params.pathVariables || {});
resolvedPath = (0, utils_1.replacePathVariables)(params.action.path, params.pathVariables || {});
}
const normalizedActionId = this.normalizeActionId(params.action._id);
const normalizedActionId = (0, utils_1.normalizeActionId)(params.action._id);
// Execute the passthrough request with all components

@@ -463,3 +454,3 @@ const result = await this.executePassthrough(normalizedActionId, params.connectionKey, params.data, resolvedPath, params.method, params.queryParams, params.headers, params.isFormData, params.isFormUrlEncoded, true);

try {
const normalizedActionId = this.normalizeActionId(params.actionId);
const normalizedActionId = (0, utils_1.normalizeActionId)(params.actionId);
const action = await this.getSingleAction(normalizedActionId);

@@ -507,3 +498,3 @@ return {

}
const normalizedActionId = this.normalizeActionId(params.action._id);
const normalizedActionId = (0, utils_1.normalizeActionId)(params.action._id);
const fullAction = await this.getSingleAction(normalizedActionId);

@@ -535,3 +526,3 @@ // Handle path variables

}
resolvedPath = this.replacePathVariables(params.action.path, params.pathVariables || {});
resolvedPath = (0, utils_1.replacePathVariables)(params.action.path, params.pathVariables || {});
}

@@ -538,0 +529,0 @@ // Execute the passthrough request with all components

@@ -9,2 +9,3 @@ export interface AvailableActions {

tags: string[];
method?: string;
}

@@ -11,0 +12,0 @@ export interface RequestConfig {

{
"name": "@picahq/ai",
"version": "2.5.1",
"version": "2.6.0",
"description": "Pica AI SDK for Vercel AI SDK integration",

@@ -5,0 +5,0 @@ "main": "dist/index.js",

@@ -32,2 +32,4 @@ # Pica AI SDK

| connectors | String[] | No | - | List of connector keys to filter by. Pass `["*"]` to initialize all available connectors, or specific connector keys to filter. If empty, no connections will be initialized |
| actions | String[] | No | All actions | List of action ids to filter by |
| permissions | `"read"` \| `"write"` \| `"admin"` | No | `"admin"` | Permissions for the Pica client. `"read"` will only allow GET requests, `"write"` will allow POST/PUT/PATCH requests, and `"admin"` will allow all methods. |
| identity | String | No | None | Filter connections by specific identifier |

@@ -78,3 +80,3 @@ | identityType | `"user"` \| `"team"` \| `"organization"` \| `"project"` | No | None | Filter connections by identity type |

![Pica OneTool](https://assets.picaos.com/git/one-tool.png)
![Pica OneTool](https://assets.picaos.com/github/one-tool.svg)

@@ -81,0 +83,0 @@ Here are some powerful examples of what you can build:

@@ -5,2 +5,7 @@ import axios from "axios";

import { getDefaultSystemPrompt } from "./prompts/defaultSystem";
import { getDefaultSystemWithAuthkitPrompt } from "./prompts/defaultSystemWithAuthkit";
import { getKnowledgeAgentSystemPrompt } from "./prompts/knowledgeAgentSystem";
import { getKnowledgeAgentWithAuthkitSystemPrompt } from "./prompts/knowledgeAgentWithAuthkitSystem";
import { normalizeActionId, paginateResults, replacePathVariables } from "./utils";
import {

@@ -12,9 +17,19 @@ AvailableActions,

} from "./types/connection";
import { getDefaultSystemPrompt } from "./prompts/defaultSystem";
import { getDefaultSystemWithAuthkitPrompt } from "./prompts/defaultSystemWithAuthkit";
import { getKnowledgeAgentSystemPrompt } from "./prompts/knowledgeAgentSystem";
import { getKnowledgeAgentWithAuthkitSystemPrompt } from "./prompts/knowledgeAgentWithAuthkitSystem";
interface PicaOptions {
/**
* The descriptor for the Pica client options.
* @property connectors - Array of connector IDs to filter available actions
* @property actions - Array of action IDs to filter available actions (default: all actions)
* @property permissions - Permissions for the Pica client: "read" (GET only), "write" (POST/PUT/PATCH), "admin" (all methods) (default: "admin")
* @property serverUrl - Custom server URL for Pica API (defaults to https://api.picaos.com)
* @property identity - Identity value for AuthKit token generation
* @property identityType - Type of identity for AuthKit ("user", "team", "organization", or "project")
* @property authkit - Whether to enable AuthKit integration
* @property knowledgeAgent - Whether to enable Knowledge Agent mode
* @property knowledgeAgentConfig - Configuration options for Knowledge Agent
*/
connectors?: string[];
actions?: string[];
permissions?: "read" | "write" | "admin";
serverUrl?: string;

@@ -43,2 +58,3 @@ identity?: string;

private knowledgeAgentConfig?: KnowledgeAgentConfig;
private options?: PicaOptions;

@@ -62,2 +78,3 @@ private baseUrl = "https://api.picaos.com";

};
this.options = options;

@@ -121,4 +138,4 @@ if (options?.serverUrl) {

const now = new Date();
const prompt = `${userSystemPrompt ? userSystemPrompt + '\n\n' : ''}=== PICA: INTEGRATION ASSISTANT ===
Everything below is for Pica (picaos.com), your integration assistant that can instantly connect your AI agents to 100+ APIs.
const prompt = `${userSystemPrompt ? userSystemPrompt + '\n\n' : ''}=== PICA: INTEGRATION ASSISTANT ===\n
Everything below is for Pica (picaos.com), your integration assistant that can instantly connect your AI agents to 100+ APIs.\n

@@ -150,3 +167,3 @@ Current Time: ${now.toLocaleString('en-US', { timeZone: 'GMT' })} (GMT)

let baseUrl = `${this.baseUrl}/v1/vault/connections`;
let baseUrl = this.getConnectionUrl;
let hasQueryParam = false;

@@ -180,3 +197,3 @@

this.connections = await this.paginateResults<Connection>(fetchPage);
this.connections = await paginateResults<Connection>(fetchPage);
} catch (error) {

@@ -192,3 +209,3 @@ console.error("Failed to initialize connections:", error);

let url = `${this.baseUrl}/v1/available-connectors`;
let url = this.getConnectionDefinitionsUrl;
let hasQueryParam = false;

@@ -212,3 +229,3 @@

this.connectionDefinitions = await this.paginateResults<ConnectionDefinition>(fetchPage);
this.connectionDefinitions = await paginateResults<ConnectionDefinition>(fetchPage);
} catch (error) {

@@ -231,33 +248,4 @@ console.error("Failed to initialize connection definitions:", error);

private async paginateResults<T>(
fetchFn: (skip: number, limit: number) => Promise<{
rows: T[],
total: number,
skip: number,
limit: number
}>,
limit = 100
): Promise<T[]> {
let skip = 0;
let allResults: T[] = [];
let total = 0;
private async getAllAvailableActions(platform: string, actions?: string[]): Promise<AvailableActions[]> {
try {
do {
const response = await fetchFn(skip, limit);
const { rows, total: totalCount } = response;
total = totalCount;
allResults = [...allResults, ...rows];
skip += limit;
} while (allResults.length < total);
return allResults;
} catch (error) {
console.error("Error in pagination:", error);
throw error;
}
}
private async getAllAvailableActions(platform: string): Promise<AvailableActions[]> {
try {
const fetchPage = (skip: number, limit: number) =>

@@ -274,11 +262,39 @@ axios.get<{

const results = await this.paginateResults<AvailableActions>(fetchPage);
const results = await paginateResults<AvailableActions>(fetchPage);
// Normalize action IDs in the results
return results.map(action => {
const normalizedResults = results.map(action => {
if (action._id) {
action._id = this.normalizeActionId(action._id);
action._id = normalizeActionId(action._id);
}
return action;
});
// Filter actions by permissions
let filteredByPermissions = normalizedResults;
const permissions = this.options?.permissions;
if (permissions === "read") {
// Filter for GET methods only
filteredByPermissions = normalizedResults.filter(action => {
let method = action.method;
return method?.toUpperCase() === "GET";
});
} else if (permissions === "write") {
// Filter for POST, PUT, PATCH methods
filteredByPermissions = normalizedResults.filter(action => {
let method = action.method?.toUpperCase();
return method === "POST" || method === "PUT" || method === "PATCH";
});
}
// For "admin" or no permissions set, return all actions (no filtering)
// Filter actions if actions array is provided
if (actions?.length) {
return filteredByPermissions.filter(action =>
actions.includes(action._id)
);
}
return filteredByPermissions;
} catch (error) {

@@ -300,15 +316,5 @@ console.error("Error fetching all available actions:", error);

private normalizeActionId(raw: string): string {
if (raw.includes("::")) {
if (!raw.startsWith("conn_mod_def::")) {
return `conn_mod_def::${raw}`;
}
return raw;
}
return raw;
}
private async getSingleAction(actionId: string): Promise<AvailableActions> {
try {
const normalizedActionId = this.normalizeActionId(actionId);
const normalizedActionId = normalizeActionId(actionId);
const response = await axios.get<{

@@ -337,3 +343,3 @@ rows: AvailableActions[],

try {
const allActions = await this.getAllAvailableActions(platform);
const allActions = await this.getAllAvailableActions(platform, this.options?.actions);
return {

@@ -447,12 +453,2 @@ total: allActions.length,

private replacePathVariables(path: string, variables: Record<string, string | number | boolean>): string {
return path.replace(/\{\{([^}]+)\}\}/g, (match, variable) => {
const value = variables[variable];
if (!value) {
throw new Error(`Missing value for path variable: ${variable}`);
}
return value.toString();
});
}
private getPromptToConnectPlatformTool() {

@@ -546,6 +542,6 @@ return {

resolvedPath = this.replacePathVariables(params.action.path, params.pathVariables || {});
resolvedPath = replacePathVariables(params.action.path, params.pathVariables || {});
}
const normalizedActionId = this.normalizeActionId(params.action._id);
const normalizedActionId = normalizeActionId(params.action._id);
// Execute the passthrough request with all components

@@ -642,3 +638,3 @@ const result = await this.executePassthrough(

try {
const normalizedActionId = this.normalizeActionId(params.actionId);
const normalizedActionId = normalizeActionId(params.actionId);
const action = await this.getSingleAction(normalizedActionId);

@@ -700,3 +696,3 @@

const normalizedActionId = this.normalizeActionId(params.action._id);
const normalizedActionId = normalizeActionId(params.action._id);
const fullAction = await this.getSingleAction(normalizedActionId);

@@ -735,3 +731,3 @@

resolvedPath = this.replacePathVariables(params.action.path, params.pathVariables || {});
resolvedPath = replacePathVariables(params.action.path, params.pathVariables || {});
}

@@ -738,0 +734,0 @@

@@ -9,2 +9,3 @@ export interface AvailableActions {

tags: string[];
method?: string;
}

@@ -11,0 +12,0 @@