agstack 1.22.0__tar.gz → 1.22.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.
Files changed (77) hide show
  1. {agstack-1.22.0 → agstack-1.22.1}/PKG-INFO +1 -1
  2. {agstack-1.22.0 → agstack-1.22.1}/agstack/llm/flow/event.py +4 -4
  3. {agstack-1.22.0 → agstack-1.22.1}/agstack/llm/flow/flow.py +12 -8
  4. {agstack-1.22.0 → agstack-1.22.1}/agstack/llm/flow/nodes/agent_node.py +4 -2
  5. {agstack-1.22.0 → agstack-1.22.1}/agstack/llm/flow/nodes/base.py +4 -2
  6. {agstack-1.22.0 → agstack-1.22.1}/agstack/llm/flow/nodes/echo_node.py +3 -2
  7. {agstack-1.22.0 → agstack-1.22.1}/agstack/llm/flow/nodes/llm_chat_node.py +6 -4
  8. {agstack-1.22.0 → agstack-1.22.1}/agstack.egg-info/PKG-INFO +1 -1
  9. {agstack-1.22.0 → agstack-1.22.1}/pyproject.toml +1 -1
  10. {agstack-1.22.0 → agstack-1.22.1}/LICENSE +0 -0
  11. {agstack-1.22.0 → agstack-1.22.1}/README.md +0 -0
  12. {agstack-1.22.0 → agstack-1.22.1}/agstack/__init__.py +0 -0
  13. {agstack-1.22.0 → agstack-1.22.1}/agstack/cache/__init__.py +0 -0
  14. {agstack-1.22.0 → agstack-1.22.1}/agstack/cache/base.py +0 -0
  15. {agstack-1.22.0 → agstack-1.22.1}/agstack/cache/memory.py +0 -0
  16. {agstack-1.22.0 → agstack-1.22.1}/agstack/cache/redis.py +0 -0
  17. {agstack-1.22.0 → agstack-1.22.1}/agstack/config/__init__.py +0 -0
  18. {agstack-1.22.0 → agstack-1.22.1}/agstack/config/logger.py +0 -0
  19. {agstack-1.22.0 → agstack-1.22.1}/agstack/config/manager.py +0 -0
  20. {agstack-1.22.0 → agstack-1.22.1}/agstack/config/types.py +0 -0
  21. {agstack-1.22.0 → agstack-1.22.1}/agstack/contexts.py +0 -0
  22. {agstack-1.22.0 → agstack-1.22.1}/agstack/decorators.py +0 -0
  23. {agstack-1.22.0 → agstack-1.22.1}/agstack/events.py +0 -0
  24. {agstack-1.22.0 → agstack-1.22.1}/agstack/exceptions.py +0 -0
  25. {agstack-1.22.0 → agstack-1.22.1}/agstack/fastapi/__init__.py +0 -0
  26. {agstack-1.22.0 → agstack-1.22.1}/agstack/fastapi/exception.py +0 -0
  27. {agstack-1.22.0 → agstack-1.22.1}/agstack/fastapi/middleware.py +0 -0
  28. {agstack-1.22.0 → agstack-1.22.1}/agstack/fastapi/offline.py +0 -0
  29. {agstack-1.22.0 → agstack-1.22.1}/agstack/fastapi/sse.py +0 -0
  30. {agstack-1.22.0 → agstack-1.22.1}/agstack/infra/db/__init__.py +0 -0
  31. {agstack-1.22.0 → agstack-1.22.1}/agstack/infra/es/__init__.py +0 -0
  32. {agstack-1.22.0 → agstack-1.22.1}/agstack/infra/kg/__init__.py +0 -0
  33. {agstack-1.22.0 → agstack-1.22.1}/agstack/infra/mq/__init__.py +0 -0
  34. {agstack-1.22.0 → agstack-1.22.1}/agstack/llm/__init__.py +0 -0
  35. {agstack-1.22.0 → agstack-1.22.1}/agstack/llm/client.py +0 -0
  36. {agstack-1.22.0 → agstack-1.22.1}/agstack/llm/flow/__init__.py +0 -0
  37. {agstack-1.22.0 → agstack-1.22.1}/agstack/llm/flow/agent.py +0 -0
  38. {agstack-1.22.0 → agstack-1.22.1}/agstack/llm/flow/context.py +0 -0
  39. {agstack-1.22.0 → agstack-1.22.1}/agstack/llm/flow/exceptions.py +0 -0
  40. {agstack-1.22.0 → agstack-1.22.1}/agstack/llm/flow/factory.py +0 -0
  41. {agstack-1.22.0 → agstack-1.22.1}/agstack/llm/flow/loader.py +0 -0
  42. {agstack-1.22.0 → agstack-1.22.1}/agstack/llm/flow/nodes/__init__.py +0 -0
  43. {agstack-1.22.0 → agstack-1.22.1}/agstack/llm/flow/nodes/detect_node.py +0 -0
  44. {agstack-1.22.0 → agstack-1.22.1}/agstack/llm/flow/nodes/llm_embed_node.py +0 -0
  45. {agstack-1.22.0 → agstack-1.22.1}/agstack/llm/flow/nodes/llm_rerank_node.py +0 -0
  46. {agstack-1.22.0 → agstack-1.22.1}/agstack/llm/flow/nodes/python_node.py +0 -0
  47. {agstack-1.22.0 → agstack-1.22.1}/agstack/llm/flow/nodes/subflow_node.py +0 -0
  48. {agstack-1.22.0 → agstack-1.22.1}/agstack/llm/flow/nodes/switch_node.py +0 -0
  49. {agstack-1.22.0 → agstack-1.22.1}/agstack/llm/flow/nodes/tool_node.py +0 -0
  50. {agstack-1.22.0 → agstack-1.22.1}/agstack/llm/flow/records.py +0 -0
  51. {agstack-1.22.0 → agstack-1.22.1}/agstack/llm/flow/registry.py +0 -0
  52. {agstack-1.22.0 → agstack-1.22.1}/agstack/llm/flow/sandbox.py +0 -0
  53. {agstack-1.22.0 → agstack-1.22.1}/agstack/llm/flow/state.py +0 -0
  54. {agstack-1.22.0 → agstack-1.22.1}/agstack/llm/flow/tool.py +0 -0
  55. {agstack-1.22.0 → agstack-1.22.1}/agstack/llm/flow/trace.py +0 -0
  56. {agstack-1.22.0 → agstack-1.22.1}/agstack/llm/prompts.py +0 -0
  57. {agstack-1.22.0 → agstack-1.22.1}/agstack/llm/token.py +0 -0
  58. {agstack-1.22.0 → agstack-1.22.1}/agstack/messagebus/__init__.py +0 -0
  59. {agstack-1.22.0 → agstack-1.22.1}/agstack/messagebus/base.py +0 -0
  60. {agstack-1.22.0 → agstack-1.22.1}/agstack/messagebus/memory.py +0 -0
  61. {agstack-1.22.0 → agstack-1.22.1}/agstack/messagebus/redis.py +0 -0
  62. {agstack-1.22.0 → agstack-1.22.1}/agstack/schema.py +0 -0
  63. {agstack-1.22.0 → agstack-1.22.1}/agstack/security/__init__.py +0 -0
  64. {agstack-1.22.0 → agstack-1.22.1}/agstack/security/casbin.py +0 -0
  65. {agstack-1.22.0 → agstack-1.22.1}/agstack/security/crypt.py +0 -0
  66. {agstack-1.22.0 → agstack-1.22.1}/agstack/status.py +0 -0
  67. {agstack-1.22.0 → agstack-1.22.1}/agstack.egg-info/SOURCES.txt +0 -0
  68. {agstack-1.22.0 → agstack-1.22.1}/agstack.egg-info/dependency_links.txt +0 -0
  69. {agstack-1.22.0 → agstack-1.22.1}/agstack.egg-info/requires.txt +0 -0
  70. {agstack-1.22.0 → agstack-1.22.1}/agstack.egg-info/top_level.txt +0 -0
  71. {agstack-1.22.0 → agstack-1.22.1}/setup.cfg +0 -0
  72. {agstack-1.22.0 → agstack-1.22.1}/tests/test_cache_memory.py +0 -0
  73. {agstack-1.22.0 → agstack-1.22.1}/tests/test_cache_redis.py +0 -0
  74. {agstack-1.22.0 → agstack-1.22.1}/tests/test_flow_io.py +0 -0
  75. {agstack-1.22.0 → agstack-1.22.1}/tests/test_flow_switch_subflow.py +0 -0
  76. {agstack-1.22.0 → agstack-1.22.1}/tests/test_messagebus_memory.py +0 -0
  77. {agstack-1.22.0 → agstack-1.22.1}/tests/test_messagebus_redis.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agstack
3
- Version: 1.22.0
3
+ Version: 1.22.1
4
4
  Summary: Production-ready toolkit for building FastAPI and LLM applications
5
5
  Author-email: XtraVisions <gitadmin@xtravisions.com>, Chen Hao <chenhao@xtravisions.com>
6
6
  Maintainer-email: XtraVisions <gitadmin@xtravisions.com>, Chen Hao <chenhao@xtravisions.com>
@@ -97,12 +97,12 @@ def run_error(*, message: str, code: str | None = None) -> dict[str, Any]:
97
97
  # ── Step ──
98
98
 
99
99
 
100
- def step_started(*, step_name: str) -> dict[str, Any]:
101
- return _ev(EventType.STEP_STARTED, step_name=step_name)
100
+ def step_started(*, step_name: str, step_id: str | None = None) -> dict[str, Any]:
101
+ return _ev(EventType.STEP_STARTED, step_name=step_name, step_id=step_id or str(uuid4()))
102
102
 
103
103
 
104
- def step_finished(*, step_name: str) -> dict[str, Any]:
105
- return _ev(EventType.STEP_FINISHED, step_name=step_name)
104
+ def step_finished(*, step_name: str, step_id: str) -> dict[str, Any]:
105
+ return _ev(EventType.STEP_FINISHED, step_name=step_name, step_id=step_id)
106
106
 
107
107
 
108
108
  # ── State ──
@@ -370,7 +370,8 @@ class Flow:
370
370
  async def stream(self, context: "FlowContext") -> AsyncIterator[dict[str, Any]]:
371
371
  """流式执行 Flow(输出 AG-UI 标准事件)"""
372
372
  context.trace.started_at = time.time()
373
- yield event.step_started(step_name=f"flow:{self.name}")
373
+ flow_sid = str(uuid4())
374
+ yield event.step_started(step_name=f"flow:{self.name}", step_id=flow_sid)
374
375
 
375
376
  try:
376
377
  if not self.edges:
@@ -386,7 +387,7 @@ class Flow:
386
387
  context.trace.finished_at = time.time()
387
388
  context.trace.total_usage = context.usage
388
389
 
389
- yield event.step_finished(step_name=f"flow:{self.name}")
390
+ yield event.step_finished(step_name=f"flow:{self.name}", step_id=flow_sid)
390
391
 
391
392
  async def _stream_sequential(self, context: "FlowContext") -> AsyncIterator[dict[str, Any]]:
392
393
  """顺序流式执行"""
@@ -437,7 +438,8 @@ class Flow:
437
438
  context.trace.record_node_start(current_node_id, "message", inputs=msg_config)
438
439
 
439
440
  # message 节点增加 STEP 事件
440
- step_evt = event.step_started(step_name=f"message:{current_node_id}")
441
+ msg_sid = str(uuid4())
442
+ step_evt = event.step_started(step_name=f"message:{current_node_id}", step_id=msg_sid)
441
443
  step_evt["_node_id"] = current_node_id
442
444
  step_evt["_label"] = msg_config.get("label")
443
445
  step_evt["_echo"] = msg_config.get("echo", True)
@@ -454,7 +456,7 @@ class Flow:
454
456
  text = template.format_map(_SafeFormatDict(context.variables))
455
457
  context.set_output(current_node_id, {"result": text})
456
458
 
457
- fin_evt = event.step_finished(step_name=f"message:{current_node_id}")
459
+ fin_evt = event.step_finished(step_name=f"message:{current_node_id}", step_id=msg_sid)
458
460
  fin_evt["_node_id"] = current_node_id
459
461
  fin_evt["_label"] = msg_config.get("label")
460
462
  fin_evt["_echo"] = msg_config.get("echo", True)
@@ -469,7 +471,8 @@ class Flow:
469
471
 
470
472
  context.trace.record_node_start(current_node_id, "parallel", inputs=config)
471
473
 
472
- step_evt = event.step_started(step_name=f"parallel:{current_node_id}")
474
+ parallel_sid = str(uuid4())
475
+ step_evt = event.step_started(step_name=f"parallel:{current_node_id}", step_id=parallel_sid)
473
476
  step_evt["_node_id"] = current_node_id
474
477
  step_evt["_label"] = None
475
478
  step_evt["_echo"] = False
@@ -510,7 +513,7 @@ class Flow:
510
513
  merged.update(branch_result)
511
514
  context.set_output(current_node_id, merged)
512
515
 
513
- fin_evt = event.step_finished(step_name=f"parallel:{current_node_id}")
516
+ fin_evt = event.step_finished(step_name=f"parallel:{current_node_id}", step_id=parallel_sid)
514
517
  fin_evt["_node_id"] = current_node_id
515
518
  fin_evt["_label"] = None
516
519
  fin_evt["_echo"] = False
@@ -533,7 +536,8 @@ class Flow:
533
536
 
534
537
  context.trace.record_node_start(current_node_id, "iteration", inputs=config)
535
538
 
536
- step_evt = event.step_started(step_name=f"iteration:{current_node_id}")
539
+ iter_sid = str(uuid4())
540
+ step_evt = event.step_started(step_name=f"iteration:{current_node_id}", step_id=iter_sid)
537
541
  step_evt["_node_id"] = current_node_id
538
542
  step_evt["_label"] = None
539
543
  step_evt["_echo"] = False
@@ -574,7 +578,7 @@ class Flow:
574
578
  iteration_output = {"results": results}
575
579
  context.set_output(current_node_id, iteration_output)
576
580
 
577
- fin_evt = event.step_finished(step_name=f"iteration:{current_node_id}")
581
+ fin_evt = event.step_finished(step_name=f"iteration:{current_node_id}", step_id=iter_sid)
578
582
  fin_evt["_node_id"] = current_node_id
579
583
  fin_evt["_label"] = None
580
584
  fin_evt["_echo"] = False
@@ -3,6 +3,7 @@
3
3
  """Agent 节点处理器 — 从 flow.py 提取"""
4
4
 
5
5
  from typing import TYPE_CHECKING, Any, AsyncIterator
6
+ from uuid import uuid4
6
7
 
7
8
  from .. import event
8
9
  from ..exceptions import FlowError
@@ -46,8 +47,9 @@ class AgentNodeHandler(NodeHandler):
46
47
  async def stream(self, node: dict, context: "FlowContext", node_id: str) -> AsyncIterator[dict[str, Any]]:
47
48
  config = node.get("config", {})
48
49
  step_name = self.get_step_name(node, node_id)
50
+ sid = str(uuid4())
49
51
 
50
- yield event.step_started(step_name=step_name)
52
+ yield event.step_started(step_name=step_name, step_id=sid)
51
53
  resolved = self.resolve_inputs(config, context)
52
54
  ag = self._create_agent(config, context)
53
55
  async for evt in ag.stream(context, inputs=resolved):
@@ -63,4 +65,4 @@ class AgentNodeHandler(NodeHandler):
63
65
  tool_calls = context.pop_execution_records()
64
66
  context.set_variable("_last_node_tool_calls", tool_calls)
65
67
 
66
- yield event.step_finished(step_name=step_name)
68
+ yield event.step_finished(step_name=step_name, step_id=sid)
@@ -3,6 +3,7 @@
3
3
  """NodeHandler 基类 — 所有执行类节点的公共接口"""
4
4
 
5
5
  from typing import TYPE_CHECKING, Any, AsyncIterator
6
+ from uuid import uuid4
6
7
 
7
8
  from .. import event
8
9
 
@@ -45,7 +46,8 @@ class NodeHandler:
45
46
  需要流式输出的节点(如 agent, llm_chat)应覆盖此方法。
46
47
  """
47
48
  step_name = self.get_step_name(node, node_id)
48
- yield event.step_started(step_name=step_name)
49
+ sid = str(uuid4())
50
+ yield event.step_started(step_name=step_name, step_id=sid)
49
51
  result = await self.execute(node, context)
50
52
  context.set_output(node_id, result)
51
- yield event.step_finished(step_name=step_name)
53
+ yield event.step_finished(step_name=step_name, step_id=sid)
@@ -32,8 +32,9 @@ class EchoNodeHandler(NodeHandler):
32
32
  async def stream(self, node: dict, context: "FlowContext", node_id: str) -> AsyncIterator[dict[str, Any]]:
33
33
  config = node.get("config", {})
34
34
  step_name = self.get_step_name(node, node_id)
35
+ sid = str(uuid4())
35
36
 
36
- yield event.step_started(step_name=step_name)
37
+ yield event.step_started(step_name=step_name, step_id=sid)
37
38
 
38
39
  resolved = self.resolve_inputs(config, context)
39
40
  content = resolved.get("content", "")
@@ -51,4 +52,4 @@ class EchoNodeHandler(NodeHandler):
51
52
  yield event.text_message_end(message_id=msg_id)
52
53
 
53
54
  context.set_output(node_id, {"result": content})
54
- yield event.step_finished(step_name=step_name)
55
+ yield event.step_finished(step_name=step_name, step_id=sid)
@@ -92,15 +92,17 @@ class LLMChatNodeHandler(NodeHandler):
92
92
  if not use_stream:
93
93
  # 非流式:走默认 execute 路径
94
94
  step_name = self.get_step_name(node, node_id)
95
- yield event.step_started(step_name=step_name)
95
+ sid = str(uuid4())
96
+ yield event.step_started(step_name=step_name, step_id=sid)
96
97
  result = await self.execute(node, context)
97
98
  context.set_output(node_id, result)
98
- yield event.step_finished(step_name=step_name)
99
+ yield event.step_finished(step_name=step_name, step_id=sid)
99
100
  return
100
101
 
101
102
  # 流式输出
102
103
  step_name = self.get_step_name(node, node_id)
103
- yield event.step_started(step_name=step_name)
104
+ sid = str(uuid4())
105
+ yield event.step_started(step_name=step_name, step_id=sid)
104
106
 
105
107
  resolved_inputs = self.resolve_inputs(config, context)
106
108
  prompt_text = self._build_prompt(config.get("prompt", ""), resolved_inputs)
@@ -153,4 +155,4 @@ class LLMChatNodeHandler(NodeHandler):
153
155
  result_text = "".join(content_parts)
154
156
  context.set_output(node_id, {"result": result_text})
155
157
 
156
- yield event.step_finished(step_name=step_name)
158
+ yield event.step_finished(step_name=step_name, step_id=sid)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agstack
3
- Version: 1.22.0
3
+ Version: 1.22.1
4
4
  Summary: Production-ready toolkit for building FastAPI and LLM applications
5
5
  Author-email: XtraVisions <gitadmin@xtravisions.com>, Chen Hao <chenhao@xtravisions.com>
6
6
  Maintainer-email: XtraVisions <gitadmin@xtravisions.com>, Chen Hao <chenhao@xtravisions.com>
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "agstack"
3
- version = "1.22.0"
3
+ version = "1.22.1"
4
4
  description = "Production-ready toolkit for building FastAPI and LLM applications"
5
5
  readme = "README.md"
6
6
  license = "MIT"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes