lionagi 0.17.8__py3-none-any.whl → 0.17.9__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.
- lionagi/_types.py +2 -0
- lionagi/protocols/action/manager.py +12 -15
- lionagi/service/connections/providers/claude_code_cli.py +1 -1
- lionagi/service/third_party/claude_code.py +53 -86
- lionagi/version.py +1 -1
- {lionagi-0.17.8.dist-info → lionagi-0.17.9.dist-info}/METADATA +1 -1
- {lionagi-0.17.8.dist-info → lionagi-0.17.9.dist-info}/RECORD +9 -9
- {lionagi-0.17.8.dist-info → lionagi-0.17.9.dist-info}/WHEEL +0 -0
- {lionagi-0.17.8.dist-info → lionagi-0.17.9.dist-info}/licenses/LICENSE +0 -0
lionagi/_types.py
CHANGED
@@ -296,19 +296,22 @@ class ActionManager(Manager):
|
|
296
296
|
if isinstance(server_config, dict) and "server" in server_config:
|
297
297
|
server_name = server_config["server"]
|
298
298
|
|
299
|
+
if request_options:
|
300
|
+
for k in list(request_options.keys()):
|
301
|
+
if not k.startswith(f"{server_name}_"):
|
302
|
+
request_options[f"{server_name}_{k}"] = (
|
303
|
+
request_options.pop(k)
|
304
|
+
)
|
305
|
+
|
299
306
|
if tool_names:
|
300
307
|
# Register specific tools with qualified names
|
301
308
|
for tool_name in tool_names:
|
302
309
|
# Use qualified name to avoid collisions
|
303
|
-
qualified_name = (
|
304
|
-
f"{server_name}_{tool_name}" if server_name else tool_name
|
305
|
-
)
|
306
|
-
|
307
310
|
# Store original tool name in config for MCP calls
|
308
311
|
config_with_metadata = dict(server_config)
|
309
312
|
config_with_metadata["_original_tool_name"] = tool_name
|
310
313
|
|
311
|
-
mcp_config = {
|
314
|
+
mcp_config = {tool_name: config_with_metadata}
|
312
315
|
|
313
316
|
# Get request_options for this tool if provided
|
314
317
|
tool_request_options = None
|
@@ -320,7 +323,7 @@ class ActionManager(Manager):
|
|
320
323
|
mcp_config=mcp_config, request_options=tool_request_options
|
321
324
|
)
|
322
325
|
self.register_tool(tool, update=update)
|
323
|
-
registered_tools.append(
|
326
|
+
registered_tools.append(tool_name)
|
324
327
|
else:
|
325
328
|
# Auto-discover tools from the server
|
326
329
|
from lionagi.service.connections.mcp.wrapper import (
|
@@ -333,16 +336,12 @@ class ActionManager(Manager):
|
|
333
336
|
|
334
337
|
# Register each discovered tool with qualified name
|
335
338
|
for tool in tools:
|
336
|
-
# Use qualified name to avoid collisions: server_toolname
|
337
|
-
qualified_name = (
|
338
|
-
f"{server_name}_{tool.name}" if server_name else tool.name
|
339
|
-
)
|
340
339
|
|
341
340
|
# Store original tool name in config for MCP calls
|
342
341
|
config_with_metadata = dict(server_config)
|
343
342
|
config_with_metadata["_original_tool_name"] = tool.name
|
344
343
|
|
345
|
-
mcp_config = {
|
344
|
+
mcp_config = {tool.name: config_with_metadata}
|
346
345
|
|
347
346
|
# Get request_options for this tool if provided
|
348
347
|
tool_request_options = None
|
@@ -356,11 +355,9 @@ class ActionManager(Manager):
|
|
356
355
|
request_options=tool_request_options,
|
357
356
|
)
|
358
357
|
self.register_tool(tool_obj, update=update)
|
359
|
-
registered_tools.append(
|
358
|
+
registered_tools.append(tool.name)
|
360
359
|
except Exception as e:
|
361
|
-
print(
|
362
|
-
f"Warning: Failed to register tool {qualified_name}: {e}"
|
363
|
-
)
|
360
|
+
print(f"Warning: Failed to register tool {tool.name}: {e}")
|
364
361
|
|
365
362
|
return registered_tools
|
366
363
|
|
@@ -79,7 +79,7 @@ class ClaudeCodeCLIEndpoint(Endpoint):
|
|
79
79
|
def create_payload(self, request: dict | BaseModel, **kwargs):
|
80
80
|
req_dict = {**self.config.kwargs, **to_dict(request), **kwargs}
|
81
81
|
messages = req_dict.pop("messages")
|
82
|
-
req_obj = ClaudeCodeRequest
|
82
|
+
req_obj = ClaudeCodeRequest(messages=messages, **req_dict)
|
83
83
|
return {"request": req_obj}, {}
|
84
84
|
|
85
85
|
async def stream(
|
@@ -26,7 +26,6 @@ from lionagi import ln
|
|
26
26
|
from lionagi.libs.schema.as_readable import as_readable
|
27
27
|
from lionagi.utils import is_coro_func, is_import_installed
|
28
28
|
|
29
|
-
HAS_CLAUDE_CODE_SDK = is_import_installed("claude_code_sdk")
|
30
29
|
HAS_CLAUDE_CODE_CLI = False
|
31
30
|
CLAUDE_CLI = None
|
32
31
|
|
@@ -68,7 +67,6 @@ __all__ = (
|
|
68
67
|
"ClaudeChunk",
|
69
68
|
"ClaudeSession",
|
70
69
|
"stream_claude_code_cli",
|
71
|
-
"stream_cc_sdk_events",
|
72
70
|
)
|
73
71
|
|
74
72
|
|
@@ -117,6 +115,59 @@ class ClaudeCodeRequest(BaseModel):
|
|
117
115
|
return "bypassPermissions"
|
118
116
|
return v
|
119
117
|
|
118
|
+
@model_validator(mode="before")
|
119
|
+
def _validate_message_prompt(cls, data):
|
120
|
+
if "prompt" in data and data["prompt"]:
|
121
|
+
return data
|
122
|
+
|
123
|
+
if not (msg := data.get("messages")):
|
124
|
+
raise ValueError("messages may not be empty")
|
125
|
+
resume = data.get("resume")
|
126
|
+
continue_conversation = data.get("continue_conversation")
|
127
|
+
|
128
|
+
prompt = ""
|
129
|
+
|
130
|
+
# 1. if resume or continue_conversation, use the last message
|
131
|
+
if resume or continue_conversation:
|
132
|
+
continue_conversation = True
|
133
|
+
prompt = msg[-1]["content"]
|
134
|
+
if isinstance(prompt, (dict, list)):
|
135
|
+
prompt = ln.json_dumps(prompt)
|
136
|
+
|
137
|
+
# 2. else, use entire messages except system message
|
138
|
+
else:
|
139
|
+
prompts = []
|
140
|
+
continue_conversation = False
|
141
|
+
for message in msg:
|
142
|
+
if message["role"] != "system":
|
143
|
+
content = message["content"]
|
144
|
+
prompts.append(
|
145
|
+
ln.json_dumps(content)
|
146
|
+
if isinstance(content, (dict, list))
|
147
|
+
else content
|
148
|
+
)
|
149
|
+
|
150
|
+
prompt = "\n".join(prompts)
|
151
|
+
|
152
|
+
# 3. assemble the request data
|
153
|
+
data_: dict[str, Any] = dict(
|
154
|
+
prompt=prompt,
|
155
|
+
resume=resume,
|
156
|
+
continue_conversation=bool(continue_conversation),
|
157
|
+
)
|
158
|
+
|
159
|
+
# 4. extract system prompt if available
|
160
|
+
if (msg[0]["role"] == "system") and (resume or continue_conversation):
|
161
|
+
data_["system_prompt"] = msg[0]["content"]
|
162
|
+
|
163
|
+
if "append_system_prompt" in data and data["append_system_prompt"]:
|
164
|
+
data_["append_system_prompt"] = str(
|
165
|
+
data.get("append_system_prompt")
|
166
|
+
)
|
167
|
+
|
168
|
+
data_.update(data)
|
169
|
+
return data_
|
170
|
+
|
120
171
|
# Workspace path derived from repo + ws
|
121
172
|
def cwd(self) -> Path:
|
122
173
|
if not self.ws:
|
@@ -209,73 +260,6 @@ class ClaudeCodeRequest(BaseModel):
|
|
209
260
|
args += ["--model", self.model or "sonnet", "--verbose"]
|
210
261
|
return args
|
211
262
|
|
212
|
-
# ------------------------ SDK helpers -----------------------------------
|
213
|
-
def as_claude_options(self):
|
214
|
-
from claude_code_sdk import ClaudeCodeOptions
|
215
|
-
|
216
|
-
data = {
|
217
|
-
k: v
|
218
|
-
for k, v in self.model_dump(exclude_none=True).items()
|
219
|
-
if k in CLAUDE_CODE_OPTION_PARAMS
|
220
|
-
}
|
221
|
-
return ClaudeCodeOptions(**data)
|
222
|
-
|
223
|
-
# ------------------------ convenience constructor -----------------------
|
224
|
-
@classmethod
|
225
|
-
def create(
|
226
|
-
cls,
|
227
|
-
messages: list[dict[str, Any]],
|
228
|
-
resume: str | None = None,
|
229
|
-
continue_conversation: bool | None = None,
|
230
|
-
**kwargs,
|
231
|
-
):
|
232
|
-
if not messages:
|
233
|
-
raise ValueError("messages may not be empty")
|
234
|
-
|
235
|
-
prompt = ""
|
236
|
-
|
237
|
-
# 1. if resume or continue_conversation, use the last message
|
238
|
-
if resume or continue_conversation:
|
239
|
-
continue_conversation = True
|
240
|
-
prompt = messages[-1]["content"]
|
241
|
-
if isinstance(prompt, (dict, list)):
|
242
|
-
prompt = ln.json_dumps(prompt)
|
243
|
-
|
244
|
-
# 2. else, use entire messages except system message
|
245
|
-
else:
|
246
|
-
prompts = []
|
247
|
-
continue_conversation = False
|
248
|
-
for message in messages:
|
249
|
-
if message["role"] != "system":
|
250
|
-
content = message["content"]
|
251
|
-
prompts.append(
|
252
|
-
ln.json_dumps(content)
|
253
|
-
if isinstance(content, (dict, list))
|
254
|
-
else content
|
255
|
-
)
|
256
|
-
|
257
|
-
prompt = "\n".join(prompts)
|
258
|
-
|
259
|
-
# 3. assemble the request data
|
260
|
-
data: dict[str, Any] = dict(
|
261
|
-
prompt=prompt,
|
262
|
-
resume=resume,
|
263
|
-
continue_conversation=bool(continue_conversation),
|
264
|
-
)
|
265
|
-
|
266
|
-
# 4. extract system prompt if available
|
267
|
-
if (messages[0]["role"] == "system") and (
|
268
|
-
resume or continue_conversation
|
269
|
-
):
|
270
|
-
data["system_prompt"] = messages[0]["content"]
|
271
|
-
if kwargs.get("append_system_prompt"):
|
272
|
-
data["append_system_prompt"] = str(
|
273
|
-
kwargs.get("append_system_prompt")
|
274
|
-
)
|
275
|
-
|
276
|
-
data.update(kwargs)
|
277
|
-
return cls.model_validate(data, strict=False)
|
278
|
-
|
279
263
|
|
280
264
|
@dataclass
|
281
265
|
class ClaudeChunk:
|
@@ -499,23 +483,6 @@ async def _ndjson_from_cli(request: ClaudeCodeRequest):
|
|
499
483
|
await proc.wait()
|
500
484
|
|
501
485
|
|
502
|
-
def _stream_claude_code(request: ClaudeCodeRequest):
|
503
|
-
from claude_code_sdk import query as sdk_query
|
504
|
-
|
505
|
-
return sdk_query(
|
506
|
-
prompt=request.prompt, options=request.as_claude_options()
|
507
|
-
)
|
508
|
-
|
509
|
-
|
510
|
-
def stream_cc_sdk_events(request: ClaudeCodeRequest):
|
511
|
-
if not HAS_CLAUDE_CODE_SDK:
|
512
|
-
raise RuntimeError(
|
513
|
-
"claude_code_sdk not installed (uv pip install lionagi[claude_code])"
|
514
|
-
)
|
515
|
-
|
516
|
-
return _stream_claude_code(request)
|
517
|
-
|
518
|
-
|
519
486
|
# --------------------------------------------------------------------------- SSE route
|
520
487
|
async def stream_cc_cli_events(request: ClaudeCodeRequest):
|
521
488
|
if not CLAUDE_CLI:
|
lionagi/version.py
CHANGED
@@ -1 +1 @@
|
|
1
|
-
__version__ = "0.17.
|
1
|
+
__version__ = "0.17.9"
|
@@ -1,11 +1,11 @@
|
|
1
1
|
lionagi/__init__.py,sha256=iS8Y4ZSsP2EPwEsqeodelqdoL1BdiK1bCAYJHak1AUM,2474
|
2
2
|
lionagi/_class_registry.py,sha256=pfUO1DjFZIqr3OwnNMkFqL_fiEBrrf8-swkGmP_KDLE,3112
|
3
3
|
lionagi/_errors.py,sha256=ia_VWhPSyr5FIJLSdPpl04SrNOLI2skN40VC8ePmzeQ,3748
|
4
|
-
lionagi/_types.py,sha256=
|
4
|
+
lionagi/_types.py,sha256=nGtsaSee7FaIZvym3PH8NPaN5PN8QscTgcZfpMNaMEo,1296
|
5
5
|
lionagi/config.py,sha256=yGnzj5D14B2TBhqVeyp1uccvAK6mk4hm0QA8dAEJUeQ,4776
|
6
6
|
lionagi/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
7
7
|
lionagi/utils.py,sha256=yRHKN_v9xRnUa-nYg1lTpCCK2wNDg4pCpicUEIyFwKg,7084
|
8
|
-
lionagi/version.py,sha256=
|
8
|
+
lionagi/version.py,sha256=MY-kSx5QDTHjTQLJRkNa1ih3bsMMiGFMr264PPlSZRY,23
|
9
9
|
lionagi/adapters/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
10
10
|
lionagi/adapters/_utils.py,sha256=sniMG1LDDkwJNzUF2K32jv7rA6Y1QcohgyNclYsptzI,453
|
11
11
|
lionagi/adapters/async_postgres_adapter.py,sha256=2XlxYNPow78dFHIQs8W1oJ2zkVD5Udn3aynMBF9Nf3k,3498
|
@@ -103,7 +103,7 @@ lionagi/protocols/ids.py,sha256=RM40pP_4waMJcfCGmEK_PfS8-k_DuDbC1fG-2Peuf6s,2472
|
|
103
103
|
lionagi/protocols/types.py,sha256=6GJ5ZgDyWl8tckNLXB0z8jbtkordWpgm5r4ht31KVRc,2431
|
104
104
|
lionagi/protocols/action/__init__.py,sha256=5y5joOZzfFWERl75auAcNcKC3lImVJ5ZZGvvHZUFCJM,112
|
105
105
|
lionagi/protocols/action/function_calling.py,sha256=jFy6Ruh3QWkERtBHXqPWVwrOH5aDitEo8oJHZgW5xnI,5066
|
106
|
-
lionagi/protocols/action/manager.py,sha256=
|
106
|
+
lionagi/protocols/action/manager.py,sha256=5RgXj7dbQn0DThrwq4qgZxM9HKAsdA_gIIdKdokAMGE,18692
|
107
107
|
lionagi/protocols/action/tool.py,sha256=_o7rLokD3poupqst6YoQqEC6RvePDueySoVrGK2S538,5850
|
108
108
|
lionagi/protocols/forms/__init__.py,sha256=5y5joOZzfFWERl75auAcNcKC3lImVJ5ZZGvvHZUFCJM,112
|
109
109
|
lionagi/protocols/forms/base.py,sha256=1J8UU2LXm1Lax5McJos0xjZTzMVLYQWd_hwtxI2wSuM,2838
|
@@ -164,7 +164,7 @@ lionagi/service/connections/mcp/__init__.py,sha256=3lzOakDoBWmMaNnT2g-YwktPKa_Wm
|
|
164
164
|
lionagi/service/connections/mcp/wrapper.py,sha256=M7k-XH7x1__SZ0pq7ddnM0_G0t5ZZD3c8O_AbldkSjA,9158
|
165
165
|
lionagi/service/connections/providers/__init__.py,sha256=3lzOakDoBWmMaNnT2g-YwktPKa_Wme4lnPRSmOQfayY,105
|
166
166
|
lionagi/service/connections/providers/anthropic_.py,sha256=vok8mIyFiuV3K83tOjdYfruA6cv1h_57ML6RtpuW-bU,3157
|
167
|
-
lionagi/service/connections/providers/claude_code_cli.py,sha256=
|
167
|
+
lionagi/service/connections/providers/claude_code_cli.py,sha256=XWIF96Ypb3ExfD-wbEggaX0phxu5O_X1OXAdImNyz2g,4448
|
168
168
|
lionagi/service/connections/providers/exa_.py,sha256=kuWD7yyYRqIa4ChSn0TsxFA5V5LwvFUD-w8TZ6mx4rk,1048
|
169
169
|
lionagi/service/connections/providers/nvidia_nim_.py,sha256=95vmo0DSONYBVHkR9SGJ5BiHNKFZNZBrjw4_7ShOXQA,3154
|
170
170
|
lionagi/service/connections/providers/oai_.py,sha256=3x5d6Ei1hKu8Mix0N2V2K21O9dd-2jtAELHhHXj5iHk,6071
|
@@ -180,7 +180,7 @@ lionagi/service/hooks/hooked_event.py,sha256=D_1HtWCH3CriNlmsksi5lerXuF_LV2lbktc
|
|
180
180
|
lionagi/service/third_party/README.md,sha256=qFjWnI8rmLivIyr6Tc-hRZh-rQwntROp76af4MBNJJc,2214
|
181
181
|
lionagi/service/third_party/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
182
182
|
lionagi/service/third_party/anthropic_models.py,sha256=oqSPSlcayYG-fS5BLiLeTtkrpaxgkPhEK_YgneumrOo,4004
|
183
|
-
lionagi/service/third_party/claude_code.py,sha256=
|
183
|
+
lionagi/service/third_party/claude_code.py,sha256=C3EKtEEqN3zto42pJhd7hhqJQt1gtShSDDeTzphUUss,23844
|
184
184
|
lionagi/service/third_party/exa_models.py,sha256=G_hnekcy-DillPLzMoDQ8ZisVAL8Mp7iMAK4xqAT_3w,5470
|
185
185
|
lionagi/service/third_party/openai_model_names.py,sha256=C44tnqexgc4ZU2-3I_sn5d688hf3WWx-25xBd50bvas,5121
|
186
186
|
lionagi/service/third_party/pplx_models.py,sha256=-EhyJgOWR6rzSv3zczUtk80X6c19p18Dg9KC6l8BFRQ,6473
|
@@ -193,7 +193,7 @@ lionagi/tools/base.py,sha256=hEGnE4MD0CM4UqnF0xsDRKB0aM-pyrTFHl8utHhyJLU,1897
|
|
193
193
|
lionagi/tools/types.py,sha256=XtJLY0m-Yi_ZLWhm0KycayvqMCZd--HxfQ0x9vFUYDE,230
|
194
194
|
lionagi/tools/file/__init__.py,sha256=5y5joOZzfFWERl75auAcNcKC3lImVJ5ZZGvvHZUFCJM,112
|
195
195
|
lionagi/tools/file/reader.py,sha256=Q9x1UP7YmBqN53e1kUN68OmIs-D1m9EM9VVbWfM35js,9658
|
196
|
-
lionagi-0.17.
|
197
|
-
lionagi-0.17.
|
198
|
-
lionagi-0.17.
|
199
|
-
lionagi-0.17.
|
196
|
+
lionagi-0.17.9.dist-info/METADATA,sha256=0v_5cWnPYJKWZwBEceY9UNdFncXb3Bfs1gg60CF8gjE,23448
|
197
|
+
lionagi-0.17.9.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
198
|
+
lionagi-0.17.9.dist-info/licenses/LICENSE,sha256=VXFWsdoN5AAknBCgFqQNgPWYx7OPp-PFEP961zGdOjc,11288
|
199
|
+
lionagi-0.17.9.dist-info/RECORD,,
|
File without changes
|
File without changes
|