lionagi 0.16.1__py3-none-any.whl → 0.16.3__py3-none-any.whl

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.
Files changed (79) hide show
  1. lionagi/adapters/_utils.py +0 -14
  2. lionagi/libs/file/save.py +8 -1
  3. lionagi/ln/__init__.py +10 -0
  4. lionagi/ln/_json_dump.py +322 -49
  5. lionagi/ln/fuzzy/__init__.py +4 -1
  6. lionagi/ln/fuzzy/_fuzzy_validate.py +109 -0
  7. lionagi/ln/fuzzy/_to_dict.py +388 -0
  8. lionagi/models/__init__.py +0 -2
  9. lionagi/operations/brainstorm/brainstorm.py +10 -10
  10. lionagi/operations/communicate/communicate.py +1 -1
  11. lionagi/operations/parse/parse.py +1 -1
  12. lionagi/protocols/generic/element.py +5 -14
  13. lionagi/protocols/generic/log.py +2 -2
  14. lionagi/protocols/generic/pile.py +1 -1
  15. lionagi/protocols/messages/message.py +8 -1
  16. lionagi/protocols/operatives/operative.py +2 -2
  17. lionagi/service/connections/endpoint.py +7 -0
  18. lionagi/service/connections/match_endpoint.py +2 -10
  19. lionagi/service/connections/providers/types.py +1 -3
  20. lionagi/service/hooks/hook_event.py +1 -1
  21. lionagi/service/hooks/hook_registry.py +1 -1
  22. lionagi/service/rate_limited_processor.py +1 -1
  23. lionagi/session/branch.py +1 -101
  24. lionagi/session/session.py +9 -14
  25. lionagi/utils.py +3 -334
  26. lionagi/version.py +1 -1
  27. {lionagi-0.16.1.dist-info → lionagi-0.16.3.dist-info}/METADATA +3 -13
  28. {lionagi-0.16.1.dist-info → lionagi-0.16.3.dist-info}/RECORD +30 -78
  29. lionagi/adapters/postgres_model_adapter.py +0 -131
  30. lionagi/libs/concurrency.py +0 -1
  31. lionagi/libs/file/params.py +0 -175
  32. lionagi/libs/nested/__init__.py +0 -3
  33. lionagi/libs/nested/flatten.py +0 -172
  34. lionagi/libs/nested/nfilter.py +0 -59
  35. lionagi/libs/nested/nget.py +0 -45
  36. lionagi/libs/nested/ninsert.py +0 -104
  37. lionagi/libs/nested/nmerge.py +0 -158
  38. lionagi/libs/nested/npop.py +0 -69
  39. lionagi/libs/nested/nset.py +0 -94
  40. lionagi/libs/nested/unflatten.py +0 -83
  41. lionagi/libs/nested/utils.py +0 -189
  42. lionagi/libs/parse.py +0 -31
  43. lionagi/libs/schema/json_schema.py +0 -231
  44. lionagi/libs/token_transform/__init__.py +0 -0
  45. lionagi/libs/token_transform/base.py +0 -54
  46. lionagi/libs/token_transform/llmlingua.py +0 -1
  47. lionagi/libs/token_transform/perplexity.py +0 -450
  48. lionagi/libs/token_transform/symbolic_compress_context.py +0 -152
  49. lionagi/libs/token_transform/synthlang.py +0 -9
  50. lionagi/libs/token_transform/synthlang_/base.py +0 -128
  51. lionagi/libs/token_transform/synthlang_/resources/frameworks/abstract_algebra.toml +0 -11
  52. lionagi/libs/token_transform/synthlang_/resources/frameworks/category_theory.toml +0 -11
  53. lionagi/libs/token_transform/synthlang_/resources/frameworks/complex_analysis.toml +0 -11
  54. lionagi/libs/token_transform/synthlang_/resources/frameworks/framework_options.json +0 -52
  55. lionagi/libs/token_transform/synthlang_/resources/frameworks/group_theory.toml +0 -11
  56. lionagi/libs/token_transform/synthlang_/resources/frameworks/math_logic.toml +0 -11
  57. lionagi/libs/token_transform/synthlang_/resources/frameworks/reflective_patterns.toml +0 -11
  58. lionagi/libs/token_transform/synthlang_/resources/frameworks/set_theory.toml +0 -11
  59. lionagi/libs/token_transform/synthlang_/resources/frameworks/topology_fundamentals.toml +0 -11
  60. lionagi/libs/token_transform/synthlang_/resources/mapping/lion_emoji_mapping.toml +0 -61
  61. lionagi/libs/token_transform/synthlang_/resources/mapping/python_math_mapping.toml +0 -41
  62. lionagi/libs/token_transform/synthlang_/resources/mapping/rust_chinese_mapping.toml +0 -60
  63. lionagi/libs/token_transform/synthlang_/resources/utility/base_synthlang_system_prompt.toml +0 -11
  64. lionagi/libs/token_transform/synthlang_/translate_to_synthlang.py +0 -140
  65. lionagi/libs/token_transform/types.py +0 -15
  66. lionagi/libs/unstructured/__init__.py +0 -0
  67. lionagi/libs/unstructured/pdf_to_image.py +0 -45
  68. lionagi/libs/unstructured/read_image_to_base64.py +0 -33
  69. lionagi/libs/validate/fuzzy_match_keys.py +0 -7
  70. lionagi/libs/validate/fuzzy_validate_mapping.py +0 -144
  71. lionagi/libs/validate/string_similarity.py +0 -7
  72. lionagi/libs/validate/xml_parser.py +0 -203
  73. lionagi/models/note.py +0 -383
  74. lionagi/operations/translate/__init__.py +0 -0
  75. lionagi/operations/translate/translate.py +0 -47
  76. lionagi/service/connections/providers/claude_code_.py +0 -294
  77. lionagi/tools/memory/tools.py +0 -495
  78. {lionagi-0.16.1.dist-info → lionagi-0.16.3.dist-info}/WHEEL +0 -0
  79. {lionagi-0.16.1.dist-info → lionagi-0.16.3.dist-info}/licenses/LICENSE +0 -0
@@ -1,294 +0,0 @@
1
- # Copyright (c) 2025, HaiyangLi <quantocean.li at gmail dot com>
2
- #
3
- # SPDX-License-Identifier: Apache-2.0
4
-
5
- from __future__ import annotations
6
-
7
- import warnings
8
-
9
- from pydantic import BaseModel
10
-
11
- from lionagi import ln
12
- from lionagi.libs.schema.as_readable import as_readable
13
- from lionagi.service.connections.endpoint import Endpoint
14
- from lionagi.service.connections.endpoint_config import EndpointConfig
15
- from lionagi.utils import to_dict, to_list
16
-
17
- from ...third_party.claude_code import (
18
- CLAUDE_CODE_OPTION_PARAMS,
19
- HAS_CLAUDE_CODE_SDK,
20
- ClaudeCodeRequest,
21
- ClaudePermission,
22
- stream_cc_sdk_events,
23
- )
24
-
25
- __all__ = (
26
- "ClaudeCodeRequest",
27
- "CLAUDE_CODE_OPTION_PARAMS", # backward compatibility
28
- "ClaudePermission", # backward compatibility
29
- "ClaudeCodeEndpoint",
30
- )
31
-
32
-
33
- # --------------------------------------------------------------------------- SDK endpoint
34
-
35
- _get_config = lambda: EndpointConfig(
36
- name="claude_code",
37
- provider="claude_code",
38
- base_url="internal",
39
- endpoint="query",
40
- request_options=ClaudeCodeRequest,
41
- timeout=3000,
42
- api_key="dummy-key",
43
- )
44
-
45
-
46
- ENDPOINT_CONFIG = _get_config() # backward compatibility
47
-
48
-
49
- class ClaudeCodeEndpoint(Endpoint):
50
- """Direct Python-SDK (non-CLI) endpoint - unchanged except for bug-fixes."""
51
-
52
- def __init__(self, config: EndpointConfig = None, **kwargs):
53
- if not HAS_CLAUDE_CODE_SDK:
54
- raise ImportError(
55
- "claude_code_sdk is not installed. "
56
- "Please install it with `uv pip install lionagi[claude_code_sdk]`."
57
- )
58
- warnings.warn(
59
- "The claude_code `query` endpoint is deprecated. Use `query_cli` endpoint instead.",
60
- DeprecationWarning,
61
- )
62
-
63
- config = config or _get_config()
64
- super().__init__(config=config, **kwargs)
65
-
66
- def create_payload(self, request: dict | BaseModel, **kwargs):
67
- req_dict = {**self.config.kwargs, **to_dict(request), **kwargs}
68
- messages = req_dict.pop("messages")
69
- req_obj = ClaudeCodeRequest.create(messages=messages, **req_dict)
70
- return {"request": req_obj}, {}
71
-
72
- async def stream(self, request: dict | BaseModel, **kwargs):
73
- payload, _ = self.create_payload(request, **kwargs)
74
- async for chunk in stream_cc_sdk_events(payload["request"]):
75
- yield chunk
76
-
77
- def _parse_claude_code_response(self, responses: list) -> dict:
78
- """Parse Claude Code responses into a clean chat completions-like format.
79
-
80
- Claude Code returns a list of messages:
81
- - SystemMessage: initialization info
82
- - AssistantMessage(s): actual assistant responses with content blocks
83
- - UserMessage(s): for tool use interactions
84
- - ResultMessage: final result with metadata
85
-
86
- When Claude Code uses tools, the ResultMessage.result may be None.
87
- In that case, we need to look at the tool results in UserMessages.
88
- """
89
- results = {
90
- "session_id": None,
91
- "model": "claude-code",
92
- "result": "",
93
- "tool_uses": [],
94
- "tool_results": [],
95
- "is_error": False,
96
- "num_turns": None,
97
- "total_cost_usd": None,
98
- "usage": {
99
- "prompt_tokens": 0,
100
- "completion_tokens": 0,
101
- "total_tokens": 0,
102
- },
103
- }
104
- from claude_code_sdk import types as cc_types
105
-
106
- for response in responses:
107
- if isinstance(response, cc_types.SystemMessage):
108
- results["session_id"] = response.data.get("session_id")
109
- results["model"] = response.data.get("model", "claude-code")
110
- if isinstance(
111
- response, cc_types.AssistantMessage | cc_types.UserMessage
112
- ):
113
- for block in to_list(
114
- response.content,
115
- flatten=True,
116
- flatten_tuple_set=True,
117
- dropna=True,
118
- ):
119
- if isinstance(block, cc_types.TextBlock):
120
- results["result"] += block.text.strip() + "\n"
121
-
122
- if isinstance(block, cc_types.ToolUseBlock):
123
- entry = {
124
- "id": block.id,
125
- "name": block.name,
126
- "input": block.input,
127
- }
128
- results["tool_uses"].append(entry)
129
-
130
- if isinstance(block, cc_types.ToolResultBlock):
131
- results["tool_results"].append(
132
- {
133
- "tool_use_id": block.tool_use_id,
134
- "content": block.content,
135
- "is_error": block.is_error,
136
- }
137
- )
138
-
139
- if isinstance(response, cc_types.ResultMessage):
140
- if response.result:
141
- results["result"] = str(response.result).strip()
142
- results["usage"] = response.usage
143
- results["is_error"] = response.is_error
144
- results["total_cost_usd"] = response.total_cost_usd
145
- results["num_turns"] = response.num_turns
146
- results["duration_ms"] = response.duration_ms
147
- results["duration_api_ms"] = response.duration_api_ms
148
-
149
- return results
150
-
151
- async def _call(
152
- self,
153
- payload: dict,
154
- headers: dict,
155
- **kwargs,
156
- ):
157
- from claude_code_sdk import query as sdk_query
158
- from claude_code_sdk import types as cc_types
159
-
160
- responses = []
161
- request: ClaudeCodeRequest = payload["request"]
162
- system: cc_types.SystemMessage = None
163
-
164
- # 1. stream the Claude Code response
165
- async for chunk in self._stream_claude_code(**payload):
166
- if request.verbose_output:
167
- _display_message(chunk, theme=request.cli_display_theme)
168
-
169
- if isinstance(chunk, cc_types.SystemMessage):
170
- system = chunk
171
- responses.append(chunk)
172
-
173
- # 2. If the last response is not a ResultMessage and auto_finish is True,
174
- # we need to query Claude Code again to get the final result message.
175
- if request.auto_finish and not isinstance(
176
- responses[-1], cc_types.ResultMessage
177
- ):
178
- options = request.as_claude_options()
179
- options.continue_conversation = True
180
- options.max_turns = 1
181
- if system:
182
- options.resume = (
183
- system.data.get("session_id", None) if system else None
184
- )
185
-
186
- async for chunk in sdk_query(
187
- prompt="Please provide a the final result message only",
188
- options=options,
189
- ):
190
- if isinstance(chunk, cc_types.ResultMessage):
191
- if request.verbose_output:
192
- str_ = _verbose_output(chunk)
193
- if str_:
194
- as_readable(
195
- str_,
196
- md=True,
197
- display_str=True,
198
- format_curly=True,
199
- max_panel_width=100,
200
- theme=request.cli_display_theme,
201
- )
202
-
203
- responses.append(chunk)
204
-
205
-
206
- def _display_message(chunk, theme):
207
- from claude_code_sdk import types as cc_types
208
-
209
- if isinstance(
210
- chunk,
211
- cc_types.SystemMessage
212
- | cc_types.AssistantMessage
213
- | cc_types.UserMessage,
214
- ):
215
- str_ = _verbose_output(chunk)
216
- if str_:
217
- if str_.startswith("Claude:"):
218
- as_readable(
219
- str_,
220
- md=True,
221
- display_str=True,
222
- max_panel_width=100,
223
- theme=theme,
224
- )
225
- else:
226
- as_readable(
227
- str_,
228
- format_curly=True,
229
- display_str=True,
230
- max_panel_width=100,
231
- theme=theme,
232
- )
233
-
234
- if isinstance(chunk, cc_types.ResultMessage):
235
- str_ = _verbose_output(chunk)
236
- as_readable(
237
- str_,
238
- md=True,
239
- display_str=True,
240
- format_curly=True,
241
- max_panel_width=100,
242
- theme=theme,
243
- )
244
-
245
-
246
- def _verbose_output(res) -> str:
247
- from claude_code_sdk import types as cc_types
248
-
249
- str_ = ""
250
- if isinstance(res, cc_types.SystemMessage):
251
- str_ = f"Claude Code Session Started: {res.data.get('session_id', 'unknown')}"
252
- str_ += f"\nModel: {res.data.get('model', 'claude-code')}\n---"
253
- return str_
254
-
255
- if isinstance(res, cc_types.AssistantMessage | cc_types.UserMessage):
256
- for block in to_list(
257
- res.content, flatten=True, flatten_tuple_set=True, dropna=True
258
- ):
259
- if isinstance(block, cc_types.TextBlock):
260
- text = (
261
- block.text.strip() if isinstance(block.text, str) else ""
262
- )
263
- str_ += f"Claude:\n{text}"
264
-
265
- if isinstance(block, cc_types.ToolUseBlock):
266
- inp_ = None
267
-
268
- if isinstance(block.input, dict | list):
269
- inp_ = ln.json_dumps(block.input)
270
- else:
271
- inp_ = str(block.input)
272
-
273
- input = inp_[:200] + "..." if len(inp_) > 200 else inp_
274
- str_ += (
275
- f"Tool Use: {block.name} - {block.id}\n - Input: {input}"
276
- )
277
-
278
- if isinstance(block, cc_types.ToolResultBlock):
279
- content = str(block.content)
280
- content = (
281
- content[:200] + "..." if len(content) > 200 else content
282
- )
283
- str_ += (
284
- f"Tool Result: {block.tool_use_id}\n - Content: {content}"
285
- )
286
- return str_
287
-
288
- if isinstance(res, cc_types.ResultMessage):
289
- str_ += f"Session Completion - {res.session_id}"
290
- str_ += f"\nResult: {res.result or 'No result'}"
291
- str_ += f"\n- Cost: ${res.total_cost_usd:.4f} USD"
292
- str_ += f"\n- Duration: {res.duration_ms} ms (API: {res.duration_api_ms} ms)"
293
- str_ += f"\n- Turns: {res.num_turns}"
294
- return str_