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 CHANGED
@@ -1,3 +1,5 @@
1
+ """lionagi type definitions."""
2
+
1
3
  # Lazy loading for heavy type imports to improve startup performance
2
4
  _lazy_type_imports = {}
3
5
 
@@ -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 = {qualified_name: config_with_metadata}
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(qualified_name)
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 = {qualified_name: config_with_metadata}
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(qualified_name)
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.create(messages=messages, **req_dict)
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.8"
1
+ __version__ = "0.17.9"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: lionagi
3
- Version: 0.17.8
3
+ Version: 0.17.9
4
4
  Summary: An Intelligence Operating System.
5
5
  Author-email: HaiyangLi <quantocean.li@gmail.com>
6
6
  License: Apache License
@@ -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=COWRrmstmABGKKn-h_cKiAREGsMp_Ik49OdR4lSS3P8,1263
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=H2Y9686JbmOVItv-s7YNC6eYseSRZPwHCIXOoDgBIEM,23
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=akq3HuLUuTRkm7ENmn8oycNH-4ksfekXOwOJky5OBrE,18835
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=kqEOnCUOOh2O_3NGi6W7r-gdLsbW-Jcp11tm30VEv4Q,4455
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=wRqNBSy4kc-pHkuntNJnstyqOVdSKK9NV1s2x3Ia704,24794
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.8.dist-info/METADATA,sha256=d_5YV53ajCQjD7HDhICy31gl4NjaJlDCt2n6pXHF4wg,23448
197
- lionagi-0.17.8.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
198
- lionagi-0.17.8.dist-info/licenses/LICENSE,sha256=VXFWsdoN5AAknBCgFqQNgPWYx7OPp-PFEP961zGdOjc,11288
199
- lionagi-0.17.8.dist-info/RECORD,,
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,,