chore: import upstream snapshot with attribution
Changesets / Create Version PR (push) Has been cancelled
Deploy Shadcn Registry / Deploy Production (push) Has been cancelled
Template Metrics / LOC + Bundle Size (push) Has been cancelled
Code Quality / Oxlint + Oxfmt (push) Has been cancelled
Code Quality / Template Sync (push) Has been cancelled
Code Quality / Build Changed Packages (push) Has been cancelled
Code Quality / Test Changed Packages (push) Has been cancelled
Deploy Expo Example / Deploy Production (push) Has been cancelled
Deploy Ink Example / Deploy Production (push) Has been cancelled
Python Tests / pytest (assistant-stream, 3.10) (push) Has been cancelled
Python Tests / pytest (assistant-stream, 3.12) (push) Has been cancelled
Python Tests / pytest (assistant-ui-sync-server-api, 3.10) (push) Has been cancelled
Python Tests / pytest (assistant-ui-sync-server-api, 3.12) (push) Has been cancelled
Changesets / Create Version PR (push) Has been cancelled
Deploy Shadcn Registry / Deploy Production (push) Has been cancelled
Template Metrics / LOC + Bundle Size (push) Has been cancelled
Code Quality / Oxlint + Oxfmt (push) Has been cancelled
Code Quality / Template Sync (push) Has been cancelled
Code Quality / Build Changed Packages (push) Has been cancelled
Code Quality / Test Changed Packages (push) Has been cancelled
Deploy Expo Example / Deploy Production (push) Has been cancelled
Deploy Ink Example / Deploy Production (push) Has been cancelled
Python Tests / pytest (assistant-stream, 3.10) (push) Has been cancelled
Python Tests / pytest (assistant-stream, 3.12) (push) Has been cancelled
Python Tests / pytest (assistant-ui-sync-server-api, 3.10) (push) Has been cancelled
Python Tests / pytest (assistant-ui-sync-server-api, 3.12) (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,41 @@
|
||||
# State Management Test
|
||||
|
||||
This is a test project for the `assistant-stream` state management functionality. It demonstrates various state operations and updates over time.
|
||||
|
||||
## Features
|
||||
|
||||
- **Simple State Test**: Basic state updates with primitive values
|
||||
- **Complex Test**: Nested state updates with objects and arrays
|
||||
- **String Operations**: String concatenation and method testing
|
||||
- **List Operations**: List manipulation with append, extend, and other operations
|
||||
- **Dictionary Operations**: Dictionary manipulation with various methods
|
||||
|
||||
## Setup
|
||||
|
||||
1. Install the requirements:
|
||||
|
||||
```
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
|
||||
2. Run the server:
|
||||
|
||||
```
|
||||
python server.py
|
||||
```
|
||||
|
||||
3. Open your browser to [http://localhost:8000](http://localhost:8000)
|
||||
|
||||
4. Click on the different test buttons to see state updates in action
|
||||
|
||||
## Implementation Details
|
||||
|
||||
This test server demonstrates the following state management features:
|
||||
|
||||
- Primitive values (strings, numbers, booleans)
|
||||
- Nested state objects
|
||||
- String operations (concatenation, methods)
|
||||
- List operations (append, extend, indexing)
|
||||
- Dictionary operations (get, setdefault, keys/values)
|
||||
|
||||
Each test endpoint updates state over time with various operations to showcase the functionality of the `StateProxy` and `StateManager` classes.
|
||||
@@ -0,0 +1,14 @@
|
||||
[project]
|
||||
name = "state-test"
|
||||
version = "0.1.0"
|
||||
description = ""
|
||||
authors = [
|
||||
{name = "Simon Farshid",email = "simon.farshid@outlook.com"}
|
||||
]
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.12"
|
||||
dependencies = []
|
||||
|
||||
[build-system]
|
||||
requires = ["hatchling"]
|
||||
build-backend = "hatchling.build"
|
||||
@@ -0,0 +1,3 @@
|
||||
fastapi>=0.68.0
|
||||
uvicorn>=0.15.0
|
||||
../assistant-stream
|
||||
@@ -0,0 +1,205 @@
|
||||
from fastapi import FastAPI
|
||||
from fastapi.middleware.cors import CORSMiddleware
|
||||
from assistant_stream import create_run, RunController
|
||||
from assistant_stream.serialization import DataStreamResponse
|
||||
|
||||
import asyncio
|
||||
|
||||
app = FastAPI()
|
||||
app.add_middleware(
|
||||
CORSMiddleware,
|
||||
allow_origins=["*"],
|
||||
allow_credentials=True,
|
||||
allow_methods=["*"],
|
||||
allow_headers=["*"],
|
||||
)
|
||||
|
||||
|
||||
@app.post("/simple-test")
|
||||
async def simple_test():
|
||||
async def run(controller: RunController):
|
||||
# Check that state is initially None
|
||||
assert controller.state is None, "Initial state should be None"
|
||||
|
||||
# Initialize state with a direct assignment
|
||||
controller.state = {
|
||||
"counter": 0,
|
||||
"message": "Starting simple test"
|
||||
}
|
||||
|
||||
# Update state over time
|
||||
for i in range(1, 6):
|
||||
controller.state["counter"] = i
|
||||
controller.state["message"] = f"Counter updated to {i}"
|
||||
|
||||
# Add a boolean and number
|
||||
controller.state["completed"] = True
|
||||
controller.state["total"] = 5.5
|
||||
|
||||
# Demonstrate setting root state again
|
||||
controller.state = {
|
||||
"final": True,
|
||||
"summary": "Test completed successfully"
|
||||
}
|
||||
|
||||
controller.append_text("hi")
|
||||
|
||||
return DataStreamResponse(create_run(run))
|
||||
|
||||
|
||||
@app.post("/complex-test")
|
||||
async def complex_test():
|
||||
async def run(controller: RunController):
|
||||
# Demonstrate that state starts as None
|
||||
print(f"Initial state: {controller.state}")
|
||||
|
||||
# Initialize nested state directly
|
||||
controller.state = {
|
||||
"user": {
|
||||
"name": "John",
|
||||
"preferences": {
|
||||
"theme": "dark",
|
||||
"notifications": True
|
||||
}
|
||||
},
|
||||
"messages": []
|
||||
}
|
||||
|
||||
# Add messages
|
||||
controller.state["messages"].append("Hello")
|
||||
controller.state["messages"].append("World")
|
||||
|
||||
# Set state back to None to demonstrate nullifying
|
||||
controller.state = {}
|
||||
controller.state["user"] = {
|
||||
"name": "Test User",
|
||||
"settings": {"theme": "light", "notifications": True},
|
||||
}
|
||||
controller.state["stats"] = {"visits": 0, "actions": []}
|
||||
|
||||
# Update nested state
|
||||
for i in range(1, 6):
|
||||
await asyncio.sleep(0.01)
|
||||
controller.state["stats"]["visits"] = i
|
||||
controller.state["stats"]["actions"].append(f"action_{i}")
|
||||
|
||||
# Toggle theme every other iteration
|
||||
if i % 2 == 0:
|
||||
controller.state["user"]["settings"]["theme"] = "dark"
|
||||
else:
|
||||
controller.state["user"]["settings"]["theme"] = "light"
|
||||
|
||||
# Final update
|
||||
await asyncio.sleep(0.01)
|
||||
controller.state["completed"] = True
|
||||
|
||||
return DataStreamResponse(create_run(run))
|
||||
|
||||
|
||||
@app.post("/string-test")
|
||||
async def string_test():
|
||||
async def run(controller: RunController):
|
||||
# Initialize string
|
||||
controller.state["message"] = "Hello"
|
||||
|
||||
# Append to string using +=
|
||||
await asyncio.sleep(1)
|
||||
controller.state["message"] += " world"
|
||||
|
||||
# Append more text
|
||||
await asyncio.sleep(1)
|
||||
controller.state["message"] += "!"
|
||||
|
||||
# String methods (these should work through the proxy)
|
||||
await asyncio.sleep(1)
|
||||
controller.state["uppercase"] = controller.state["message"].upper()
|
||||
|
||||
await asyncio.sleep(1)
|
||||
controller.state["contains_world"] = "world" in controller.state["message"]
|
||||
|
||||
await asyncio.sleep(1)
|
||||
controller.state["length"] = len(controller.state["message"])
|
||||
|
||||
return DataStreamResponse(create_run(run))
|
||||
|
||||
|
||||
@app.post("/list-test")
|
||||
async def list_test():
|
||||
async def run(controller: RunController):
|
||||
# Initialize list
|
||||
controller.state["items"] = []
|
||||
|
||||
# Append items one by one
|
||||
for i in range(5):
|
||||
await asyncio.sleep(1)
|
||||
controller.state["items"].append(f"item_{i}")
|
||||
|
||||
# Extend list with multiple items
|
||||
await asyncio.sleep(1)
|
||||
controller.state["items"] += ["batch_1", "batch_2"]
|
||||
|
||||
# Access by index
|
||||
await asyncio.sleep(1)
|
||||
controller.state["first_item"] = controller.state["items"][0]
|
||||
|
||||
# Get length
|
||||
await asyncio.sleep(1)
|
||||
controller.state["count"] = len(controller.state["items"])
|
||||
|
||||
# Check membership
|
||||
await asyncio.sleep(1)
|
||||
controller.state["contains_batch"] = "batch_1" in controller.state["items"]
|
||||
|
||||
# Clear the list
|
||||
await asyncio.sleep(1)
|
||||
controller.state["items"].clear()
|
||||
|
||||
return DataStreamResponse(create_run(run))
|
||||
|
||||
|
||||
@app.post("/dict-test")
|
||||
async def dict_test():
|
||||
async def run(controller: RunController):
|
||||
# Initialize dictionary
|
||||
controller.state["config"] = {}
|
||||
|
||||
# Add items one by one
|
||||
await asyncio.sleep(1)
|
||||
controller.state["config"]["theme"] = "light"
|
||||
|
||||
await asyncio.sleep(1)
|
||||
controller.state["config"]["language"] = "en"
|
||||
|
||||
# Set default value
|
||||
await asyncio.sleep(1)
|
||||
controller.state["config"].setdefault("notifications", True)
|
||||
|
||||
# Try to set default for existing key (should not change)
|
||||
await asyncio.sleep(1)
|
||||
controller.state["config"].setdefault("theme", "dark")
|
||||
controller.state["theme_unchanged"] = (
|
||||
controller.state["config"]["theme"] == "light"
|
||||
)
|
||||
|
||||
# Get with default
|
||||
await asyncio.sleep(1)
|
||||
controller.state["missing_with_default"] = controller.state["config"].get(
|
||||
"missing", "default_value"
|
||||
)
|
||||
|
||||
# Keys, values, items
|
||||
await asyncio.sleep(1)
|
||||
controller.state["all_keys"] = list(controller.state["config"].keys())
|
||||
controller.state["all_values"] = list(controller.state["config"].values())
|
||||
|
||||
# Clear the dictionary
|
||||
await asyncio.sleep(1)
|
||||
controller.state["config"].clear()
|
||||
|
||||
return DataStreamResponse(create_run(run))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import uvicorn
|
||||
|
||||
uvicorn.run(app, host="0.0.0.0", port=8000)
|
||||
Generated
+8
@@ -0,0 +1,8 @@
|
||||
version = 1
|
||||
revision = 3
|
||||
requires-python = ">=3.12"
|
||||
|
||||
[[package]]
|
||||
name = "state-test"
|
||||
version = "0.1.0"
|
||||
source = { editable = "." }
|
||||
Reference in New Issue
Block a user