jaf-py 2.6.5__py3-none-any.whl → 2.6.7__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.
jaf/__init__.py CHANGED
@@ -201,7 +201,7 @@ def generate_run_id() -> RunId:
201
201
  return create_run_id(str(uuid.uuid4()))
202
202
 
203
203
 
204
- __version__ = "2.6.5"
204
+ __version__ = "2.6.7"
205
205
  __all__ = [
206
206
  # Core types and functions
207
207
  "TraceId",
jaf/core/agent_tool.py CHANGED
@@ -78,6 +78,7 @@ def create_agent_tool(
78
78
  metadata: Optional[Dict[str, Any]] = None,
79
79
  timeout: Optional[float] = None,
80
80
  preserve_session: bool = False,
81
+ preserve_session_id: bool = False,
81
82
  ) -> Tool[AgentToolInput, Ctx]:
82
83
  """
83
84
  Create a tool from an agent.
@@ -91,6 +92,10 @@ def create_agent_tool(
91
92
  is_enabled: Whether the tool is enabled (bool, sync function, or async function)
92
93
  metadata: Optional metadata for the tool
93
94
  timeout: Optional timeout for tool execution
95
+ preserve_session: When True, inherit parent's conversation_id AND memory (shared session)
96
+ preserve_session_id: When True, inherit ONLY parent's conversation_id for tracing (no memory).
97
+ This allows subagent traces to appear together in Langfuse without
98
+ loading previous invocation history. Mutually exclusive with preserve_session.
94
99
 
95
100
  Returns:
96
101
  A Tool that wraps the agent execution
@@ -242,6 +247,24 @@ def create_agent_tool(
242
247
  subagent_model_override = parent_config.model_override
243
248
  subagent_model_provider = parent_config.model_provider
244
249
 
250
+ # Determine conversation_id and memory inheritance based on session preservation settings:
251
+ # - preserve_session=True: inherit both conversation_id AND memory (full shared session)
252
+ # - preserve_session_id=True: inherit ONLY conversation_id for tracing (no memory, stateless calls)
253
+ # - Both False: completely ephemeral sub-agent run
254
+ #
255
+ # preserve_session_id is useful when you want:
256
+ # 1. Subagent traces to appear together in Langfuse under the same conversation
257
+ # 2. But each subagent invocation to be stateless (no accumulated history from previous calls)
258
+ if preserve_session:
259
+ subagent_memory = parent_config.memory
260
+ subagent_conversation_id = parent_config.conversation_id
261
+ elif preserve_session_id:
262
+ subagent_memory = None # No memory inheritance - stateless
263
+ subagent_conversation_id = parent_config.conversation_id # Only for tracing
264
+ else:
265
+ subagent_memory = None
266
+ subagent_conversation_id = None
267
+
245
268
  sub_config = RunConfig(
246
269
  agent_registry={agent.name: agent, **parent_config.agent_registry},
247
270
  model_provider=subagent_model_provider,
@@ -252,8 +275,8 @@ def create_agent_tool(
252
275
  on_event=parent_config.on_event,
253
276
  before_llm_call=parent_config.before_llm_call,
254
277
  after_llm_call=parent_config.after_llm_call,
255
- memory=parent_config.memory if preserve_session else None,
256
- conversation_id=parent_config.conversation_id if preserve_session else None,
278
+ memory=subagent_memory,
279
+ conversation_id=subagent_conversation_id,
257
280
  default_tool_timeout=parent_config.default_tool_timeout,
258
281
  prefer_streaming=parent_config.prefer_streaming,
259
282
  )
jaf/core/tracing.py CHANGED
@@ -469,7 +469,7 @@ class LangfuseTraceCollector:
469
469
  public_key=public_key,
470
470
  secret_key=secret_key,
471
471
  host=host,
472
- release="jaf-py-v2.6.5",
472
+ release="jaf-py-v2.6.7",
473
473
  httpx_client=client,
474
474
  )
475
475
  self._httpx_client = client
jaf/core/types.py CHANGED
@@ -428,6 +428,7 @@ class Agent(Generic[Ctx, Out]):
428
428
  metadata: Optional[Dict[str, Any]] = None,
429
429
  timeout: Optional[float] = None,
430
430
  preserve_session: bool = False,
431
+ preserve_session_id: bool = False,
431
432
  ) -> Tool[Any, Ctx]:
432
433
  """
433
434
  Convert this agent into a tool that can be used by other agents.
@@ -440,6 +441,11 @@ class Agent(Generic[Ctx, Out]):
440
441
  is_enabled: Whether the tool is enabled (bool, sync function, or async function)
441
442
  metadata: Optional metadata for the tool
442
443
  timeout: Optional timeout for the tool execution
444
+ preserve_session: When True, inherit parent's conversation_id AND memory (shared session)
445
+ preserve_session_id: When True, inherit ONLY parent's conversation_id for tracing (no memory).
446
+ This allows subagent traces to appear together in Langfuse without
447
+ loading previous invocation history. Useful for stateless subagent calls
448
+ that should still be grouped together in traces.
443
449
 
444
450
  Returns:
445
451
  A Tool that wraps this agent's execution
@@ -456,6 +462,7 @@ class Agent(Generic[Ctx, Out]):
456
462
  metadata=metadata,
457
463
  timeout=timeout,
458
464
  preserve_session=preserve_session,
465
+ preserve_session_id=preserve_session_id,
459
466
  )
460
467
 
461
468
 
jaf/providers/model.py CHANGED
@@ -378,6 +378,10 @@ def make_litellm_provider(
378
378
  # Prepare request parameters
379
379
  request_params = {"model": model_name, "messages": messages, "stream": False}
380
380
 
381
+ # Add session_id from conversation_id for LiteLLM tracking
382
+ if config.conversation_id:
383
+ request_params["extra_body"] = {"session_id": config.conversation_id}
384
+
381
385
  # Add optional parameters
382
386
  if agent.model_config:
383
387
  if agent.model_config.temperature is not None:
@@ -620,6 +624,10 @@ def make_litellm_provider(
620
624
  "messages": messages,
621
625
  }
622
626
 
627
+ # Add session_id from conversation_id for LiteLLM tracking
628
+ if config.conversation_id:
629
+ request_params["extra_body"] = {"session_id": config.conversation_id}
630
+
623
631
  # Add optional parameters
624
632
  if agent.model_config:
625
633
  if agent.model_config.temperature is not None:
@@ -827,6 +835,10 @@ def make_litellm_sdk_provider(
827
835
  # Prepare request parameters for LiteLLM
828
836
  request_params = {"model": model_name, "messages": messages, **self.litellm_kwargs}
829
837
 
838
+ # Add session_id from conversation_id for LiteLLM tracking
839
+ if config.conversation_id:
840
+ request_params["session_id"] = config.conversation_id
841
+
830
842
  # Add API key if provided
831
843
  if self.api_key:
832
844
  request_params["api_key"] = self.api_key
@@ -1007,6 +1019,10 @@ def make_litellm_sdk_provider(
1007
1019
  **self.litellm_kwargs,
1008
1020
  }
1009
1021
 
1022
+ # Add session_id from conversation_id for LiteLLM tracking
1023
+ if config.conversation_id:
1024
+ request_params["session_id"] = config.conversation_id
1025
+
1010
1026
  # Add API key if provided
1011
1027
  if self.api_key:
1012
1028
  request_params["api_key"] = self.api_key
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: jaf-py
3
- Version: 2.6.5
3
+ Version: 2.6.7
4
4
  Summary: A purely functional agent framework with immutable state and composable tools - Python implementation
5
5
  Author: JAF Contributors
6
6
  Maintainer: JAF Contributors
@@ -82,7 +82,7 @@ Dynamic: license-file
82
82
 
83
83
  <!-- ![JAF Banner](docs/cover.png) -->
84
84
 
85
- [![Version](https://img.shields.io/badge/version-2.6.5-blue.svg)](https://github.com/xynehq/jaf-py)
85
+ [![Version](https://img.shields.io/badge/version-2.6.7-blue.svg)](https://github.com/xynehq/jaf-py)
86
86
  [![Python](https://img.shields.io/badge/python-3.10%2B-blue.svg)](https://www.python.org/)
87
87
  [![Docs](https://img.shields.io/badge/Docs-Live-brightgreen)](https://xynehq.github.io/jaf-py/)
88
88
 
@@ -1,4 +1,4 @@
1
- jaf/__init__.py,sha256=clE4UWW2Y5bty2ataCPqnL__bVP8HGO1EBIR1VYI9ZU,8652
1
+ jaf/__init__.py,sha256=nkcZREAFiazg-N4BdAZAWvirwc574BX7FtM4XasfpTM,8652
2
2
  jaf/cli.py,sha256=EDMMA5uX0e3TUIedLdyP3p4Qy-aXADvpht3VgJPJagU,8299
3
3
  jaf/exceptions.py,sha256=FdLIw7bdCNtBYfqRyJBkRT4Z1vWuvkzrMqFiMAzjL8Y,9158
4
4
  jaf/a2a/__init__.py,sha256=r4W-WHZNjoxR8EQ0x41_rY3fl12OH5qcSn0KycXaKKU,7752
@@ -39,7 +39,7 @@ jaf/a2a/tests/test_integration.py,sha256=hfGAtwXOfV9OXrFgS94twMbzxMQ4Vfj0KYoNT5V
39
39
  jaf/a2a/tests/test_protocol.py,sha256=3Ov9fTqznDqJLg8PqY2oy9I2Tpvwv_N0aN-rpFpAmjM,22215
40
40
  jaf/a2a/tests/test_types.py,sha256=rSUhZmOQcFrgNiEg4hDCZwypj19h6mSamVapWkrzZWc,17329
41
41
  jaf/core/__init__.py,sha256=4IqKRspv8gvgAtbmvaMvUgYZB1fSIy3vsyCXkjF8PjU,2013
42
- jaf/core/agent_tool.py,sha256=bwYQtRK9YfwPM_3s2kjp3Vl-6vR64jUlOnviqM0Z5tM,15411
42
+ jaf/core/agent_tool.py,sha256=l8Dr8-BexrmO3T6o5AymqQbD-nzmF9yP_jyHrSqSDL0,16848
43
43
  jaf/core/analytics.py,sha256=ypdhllyOThXZB-TY_eR1t1n2qrnAVN7Ljb8PaOtJft0,23267
44
44
  jaf/core/checkpoint.py,sha256=O7mfi7gFOAUgJ3zHzgJsr11uzn-BU-Vj1iKyKjcirMk,8398
45
45
  jaf/core/composition.py,sha256=Tj0-FRTVWygmAfsBLld7pnZK4nrGMMBx2YYJW_KQPoo,25393
@@ -56,8 +56,8 @@ jaf/core/state.py,sha256=fdWDc2DQ-o_g_8E4ibg2QM0Vad_XUique3a5iYBwGZo,9516
56
56
  jaf/core/streaming.py,sha256=5ntOtJrZVCHuGsygquyCLG2J5yuSxE6DN5OM-BrQiGw,16818
57
57
  jaf/core/tool_results.py,sha256=L9U3JDQAjAH5YR7iMpSxfVky2Nxo6FYQs4WE05RATaQ,11283
58
58
  jaf/core/tools.py,sha256=rHxzAfGVGpYk3YJKmrq3AQLW0oE3ACkiJBOwle2bLdc,15146
59
- jaf/core/tracing.py,sha256=p5C7l0X1Is3cNjsINiEsUv01rnUFz9Z0lh4DFWRXsUE,59360
60
- jaf/core/types.py,sha256=lJXlkL55devvzbc5efT5FdQ_LX3JcsMWA10Hy8Cd5Qs,37015
59
+ jaf/core/tracing.py,sha256=pRenMT87-PlHWNSsuH7gcW6sD7zv-XnOqRkMCk2XQ1s,59360
60
+ jaf/core/types.py,sha256=u93jroIe1fFbRBNpOTBrc3exWrjjvetxsjTtu3jTtVA,37605
61
61
  jaf/core/workflows.py,sha256=0825AoD1QwEiGAs5IRlWHmaKrjurx6xF7oDJR6POBsg,25651
62
62
  jaf/memory/__init__.py,sha256=YfANOg5vUFSPVG7gpBE4_lYkV5X3_U6Yj9v1_QexfN0,1396
63
63
  jaf/memory/approval_storage.py,sha256=DcwtERcoIMH7B-abK9hqND3Moz4zSETsPlgJNkvqcaM,10573
@@ -75,7 +75,7 @@ jaf/policies/handoff.py,sha256=3lPegkSV_2LUf6jEZnj68_g3XUGFB_Fsj1C_6Svr2Kg,8128
75
75
  jaf/policies/validation.py,sha256=-zhB5ysH0Y4JnstHzo3I8tt-PFB9FSHBwSUALITBxw4,11016
76
76
  jaf/providers/__init__.py,sha256=PfIQkCtXb_yiTEjqs5msGv5-a6De2ujFCEaDGJEe_TQ,2100
77
77
  jaf/providers/mcp.py,sha256=fGfrlYx5g7ZX1fBUkPmAYSePKrCc4pG_HKngV_QCdRU,13148
78
- jaf/providers/model.py,sha256=FCnenKOLwh5JJ8hcXy7pemJb32EO0uvoww5ZTqd4mlE,58619
78
+ jaf/providers/model.py,sha256=LmZMEozLP3EpnESD5Bhgf31427jEVVzA-dCbkaBK8lM,59387
79
79
  jaf/server/__init__.py,sha256=cYqdruJCJ3W1AMmmxMjAnDlj9gh3XbHhtegjq4nYRNY,391
80
80
  jaf/server/main.py,sha256=usdCRZfDP3GWQchh1o2tHd4KqTTFyQQCD9w4khd9rSo,2113
81
81
  jaf/server/server.py,sha256=ZhZ2gmY10eQNaKUlE7ecMkrwMkYkAh-QgKdUJ2q7ktM,51532
@@ -89,9 +89,9 @@ jaf/visualization/functional_core.py,sha256=0Xs2R8ELADKNIgokcbjuxmWwxEyCH1yXIEdG
89
89
  jaf/visualization/graphviz.py,sha256=EwWVIRv8Z7gTiO5Spvcm-z_UUQ1oWNPRgdE33ZzFwx8,11569
90
90
  jaf/visualization/imperative_shell.py,sha256=N5lWzOLMIU_iCoy3n5WCg49eec8VxV8f7JIG6_wNtVw,2506
91
91
  jaf/visualization/types.py,sha256=90G8oClsFa_APqTuMrTW6KjD0oG9I4kVur773dXNW0E,1393
92
- jaf_py-2.6.5.dist-info/licenses/LICENSE,sha256=LXUQBJxdyr-7C4bk9cQBwvsF_xwA-UVstDTKabpcjlI,1063
93
- jaf_py-2.6.5.dist-info/METADATA,sha256=sacV8SfppPc9buMj-yoaNvDqrtF7S-k9P51zRZqp6ls,27743
94
- jaf_py-2.6.5.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
95
- jaf_py-2.6.5.dist-info/entry_points.txt,sha256=OtIJeNJpb24kgGrqRx9szGgDx1vL9ayq8uHErmu7U5w,41
96
- jaf_py-2.6.5.dist-info/top_level.txt,sha256=Xu1RZbGaM4_yQX7bpalo881hg7N_dybaOW282F15ruE,4
97
- jaf_py-2.6.5.dist-info/RECORD,,
92
+ jaf_py-2.6.7.dist-info/licenses/LICENSE,sha256=LXUQBJxdyr-7C4bk9cQBwvsF_xwA-UVstDTKabpcjlI,1063
93
+ jaf_py-2.6.7.dist-info/METADATA,sha256=ZBxUFxg-O8CN9xh_WtdDJsOfwduKX9GoEoSCVMq8mIY,27743
94
+ jaf_py-2.6.7.dist-info/WHEEL,sha256=qELbo2s1Yzl39ZmrAibXA2jjPLUYfnVhUNTlyF1rq0Y,92
95
+ jaf_py-2.6.7.dist-info/entry_points.txt,sha256=OtIJeNJpb24kgGrqRx9szGgDx1vL9ayq8uHErmu7U5w,41
96
+ jaf_py-2.6.7.dist-info/top_level.txt,sha256=Xu1RZbGaM4_yQX7bpalo881hg7N_dybaOW282F15ruE,4
97
+ jaf_py-2.6.7.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.9.0)
2
+ Generator: setuptools (80.10.1)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5