1.0.12 • Published 11 months ago

@paymanai/payman-ts v1.0.12

Weekly downloads
-
License
MIT
Repository
github
Last release
11 months ago

Payman SDK TypeScript

This SDK provides a simple way to interact with the Payman AI Platform's API using client credentials authentication. The SDK automatically handles token management, including fetching and refreshing access tokens.

Installation

npm install @paymanai/payman-ts

Environment Setup

Before running the SDK or tests, you need to set up your environment variables. Create a .env file in the root directory with the following variables:

PAYMAN_CLIENT_ID=your-client-id
PAYMAN_CLIENT_SECRET=your-client-secret

These credentials are required for both running the SDK and executing tests.

Testing

The SDK uses Jest for testing. To run the tests:

  1. Make sure you have set up your .env file with the required credentials
  2. Install dependencies:
npm install
  1. Run the tests:
npm test

The test suite will verify the SDK's functionality, including authentication, API interactions, and response handling.

Usage

Initialization

The SDK provides three ways to initialize the client:

  1. Using client credentials (recommended for server-side applications):
import { PaymanClient } from '@paymanai/payman-ts';

const payman = PaymanClient.withCredentials({
  clientId: "your-client-id",
  clientSecret: "your-client-secret",
});
  1. Using an authorization code (for OAuth flow):
const payman = PaymanClient.withAuthCode({
  clientId: "your-client-id",
  environment: "TEST"
}, "your-auth-code");
  1. Using an access token (when you already have a token):
const payman = PaymanClient.withToken(
  "your-client-id",
  {
    accessToken: "your-access-token",
    expiresIn: 3600 // token expiry in seconds
  },
);

Making Requests

  1. Get a formatted response (recommended for most use cases):
const response = await payman.ask("What's the weather?");
console.log(response);
  1. Get a raw response (when you need the full JSON-RPC response):
const rawResponse = await payman.ask("What's the weather?", {
  outputFormat: 'json'
});
console.log(rawResponse);
  1. Streaming request with formatted responses:
await payman.ask("What's the weather?", {
  onMessage: (response) => {
    console.log("Formatted response:", response);
  },
  outputFormat: 'markdown'
});
  1. Streaming request with raw responses:
await payman.ask("What's the weather?", {
  onMessage: (response) => {
    console.log("Raw response:", response);
  },
  outputFormat: 'json'
});
  1. Start a new session with metadata:
const response = await payman.ask("Hello!", {
  newSession: true,
  metadata: { source: "web-app" }
});

Session Management

The SDK automatically manages sessions for you. Each client instance maintains a session ID that persists across requests. You can start a new session at any time by setting newSession: true in the options.

The SDK also handles OAuth token management automatically:

  • Fetches an access token during initialization
  • Refreshes the token before it expires (within 60 seconds of expiry)
  • Handles token management transparently

Streaming Responses

When using streaming responses with the onMessage callback, you'll receive updates in real-time as they become available. This is useful for:

  • Long-running tasks
  • Real-time updates
  • Progress monitoring
  • Handling artifacts as they become available

The streaming response can include different types of events:

  1. Status Updates:
await client.ask("List all payees", {
  onMessage: (response) => {
    if ('status' in response) {
      console.log(`Task status: ${response.status}`);
      console.log(`Is final: ${response.isFinal}`);
    }
  }
});
  1. Artifact Updates:
await client.ask("List all payees", {
  onMessage: (response) => {
    if ('artifacts' in response) {
      console.log(`New artifact: ${response.artifacts[response.artifacts.length - 1]}`);
    }
  }
});

Using Metadata

The SDK supports various types of metadata that can be attached to requests:

  1. Request-level metadata:
await client.ask("Pay Tyllen 50$?", {
  metadata: {
    source: "mobile-app",
    userId: "user123",
    requestId: "req456"
  }
});
  1. Message-level metadata:
await client.ask("Create a new payee with the email tyllen@paymanai.com", {
  messageMetadata: {
    priority: "high",
    category: "payee creation"
  }
});
  1. Part-level metadata:
await client.ask("List all wallets", {
  partMetadata: {
    currency: "USD",
    format: "text"
  }
});

API Reference

PaymanClient

Static Methods

  • withCredentials(config: PaymanConfig): PaymanClient

    • Creates a client using client credentials
    • config: Configuration object containing clientId, clientSecret, and optional environment
  • withAuthCode(config: PaymanConfig, authCode: string): PaymanClient

    • Creates a client using an authorization code
    • config: Configuration object containing clientId, clientSecret, and optional environment
    • authCode: Authorization code obtained via OAuth
  • withToken(clientId: string, tokenInfo: { accessToken: string; expiresIn: number }, environment?: 'TEST' | 'LIVE' | 'INTERNAL'): PaymanClient

    • Creates a client using an existing access token
    • clientId: Your Payman client ID
    • tokenInfo: Object containing access token and its expiration time
    • environment: Optional environment to use (defaults to "LIVE")

Instance Methods

  • ask(text: string, options?: AskOptions, raw?: boolean): Promise<FormattedTaskResponse | TaskResponse>

    • Sends a message to the Payman AI Agent
    • text: The message or question to send
    • options: Optional parameters for the request
  • getAccessToken(): { accessToken: string; expiresIn: number } | undefined

    • Gets the current access token and its expiration information
    • Returns undefined if no token is set
  • isAccessTokenExpired(): boolean

    • Checks if the current access token has expired
    • Returns true if the token has expired or is about to expire within 60 seconds

Types

  • PaymanConfig

    {
      clientId: string;
      clientSecret: string;
      environment?: 'TEST' | 'LIVE' | 'INTERNAL';
    }
  • AskOptions

    {
      onMessage?: (response: FormattedTaskResponse | TaskResponse) => void;
      newSession?: boolean;
      outputFormat?: 'markdown' | 'json';
      metadata?: Record<string, unknown>;
      partMetadata?: Record<string, unknown>;
      messageMetadata?: Record<string, unknown>;
    }

Response Types

  • FormattedTaskResponse

    {
      status: 'completed' | 'failed' | 'in_progress';
      isFinal: boolean;
      artifacts?: Array<{
        type: string;
        content: unknown;
        metadata?: Record<string, unknown>;
      }>;
      error?: {
        code: number;
        message: string;
      };
    }
  • TaskResponse

    {
      jsonrpc: '2.0';
      id: string;
      result?: {
        status: 'completed' | 'failed' | 'in_progress';
        isFinal: boolean;
        artifacts?: Array<{
          type: string;
          content: unknown;
          metadata?: Record<string, unknown>;
        }>;
      };
      error?: {
        code: number;
        message: string;
        data?: unknown;
      };
    }

Events

  • TaskStatusUpdateEvent

    {
      type: 'status_update';
      status: 'completed' | 'failed' | 'in_progress';
      isFinal: boolean;
    }
  • TaskArtifactUpdateEvent

    {
      type: 'artifact_update';
      artifacts: Array<{
        type: string;
        content: unknown;
        metadata?: Record<string, unknown>;
      }>;
    }

Error Handling

The SDK uses Axios for HTTP requests. All API calls will throw an error if the request fails. You can catch these errors and handle them appropriately:

try {
  const response = await client.ask("What's the weather?");
} catch (error) {
  if (error.response) {
    // The request was made and the server responded with a status code
    // that falls out of the range of 2xx
    console.error(error.response.data);
    console.error(error.response.status);
  } else if (error.request) {
    // The request was made but no response was received
    console.error(error.request);
  } else {
    // Something happened in setting up the request that triggered an Error
    console.error('Error', error.message);
  }
}
1.0.12

11 months ago

1.0.11

11 months ago

1.0.10

11 months ago

1.0.9

11 months ago

1.0.8

11 months ago

1.0.7

11 months ago

1.0.6

11 months ago

1.0.5

11 months ago

1.0.4

11 months ago

1.0.3

11 months ago

1.0.2

11 months ago

1.0.1

11 months ago

1.0.0

11 months ago