chore: import upstream snapshot with attribution
rowboat / apps/x Vitest suites (push) Has been cancelled
rowboat / apps/x Electron package smoke test (push) Has been cancelled

This commit is contained in:
wehub-resource-sync
2026-07-13 13:33:34 +08:00
commit 221778fa98
1462 changed files with 303427 additions and 0 deletions
+4
View File
@@ -0,0 +1,4 @@
__pycache__/
venv/
.venv/
dist/
+76
View File
@@ -0,0 +1,76 @@
# Rowboat Python SDK
A Python SDK for interacting with the Rowboat API.
## Installation
You can install the package using pip:
```bash
pip install rowboat
```
## Usage
### Basic Usage
The main way to interact with Rowboat is using the `Client` class, which provides a stateless chat API. You can manage conversation state using the `conversationId` returned in each response.
```python
from rowboat.client import Client
from rowboat.schema import UserMessage
# Initialize the client
client = Client(
host="<HOST>",
projectId="<PROJECT_ID>",
apiKey="<API_KEY>"
)
# Start a new conversation
result = client.run_turn(
messages=[
UserMessage(role='user', content="list my github repos")
]
)
print(result.turn.output[-1].content)
print("Conversation ID:", result.conversationId)
# Continue the conversation by passing the conversationId
result = client.run_turn(
messages=[
UserMessage(role='user', content="how many did you find?")
],
conversationId=result.conversationId
)
print(result.turn.output[-1].content)
```
### Using Tool Overrides (Mock Tools)
You can provide tool override instructions to test a specific configuration using the `mockTools` argument:
```python
result = client.run_turn(
messages=[
UserMessage(role='user', content="What's the weather?")
],
mockTools={
"weather_lookup": "The weather in any city is sunny and 25°C.",
"calculator": "The result of any calculation is 42."
}
)
print(result.turn.output[-1].content)
```
### Message Types
You can use different message types as defined in `rowboat.schema`, such as `UserMessage`, `SystemMessage`, etc. See `schema.py` for all available message types.
### Error Handling
If the API returns a non-200 status code, a `ValueError` will be raised with the error details.
---
For more advanced usage, see the docstrings in `client.py` and the message schemas in `schema.py`.
+26
View File
@@ -0,0 +1,26 @@
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[project]
name = "rowboat"
version = "5.0.1"
authors = [
{ name = "Ramnique Singh", email = "ramnique@rowboatlabs.com" },
]
description = "Python sdk for the Rowboat API"
readme = "README.md"
requires-python = ">=3.7"
classifiers = [
"Programming Language :: Python :: 3",
"License :: OSI Approved :: Apache Software License",
"Operating System :: OS Independent",
]
dependencies = [
"requests>=2.25.0",
"pydantic>=2.0.0",
]
[project.urls]
"Homepage" = "https://github.com/rowboatlabs/rowboat/tree/main/apps/python-sdk"
"Bug Tracker" = "https://github.com/rowboatlabs/rowboat/issues"
+9
View File
@@ -0,0 +1,9 @@
annotated-types==0.7.0
certifi==2024.12.14
charset-normalizer==3.4.1
idna==3.10
pydantic==2.10.5
pydantic_core==2.27.2
requests==2.32.3
typing_extensions==4.12.2
urllib3==2.3.0
+11
View File
@@ -0,0 +1,11 @@
from .client import Client
from .schema import (
ApiMessage,
UserMessage,
SystemMessage,
AssistantMessage,
AssistantMessageWithToolCalls,
ToolMessage,
ApiRequest,
ApiResponse
)
+73
View File
@@ -0,0 +1,73 @@
from typing import Dict, List, Optional
import requests
from .schema import (
ApiRequest,
ApiResponse,
ApiMessage,
UserMessage,
)
class Client:
def __init__(self, host: str, projectId: str, apiKey: str) -> None:
self.base_url: str = f'{host}/api/v1/{projectId}/chat'
self.headers: Dict[str, str] = {
'Content-Type': 'application/json',
'Authorization': f'Bearer {apiKey}'
}
def _call_api(
self,
messages: List[ApiMessage],
conversationId: Optional[str] = None,
mockTools: Optional[Dict[str, str]] = None
) -> ApiResponse:
request = ApiRequest(
messages=messages,
conversationId=conversationId,
mockTools=mockTools
)
json_data = request.model_dump()
response = requests.post(self.base_url, headers=self.headers, json=json_data)
if not response.status_code == 200:
raise ValueError(f"Error: {response.status_code} - {response.text}")
return ApiResponse.model_validate(response.json())
def run_turn(
self,
messages: List[ApiMessage],
conversationId: Optional[str] = None,
mockTools: Optional[Dict[str, str]] = None,
) -> ApiResponse:
"""Stateless chat method that handles a single conversation turn"""
# call api
return self._call_api(
messages=messages,
conversationId=conversationId,
mockTools=mockTools,
)
if __name__ == "__main__":
host: str = "<HOST>"
project_id: str = "<PROJECT_ID>"
api_key: str = "<API_KEY>"
client = Client(host, project_id, api_key)
result = client.run_turn(
messages=[
UserMessage(role='user', content="list my github repos")
]
)
print(result.turn.output[-1].content)
print(result.conversationId)
result = client.run_turn(
messages=[
UserMessage(role='user', content="how many did you find?")
],
conversationId=result.conversationId
)
print(result.turn.output[-1].content)
+58
View File
@@ -0,0 +1,58 @@
from typing import List, Optional, Union, Literal, Dict
from pydantic import BaseModel
class SystemMessage(BaseModel):
role: Literal['system']
content: str
class UserMessage(BaseModel):
role: Literal['user']
content: str
class AssistantMessage(BaseModel):
role: Literal['assistant']
content: str
agenticName: Optional[str] = None
responseType: Literal['internal', 'external']
class FunctionCall(BaseModel):
name: str
arguments: str
class ToolCall(BaseModel):
id: str
type: Literal['function']
function: FunctionCall
class AssistantMessageWithToolCalls(BaseModel):
role: Literal['assistant']
content: Optional[str] = None
toolCalls: List[ToolCall]
agenticName: Optional[str] = None
class ToolMessage(BaseModel):
role: Literal['tool']
content: str
toolCallId: str
toolName: str
ApiMessage = Union[
SystemMessage,
UserMessage,
AssistantMessage,
AssistantMessageWithToolCalls,
ToolMessage
]
class Turn(BaseModel):
id: str
output: List[ApiMessage]
class ApiRequest(BaseModel):
conversationId: Optional[str] = None
messages: List[ApiMessage]
mockTools: Optional[Dict[str, str]] = None
class ApiResponse(BaseModel):
conversationId: str
turn: Turn