Update docs and simplify sdk

This commit is contained in:
Ramnique Singh 2025-04-10 00:24:47 +05:30
parent c338ec4dec
commit 97feb71869
10 changed files with 265 additions and 446 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 87 KiB

After

Width:  |  Height:  |  Size: 88 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 106 KiB

After

Width:  |  Height:  |  Size: 41 KiB

Before After
Before After

View file

@ -28,8 +28,8 @@ RowBoat Studio lets you create AI agents in minutes, using a visual interface an
| Copilot | AI-powered concierge that creates and<br>updates agents and tools on your behalf |• Context-aware of all components including playground<br>• Improves agents based on conversations and feedback <br>• Understands your requests in plain language|
### RowBoat Chat API & SDK
- RowBoat Chat API is a stateless HTTP API to interface with the assistant created on RowBoat Studio. You can use the API to drive end-user facing conversations in your app or website.
- RowBoat Chat SDK is a simple SDK (currently available in Python) which wraps the HTTP API under the hood. It offers both stateful and stateless (OpenAI-style) implementations.
- [RowBoat Chat API](/using_the_api) is a stateless HTTP API to interface with the assistant created on RowBoat Studio. You can use the API to drive end-user facing conversations in your app or website.
- [RowBoat Chat SDK](/using_the_sdk) is a simple SDK (currently available in Python) which wraps the HTTP API under the hood. It offers both stateful and stateless (OpenAI-style) implementations.
### Steps
**RowBoat Studio:**

View file

@ -10,27 +10,27 @@ This is a guide on using the HTTP API to power conversations with the assistant
Generate API keys via the developer configs in your project. Copy the Project ID from the same page.
![Developer Configs](img/dev-config.png)
## Call the API
## API Endpoint
When you provide your Project ID in the API call, RowBoat uses the version of your assistant deployed to production.
```
POST <HOST>/api/v1/<PROJECT_ID>/chat
```
**Request parameters:**
Where:
- `messages`: history of all messages in the conversation till now (system, user, tool and assistant messages)
- `state`: generated from the previous turn (this is needed because the API does not maintain state on its own)
- For self-hosted: `<HOST>` is `http://localhost:3000`
**Response parameters:**
## Authentication
- `messages`: assistant responses for the current turn (the last message in `messages` is either the user-facing response or a tool call by the assistant)
- `state`: to be passed to the next turn
Include your API key in the Authorization header:
### API Host
- For the open source installation, the `<HOST>` is [http://localhost:3000](http://localhost:3000)
- When using the hosted app, the `<HOST>` is [https://app.rowboatlabs.com](https://app.rowboatlabs.com)
### Example first turn of a chat
```
Authorization: Bearer <API_KEY>
```
#### Request
## Examples
### First Turn
```bash
curl --location '<HOST>/api/v1/<PROJECT_ID>/chat' \
@ -38,206 +38,129 @@ curl --location '<HOST>/api/v1/<PROJECT_ID>/chat' \
--header 'Authorization: Bearer <API_KEY>' \
--data '{
"messages": [
{
"role": "system",
"content": "UserID: 345227"
// Provide context to be passed to all agents in the assistant
// E.g. user identity info (user ID) for logged in users
},
{
"role": "user",
"content": "What is my outstanding balance and how do I make the payment?"
"content": "Hello, can you help me?"
}
],
"state": {
"last_agent_name": "Credit Card Hub"
// Last agent used in the previous turn
// Set to the "start agent" for first turn of chats
}
"state": null
}'
```
#### Response
Response:
```json
{
"messages": [
{
"sender": "Credit Card Hub",
"role": "assistant",
"response_type": "internal",
"content": null,
"current_turn": true,
"tool_calls": [
{
"function": {
// Internal tool calls are used to transfer between agents
"name": "transfer_to_outstanding_payments",
"arguments": "{\"args\":\"\",\"kwargs\":\"\"}"
},
"id": "call_SLyQKXt9ZMqnxSqJjo9j1fU5",
"type": "function"
}
]
},
{
"role": "tool",
"tool_name": "transfer_to_outstanding_payments",
"content": "{\"assistant\": \"Outstanding Payments\"}",
"tool_call_id": "call_SLyQKXt9ZMqnxSqJjo9j1fU5"
},
{
// Last message in response messages is a tool call
"sender": "Outstanding Payments",
"role": "assistant",
"response_type": "internal",
"content": null,
"current_turn": true,
"tool_calls": [
{
"function": {
"name": "get_outstanding_balance",
"arguments": "{\"user_id\":\"345227\"}"
},
"id": "call_MNAUg7UTszYMt5RL4n5QqUTw",
"type": "function"
}
]
"content": "Hello! Yes, I'd be happy to help you. What can I assist you with today?",
"agenticResponseType": "external"
}
],
"state": {
"agent_data": [
// Agents that were involved in this turn
{
"name": "Credit Card Hub",
"instructions": "// agent instructions",
"history": [
// History of agent-relevant messages
// in the same format as "messages"
],
"child_functions": [
"transfer_to_outstanding_payments",
"transfer_to_transaction_disputes",
"transfer_to_rewards_redemption"
],
},
{
"name": "Outstanding Payments",
"instructions": // Agent instructions,
"history": [
// History of agent-relevant messages
// in the same format as "messages"
],
"external_tools": [
"get_outstanding_balance",
"get_saved_credit_card"
],
},
// Other agents - have not yet participated in the conversation
{
"name": "Rewards Redemption",
"instructions": // Agent instructions,
"history": [], //
}
],
"last_agent_name": "Outstanding Payments"
"last_agent_name": "MainAgent"
}
}
```
### Example where the assistant is expecting a tool response
#### Request
### Subsequent Turn
Notice how we include both the previous messages and the state from the last response:
```bash
curl --location 'http://localhost:3000/api/v1/<PROJECT_ID>/chat' \
curl --location '<HOST>/api/v1/<PROJECT_ID>/chat' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <API_KEY>' \
--data '{
"messages": [
{
"role": "system",
"content": "UserID: 345227"
"role": "user",
"content": "Hello, can you help me?"
},
{
"role": "assistant",
"content": "Hello! Yes, I'd be happy to help you. What can I assist you with today?",
"agenticResponseType": "external"
},
{
"role": "user",
"content": "What is my outstanding balance and how do I make the payment?"
},
{
"sender": "Credit Card Hub",
"role": "assistant",
"response_type": "internal",
"content": null,
"tool_calls": [
{
"function": {
"arguments": "{\"args\":\"\",\"kwargs\":\"\"}",
"name": "transfer_to_outstanding_payments"
},
"id": "call_SLyQKXt9ZMqnxSqJjo9j1fU5",
"type": "function"
}
],
},
{
"role": "tool",
"tool_name": "transfer_to_outstanding_payments",
"content": "{\"assistant\": \"Outstanding Payments\"}",
"tool_call_id": "call_SLyQKXt9ZMqnxSqJjo9j1fU5"
},
{
"sender": "Outstanding Payments",
"role": "assistant",
"response_type": "internal",
"content": null,
"tool_calls": [
{
"function": {
"arguments": "{\"user_id\":\"345227\"}",
"name": "get_outstanding_balance"
},
"id": "call_MNAUg7UTszYMt5RL4n5QqUTw",
"type": "function"
}
],
},
{
// New message is a tool response to the previous tool call
"role": "tool",
"tool_name": "get_outstanding_balance"
"content": "{\"result\":{\"outstanding_balance\":\"$250.00\",\"due_date\":\"2025-02-15\",\"payment_methods\":[\"Credit Card\",\"Bank Transfer\",\"PayPal\"]}}",
"tool_call_id": "call_MNAUg7UTszYMt5RL4n5QqUTw",
},
],
"state": {
// State returned by the API in the previous turn
}
}'
```
#### Response
```json
{
"messages": [
{
"sender": "Outstanding Payments",
"role": "assistant",
// Response is not user-facing, to enable further post processing
"response_type": "internal",
"content": "Your outstanding balance is $250.00, due by February 15, 2025.\n\nYou have several payment options available, including:\n- **Credit Card**\n- **Bank Transfer**\n- **PayPal**\n\nPlease let me know which option you'd like to use, and I'll guide you through the process!",
"current_turn": true
},
{
"sender": "Outstanding Payments >> Post process",
"role": "assistant",
// Response is user-facing
"response_type": "external",
"content": "Your outstanding balance is $250.00, due by February 15, 2025. \n\nPayment options include:\n- **Credit Card:** You can use your saved Visa card ending in 1234.\n- **Bank Transfer**\n- **PayPal**\n\nLet me know your preferred payment method, and Ill assist you!",
"current_turn": true,
"content": "What services do you offer?"
}
],
"state": {
"agent_data": [
// Omitted for brevity
],
"last_agent_name": "Outstanding Payments"
"last_agent_name": "MainAgent"
}
}'
```
## API Specification
### Request Schema
```typescript
{
// Required fields
messages: Message[]; // Array of message objects representing the conversation history
state: any; // State object from previous response, or null for first message
// Optional fields
workflowId?: string; // Specific workflow ID to use (defaults to production workflow)
testProfileId?: string; // Test profile ID for simulation
}
```
```
### Message Types
Messages can be one of the following types:
1. System Message
```typescript
{
role: "system";
content: string;
}
```
2. User Message
```typescript
{
role: "user";
content: string;
}
```
3. Assistant Message
```typescript
{
role: "assistant";
content: string;
agenticResponseType: "internal" | "external";
agenticSender?: string | null;
}
```
### Response Schema
```typescript
{
messages: Message[]; // Array of new messages from this turn
state: any; // State object to pass in the next request
}
```
## Important Notes
1. Always pass the complete conversation history in the `messages` array
2. Always include the `state` from the previous response in your next request
3. The last message in the response's `messages` array will be a user-facing assistant message (`agenticResponseType: "external"`)
## Rate Limiting
The API has rate limits per project. If exceeded, you'll receive a 429 status code.
## Error Responses
- 400: Invalid request body or missing/invalid Authorization header
- 403: Invalid API key
- 404: Project or workflow not found
- 429: Rate limit exceeded

View file

@ -13,13 +13,68 @@ This is a guide on using the RowBoat Python SDK as an alternative to the [RowBoa
## Usage
### Basic Usage
### Basic Usage with StatefulChat
Initialize a client and use the chat method directly:
The easiest way to interact with Rowboat is using the `StatefulChat` class, which maintains conversation state automatically:
```python
from rowboat import Client
from rowboat.schema import UserMessage, SystemMessage
from rowboat import Client, StatefulChat
# Initialize the client
client = Client(
host="<HOST>",
project_id="<PROJECT_ID>",
api_key="<API_KEY>"
)
# Create a stateful chat session
chat = StatefulChat(client)
# Have a conversation
response = chat.run("What is the capital of France?")
print(response)
# The capital of France is Paris.
# Continue the conversation - the context is maintained automatically
response = chat.run("What other major cities are in that country?")
print(response)
# Other major cities in France include Lyon, Marseille, Toulouse, and Nice.
response = chat.run("What's the population of the first city you mentioned?")
print(response)
# Lyon has a population of approximately 513,000 in the city proper.
```
### Advanced Usage
#### Using a specific workflow
You can specify a workflow ID to use a particular conversation configuration:
```python
chat = StatefulChat(
client,
workflow_id="<WORKFLOW_ID>"
)
```
#### Using a test profile
You can specify a test profile ID to use a specific test configuration:
```python
chat = StatefulChat(
client,
test_profile_id="<TEST_PROFILE_ID>"
)
```
### Low-Level Usage
For more control over the conversation, you can use the `Client` class directly:
```python
from rowboat.schema import UserMessage
# Initialize the client
client = Client(
@ -30,57 +85,15 @@ client = Client(
# Create messages
messages = [
SystemMessage(role='system', content="You are a helpful assistant"),
UserMessage(role='user', content="Hello, how are you?")
]
# Get response
response_messages, state = client.chat(messages=messages)
print(response_messages[-1].content)
response = client.chat(messages=messages)
print(response.messages[-1].content)
# For subsequent messages, include previous messages and state
messages.extend(response_messages)
# For subsequent messages, you need to manage the message history and state manually
messages.extend(response.messages)
messages.append(UserMessage(role='user', content="What's your name?"))
response_messages, state = client.chat(messages=messages, state=state)
```
### Using Tools
The SDK supports function calling through tools:
```python
def weather_lookup(city_name: str) -> str:
return f"The weather in {city_name} is 22°C."
# Create a tools dictionary
tools = {
'weather_lookup': weather_lookup
}
# Use tools with the chat method
response_messages, state = client.chat(
messages=messages,
tools=tools
)
```
The last message in `response_messages` is either a user-facing response or a tool call by the assistant.
### Stateful Chat (Convenience Wrapper)
For simpler use cases, the SDK provides a `StatefulChat` class that maintains conversation state automatically:
```python
from rowboat import StatefulChat
# Initialize stateful chat
chat = StatefulChat(
client,
tools=tools,
system_prompt="You are a helpful assistant."
)
# Simply send messages and get responses
response = chat.run("Hello, how are you?")
print(response)
# I'm good, thanks! How can I help you today?
response = client.chat(messages=messages, state=response.state)
```