aiqtoolkit 1.1.0rc3__py3-none-any.whl → 1.1.0rc5__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.

Potentially problematic release.


This version of aiqtoolkit might be problematic. Click here for more details.

aiq/builder/context.py CHANGED
@@ -68,6 +68,8 @@ class AIQContextState(metaclass=Singleton):
68
68
  self.active_function: ContextVar[InvocationNode] = ContextVar("active_function",
69
69
  default=InvocationNode(function_id="root",
70
70
  function_name="root"))
71
+ self.active_span_id_stack: ContextVar[list[str]] = ContextVar("active_span_id_stack", default=["root"])
72
+
71
73
  # Default is a lambda no-op which returns NoneType
72
74
  self.user_input_callback: ContextVar[Callable[[InteractionPrompt], Awaitable[HumanResponse | None]]
73
75
  | None] = ContextVar(
@@ -198,6 +200,19 @@ class AIQContext:
198
200
  """
199
201
  return self._context_state.active_function.get()
200
202
 
203
+ @property
204
+ def active_span_id(self) -> str:
205
+ """
206
+ Retrieves the active span ID from the context state.
207
+
208
+ This property provides access to the active span ID stored in the context state. The active span ID represents
209
+ the currently running function/tool/llm/agent/etc and can be used to group telemetry data together.
210
+
211
+ Returns:
212
+ str: The active span ID.
213
+ """
214
+ return self._context_state.active_span_id_stack.get()[-1]
215
+
201
216
  @staticmethod
202
217
  def get() -> "AIQContext":
203
218
  """
@@ -13,9 +13,9 @@
13
13
  # See the License for the specific language governing permissions and
14
14
  # limitations under the License.
15
15
 
16
- import contextvars
17
16
  import dataclasses
18
17
  import logging
18
+ import typing
19
19
 
20
20
  from aiq.data_models.intermediate_step import IntermediateStep
21
21
  from aiq.data_models.intermediate_step import IntermediateStepPayload
@@ -26,9 +26,10 @@ from aiq.utils.reactive.observable import OnError
26
26
  from aiq.utils.reactive.observable import OnNext
27
27
  from aiq.utils.reactive.subscription import Subscription
28
28
 
29
- logger = logging.getLogger(__name__)
29
+ if typing.TYPE_CHECKING:
30
+ from aiq.builder.context import AIQContextState
30
31
 
31
- _current_open_step_id = contextvars.ContextVar[str | None]("_current_open_step_id", default=None)
32
+ logger = logging.getLogger(__name__)
32
33
 
33
34
 
34
35
  @dataclasses.dataclass
@@ -37,8 +38,6 @@ class OpenStep:
37
38
  step_name: str
38
39
  step_type: str
39
40
  step_parent_id: str | None
40
- context: contextvars.Context
41
- token: contextvars.Token[str | None]
42
41
 
43
42
 
44
43
  class IntermediateStepManager:
@@ -59,18 +58,20 @@ class IntermediateStepManager:
59
58
  if not isinstance(payload, IntermediateStepPayload):
60
59
  raise TypeError(f"Payload must be of type IntermediateStepPayload, not {type(payload)}")
61
60
 
62
- parent_step_id = _current_open_step_id.get()
61
+ active_span_id_stack = self._context_state.active_span_id_stack.get()
63
62
 
64
63
  if (payload.event_state == IntermediateStepState.START):
65
64
 
66
- token = _current_open_step_id.set(payload.UUID)
65
+ parent_step_id = active_span_id_stack[-1]
66
+
67
+ # Note, this must not mutate the active_span_id_stack in place
68
+ active_span_id_stack = active_span_id_stack + [payload.UUID]
69
+ self._context_state.active_span_id_stack.set(active_span_id_stack)
67
70
 
68
71
  self._outstanding_start_steps[payload.UUID] = OpenStep(step_id=payload.UUID,
69
- step_name=payload.name,
72
+ step_name=payload.name or payload.UUID,
70
73
  step_type=payload.event_type,
71
- step_parent_id=parent_step_id,
72
- context=contextvars.copy_context(),
73
- token=token)
74
+ step_parent_id=parent_step_id)
74
75
 
75
76
  elif (payload.event_state == IntermediateStepState.END):
76
77
 
@@ -81,14 +82,21 @@ class IntermediateStepManager:
81
82
  logger.warning("Step id %s not found in outstanding start steps", payload.UUID)
82
83
  return
83
84
 
84
- # Restore the parent step ID directly instead of using a cross‑context token.
85
- if parent_step_id == payload.UUID:
86
- _current_open_step_id.set(open_step.step_parent_id)
87
- else:
88
- # Different context (e.g. thread‑pool); safely restore the parent ID **without**
89
- # trying to use a token that belongs to another Context.
90
- _current_open_step_id.set(open_step.step_parent_id)
91
- parent_step_id = open_step.step_parent_id
85
+ # Remove the current step from the active span id stack. Look for the step id in the stack and remove it to
86
+ # correct errors
87
+ current_step_index = active_span_id_stack.index(payload.UUID)
88
+
89
+ if (current_step_index is not None):
90
+ if (current_step_index != len(active_span_id_stack) - 1):
91
+ logger.warning(
92
+ "Step id %s not the last step in the stack. "
93
+ "Removing it from the stack but this is likely an error",
94
+ payload.UUID)
95
+
96
+ active_span_id_stack = active_span_id_stack[:current_step_index]
97
+ self._context_state.active_span_id_stack.set(active_span_id_stack)
98
+
99
+ parent_step_id = open_step.step_parent_id
92
100
 
93
101
  elif (payload.event_state == IntermediateStepState.CHUNK):
94
102
 
@@ -103,14 +111,14 @@ class IntermediateStepManager:
103
111
  payload.UUID)
104
112
  return
105
113
 
106
- if (parent_step_id != payload.UUID):
107
- # Manually set the parent step ID. This happens when running on the thread pool
108
- parent_step_id = open_step.step_parent_id
114
+ parent_step_id = open_step.step_parent_id
115
+
116
+ active_function = self._context_state.active_function.get()
109
117
 
110
- function_ancestry = InvocationNode(function_name=self._context_state.active_function.get().function_name,
111
- function_id=self._context_state.active_function.get().function_id,
118
+ function_ancestry = InvocationNode(function_name=active_function.function_name,
119
+ function_id=active_function.function_id,
112
120
  parent_id=parent_step_id,
113
- parent_name=self._context_state.active_function.get().parent_name)
121
+ parent_name=active_function.parent_name)
114
122
 
115
123
  intermediate_step = IntermediateStep(function_ancestry=function_ancestry, payload=payload)
116
124
 
@@ -23,6 +23,7 @@ import click
23
23
  import yaml
24
24
 
25
25
  from aiq.utils.data_models.schema_validator import validate_yaml
26
+ from aiq.utils.io.yaml_tools import yaml_load
26
27
 
27
28
  logger = logging.getLogger(__name__)
28
29
 
@@ -183,12 +184,9 @@ class LayeredConfig:
183
184
 
184
185
  def load_and_override_config(config_file: Path, overrides: tuple[tuple[str, str], ...]) -> dict[str, Any]:
185
186
  """Load config file and apply any overrides"""
186
- # First validate the original config file
187
- validate_yaml(None, None, config_file)
188
187
 
189
188
  # Load the base config
190
- with open(config_file, 'r', encoding='utf-8') as f:
191
- base_config = yaml.safe_load(f)
189
+ base_config = yaml_load(config_file)
192
190
 
193
191
  # Create layered config
194
192
  config = LayeredConfig(base_config)
@@ -51,9 +51,9 @@ class StepAdaptor:
51
51
  # default existing behavior: show LLM events + TOOL_END + FUNCTION events
52
52
  if step.event_category == IntermediateStepCategory.LLM:
53
53
  return True
54
- if step.event_type == IntermediateStepType.TOOL_END:
54
+ if step.event_category == IntermediateStepCategory.TOOL:
55
55
  return True
56
- if step.event_type in [IntermediateStepType.FUNCTION_START, IntermediateStepType.FUNCTION_END]:
56
+ if step.event_category == IntermediateStepCategory.FUNCTION:
57
57
  return True
58
58
  return False
59
59
 
@@ -120,39 +120,57 @@ class StepAdaptor:
120
120
 
121
121
  return event
122
122
 
123
- def _handle_tool_end(self, payload: IntermediateStepPayload,
124
- ancestry: InvocationNode) -> AIQResponseSerializable | None:
123
+ def _handle_tool(self, step: IntermediateStepPayload, ancestry: InvocationNode) -> AIQResponseSerializable | None:
125
124
  """
126
- Handles the TOOL_END event
125
+ Handles both TOOL_START and TOOL_END events
127
126
  """
128
- escaped_tool_input = html.escape(str(payload.data.input), quote=False)
129
- escaped_tool_output = html.escape(str(payload.data.output), quote=False)
127
+ input_str: str | None = None
128
+ output_str: str | None = None
130
129
 
131
- escaped_tool_input = escaped_tool_input.replace("\n", "")
132
- escaped_tool_output = escaped_tool_output.replace("\n", "")
130
+ # Find the start in the history with matching run_id
131
+ start_step = next(
132
+ (x for x in self._history if x.event_type == IntermediateStepType.TOOL_START and x.UUID == step.UUID), None)
133
133
 
134
- # Determine the format
135
- format_input_type = "json" if is_valid_json(escaped_tool_input) else "python"
136
- format_output_type = "json" if is_valid_json(escaped_tool_output) else "python"
134
+ if not start_step:
135
+ # If we don't have a start step, we can't do anything
136
+ return None
137
+
138
+ input_str = str(start_step.data.input)
139
+
140
+ if step.event_type == IntermediateStepType.TOOL_END:
141
+ output_str = str(step.data.output)
142
+
143
+ if not input_str and not output_str:
144
+ return None
145
+
146
+ escaped_input = html.escape(input_str, quote=False)
147
+ format_input_type = "json" if is_valid_json(escaped_input) else "python"
137
148
 
138
149
  # Dont use f-strings here because the payload is markdown and screws up the dedent
139
- payload_str = dedent("""
150
+ payload = dedent("""
140
151
  **Input:**
141
152
  ```{format_input_type}
142
153
  {input_value}
143
154
  ```
144
- **Output:**
145
- ```{format_output_type}
146
- {output_value}
147
- ```
148
- """).strip("\n").format(input_value=escaped_tool_input,
149
- output_value=escaped_tool_output,
150
- format_input_type=format_input_type,
151
- format_output_type=format_output_type)
155
+ """).strip("\n").format(input_value=escaped_input, format_input_type=format_input_type)
152
156
 
153
- event = AIQResponseIntermediateStep(id=payload.UUID,
154
- name=f"Tool: {payload.name}",
155
- payload=payload_str,
157
+ if output_str:
158
+ escaped_output = html.escape(output_str, quote=False)
159
+ format_output_type = "json" if is_valid_json(escaped_output) else "python"
160
+
161
+ # Dont use f-strings here because the payload is markdown and screws up the dedent
162
+ payload = dedent("""
163
+ {payload}
164
+
165
+ **Output:**
166
+ ```{format_output_type}
167
+ {output_value}
168
+ ```
169
+ """).strip("\n").format(payload=payload, output_value=escaped_output, format_output_type=format_output_type)
170
+
171
+ event = AIQResponseIntermediateStep(id=step.UUID,
172
+ name=f"Tool: {step.name}",
173
+ payload=payload,
156
174
  parent_id=ancestry.function_id)
157
175
 
158
176
  return event
@@ -284,29 +302,16 @@ class StepAdaptor:
284
302
 
285
303
  try:
286
304
 
287
- if self.config.mode == StepAdaptorMode.DEFAULT:
288
-
289
- if step.event_category == IntermediateStepCategory.LLM:
290
- return self._handle_llm(payload, ancestry)
291
-
292
- if step.event_type == IntermediateStepType.TOOL_END:
293
- return self._handle_tool_end(payload, ancestry)
294
-
295
- if step.event_type in [IntermediateStepType.FUNCTION_START, IntermediateStepType.FUNCTION_END]:
296
- return self._handle_function(payload, ancestry)
297
-
298
- if self.config.mode == StepAdaptorMode.CUSTOM:
299
- # Now we're processing user defined custom types
300
-
301
- if step.event_category == IntermediateStepCategory.LLM:
302
- return self._handle_llm(payload, ancestry)
305
+ if step.event_category == IntermediateStepCategory.LLM:
306
+ return self._handle_llm(payload, ancestry)
303
307
 
304
- if step.event_type == IntermediateStepType.TOOL_END:
305
- return self._handle_tool_end(payload, ancestry)
308
+ if step.event_category == IntermediateStepCategory.TOOL:
309
+ return self._handle_tool(payload, ancestry)
306
310
 
307
- if step.event_type in [IntermediateStepType.FUNCTION_START, IntermediateStepType.FUNCTION_END]:
308
- return self._handle_function(payload, ancestry)
311
+ if step.event_category == IntermediateStepCategory.FUNCTION:
312
+ return self._handle_function(payload, ancestry)
309
313
 
314
+ if step.event_category == IntermediateStepCategory.CUSTOM:
310
315
  return self._handle_custom(payload, ancestry)
311
316
 
312
317
  except Exception as e:
aiq/memory/models.py CHANGED
@@ -37,39 +37,49 @@ class MemoryItem(BaseModel):
37
37
  memory : str or None
38
38
  Optional memory string. Helpful when returning a memory.
39
39
  """
40
+ # yapf: disable
40
41
  model_config = ConfigDict(
41
- # Add an example for the schema
42
42
  json_schema_extra={
43
- "examples": [{
44
- "conversation": [
45
- {
46
- "role": "user",
47
- "content": "Hi, I'm Alex. I'm a vegetarian and I'm allergic to nuts.",
48
- },
49
- {
50
- "role": "assistant",
51
- "content": "Hello Alex! I've noted that you're a vegetarian and have a nut allergy.",
52
- },
53
- ],
54
- "user_id": "user_abc",
55
- "metadata": {
56
- "key_value_pairs": {
57
- "type": "technology", "relevance": "high"
43
+ "examples": [
44
+ {
45
+ "conversation": [
46
+ {
47
+ "role": "user",
48
+ "content": "Hi, I'm Alex. I'm a vegetarian and I'm allergic to nuts."
49
+ },
50
+ {
51
+ "role": "assistant",
52
+ "content": "Hello Alex! I've noted that you're a vegetarian and have a nut allergy."
53
+ }
54
+ ],
55
+ "user_id": "user_abc",
56
+ "tags": ["diet", "allergy"],
57
+ "metadata": {
58
+ "key_value_pairs": {
59
+ "type": "profile",
60
+ "relevance": "high"
61
+ }
58
62
  }
63
+ },
64
+ {
65
+ "memory": "User prefers expensive hotels and is vegan.",
66
+ "user_id": "user_abc",
67
+ "tags": ["hotel", "restaurant"]
59
68
  }
60
- }]
69
+ ]
61
70
  },
62
71
  # Allow population of models from arbitrary types (e.g., ORM objects)
63
72
  arbitrary_types_allowed=True,
64
73
  # Enable aliasing if needed
65
- populate_by_name=True)
66
-
67
- conversation: list[dict[str, str]] = Field(description="List of conversation messages. "
68
- "Each message must have a \"role\" "
69
- "key (user or assistant. It must "
70
- "als have a \"content\" key.")
74
+ populate_by_name=True
75
+ )
76
+ # yapf: enable
77
+ conversation: list[dict[str, str]] | None = Field(
78
+ description="List of conversation messages. Each message must have a \"role\" "
79
+ "key (user or assistant. It must also have a \"content\" key.",
80
+ default=None)
71
81
  tags: list[str] = Field(default_factory=list, description="List of tags applied to the item.")
72
- metadata: dict[str, typing.Any] = Field(description="Metadata about the memory item.")
82
+ metadata: dict[str, typing.Any] = Field(description="Metadata about the memory item.", default={})
73
83
  user_id: str = Field(description="The user's ID.")
74
84
  memory: str | None = Field(default=None)
75
85
 
aiq/meta/pypi.md CHANGED
@@ -15,31 +15,30 @@ See the License for the specific language governing permissions and
15
15
  limitations under the License.
16
16
  -->
17
17
 
18
- ![NVIDIA Agent Intelligence Toolkit](https://media.githubusercontent.com/media/NVIDIA/AIQToolkit/refs/heads/main/docs/source/_static/aiqtoolkit_banner.png "AIQ Toolkit banner image")
18
+ ![NVIDIA Agent Intelligence Toolkit](https://media.githubusercontent.com/media/NVIDIA/AIQToolkit/refs/heads/main/docs/source/_static/aiqtoolkit_banner.png "AIQ toolkit banner image")
19
19
 
20
20
  # NVIDIA Agent Intelligence Toolkit
21
21
 
22
- AIQ Toolkit is a flexible library designed to seamlessly integrate your enterprise agents—regardless of framework—with various data sources and tools. By treating agents, tools, and agentic workflows as simple function calls, AIQ Toolkit enables true composability: build once and reuse anywhere.
22
+ AIQ toolkit is a flexible library designed to seamlessly integrate your enterprise agents—regardless of framework—with various data sources and tools. By treating agents, tools, and agentic workflows as simple function calls, AIQ toolkit enables true composability: build once and reuse anywhere.
23
23
 
24
24
  ## Key Features
25
25
 
26
- - [**Framework Agnostic:**](https://docs.nvidia.com/aiqtoolkit/latest/concepts/plugins.html) Works with any agentic framework, so you can use your current technology stack without replatforming.
27
- - [**Reusability:**](https://docs.nvidia.com/aiqtoolkit/latest/guides/sharing-workflows-and-tools.html) Every agent, tool, or workflow can be combined and repurposed, allowing developers to leverage existing work in new scenarios.
28
- - [**Rapid Development:**](https://docs.nvidia.com/aiqtoolkit/latest/guides/create-customize-workflows.html) Start with a pre-built agent, tool, or workflow, and customize it to your needs.
29
- - [**Profiling:**](https://docs.nvidia.com/aiqtoolkit/latest/guides/profiler.html) Profile entire workflows down to the tool and agent level, track input/output tokens and timings, and identify bottlenecks.
30
- - [**Observability:**](https://docs.nvidia.com/aiqtoolkit/latest/guides/observe-workflow-with-phoenix.html) Monitor and debug your workflows with any OpenTelemetry-compatible observability tool. (OpenTelemetry and Phoenix integration are optional and can be installed separately if needed.)
31
- - [**Evaluation System:**](https://docs.nvidia.com/aiqtoolkit/latest/guides/evaluate.html) Validate and maintain accuracy of agentic workflows with built-in evaluation tools.
32
- - [**User Interface:**](https://docs.nvidia.com/aiqtoolkit/latest/guides/using-aiqtoolkit-ui-and-server.html) Use the AIQ Toolkit UI chat interface to interact with your agents, visualize output, and debug workflows.
33
- - [**MCP Compatibility**](https://docs.nvidia.com/aiqtoolkit/latest/components/mcp.html) Compatible with Model Context Protocol (MCP), allowing tools served by MCP Servers to be used as AIQ Toolkit functions.
26
+ - [**Framework Agnostic:**](https://docs.nvidia.com/aiqtoolkit/v1.1.0-rc5/extend/plugins.html) Works with any agentic framework, so you can use your current technology stack without replatforming.
27
+ - [**Reusability:**](https://docs.nvidia.com/aiqtoolkit/v1.1.0-rc5/extend/sharing-components.html) Every agent, tool, or workflow can be combined and repurposed, allowing developers to leverage existing work in new scenarios.
28
+ - [**Rapid Development:**](https://docs.nvidia.com/aiqtoolkit/v1.1.0-rc5/tutorials/index.html) Start with a pre-built agent, tool, or workflow, and customize it to your needs.
29
+ - [**Profiling:**](https://docs.nvidia.com/aiqtoolkit/v1.1.0-rc5/workflows/profiler.html) Profile entire workflows down to the tool and agent level, track input/output tokens and timings, and identify bottlenecks.
30
+ - [**Observability:**](https://docs.nvidia.com/aiqtoolkit/v1.1.0-rc5/workflows/observe/observe-workflow-with-phoenix.html) Monitor and debug your workflows with any OpenTelemetry-compatible observability tool, with examples using [Phoenix](https://docs.nvidia.com/aiqtoolkit/v1.1.0-rc5/workflows/observe/observe-workflow-with-phoenix.html) and [W&B Weave](https://docs.nvidia.com/aiqtoolkit/v1.1.0-rc5/workflows/observe/observe-workflow-with-weave.html).
31
+ - [**Evaluation System:**](https://docs.nvidia.com/aiqtoolkit/v1.1.0-rc5/workflows/evaluate.html) Validate and maintain accuracy of agentic workflows with built-in evaluation tools.
32
+ - [**User Interface:**](https://docs.nvidia.com/aiqtoolkit/v1.1.0-rc5/quick-start/launching-ui.html) Use the AIQ toolkit UI chat interface to interact with your agents, visualize output, and debug workflows.
33
+ - [**MCP Compatibility**](https://docs.nvidia.com/aiqtoolkit/v1.1.0-rc5/workflows/mcp/mcp-client.html) Compatible with Model Context Protocol (MCP), allowing tools served by MCP Servers to be used as AIQ toolkit functions.
34
34
 
35
- With AIQ Toolkit, you can move quickly, experiment freely, and ensure reliability across all your agent-driven projects.
35
+ With AIQ toolkit, you can move quickly, experiment freely, and ensure reliability across all your agent-driven projects.
36
36
 
37
37
  ## Links
38
- * [Documentation](https://docs.nvidia.com/aiqtoolkit/latest/index.html): Explore the full documentation for AIQ Toolkit.
39
- * [About AIQ Toolkit](https://docs.nvidia.com/aiqtoolkit/latest/intro/why-aiqtoolkit.html): Learn more about the benefits of using AIQ Toolkit.
38
+ * [Documentation](https://docs.nvidia.com/aiqtoolkit/v1.1.0-rc5/index.html): Explore the full documentation for AIQ toolkit.
40
39
 
41
40
  ## First time user?
42
- If this is your first time using AIQ Toolkit, it is recommended to install the latest version from the [source repository](https://github.com/NVIDIA/AIQToolkit?tab=readme-ov-file#get-started) on GitHub. This package is intended for users who are familiar with AIQ Toolkit applications and need to add AIQ Toolkit as a dependency to their project.
41
+ If this is your first time using AIQ toolkit, it is recommended to install the latest version from the [source repository](https://github.com/NVIDIA/AIQToolkit?tab=readme-ov-file#quick-start) on GitHub. This package is intended for users who are familiar with AIQ toolkit applications and need to add AIQ toolkit as a dependency to their project.
43
42
 
44
43
  ## Feedback
45
44
 
@@ -47,7 +46,7 @@ We would love to hear from you! Please file an issue on [GitHub](https://github.
47
46
 
48
47
  ## Acknowledgements
49
48
 
50
- We would like to thank the following open source projects that made AIQ Toolkit possible:
49
+ We would like to thank the following open source projects that made AIQ toolkit possible:
51
50
 
52
51
  - [CrewAI](https://github.com/crewAIInc/crewAI)
53
52
  - [FastAPI](https://github.com/tiangolo/fastapi)
@@ -57,7 +57,8 @@ except TelemetryOptionalImportError:
57
57
  from aiq.utils.optional_imports import DummyTrace # pylint: disable=ungrouped-imports
58
58
  from aiq.utils.optional_imports import DummyTracerProvider # pylint: disable=ungrouped-imports
59
59
  from aiq.utils.optional_imports import dummy_set_span_in_context # pylint: disable=ungrouped-imports
60
- trace = DummyTrace
60
+
61
+ trace = DummyTrace # pylint: disable=invalid-name
61
62
  TracerProvider = DummyTracerProvider
62
63
  Span = DummySpan
63
64
  set_span_in_context = dummy_set_span_in_context
@@ -290,6 +291,8 @@ class AsyncOtelSpanListener:
290
291
  logger.warning("No subspan found for step %s", step.UUID)
291
292
  return
292
293
 
294
+ self._span_stack.pop(step.UUID, None)
295
+
293
296
  # Optionally add more attributes from usage_info or data
294
297
  usage_info = step.payload.usage_info
295
298
  if usage_info:
@@ -316,7 +319,7 @@ class AsyncOtelSpanListener:
316
319
 
317
320
  # Finish corresponding Weave call if Weave is available and initialized
318
321
  if self.gc is not None:
319
- self._finish_weave_call(step, sub_span)
322
+ self._finish_weave_call(step)
320
323
 
321
324
  @contextmanager
322
325
  def parent_call(self, trace_id: str, parent_call_id: str):
@@ -342,13 +345,13 @@ class AsyncOtelSpanListener:
342
345
  # use it as the parent
343
346
  if existing_call is not None:
344
347
  parent_call = existing_call
345
- logger.debug(f"Found existing Weave call: {existing_call.id} from trace: {existing_call.trace_id}")
348
+ logger.debug("Found existing Weave call: %s from trace: %s", existing_call.id, existing_call.trace_id)
346
349
  # Otherwise, check our internal stack for parent relationships
347
350
  elif len(self._weave_calls) > 0 and len(self._span_stack) > 1:
348
351
  # Get the parent span using stack position (one level up)
349
352
  parent_span_id = self._span_stack[-2].get_span_context().span_id
350
353
  # Find the corresponding weave call for this parent span
351
- for uuid, call in self._weave_calls.items():
354
+ for call in self._weave_calls.values():
352
355
  if getattr(call, "span_id", None) == parent_span_id:
353
356
  parent_call = call
354
357
  break
@@ -387,7 +390,7 @@ class AsyncOtelSpanListener:
387
390
 
388
391
  return call
389
392
 
390
- def _finish_weave_call(self, step: IntermediateStep, span: Span) -> None:
393
+ def _finish_weave_call(self, step: IntermediateStep) -> None:
391
394
  """
392
395
  Finish a previously created Weave call
393
396
  """
aiq/tool/mcp/mcp_tool.py CHANGED
@@ -40,10 +40,15 @@ class MCPToolConfig(FunctionBaseConfig, name="mcp_tool_wrapper"):
40
40
  Description for the tool that will override the description provided by the MCP server. Should only be used if
41
41
  the description provided by the server is poor or nonexistent
42
42
  """)
43
+ return_exception: bool = Field(default=True,
44
+ description="""
45
+ If true, the tool will return the exception message if the tool call fails.
46
+ If false, raise the exception.
47
+ """)
43
48
 
44
49
 
45
50
  @register_function(config_type=MCPToolConfig)
46
- async def mcp_tool(config: MCPToolConfig, builder: Builder):
51
+ async def mcp_tool(config: MCPToolConfig, builder: Builder): # pylint: disable=unused-argument
47
52
  """
48
53
  Generate an AIQ Toolkit Function that wraps a tool provided by the MCP server.
49
54
  """
@@ -63,12 +68,26 @@ async def mcp_tool(config: MCPToolConfig, builder: Builder):
63
68
  return tool.input_schema.model_validate_json(input_str)
64
69
 
65
70
  async def _response_fn(tool_input: BaseModel | None = None, **kwargs) -> str:
66
- if tool_input:
67
- args = tool_input.model_dump()
68
- return await tool.acall(args)
69
-
70
- _ = tool.input_schema.model_validate(kwargs)
71
- return await tool.acall(kwargs)
71
+ # Run the tool, catching any errors and sending to agent for correction
72
+ try:
73
+ if tool_input:
74
+ args = tool_input.model_dump()
75
+ return await tool.acall(args)
76
+
77
+ _ = tool.input_schema.model_validate(kwargs)
78
+ return await tool.acall(kwargs)
79
+ except Exception as e:
80
+ if config.return_exception:
81
+ if tool_input:
82
+ logger.warning("Error calling tool %s with serialized input: %s",
83
+ tool.name,
84
+ tool_input.model_dump(),
85
+ exc_info=True)
86
+ else:
87
+ logger.warning("Error calling tool %s with input: %s", tool.name, kwargs, exc_info=True)
88
+ return str(e)
89
+ # If the tool call fails, raise the exception.
90
+ raise
72
91
 
73
92
  yield FunctionInfo.create(single_fn=_response_fn,
74
93
  description=tool.description,
@@ -43,7 +43,6 @@ async def add_memory_tool(config: AddToolConfig, builder: Builder):
43
43
  """
44
44
  Function to add memory to a hosted memory platform.
45
45
  """
46
-
47
46
  from langchain_core.tools import ToolException
48
47
 
49
48
  # First, retrieve the memory client
@@ -52,16 +51,29 @@ async def add_memory_tool(config: AddToolConfig, builder: Builder):
52
51
  async def _arun(item: MemoryItem) -> str:
53
52
  """
54
53
  Asynchronous execution of addition of memories.
55
- """
56
54
 
55
+ Args:
56
+ item (MemoryItem): The memory item to add. Must include:
57
+ - conversation: List of dicts with "role" and "content" keys
58
+ - user_id: String identifier for the user
59
+ - metadata: Dict of metadata (can be empty)
60
+ - tags: Optional list of tags
61
+ - memory: Optional memory string
62
+
63
+ Note: If conversation is not provided, it will be created from the memory field
64
+ if available, otherwise an error will be raised.
65
+ """
57
66
  try:
67
+ # If conversation is not provided but memory is, create a conversation
68
+ if not item.conversation and item.memory:
69
+ item.conversation = [{"role": "user", "content": item.memory}]
70
+ elif not item.conversation:
71
+ raise ToolException("Either conversation or memory must be provided")
58
72
 
59
73
  await memory_editor.add_items([item])
60
-
61
74
  return "Memory added successfully. You can continue. Please respond to the user."
62
75
 
63
76
  except Exception as e:
64
-
65
77
  raise ToolException(f"Error adding memory: {e}") from e
66
78
 
67
79
  yield FunctionInfo.from_fn(_arun, description=config.description)
aiq/tool/register.py CHANGED
@@ -22,6 +22,7 @@ from . import document_search
22
22
  from . import github_tools
23
23
  from . import nvidia_rag
24
24
  from . import retriever
25
+ from . import server_tools
25
26
  from .code_execution import register
26
27
  from .github_tools import create_github_commit
27
28
  from .github_tools import create_github_issue
@@ -0,0 +1,63 @@
1
+ # SPDX-FileCopyrightText: Copyright (c) 2024-2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2
+ # SPDX-License-Identifier: Apache-2.0
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ from aiq.builder.builder import Builder
17
+ from aiq.builder.function_info import FunctionInfo
18
+ from aiq.cli.register_workflow import register_function
19
+ from aiq.data_models.function import FunctionBaseConfig
20
+
21
+
22
+ class RequestAttributesTool(FunctionBaseConfig, name="current_request_attributes"):
23
+ """
24
+ A simple tool that demonstrates how to retrieve user-defined request attributes from HTTP requests
25
+ within workflow tools. Please refer to the 'general' section of the configuration file located in the
26
+ 'examples/simple_calculator/configs/config-metadata.yml' directory to see how to define a custom route using a
27
+ YAML file and associate it with a corresponding function to acquire request attributes.
28
+ """
29
+ pass
30
+
31
+
32
+ @register_function(config_type=RequestAttributesTool)
33
+ async def current_request_attributes(config: RequestAttributesTool, builder: Builder):
34
+
35
+ from starlette.datastructures import Headers
36
+ from starlette.datastructures import QueryParams
37
+
38
+ async def _get_request_attributes(unused: str) -> str:
39
+
40
+ from aiq.builder.context import AIQContext
41
+ aiq_context = AIQContext.get()
42
+ method: str | None = aiq_context.metadata.method
43
+ url_path: str | None = aiq_context.metadata.url_path
44
+ url_scheme: str | None = aiq_context.metadata.url_scheme
45
+ headers: Headers | None = aiq_context.metadata.headers
46
+ query_params: QueryParams | None = aiq_context.metadata.query_params
47
+ path_params: dict[str, str] | None = aiq_context.metadata.path_params
48
+ client_host: str | None = aiq_context.metadata.client_host
49
+ client_port: int | None = aiq_context.metadata.client_port
50
+ cookies: dict[str, str] | None = aiq_context.metadata.cookies
51
+
52
+ return (f"Method: {method}, "
53
+ f"URL Path: {url_path}, "
54
+ f"URL Scheme: {url_scheme}, "
55
+ f"Headers: {dict(headers) if headers is not None else 'None'}, "
56
+ f"Query Params: {dict(query_params) if query_params is not None else 'None'}, "
57
+ f"Path Params: {path_params}, "
58
+ f"Client Host: {client_host}, "
59
+ f"Client Port: {client_port}, "
60
+ f"Cookies: {cookies}")
61
+
62
+ yield FunctionInfo.from_fn(_get_request_attributes,
63
+ description="Returns the acquired user defined request attriubutes.")
@@ -1,7 +1,7 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: aiqtoolkit
3
- Version: 1.1.0rc3
4
- Summary: Agent Intelligence Toolkit (AIQ Toolkit)
3
+ Version: 1.1.0rc5
4
+ Summary: NVIDIA Agent Intelligence toolkit
5
5
  Author: NVIDIA Corporation
6
6
  Maintainer: NVIDIA Corporation
7
7
  License: Apache License
@@ -288,31 +288,30 @@ See the License for the specific language governing permissions and
288
288
  limitations under the License.
289
289
  -->
290
290
 
291
- ![NVIDIA Agent Intelligence Toolkit](https://media.githubusercontent.com/media/NVIDIA/AIQToolkit/refs/heads/main/docs/source/_static/aiqtoolkit_banner.png "AIQ Toolkit banner image")
291
+ ![NVIDIA Agent Intelligence Toolkit](https://media.githubusercontent.com/media/NVIDIA/AIQToolkit/refs/heads/main/docs/source/_static/aiqtoolkit_banner.png "AIQ toolkit banner image")
292
292
 
293
293
  # NVIDIA Agent Intelligence Toolkit
294
294
 
295
- AIQ Toolkit is a flexible library designed to seamlessly integrate your enterprise agents—regardless of framework—with various data sources and tools. By treating agents, tools, and agentic workflows as simple function calls, AIQ Toolkit enables true composability: build once and reuse anywhere.
295
+ AIQ toolkit is a flexible library designed to seamlessly integrate your enterprise agents—regardless of framework—with various data sources and tools. By treating agents, tools, and agentic workflows as simple function calls, AIQ toolkit enables true composability: build once and reuse anywhere.
296
296
 
297
297
  ## Key Features
298
298
 
299
- - [**Framework Agnostic:**](https://docs.nvidia.com/aiqtoolkit/latest/concepts/plugins.html) Works with any agentic framework, so you can use your current technology stack without replatforming.
300
- - [**Reusability:**](https://docs.nvidia.com/aiqtoolkit/latest/guides/sharing-workflows-and-tools.html) Every agent, tool, or workflow can be combined and repurposed, allowing developers to leverage existing work in new scenarios.
301
- - [**Rapid Development:**](https://docs.nvidia.com/aiqtoolkit/latest/guides/create-customize-workflows.html) Start with a pre-built agent, tool, or workflow, and customize it to your needs.
302
- - [**Profiling:**](https://docs.nvidia.com/aiqtoolkit/latest/guides/profiler.html) Profile entire workflows down to the tool and agent level, track input/output tokens and timings, and identify bottlenecks.
303
- - [**Observability:**](https://docs.nvidia.com/aiqtoolkit/latest/guides/observe-workflow-with-phoenix.html) Monitor and debug your workflows with any OpenTelemetry-compatible observability tool. (OpenTelemetry and Phoenix integration are optional and can be installed separately if needed.)
304
- - [**Evaluation System:**](https://docs.nvidia.com/aiqtoolkit/latest/guides/evaluate.html) Validate and maintain accuracy of agentic workflows with built-in evaluation tools.
305
- - [**User Interface:**](https://docs.nvidia.com/aiqtoolkit/latest/guides/using-aiqtoolkit-ui-and-server.html) Use the AIQ Toolkit UI chat interface to interact with your agents, visualize output, and debug workflows.
306
- - [**MCP Compatibility**](https://docs.nvidia.com/aiqtoolkit/latest/components/mcp.html) Compatible with Model Context Protocol (MCP), allowing tools served by MCP Servers to be used as AIQ Toolkit functions.
299
+ - [**Framework Agnostic:**](https://docs.nvidia.com/aiqtoolkit/v1.1.0-rc5/extend/plugins.html) Works with any agentic framework, so you can use your current technology stack without replatforming.
300
+ - [**Reusability:**](https://docs.nvidia.com/aiqtoolkit/v1.1.0-rc5/extend/sharing-components.html) Every agent, tool, or workflow can be combined and repurposed, allowing developers to leverage existing work in new scenarios.
301
+ - [**Rapid Development:**](https://docs.nvidia.com/aiqtoolkit/v1.1.0-rc5/tutorials/index.html) Start with a pre-built agent, tool, or workflow, and customize it to your needs.
302
+ - [**Profiling:**](https://docs.nvidia.com/aiqtoolkit/v1.1.0-rc5/workflows/profiler.html) Profile entire workflows down to the tool and agent level, track input/output tokens and timings, and identify bottlenecks.
303
+ - [**Observability:**](https://docs.nvidia.com/aiqtoolkit/v1.1.0-rc5/workflows/observe/observe-workflow-with-phoenix.html) Monitor and debug your workflows with any OpenTelemetry-compatible observability tool, with examples using [Phoenix](https://docs.nvidia.com/aiqtoolkit/v1.1.0-rc5/workflows/observe/observe-workflow-with-phoenix.html) and [W&B Weave](https://docs.nvidia.com/aiqtoolkit/v1.1.0-rc5/workflows/observe/observe-workflow-with-weave.html).
304
+ - [**Evaluation System:**](https://docs.nvidia.com/aiqtoolkit/v1.1.0-rc5/workflows/evaluate.html) Validate and maintain accuracy of agentic workflows with built-in evaluation tools.
305
+ - [**User Interface:**](https://docs.nvidia.com/aiqtoolkit/v1.1.0-rc5/quick-start/launching-ui.html) Use the AIQ toolkit UI chat interface to interact with your agents, visualize output, and debug workflows.
306
+ - [**MCP Compatibility**](https://docs.nvidia.com/aiqtoolkit/v1.1.0-rc5/workflows/mcp/mcp-client.html) Compatible with Model Context Protocol (MCP), allowing tools served by MCP Servers to be used as AIQ toolkit functions.
307
307
 
308
- With AIQ Toolkit, you can move quickly, experiment freely, and ensure reliability across all your agent-driven projects.
308
+ With AIQ toolkit, you can move quickly, experiment freely, and ensure reliability across all your agent-driven projects.
309
309
 
310
310
  ## Links
311
- * [Documentation](https://docs.nvidia.com/aiqtoolkit/latest/index.html): Explore the full documentation for AIQ Toolkit.
312
- * [About AIQ Toolkit](https://docs.nvidia.com/aiqtoolkit/latest/intro/why-aiqtoolkit.html): Learn more about the benefits of using AIQ Toolkit.
311
+ * [Documentation](https://docs.nvidia.com/aiqtoolkit/v1.1.0-rc5/index.html): Explore the full documentation for AIQ toolkit.
313
312
 
314
313
  ## First time user?
315
- If this is your first time using AIQ Toolkit, it is recommended to install the latest version from the [source repository](https://github.com/NVIDIA/AIQToolkit?tab=readme-ov-file#get-started) on GitHub. This package is intended for users who are familiar with AIQ Toolkit applications and need to add AIQ Toolkit as a dependency to their project.
314
+ If this is your first time using AIQ toolkit, it is recommended to install the latest version from the [source repository](https://github.com/NVIDIA/AIQToolkit?tab=readme-ov-file#quick-start) on GitHub. This package is intended for users who are familiar with AIQ toolkit applications and need to add AIQ toolkit as a dependency to their project.
316
315
 
317
316
  ## Feedback
318
317
 
@@ -320,7 +319,7 @@ We would love to hear from you! Please file an issue on [GitHub](https://github.
320
319
 
321
320
  ## Acknowledgements
322
321
 
323
- We would like to thank the following open source projects that made AIQ Toolkit possible:
322
+ We would like to thank the following open source projects that made AIQ toolkit possible:
324
323
 
325
324
  - [CrewAI](https://github.com/crewAIInc/crewAI)
326
325
  - [FastAPI](https://github.com/tiangolo/fastapi)
@@ -19,7 +19,7 @@ aiq/agent/tool_calling_agent/register.py,sha256=qWY1KmDhpG9AIwM3fO5nsF8zE7lWln5q
19
19
  aiq/builder/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
20
20
  aiq/builder/builder.py,sha256=JE3uCw6qTmWX2akUfS-Ga5WSiJVTzBjDQPniiONMjy4,7448
21
21
  aiq/builder/component_utils.py,sha256=2jIXWSLIlKxDKAO7kdXz_4BHqQNWw4t9GmcQfw0ER4g,12923
22
- aiq/builder/context.py,sha256=Sk2Vcduz7zbGkJe28VxCDt8GC5GKDhwvl1zLuRBTmss,8574
22
+ aiq/builder/context.py,sha256=f-kw7JfsIFW83V3ZJFv2OU8LcvNVAg-vRVZ9qtbVESo,9173
23
23
  aiq/builder/embedder.py,sha256=M-n2oXSlwE7u-nmpzRbPq6UVWtFtMvrEdKqqsbKQZLk,965
24
24
  aiq/builder/eval_builder.py,sha256=UnNgtQiDAUfT3yuwjZQVerenI09-4q0Cse9uwLjk3Fg,4657
25
25
  aiq/builder/evaluator.py,sha256=O6Gu0cUwQkrPxPX29Vf_-RopgijxPnhy7mhg_j-9A84,1162
@@ -28,7 +28,7 @@ aiq/builder/front_end.py,sha256=Xhvfi4VcDh5EoCtLr6AlLQfbRm8_TyugUc_IRfirN6Y,2225
28
28
  aiq/builder/function.py,sha256=Sh4LKgC-gipsMkNexUY4mw-Br4dWZxq6AHv-als0-e0,11430
29
29
  aiq/builder/function_base.py,sha256=AF5a56y-Nw9OpWsP8IFukUKM2FtP8758qYQW6EfObO0,13109
30
30
  aiq/builder/function_info.py,sha256=pGPIAL0tjVqLOJymIRB0boI9pzJGdXiPK3KiZvXQsqM,25266
31
- aiq/builder/intermediate_step_manager.py,sha256=_QGpn8xyLMY3OPfRk0m-z-RIKWmqqcH8Suyh_Z_R-m4,5577
31
+ aiq/builder/intermediate_step_manager.py,sha256=TafKueZRFxAzhoYH2BH57giaGAhc4FLR6WM1dfx8yzo,5669
32
32
  aiq/builder/llm.py,sha256=DcoYCyschsRjkW_yGsa_Ci7ELSpk5KRbi9778Dm_B9c,951
33
33
  aiq/builder/retriever.py,sha256=GM7L1T4NdNZKerFZiCfLcQOwsGoX0NRlF8my7SMq3l4,970
34
34
  aiq/builder/user_interaction_manager.py,sha256=OXr-RxWf1sEZjzQH_jt0nmqrLBtYLHGEZEcfDYYFV88,2913
@@ -40,7 +40,7 @@ aiq/cli/main.py,sha256=yVTX5-5-21OOfG8qAdcK3M1fCQUxdr3G37Mb5OldPQc,1772
40
40
  aiq/cli/register_workflow.py,sha256=KJgSMQxjOyidLFd8RXE4hWsUD5zXU4L-OGzuG4HIkG0,18277
41
41
  aiq/cli/type_registry.py,sha256=1Cos4g-fFLMNfYq4GtJRfLImVZVTPlPRXK85A76h3ew,40206
42
42
  aiq/cli/cli_utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
43
- aiq/cli/cli_utils/config_override.py,sha256=STgJRFC-rO0rCYPGT5NNlMcUENWuCpv01lWaFukVlaA,9017
43
+ aiq/cli/cli_utils/config_override.py,sha256=WuX9ki1W0Z6jTqjm553U_owWFxbVzjbKRWGJINFPCvI,8919
44
44
  aiq/cli/cli_utils/validation.py,sha256=GlKpoi3HfE5HELjmz5wk8ezGbb5iZeY0zmA3uxmCrBU,1302
45
45
  aiq/cli/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
46
46
  aiq/cli/commands/evaluate.py,sha256=_pqAuvrNKBf0DvGpZFO28vAKBWp6izMpaLbAVnP57_4,4783
@@ -151,7 +151,7 @@ aiq/front_ends/fastapi/message_handler.py,sha256=3rFDXG633Upom1taW3ab_sC3KKxN8Y_
151
151
  aiq/front_ends/fastapi/message_validator.py,sha256=NqjeIG0InGAS6yooEnTaYwjfy3qtQHNgmdJ4zZlxgSQ,17407
152
152
  aiq/front_ends/fastapi/register.py,sha256=-Vr6HEDy7L1IIBQZy6VFKZWWKYNtSI-cxk3l4ZPPLko,1159
153
153
  aiq/front_ends/fastapi/response_helpers.py,sha256=JnOOvurlkhh6akpzkKDNh1xCi5ClQTePyW_ScEY1pLo,9111
154
- aiq/front_ends/fastapi/step_adaptor.py,sha256=IgCV600zGZyUW2UQlhZV0Oqmp-UUILD5XYza1VYvoXo,12677
154
+ aiq/front_ends/fastapi/step_adaptor.py,sha256=2ps136GzZ7EFgNrN0rPCUSJllvO-GNZPtADrGYseCNc,12551
155
155
  aiq/front_ends/fastapi/websocket.py,sha256=upRuFSceWRZcjBcjWG7l6Tl6fxY4NnMroSq372bdkpw,6569
156
156
  aiq/front_ends/mcp/__init__.py,sha256=Xs1JQ16L9btwreh4pdGKwskffAw1YFO48jKrU4ib_7c,685
157
157
  aiq/front_ends/mcp/mcp_front_end_config.py,sha256=Mp2mgCh1pJkegih5DEJ3t0OKEiCiCg8-rM5vnLpLS6U,1470
@@ -169,11 +169,11 @@ aiq/llm/utils/env_config_value.py,sha256=SBpppIRszDXNcEEG2L6kVojY7LH_EpHfK7bu92T
169
169
  aiq/llm/utils/error.py,sha256=gFFDG_v_3hBZVWpcD7HWkno-NBHDjXae7qDGnfiCNwA,820
170
170
  aiq/memory/__init__.py,sha256=sNqiLatqyTNSBUKKgmInOvCmebkuDHRTErZaeOaE8C8,844
171
171
  aiq/memory/interfaces.py,sha256=lyj1TGr3Fhibul8Y64Emj-BUEqDotmmFoVCEMqTujUA,5531
172
- aiq/memory/models.py,sha256=4TZW2VSroLx0Ea11F_33_Rmx1diAk1jFpz-45jyPpnc,4026
172
+ aiq/memory/models.py,sha256=c5dA7nKHQ4AS1_ptQZcfC_oXO495-ehocnf_qXTE6c8,4319
173
173
  aiq/meta/module_to_distro.json,sha256=1XV7edobFrdDKvsSoynfodXg_hczUWpDrQzGkW9qqEs,28
174
- aiq/meta/pypi.md,sha256=pLZaYl3LQrSOUBET9EW_kT5WQuAU9yYgNnsjOrLZ05c,4392
174
+ aiq/meta/pypi.md,sha256=OYkfnhA2QhkEgG0nxc70UjJLaBDJvuBDgMRiZ-X1gnE,4417
175
175
  aiq/observability/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
176
- aiq/observability/async_otel_listener.py,sha256=bEml7HVVdS8JfMPH7L0d-PRsZpwlYCo-TIxT6abVhFc,17611
176
+ aiq/observability/async_otel_listener.py,sha256=oyDO_8XNzQqyiFe-8iJhZr3z9kWsEJEuKEoOPf7L-Bk,17667
177
177
  aiq/observability/register.py,sha256=ZDQOaSuy9igc7nAKG7XWP2u6JanC2T8yufMWItNpPJI,4245
178
178
  aiq/plugins/.namespace,sha256=Gace0pOC3ETEJf-TBVuNw0TQV6J_KtOPpEiSzMH-odo,215
179
179
  aiq/profiler/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -255,8 +255,9 @@ aiq/tool/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
255
255
  aiq/tool/datetime_tools.py,sha256=6yvTO4cCaxko7-wK6fdCXUwNJFwxuEllfR5S57uo02k,1664
256
256
  aiq/tool/document_search.py,sha256=w3D3r5ZBS2jYmVAZZ7lC7xCoi25bA1RePoFjjlV1Zog,6793
257
257
  aiq/tool/nvidia_rag.py,sha256=9mS3igONo1RywxXNj_ITh2-qD91x1R0f7uhOWMZQX3o,4178
258
- aiq/tool/register.py,sha256=l3_cjRYA2bTHlJG_PEpmcGKCruNDC7bqHH2H2PqbUTU,1434
258
+ aiq/tool/register.py,sha256=l9TbCf9T7IXvvXCidzjYPDygBx_E5as5okN2kIZtieE,1461
259
259
  aiq/tool/retriever.py,sha256=DnuU4khpJkd4epDBGQsowDOqDBKFiLQrnyKXgU6IRW8,3724
260
+ aiq/tool/server_tools.py,sha256=e_HCYleB64KqAzT7HZ-i__mZ3QsNXEZzBTGtDOYMLvw,3063
260
261
  aiq/tool/code_execution/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
261
262
  aiq/tool/code_execution/code_sandbox.py,sha256=ha0IVHmWsEp0U5A0XywG6hp42pFdj5esM19CRS94_30,5986
262
263
  aiq/tool/code_execution/register.py,sha256=H-4eZwu6f5jANEBnyONcDdeBrivkHjw-aZU-V7CLMRs,3143
@@ -276,9 +277,9 @@ aiq/tool/github_tools/get_github_pr.py,sha256=b7eCOqrVoejGjRwmUVdU45uF07ihbY8lRa
276
277
  aiq/tool/github_tools/update_github_issue.py,sha256=TUElxUuzjZr_QldL_48RcqSx0A9b23NB_lA82QwFjkM,4103
277
278
  aiq/tool/mcp/__init__.py,sha256=GUJrgGtpvyMUCjUBvR3faAdv-tZzbU9W-izgx9aMEQg,680
278
279
  aiq/tool/mcp/mcp_client.py,sha256=5TaYbYqvfswBzO9al8Ir89KZ3FhxJtzkJPHLBO_iNWY,7469
279
- aiq/tool/mcp/mcp_tool.py,sha256=9RaAYTFvNJLkA1nlnxzZFd8gM4uYj4y0l6qt9BxDXpQ,3043
280
+ aiq/tool/mcp/mcp_tool.py,sha256=rQQcaCT-GHQcDmG5weX-2Y-HxBPX-0cC73LjL1u0FUU,4009
280
281
  aiq/tool/memory_tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
281
- aiq/tool/memory_tools/add_memory_tool.py,sha256=nOWKW896ghreWnHTx3GVFkYqqC3dfZroNbehuDVASKk,2491
282
+ aiq/tool/memory_tools/add_memory_tool.py,sha256=9EjB3DpYhxwasz7o3O8Rq__Ys5986fciv44ahC6mVCo,3349
282
283
  aiq/tool/memory_tools/delete_memory_tool.py,sha256=wdB_I8y-1D1OpNtBi6ZOg36vvNkbaxp-yvdqFMc2Suk,2532
283
284
  aiq/tool/memory_tools/get_memory_tool.py,sha256=-i0Bt5xYeapbbd2wtAgPc0pOv0Dx4jK1-yyHG7YCeQ0,2749
284
285
  aiq/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -306,10 +307,10 @@ aiq/utils/reactive/base/observer_base.py,sha256=UAlyAY_ky4q2t0P81RVFo2Bs_R7z5Nde
306
307
  aiq/utils/reactive/base/subject_base.py,sha256=Ed-AC6P7cT3qkW1EXjzbd5M9WpVoeN_9KCe3OM3FLU4,2521
307
308
  aiq/utils/settings/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
308
309
  aiq/utils/settings/global_settings.py,sha256=U9TCLdoZsKq5qOVGjREipGVv9e-FlStzqy5zv82_VYk,7454
309
- aiqtoolkit-1.1.0rc3.dist-info/licenses/LICENSE-3rd-party.txt,sha256=8o7aySJa9CBvFshPcsRdJbczzdNyDGJ8b0J67WRUQ2k,183936
310
- aiqtoolkit-1.1.0rc3.dist-info/licenses/LICENSE.md,sha256=QwcOLU5TJoTeUhuIXzhdCEEDDvorGiC6-3YTOl4TecE,11356
311
- aiqtoolkit-1.1.0rc3.dist-info/METADATA,sha256=FEMHhzlRKums0pcRKq8SaJKb31ePO2U3rP0LxQqhPKY,20132
312
- aiqtoolkit-1.1.0rc3.dist-info/WHEEL,sha256=0CuiUZ_p9E4cD6NyLD6UG80LBXYyiSYZOKDm5lp32xk,91
313
- aiqtoolkit-1.1.0rc3.dist-info/entry_points.txt,sha256=gRlPfR5g21t328WNEQ4CcEz80S1sJNS8A7rMDYnzl4A,452
314
- aiqtoolkit-1.1.0rc3.dist-info/top_level.txt,sha256=fo7AzYcNhZ_tRWrhGumtxwnxMew4xrT1iwouDy_f0Kc,4
315
- aiqtoolkit-1.1.0rc3.dist-info/RECORD,,
310
+ aiqtoolkit-1.1.0rc5.dist-info/licenses/LICENSE-3rd-party.txt,sha256=8o7aySJa9CBvFshPcsRdJbczzdNyDGJ8b0J67WRUQ2k,183936
311
+ aiqtoolkit-1.1.0rc5.dist-info/licenses/LICENSE.md,sha256=QwcOLU5TJoTeUhuIXzhdCEEDDvorGiC6-3YTOl4TecE,11356
312
+ aiqtoolkit-1.1.0rc5.dist-info/METADATA,sha256=A21grEksHmg5DsTpzbcn9QbLQL3Q11DrAagRmLjB_Vw,20150
313
+ aiqtoolkit-1.1.0rc5.dist-info/WHEEL,sha256=Nw36Djuh_5VDukK0H78QzOX-_FQEo6V37m3nkm96gtU,91
314
+ aiqtoolkit-1.1.0rc5.dist-info/entry_points.txt,sha256=gRlPfR5g21t328WNEQ4CcEz80S1sJNS8A7rMDYnzl4A,452
315
+ aiqtoolkit-1.1.0rc5.dist-info/top_level.txt,sha256=fo7AzYcNhZ_tRWrhGumtxwnxMew4xrT1iwouDy_f0Kc,4
316
+ aiqtoolkit-1.1.0rc5.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.3.1)
2
+ Generator: setuptools (80.7.1)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5