1.0.12 • Published 7 months ago

@paymanai/payman-ts v1.0.12

Weekly downloads
-
License
MIT
Repository
github
Last release
7 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

7 months ago

1.0.11

7 months ago

1.0.10

7 months ago

1.0.9

7 months ago

1.0.8

7 months ago

1.0.7

7 months ago

1.0.6

7 months ago

1.0.5

7 months ago

1.0.4

7 months ago

1.0.3

7 months ago

1.0.2

7 months ago

1.0.1

7 months ago

1.0.0

7 months ago