diff --git a/apps/docs/docs/img/dev-config.png b/apps/docs/docs/img/dev-config.png
index 3010566d..d9b45efa 100644
Binary files a/apps/docs/docs/img/dev-config.png and b/apps/docs/docs/img/dev-config.png differ
diff --git a/apps/docs/docs/img/prod-deploy.png b/apps/docs/docs/img/prod-deploy.png
index fa22f93a..f1745213 100644
Binary files a/apps/docs/docs/img/prod-deploy.png and b/apps/docs/docs/img/prod-deploy.png differ
diff --git a/apps/docs/docs/index.md b/apps/docs/docs/index.md
index ffadc7b7..89626228 100644
--- a/apps/docs/docs/index.md
+++ b/apps/docs/docs/index.md
@@ -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
updates agents and tools on your behalf |• Context-aware of all components including playground
• Improves agents based on conversations and feedback
• 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:**
diff --git a/apps/docs/docs/using_the_api.md b/apps/docs/docs/using_the_api.md
index 5e599a3a..413540ab 100644
--- a/apps/docs/docs/using_the_api.md
+++ b/apps/docs/docs/using_the_api.md
@@ -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.

-## 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 /api/v1//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: `` 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 `` is [http://localhost:3000](http://localhost:3000)
-- When using the hosted app, the `` is [https://app.rowboatlabs.com](https://app.rowboatlabs.com)
-
-### Example first turn of a chat
+```
+Authorization: Bearer
+```
-#### Request
+## Examples
+
+### First Turn
```bash
curl --location '/api/v1//chat' \
@@ -38,206 +38,129 @@ curl --location '/api/v1//chat' \
--header 'Authorization: Bearer ' \
--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//chat' \
+curl --location '/api/v1//chat' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer ' \
--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 I’ll 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
}
-```
\ No newline at end of file
+```
+
+### 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
\ No newline at end of file
diff --git a/apps/docs/docs/using_the_sdk.md b/apps/docs/docs/using_the_sdk.md
index 802b5a3e..c867bcbc 100644
--- a/apps/docs/docs/using_the_sdk.md
+++ b/apps/docs/docs/using_the_sdk.md
@@ -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="",
+ project_id="",
+ 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=""
+)
+```
+
+#### Using a test profile
+
+You can specify a test profile ID to use a specific test configuration:
+
+```python
+chat = StatefulChat(
+ client,
+ 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)
```
\ No newline at end of file
diff --git a/apps/python-sdk/README.md b/apps/python-sdk/README.md
index e4442035..91a0b461 100644
--- a/apps/python-sdk/README.md
+++ b/apps/python-sdk/README.md
@@ -12,13 +12,68 @@ pip install rowboat
## 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="",
+ project_id="",
+ 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=""
+)
+```
+
+#### Using a test profile
+
+You can specify a test profile ID to use a specific test configuration:
+
+```python
+chat = StatefulChat(
+ client,
+ 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(
@@ -29,108 +84,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
-)
-```
-
-### 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?
-```
-
-### Advanced Usage
-
-#### Using a specific workflow
-
-```python
-response_messages, state = client.chat(
- messages=messages,
- workflow_id=""
-)
-
-# or
-
-chat = StatefulChat(
- client,
- workflow_id=""
-)
-```
-
-#### Using a test profile
-You can specify a test profile ID to use a specific test configuration:
-
-```python
-response_messages, state = client.chat(
- messages=messages,
- test_profile_id=""
-)
-
-# or
-
-chat = StatefulChat(
- client,
- test_profile_id=""
-)
-```
-
-#### Skip tool call runs
-This will surface the tool calls to the SDK instead of running them automatically on the Rowboat server.
-
-```python
-response_messages, state = client.chat(
- messages=messages,
- skip_tool_calls=True
-)
-
-# or
-
-chat = StatefulChat(
- client,
- skip_tool_calls=True
-)
+response = client.chat(messages=messages, state=response.state)
```
diff --git a/apps/python-sdk/pyproject.toml b/apps/python-sdk/pyproject.toml
index 6d1cabdc..b107d8b6 100644
--- a/apps/python-sdk/pyproject.toml
+++ b/apps/python-sdk/pyproject.toml
@@ -4,9 +4,9 @@ build-backend = "hatchling.build"
[project]
name = "rowboat"
-version = "2.1.0"
+version = "3.0.0"
authors = [
- { name = "Your Name", email = "your.email@example.com" },
+ { name = "Ramnique Singh", email = "ramnique@rowboatlabs.com" },
]
description = "Python sdk for the Rowboat API"
readme = "README.md"
diff --git a/apps/python-sdk/src/rowboat/client.py b/apps/python-sdk/src/rowboat/client.py
index 2997ed08..d270c0c5 100644
--- a/apps/python-sdk/src/rowboat/client.py
+++ b/apps/python-sdk/src/rowboat/client.py
@@ -1,18 +1,14 @@
-from typing import Dict, List, Optional, Any, Callable, Union, Tuple
+from typing import Dict, List, Optional, Any, Union
import requests
-import json
from .schema import (
ApiRequest,
ApiResponse,
ApiMessage,
- ToolMessage,
UserMessage,
- SystemMessage,
AssistantMessage,
AssistantMessageWithToolCalls
)
-
class Client:
def __init__(self, host: str, project_id: str, api_key: str) -> None:
self.base_url: str = f'{host}/api/v1/{project_id}/chat'
@@ -25,16 +21,12 @@ class Client:
self,
messages: List[ApiMessage],
state: Optional[Dict[str, Any]] = None,
- skip_tool_calls: bool = False,
- max_turns: int = 3,
workflow_id: Optional[str] = None,
test_profile_id: Optional[str] = None
) -> ApiResponse:
request = ApiRequest(
messages=messages,
state=state,
- skipToolCalls=skip_tool_calls,
- maxTurns=max_turns,
workflowId=workflow_id,
testProfileId=test_profile_id
)
@@ -55,86 +47,27 @@ class Client:
return response_data
- def _process_tool_calls(
- self,
- tool_calls: List[Any],
- tools: Dict[str, Callable[..., str]]
- ) -> List[ToolMessage]:
- """Process tool calls and return a list of tool response messages"""
- tool_messages = []
- for tool_call in tool_calls:
- tool_name = tool_call.function.name
- tool_arguments = json.loads(tool_call.function.arguments)
-
- if tool_name not in tools:
- raise ValueError(f'Missing tool: {tool_name}')
-
- tool_response = tools[tool_name](**tool_arguments)
- tool_msg = ToolMessage(
- role='tool',
- content=tool_response,
- tool_call_id=tool_call.id,
- tool_name=tool_name
- )
- tool_messages.append(tool_msg)
- return tool_messages
-
def chat(
self,
messages: List[ApiMessage],
- tools: Optional[Dict[str, Callable[..., str]]] = None,
state: Optional[Dict[str, Any]] = None,
- max_turns: int = 3,
- skip_tool_calls: bool = False,
workflow_id: Optional[str] = None,
test_profile_id: Optional[str] = None
- ) -> Tuple[List[ApiMessage], Optional[Dict[str, Any]]]:
- """Stateless chat method that handles a single conversation turn with multiple tool call rounds"""
+ ) -> ApiResponse:
+ """Stateless chat method that handles a single conversation turn"""
- current_messages = messages[:]
- current_state = state
- turns = 0
+ # call api
+ response_data = self._call_api(
+ messages=messages,
+ state=state,
+ workflow_id=workflow_id,
+ test_profile_id=test_profile_id
+ )
- response_messages = []
- response_state = None
- has_tool_calls = False
-
- while turns < max_turns:
- # call api
- response_data = self._call_api(
- messages=current_messages,
- state=current_state,
- skip_tool_calls=skip_tool_calls,
- max_turns=max_turns,
- workflow_id=workflow_id,
- test_profile_id=test_profile_id
- )
-
- current_messages.extend(response_data.messages)
- current_state = response_data.state
- response_messages = response_data.messages
- response_state = response_data.state
-
- # Process tool calls if present and tools are provided
- last_message = response_data.messages[-1]
- has_tool_calls = hasattr(last_message, 'tool_calls') and last_message.tool_calls
- if has_tool_calls:
- tool_messages = self._process_tool_calls(last_message.tool_calls, tools)
- current_messages.extend(tool_messages)
-
- # If no tool calls were made, we're done
- if not has_tool_calls:
- break
-
- turns += 1
-
- if turns == max_turns and has_tool_calls:
- raise ValueError("Max turns reached")
-
- if not last_message.agenticResponseType == 'external':
+ if not response_data.messages[-1].agenticResponseType == 'external':
raise ValueError("Last message was not an external message")
- return response_messages, response_state
+ return response_data
class StatefulChat:
"""Maintains conversation state across multiple turns"""
@@ -142,23 +75,14 @@ class StatefulChat:
def __init__(
self,
client: Client,
- tools: Optional[Dict[str, Callable[..., str]]] = None,
- system_prompt: Optional[str] = None,
- max_turns: int = 3,
- skip_tool_calls: bool = False,
workflow_id: Optional[str] = None,
test_profile_id: Optional[str] = None
) -> None:
self.client = client
- self.tools = tools
self.messages: List[ApiMessage] = []
self.state: Optional[Dict[str, Any]] = None
- self.max_turns = max_turns
- self.skip_tool_calls = skip_tool_calls
self.workflow_id = workflow_id
self.test_profile_id = test_profile_id
- if system_prompt:
- self.messages.append(SystemMessage(role='system', content=system_prompt))
def run(self, message: Union[str]) -> str:
"""Handle a single user turn in the conversation"""
@@ -168,22 +92,19 @@ class StatefulChat:
self.messages.append(user_msg)
# Get response using the client's chat method
- new_messages, new_state = self.client.chat(
+ response_data = self.client.chat(
messages=self.messages,
- tools=self.tools,
state=self.state,
- max_turns=self.max_turns,
- skip_tool_calls=self.skip_tool_calls,
workflow_id=self.workflow_id,
test_profile_id=self.test_profile_id
)
# Update internal state
- self.messages = new_messages
- self.state = new_state
+ self.messages = response_data.messages
+ self.state = response_data.state
# Return only the final message content
- last_message = new_messages[-1]
+ last_message = self.messages[-1]
return last_message.content
@@ -197,9 +118,13 @@ if __name__ == "__main__":
api_key: str = ""
client = Client(host, project_id, api_key)
- tools: Dict[str, Callable[..., str]] = {
- 'weather_lookup': weather_lookup_tool
- }
- chat_session = StatefulChat(client, tools)
- resp = chat_session.run("whats the weather in london?")
+ result = client.chat(
+ messages=[
+ UserMessage(role='user', content="Hello")
+ ]
+ )
+ print(result.messages[-1].content)
+
+ chat_session = StatefulChat(client)
+ resp = chat_session.run("Hello")
print(resp)
\ No newline at end of file
diff --git a/apps/python-sdk/src/rowboat/schema.py b/apps/python-sdk/src/rowboat/schema.py
index c95d4554..0ee959dc 100644
--- a/apps/python-sdk/src/rowboat/schema.py
+++ b/apps/python-sdk/src/rowboat/schema.py
@@ -48,8 +48,6 @@ ApiMessage = Union[
class ApiRequest(BaseModel):
messages: List[ApiMessage]
state: Any
- skipToolCalls: Optional[bool] = None
- maxTurns: Optional[int] = None
workflowId: Optional[str] = None
testProfileId: Optional[str] = None
diff --git a/apps/rowboat/app/lib/types/types.ts b/apps/rowboat/app/lib/types/types.ts
index 911d857c..c4544d6b 100644
--- a/apps/rowboat/app/lib/types/types.ts
+++ b/apps/rowboat/app/lib/types/types.ts
@@ -111,8 +111,6 @@ export const ApiMessage = z.union([
export const ApiRequest = z.object({
messages: z.array(ApiMessage),
state: z.unknown(),
- skipToolCalls: z.boolean().nullable().optional(),
- maxTurns: z.number().nullable().optional(),
workflowId: z.string().nullable().optional(),
testProfileId: z.string().nullable().optional(),
});