diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..831f175 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,16 @@ +# Changelog + +All notable changes to the **AgentScope** project will be documented in this file. + +## [1.0.0] - 2026-08-10 + +### Added +- Created the core Next.js developer dashboard UI package (`packages/ui`). +- Implemented dual-pool WebSocket manager and REST API router endpoints on the server. +- Built SQL-based pagination for session telemetry event queries. +- Added database session retention and pruning policies (`RETENTION_DAYS`, `MAX_SESSIONS`). +- Integrated timezone-aware ISO-8601 formatting for standard UTC timestamps. +- Added support for Claude 3 (Haiku, Sonnet, Opus) and Gemini 1.5 (Pro, Flash) model price resolutions. +- Implemented custom environment pricing overrides via `AGENTSCOPE_CUSTOM_PRICING` and programmatic configuration overrides. +- Covered all trace decorator client and websocket emissions in try-except statements to guarantee non-intrusive operations. +- Added detailed step-by-step installation guides and verification scripts in `docs/DEVELOPMENT.md` and runnable integration examples. diff --git a/examples/01_basic_chain.py b/examples/01_basic_chain.py new file mode 100644 index 0000000..36ac54f --- /dev/null +++ b/examples/01_basic_chain.py @@ -0,0 +1,32 @@ +import time +from langchain_core.prompts import ChatPromptTemplate +from langchain_community.llms.fake import FakeListLLM +from agentscope.callback import AgentScopeCallback + +# 1. Initialize AgentScope callback handler +callback = AgentScopeCallback( + host="127.0.0.1", + port=8765, + session_name="Basic LLM Chain Tracing", +) + +# 2. Build simple mock LLM and prompt +llm = FakeListLLM( + responses=["Antigravity is a hypothetical force that opposes gravity."] +) +prompt = ChatPromptTemplate.from_template("Explain the concept of {topic}.") + +# 3. Chain prompt and LLM +chain = prompt | llm + +if __name__ == "__main__": + print("Executing LangChain pipeline with AgentScope telemetry...") + # Run the chain passing the callback handler + result = chain.invoke( + {"topic": "antigravity"}, config={"callbacks": [callback]} + ) + print(f"Result: {result}") + + # Wait briefly for client logs to flush + time.sleep(2) + print("Telemetry complete.") diff --git a/examples/02_agent_executor.py b/examples/02_agent_executor.py new file mode 100644 index 0000000..b34cf1b --- /dev/null +++ b/examples/02_agent_executor.py @@ -0,0 +1,66 @@ +import time +from langchain.agents import AgentExecutor, create_react_agent +from langchain_core.prompts import PromptTemplate +from langchain_core.tools import tool +from langchain_community.llms.fake import FakeListLLM +from agentscope.callback import AgentScopeCallback + +# 1. Initialize callback handler +callback = AgentScopeCallback( + host="127.0.0.1", + port=8765, + session_name="AgentExecutor Telemetry Session", +) + +# 2. Define custom developer tool +@tool +def calculate_velocity(mass_and_force: str) -> float: + """Calculate velocity based on force and mass inputs. The input should be 'mass, force'.""" + time.sleep(0.3) + try: + mass_str, force_str = mass_and_force.split(",") + return float(force_str) / float(mass_str) + except Exception: + return 0.0 + + +tools = [calculate_velocity] + +# 3. Create reactive LLM and prompt +llm = FakeListLLM( + responses=[ + "Thought: I need to calculate the velocity using the tool.\nAction: calculate_velocity\nAction Input: 10.0, 50.0", + "Final Answer: The calculated velocity is 5.0 m/s.", + ] +) + +prompt = PromptTemplate.from_template( + "Answer the following questions as best you can. You have access to the following tools:\n\n" + "{tools}\n\nUse the following format:\n\n" + "Question: the input question you must answer\n" + "Thought: you should always think about what to do\n" + "Action: the action to take, should be one of [{tool_names}]\n" + "Action Input: the input to the action\n" + "Observation: the result of the action\n" + "... (this Thought/Action/Action Input/Observation can repeat N times)\n" + "Thought: I now know the final answer\n" + "Final Answer: the final answer to the original question\n\n" + "Question: {input}\n\n" + "Thought:\n{agent_scratchpad}" +) + +# 4. Initialize reactive agent and executor +agent = create_react_agent(llm, tools, prompt) +executor = AgentExecutor(agent=agent, tools=tools, verbose=True) + +if __name__ == "__main__": + print("Launching AgentExecutor pipeline with AgentScope telemetry...") + result = executor.invoke( + {"input": "What is the velocity for mass 10 and force 50?"}, + config={"callbacks": [callback]}, + ) + print(f"Final Answer: {result['output']}") + + # Flush logs + time.sleep(2) + print("Telemetry complete.") diff --git a/examples/03_decorator_trace.py b/examples/03_decorator_trace.py new file mode 100644 index 0000000..4f3c4cb --- /dev/null +++ b/examples/03_decorator_trace.py @@ -0,0 +1,37 @@ +import time +import asyncio +import agentscope.decorators as as_deco + +# 1. Configure the global telemetry client settings +as_deco.configure( + host="127.0.0.1", port=8765, session_name="Decorator Tracing Session" +) + + +# 2. Decorate standard synchronous function +@as_deco.trace(name="SyncMathProcess", agent_type="chain") +def process_data_sync(value: int) -> int: + print(f"Inside sync process: value={value}") + time.sleep(0.4) + return value + 100 + + +# 3. Decorate standard asynchronous function +@as_deco.trace(name="AsyncNetworkRequest", agent_type="retriever") +async def fetch_data_async(url: str) -> dict: + print(f"Inside async fetch: url={url}") + await asyncio.sleep(0.3) + return {"status": 200, "data": "telemetry payload"} + + +if __name__ == "__main__": + print("Launching synchronous trace step...") + res_sync = process_data_sync(10) + print(f"Sync result: {res_sync}\n") + + print("Launching asynchronous trace step...") + res_async = asyncio.run(fetch_data_async("https://api.agentscope.dev/v1")) + print(f"Async result: {res_async}") + + time.sleep(2) + print("Telemetry complete.") diff --git a/packages/server/README.md b/packages/server/README.md new file mode 100644 index 0000000..5424686 --- /dev/null +++ b/packages/server/README.md @@ -0,0 +1,14 @@ +# AgentScope Observability Server + +The backend hub for AgentScope. It exposes a FastAPI server that acts as a central telemetry store, consuming telemetry streams via WebSockets and serving them via REST API to the React-based developer dashboard UI. + +## Features + +- **Double-pool WebSocket Manager**: Handles SDK telemetry event connections and UI client event subscription streams concurrently. +- **SQLite Database Backend**: Persists sessions, events, and metrics locally. +- **Automatic Database Pruning**: Periodically prunes expired or excess sessions according to configured policies (`RETENTION_DAYS`, `MAX_SESSIONS`). +- **REST Endpoints**: Provides paginated sessions, events, and layout DAG graphs. + +## Dev Setup & Running + +For instructions on setting up python environment and starting the server, please refer to the main [Development Setup Guide](../../docs/DEVELOPMENT.md). diff --git a/packages/ui/README.md b/packages/ui/README.md new file mode 100644 index 0000000..5eea991 --- /dev/null +++ b/packages/ui/README.md @@ -0,0 +1,14 @@ +# AgentScope Developer Dashboard UI + +The Next.js/Tailwind CSS frontend for AgentScope. It displays real-time agent execution sessions, trace lists, metrics charts, and agent call hierarchy graphs. + +## Features + +- **Real-time Live Ingestion**: Streams events instantly from the FastAPI server using WebSockets. +- **State Management**: Uses Zustand to cache session events and update layouts. +- **Metric Grids**: Real-time charts of tokens consumed, durations, latencies, and costs. +- **Interactive Call Feed**: Chronological nested listings of event payloads with details. + +## Dev Setup & Running + +For instructions on installing node modules and launching the dev server, please refer to the main [Development Setup Guide](../../docs/DEVELOPMENT.md).