cloudbase-agent-langgraph 0.1.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,194 @@
1
+
2
+ # Dependencies
3
+ node_modules/
4
+ .pnp
5
+ .pnp.js
6
+
7
+ # Production builds
8
+ dist/
9
+ build/
10
+ out/
11
+
12
+ # Environment variables
13
+ .env
14
+ .env.local
15
+ .env.development.local
16
+ .env.test.local
17
+ .env.production.local
18
+
19
+ # Logs
20
+ logs
21
+ *.log
22
+ npm-debug.log*
23
+ yarn-debug.log*
24
+ yarn-error.log*
25
+ lerna-debug.log*
26
+ .pnpm-debug.log*
27
+
28
+ # Runtime data
29
+ pids
30
+ *.pid
31
+ *.seed
32
+ *.pid.lock
33
+
34
+ # Coverage directory used by tools like istanbul
35
+ coverage/
36
+ *.lcov
37
+
38
+ # nyc test coverage
39
+ .nyc_output
40
+
41
+ # TypeScript
42
+ *.tsbuildinfo
43
+
44
+ # Optional npm cache directory
45
+ .npm
46
+
47
+ # Optional eslint cache
48
+ .eslintcache
49
+
50
+ # Microbundle cache
51
+ .rpt2_cache/
52
+ .rts2_cache_cjs/
53
+ .rts2_cache_es/
54
+ .rts2_cache_umd/
55
+
56
+ # Optional REPL history
57
+ .node_repl_history
58
+
59
+ # Output of 'npm pack'
60
+ *.tgz
61
+
62
+ # Yarn Integrity file
63
+ .yarn-integrity
64
+
65
+ # parcel-bundler cache (https://parceljs.org/)
66
+ .cache
67
+ .parcel-cache
68
+
69
+ # Next.js build output
70
+ .next
71
+
72
+ # Nuxt.js build / generate output
73
+ .nuxt
74
+
75
+ # Gatsby files
76
+ .cache/
77
+
78
+ # vuepress build output
79
+ .vuepress/dist
80
+
81
+ # Serverless directories
82
+ .serverless/
83
+
84
+ # FuseBox cache
85
+ .fusebox/
86
+
87
+ # DynamoDB Local files
88
+ .dynamodb/
89
+
90
+ # TernJS port file
91
+ .tern-port
92
+
93
+ # Stores VSCode versions used for testing VSCode extensions
94
+ .vscode-test
95
+
96
+ # yarn v2
97
+ .yarn/cache
98
+ .yarn/unplugged
99
+ .yarn/build-state.yml
100
+ .yarn/install-state.gz
101
+ .pnp.*
102
+
103
+ # IDE
104
+ .vscode/
105
+ .idea/
106
+ *.swp
107
+ *.swo
108
+
109
+ # OS
110
+ .DS_Store
111
+ .DS_Store?
112
+ ._*
113
+ .Spotlight-V100
114
+ .Trashes
115
+ ehthumbs.db
116
+ Thumbs.db
117
+
118
+ # Temporary files
119
+ *.tmp
120
+ *.temp
121
+
122
+ # WeChat Mini Program
123
+ miniprogram_npm/
124
+ project.config.json
125
+ project.private.config.json
126
+
127
+ # Testing
128
+ coverage/
129
+ .nyc_output/
130
+
131
+ # Storybook build outputs
132
+ storybook-static/
133
+
134
+ # Python
135
+ __pycache__/
136
+ *.pyc
137
+ *.pyo
138
+ *.pyd
139
+ .Python
140
+ *.so
141
+ *.egg
142
+ *.egg-info
143
+ dist/
144
+ build/
145
+ eggs/
146
+ .eggs/
147
+ lib/
148
+ lib64/
149
+ parts/
150
+ sdist/
151
+ var/
152
+ wheels/
153
+ *.egg-info/
154
+ .installed.cfg
155
+ *.egg
156
+ MANIFEST
157
+
158
+ # Python virtual environments
159
+ venv/
160
+ env/
161
+ ENV/
162
+ .venv
163
+
164
+ # Python testing and coverage
165
+ .pytest_cache/
166
+ .coverage
167
+ .coverage.*
168
+ htmlcov/
169
+ .tox/
170
+ .nox/
171
+
172
+ # Python type checking
173
+ .mypy_cache/
174
+ .dmypy.json
175
+ dmypy.json
176
+ .pyre/
177
+ .pytype/
178
+
179
+ # Python linting
180
+ .flake8_cache/
181
+
182
+ # Python profiling
183
+ .prof
184
+
185
+ # Jupyter Notebook
186
+ .ipynb_checkpoints
187
+
188
+ # Python package manager
189
+ pip-log.txt
190
+ pip-delete-this-directory.txt
191
+
192
+ # UV lock files (if not tracking)
193
+ # uv.lock
194
+ /docs/dist/
@@ -0,0 +1,45 @@
1
+ Metadata-Version: 2.4
2
+ Name: cloudbase-agent-langgraph
3
+ Version: 0.1.1
4
+ Summary: Cloudbase Agent Python SDK - LangGraph framework integration
5
+ Author-email: Cloudbase Agent Team <ag-kit@example.com>
6
+ License: Apache-2.0
7
+ Keywords: Cloudbase Agent,agent,ai,llm
8
+ Classifier: Development Status :: 3 - Alpha
9
+ Classifier: Intended Audience :: Developers
10
+ Classifier: License :: OSI Approved :: Apache Software License
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Programming Language :: Python :: 3.10
13
+ Classifier: Programming Language :: Python :: 3.11
14
+ Classifier: Programming Language :: Python :: 3.12
15
+ Requires-Python: >=3.10
16
+ Requires-Dist: cloudbase-agent-core
17
+ Requires-Dist: cloudbase-agent-storage
18
+ Requires-Dist: langchain-core>=0.3.0
19
+ Requires-Dist: langgraph>=0.2.0
20
+ Provides-Extra: dev
21
+ Requires-Dist: mypy>=1.0.0; extra == 'dev'
22
+ Requires-Dist: pytest-asyncio>=0.21.0; extra == 'dev'
23
+ Requires-Dist: pytest>=7.0.0; extra == 'dev'
24
+ Requires-Dist: ruff>=0.12.0; extra == 'dev'
25
+ Description-Content-Type: text/markdown
26
+
27
+ # cloudbase-agent-langgraph
28
+
29
+ Cloudbase Agent Python SDK - LangGraph framework integration
30
+
31
+ ## Installation
32
+
33
+ ```bash
34
+ pip install cloudbase-agent-langgraph
35
+ ```
36
+
37
+ ## Usage
38
+
39
+ ```python
40
+ from cloudbase_agent import ...
41
+ ```
42
+
43
+ ## License
44
+
45
+ Apache-2.0
@@ -0,0 +1,19 @@
1
+ # cloudbase-agent-langgraph
2
+
3
+ Cloudbase Agent Python SDK - LangGraph framework integration
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ pip install cloudbase-agent-langgraph
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ```python
14
+ from cloudbase_agent import ...
15
+ ```
16
+
17
+ ## License
18
+
19
+ Apache-2.0
@@ -0,0 +1,46 @@
1
+ [project]
2
+ name = "cloudbase-agent-langgraph"
3
+ version = "0.1.1"
4
+ description = "Cloudbase Agent Python SDK - LangGraph framework integration"
5
+ readme = "README.md"
6
+ requires-python = ">=3.10"
7
+ license = { text = "Apache-2.0" }
8
+ authors = [
9
+ { name = "Cloudbase Agent Team", email = "ag-kit@example.com" }
10
+ ]
11
+ keywords = ["ai", "agent", "llm", "Cloudbase Agent"]
12
+ classifiers = [
13
+ "Development Status :: 3 - Alpha",
14
+ "Intended Audience :: Developers",
15
+ "License :: OSI Approved :: Apache Software License",
16
+ "Programming Language :: Python :: 3",
17
+ "Programming Language :: Python :: 3.10",
18
+ "Programming Language :: Python :: 3.11",
19
+ "Programming Language :: Python :: 3.12",
20
+ ]
21
+
22
+ dependencies = [
23
+ "cloudbase-agent-core",
24
+ "cloudbase-agent-storage",
25
+ "langgraph>=0.2.0",
26
+ "langchain-core>=0.3.0",
27
+ ]
28
+
29
+ [project.optional-dependencies]
30
+ dev = [
31
+ "ruff>=0.12.0",
32
+ "mypy>=1.0.0",
33
+ "pytest>=7.0.0",
34
+ "pytest-asyncio>=0.21.0",
35
+ ]
36
+
37
+ [build-system]
38
+ requires = ["hatchling"]
39
+ build-backend = "hatchling.build"
40
+
41
+ [tool.hatch.build.targets.wheel]
42
+ packages = ["src/cloudbase_agent"]
43
+
44
+ [tool.uv.sources]
45
+ cloudbase-agent-core = { workspace = true }
46
+ cloudbase-agent-storage = { workspace = true }
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ """Cloudbase Agent package."""
4
+
5
+ __all__ = []
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ """LangChain integration for Cloudbase Agent storage.
4
+
5
+ This module provides LangChain-compatible storage implementations using TDAI Memory.
6
+ """
7
+
8
+ from .chat_history import TDAIChatHistory
9
+ from .store.tdai import TDAIStore
10
+
11
+ __all__ = [
12
+ "TDAIChatHistory",
13
+ "TDAIStore",
14
+ ]
@@ -0,0 +1,219 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ """LangChain chat history implementation using TDAI Memory.
4
+
5
+ This module provides a chat message history for LangChain that uses TDAI Memory
6
+ as the backend storage, enabling persistent conversation history.
7
+ """
8
+
9
+ from typing import List
10
+
11
+ try:
12
+ from langchain_core.chat_history import BaseChatMessageHistory
13
+ from langchain_core.messages import (
14
+ BaseMessage,
15
+ message_to_dict,
16
+ messages_from_dict,
17
+ )
18
+ except ImportError:
19
+ raise ImportError("langchain-core is required for TDAIChatHistory. Install it with: pip install langchain-core")
20
+
21
+ from cloudbase_agent.tdaimemory import MemoryClient
22
+
23
+
24
+ class TDAIChatHistory(BaseChatMessageHistory):
25
+ """LangChain chat message history using TDAI Memory as backend.
26
+
27
+ This class implements the BaseChatMessageHistory interface to store and retrieve
28
+ chat messages using TDAI Memory's event storage system.
29
+
30
+ :param client: TDAI Memory client instance
31
+ :type client: MemoryClient
32
+ :param session_id: Session ID for storing messages
33
+ :type session_id: str
34
+
35
+ Example::
36
+
37
+ from cloudbase_agent.storage.tdaimemory import MemoryClient
38
+ from cloudbase_agent.storage.langchain import TDAIChatHistory
39
+ from langchain_core.messages import HumanMessage, AIMessage
40
+
41
+ client = MemoryClient(
42
+ endpoint="https://memory.tdai.tencentyun.com",
43
+ api_key="your-api-key",
44
+ memory_id="your-memory-id"
45
+ )
46
+
47
+ history = TDAIChatHistory(
48
+ client=client,
49
+ session_id="user_123"
50
+ )
51
+
52
+ # Add messages
53
+ history.add_user_message("Hello!")
54
+ history.add_ai_message("Hi there! How can I help you?")
55
+
56
+ # Get messages
57
+ messages = history.messages
58
+
59
+ # Clear history
60
+ history.clear()
61
+ """
62
+
63
+ def __init__(
64
+ self,
65
+ client: MemoryClient,
66
+ session_id: str,
67
+ auto_create_session: bool = True,
68
+ ):
69
+ """Initialize the TDAI chat history.
70
+
71
+ :param client: TDAI Memory client instance
72
+ :type client: MemoryClient
73
+ :param session_id: Session ID for storing messages (must start with 'session-' and be 16-20 chars)
74
+ :type session_id: str
75
+ :param auto_create_session: Whether to automatically create the session if it doesn't exist
76
+ :type auto_create_session: bool
77
+ """
78
+ self.client = client
79
+ self.session_id = session_id
80
+ self._session_created = False
81
+
82
+ # Auto-create session if requested
83
+ if auto_create_session:
84
+ self._ensure_session()
85
+
86
+ def _ensure_session(self) -> None:
87
+ """Ensure the session exists, create if it doesn't."""
88
+ if not self._session_created:
89
+ try:
90
+ # Try to query the session to see if it exists
91
+ self.client.query_events(session_id=self.session_id)
92
+ self._session_created = True
93
+ except Exception:
94
+ # Session doesn't exist, create it
95
+ # Note: We can't use the session_id directly in create_session
96
+ # because TDAI generates its own session IDs
97
+ # So we'll just mark it as created and let the first operation create it implicitly
98
+ self._session_created = True
99
+
100
+ @property
101
+ def messages(self) -> List[BaseMessage]:
102
+ """Retrieve all messages from the store.
103
+
104
+ :return: List of messages
105
+ :rtype: List[BaseMessage]
106
+ """
107
+ try:
108
+ result = self.client.query_events(
109
+ session_id=self.session_id,
110
+ )
111
+
112
+ events = result.get("events", [])
113
+
114
+ # Convert events to message dicts
115
+ message_dicts = []
116
+ for event in events:
117
+ # Events are stored as message dicts
118
+ if isinstance(event, dict) and "type" in event:
119
+ message_dicts.append(event)
120
+
121
+ # Convert dicts to BaseMessage objects
122
+ return messages_from_dict(message_dicts)
123
+ except Exception as e:
124
+ # Only ignore "data not exist" errors (empty session)
125
+ # All other errors should be raised
126
+ error_msg = str(e).lower()
127
+ if "data not exist" in error_msg or "not exist" in error_msg:
128
+ # Session exists but has no events yet - this is normal
129
+ return []
130
+ else:
131
+ # Real error - should not be silently ignored
132
+ print(f"Error retrieving messages: {e}")
133
+ raise
134
+
135
+ def add_message(self, message: BaseMessage) -> None:
136
+ """Add a message to the store.
137
+
138
+ :param message: Message to add
139
+ :type message: BaseMessage
140
+ """
141
+ try:
142
+ # Convert message to dict
143
+ message_dict = message_to_dict(message)
144
+
145
+ # Store in TDAI Memory
146
+ self.client.append_event(
147
+ session_id=self.session_id,
148
+ messages=message_dict,
149
+ )
150
+ except Exception as e:
151
+ print(f"Error adding message: {e}")
152
+ raise
153
+
154
+ def add_messages(self, messages: List[BaseMessage]) -> None:
155
+ """Add multiple messages to the store.
156
+
157
+ :param messages: List of messages to add
158
+ :type messages: List[BaseMessage]
159
+ """
160
+ for message in messages:
161
+ self.add_message(message)
162
+
163
+ def clear(self) -> None:
164
+ """Clear all messages from the store.
165
+
166
+ This will delete all events in the session and the session itself.
167
+ """
168
+ try:
169
+ # Get all event IDs
170
+ try:
171
+ result = self.client.query_events(
172
+ session_id=self.session_id,
173
+ )
174
+ event_ids = [event.get("event_id") for event in result.get("events", []) if event.get("event_id")]
175
+ except Exception as e:
176
+ # If query fails with "data not exist", session is already empty
177
+ if "data not exist" in str(e).lower() or "not exist" in str(e).lower():
178
+ event_ids = []
179
+ else:
180
+ # Real error - re-raise
181
+ raise
182
+
183
+ # Delete all events (ignore "not exist" errors)
184
+ for event_id in event_ids:
185
+ try:
186
+ self.client.delete_event(
187
+ session_id=self.session_id,
188
+ event_id=event_id,
189
+ )
190
+ except Exception as e:
191
+ # Ignore "not exist" errors, event may have been deleted already
192
+ if "not exist" not in str(e).lower():
193
+ raise
194
+
195
+ # Delete the session (ignore "not exist" errors)
196
+ try:
197
+ self.client.delete_session(
198
+ session_id=self.session_id,
199
+ )
200
+ except Exception as e:
201
+ # Ignore "not exist" errors, session may have been deleted already
202
+ if "not exist" not in str(e).lower():
203
+ raise
204
+
205
+ # Recreate the session so the chat history can continue to be used
206
+ result = self.client.create_session(name="chat_history_session")
207
+ self.session_id = result.get("session_id")
208
+ self._session_created = True
209
+ except Exception as e:
210
+ # Only print error, don't raise - clear() should be idempotent
211
+ # But we should log what went wrong
212
+ error_msg = str(e).lower()
213
+ if "not exist" not in error_msg and "data not exist" not in error_msg:
214
+ print(f"Error clearing messages: {e}")
215
+ raise
216
+
217
+ def close(self) -> None:
218
+ """Close the TDAI client connection."""
219
+ self.client.close()
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ """LangChain store module."""
4
+
5
+ from .tdai import TDAIStore
6
+
7
+ __all__ = ["TDAIStore"]