griptape-nodes 0.68.0__py3-none-any.whl → 0.68.1__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.
@@ -33,6 +33,7 @@ class MCPServerConfig(TypedDict, total=False):
33
33
  terminate_on_close: bool # Session termination behavior for streamable HTTP transport
34
34
  description: str | None
35
35
  capabilities: list[str] | None
36
+ rules: str | None # Optional rules for this MCP server as a single string
36
37
 
37
38
 
38
39
  class MCPServerCapability(TypedDict):
@@ -162,6 +163,7 @@ class CreateMCPServerRequest(RequestPayload):
162
163
  description: Optional description of the server
163
164
  capabilities: List of server capabilities
164
165
  enabled: Whether the server is enabled by default
166
+ rules: Optional rules for this MCP server as a single string
165
167
  """
166
168
 
167
169
  name: str
@@ -186,6 +188,7 @@ class CreateMCPServerRequest(RequestPayload):
186
188
  # Common fields
187
189
  description: str | None = None
188
190
  capabilities: list[str] | None = None
191
+ rules: str | None = None
189
192
 
190
193
 
191
194
  @dataclass
@@ -224,6 +227,7 @@ class UpdateMCPServerRequest(RequestPayload):
224
227
  terminate_on_close: Updated session termination behavior for streamable HTTP transport
225
228
  description: Updated description of the server
226
229
  capabilities: Updated list of server capabilities
230
+ rules: Updated rules for this MCP server as a single string
227
231
  """
228
232
 
229
233
  name: str
@@ -249,6 +253,7 @@ class UpdateMCPServerRequest(RequestPayload):
249
253
  # Common fields
250
254
  description: str | None = None
251
255
  capabilities: list[str] | None = None
256
+ rules: str | None = None
252
257
 
253
258
 
254
259
  @dataclass
@@ -389,49 +389,107 @@ class AgentManager:
389
389
  driver = self.thread_storage_driver.get_conversation_memory_driver(thread_id)
390
390
  conversation_memory = ConversationMemory(conversation_memory_driver=driver)
391
391
 
392
+ # Collect MCP server rulesets
393
+ mcp_rulesets = self._collect_mcp_server_rulesets(additional_mcp_servers)
394
+
395
+ # Get default rulesets
396
+ default_rulesets = self._get_default_rulesets()
397
+
392
398
  return Agent(
393
399
  prompt_driver=self.prompt_driver,
394
400
  conversation_memory=conversation_memory,
395
401
  tools=tools,
396
402
  output_schema=output_schema,
397
- rulesets=[
398
- Ruleset(
399
- name="generated_image_urls",
400
- rules=[
401
- Rule("Do not hallucinate generated_image_urls."),
402
- Rule("Only set generated_image_urls with images generated with your tools."),
403
- ],
404
- ),
405
- # Note: Griptape's MCPTool automatically wraps arguments in a 'values' key, but our MCP server
406
- # expects arguments directly. This ruleset instructs the agent to provide arguments without
407
- # the 'values' wrapper to avoid validation errors. If MCPTool behavior changes in the future,
408
- # this ruleset may need to be updated or removed.
409
- Ruleset(
410
- name="mcp_tool_usage",
411
- rules=[
412
- Rule(
413
- "When calling MCP tools (mcpGriptapeNodes), provide arguments directly without wrapping them in a 'values' key. "
414
- "For example, use {'node_type': 'FluxImageGeneration', 'node_name': 'MyNode'} not {'values': {'node_type': 'FluxImageGeneration'}}."
415
- ),
416
- ],
417
- ),
418
- Ruleset(
419
- name="node_rulesets",
420
- rules=[
421
- Rule(
422
- "When asked to create a node, use ListNodeTypesInLibraryRequest or GetAllInfoForAllLibrariesRequest to check available node types and find the appropriate node."
423
- ),
424
- Rule(
425
- "When matching user requests to node types, account for variations: users may include spaces (e.g., 'Image Generation' vs 'ImageGeneration') or reorder words (e.g., 'Generate Image' vs 'Image Generation'). Match based on the words present, not exact spelling."
426
- ),
427
- Rule(
428
- "If you cannot determine the correct node type or node creation fails, ask the user for clarification."
429
- ),
430
- ],
431
- ),
432
- ],
403
+ rulesets=[*default_rulesets, *mcp_rulesets],
433
404
  )
434
405
 
406
+ @staticmethod
407
+ def _create_ruleset_from_rules_string(rules_string: str | None, server_name: str) -> Ruleset | None:
408
+ """Create a Ruleset from a rules string for an MCP server.
409
+
410
+ Args:
411
+ rules_string: Optional rules string for the MCP server
412
+ server_name: Name of the MCP server
413
+
414
+ Returns:
415
+ Ruleset with a single Rule containing the rules string, or None if rules_string is None/empty
416
+ """
417
+ if not rules_string or not rules_string.strip():
418
+ return None
419
+
420
+ rules_text = rules_string.strip()
421
+ ruleset_name = f"mcp_{server_name}_rules"
422
+
423
+ return Ruleset(name=ruleset_name, rules=[Rule(rules_text)])
424
+
425
+ def _collect_mcp_server_rulesets(self, additional_mcp_servers: list[str] | None) -> list[Ruleset]:
426
+ """Collect rulesets from MCP server configurations."""
427
+ mcp_rulesets = []
428
+
429
+ # Collect server names to get rules for
430
+ server_names_to_check = []
431
+ if additional_mcp_servers:
432
+ server_names_to_check.extend(additional_mcp_servers)
433
+
434
+ # Get rules for all MCP servers
435
+ if not server_names_to_check:
436
+ return mcp_rulesets
437
+
438
+ enabled_result = GriptapeNodes.handle_request(GetEnabledMCPServersRequest())
439
+ if not isinstance(enabled_result, GetEnabledMCPServersResultSuccess):
440
+ return mcp_rulesets
441
+
442
+ for server_name in server_names_to_check:
443
+ if server_name not in enabled_result.servers:
444
+ continue
445
+
446
+ server_config = enabled_result.servers[server_name]
447
+ rules_string = server_config.get("rules")
448
+ ruleset = AgentManager._create_ruleset_from_rules_string(rules_string, server_name)
449
+ if ruleset is not None:
450
+ mcp_rulesets.append(ruleset)
451
+
452
+ return mcp_rulesets
453
+
454
+ def _get_default_rulesets(self) -> list[Ruleset]:
455
+ """Get the default rulesets for agents."""
456
+ return [
457
+ Ruleset(
458
+ name="generated_image_urls",
459
+ rules=[
460
+ Rule("Do not hallucinate generated_image_urls."),
461
+ Rule("Only set generated_image_urls with images generated with your tools."),
462
+ ],
463
+ ),
464
+ # Note: Griptape's MCPTool automatically wraps arguments in a 'values' key, but our MCP server
465
+ # expects arguments directly. This ruleset instructs the agent to provide arguments without
466
+ # the 'values' wrapper to avoid validation errors. If MCPTool behavior changes in the future,
467
+ # this ruleset may need to be updated or removed.
468
+ Ruleset(
469
+ name="mcp_tool_usage",
470
+ rules=[
471
+ Rule(
472
+ "When calling MCP tools (mcpGriptapeNodes), provide arguments directly without wrapping them in a 'values' key. "
473
+ "For example, use {'node_type': 'FluxImageGeneration', 'node_name': 'MyNode'} not {'values': {'node_type': 'FluxImageGeneration'}}."
474
+ ),
475
+ ],
476
+ ),
477
+ Ruleset(
478
+ name="node_rulesets",
479
+ rules=[
480
+ Rule(
481
+ "When asked to create a node, use ListNodeTypesInLibraryRequest or GetAllInfoForAllLibrariesRequest to check available node types and find the appropriate node."
482
+ ),
483
+ Rule(
484
+ "When matching user requests to node types, account for variations: users may include spaces (e.g., 'Image Generation' vs 'ImageGeneration') or reorder words (e.g., 'Generate Image' vs 'Image Generation'). Match based on the words present, not exact spelling."
485
+ ),
486
+ Rule(
487
+ "If you cannot determine the correct node type or node creation fails, ask the user for clarification."
488
+ ),
489
+ ],
490
+ ),
491
+ ]
492
+
435
493
  def _validate_thread_for_run(self, thread_id: str | None) -> str:
436
494
  """Validate and return thread_id for agent run, or raise ValueError."""
437
495
  if thread_id is None:
@@ -510,10 +568,7 @@ class AgentManager:
510
568
  additional_tools = []
511
569
 
512
570
  try:
513
- app = GriptapeNodes()
514
-
515
- enabled_request = GetEnabledMCPServersRequest()
516
- enabled_result = app.handle_request(enabled_request)
571
+ enabled_result = GriptapeNodes.handle_request(GetEnabledMCPServersRequest())
517
572
 
518
573
  if not isinstance(enabled_result, GetEnabledMCPServersResultSuccess):
519
574
  msg = f"Failed to get enabled MCP servers for additional tools: {enabled_result}. Agent will continue with default MCP tool only."
@@ -127,6 +127,7 @@ class MCPManager:
127
127
  "terminate_on_close": "terminate_on_close",
128
128
  "description": "description",
129
129
  "capabilities": "capabilities",
130
+ "rules": "rules",
130
131
  }
131
132
 
132
133
  # Update fields that are not None
@@ -213,6 +214,7 @@ class MCPManager:
213
214
  # Common fields
214
215
  description=request.description,
215
216
  capabilities=request.capabilities or [],
217
+ rules=request.rules,
216
218
  )
217
219
 
218
220
  servers.append(server_config)
@@ -97,6 +97,7 @@ class MCPServerConfig(BaseModel):
97
97
  # Common fields
98
98
  description: str | None = Field(default=None, description="Optional description of what this MCP server provides")
99
99
  capabilities: list[str] = Field(default_factory=list, description="List of capabilities this MCP server provides")
100
+ rules: str | None = Field(default=None, description="Optional rules for this MCP server as a single string.")
100
101
 
101
102
  def __str__(self) -> str:
102
103
  return f"{self.name} ({'enabled' if self.enabled else 'disabled'})"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: griptape-nodes
3
- Version: 0.68.0
3
+ Version: 0.68.1
4
4
  Summary: Add your description here
5
5
  Requires-Dist: griptape>=1.8.12
6
6
  Requires-Dist: pydantic>=2.10.6
@@ -128,7 +128,7 @@ griptape_nodes/retained_mode/events/flow_events.py,sha256=UcRHfaubb1GpDFSPg-5HRW
128
128
  griptape_nodes/retained_mode/events/generate_request_payload_schemas.py,sha256=PQ0QRZAUBljSIGjB8QhYUeRmSrfmLsJ6XVcygJKi13I,1102
129
129
  griptape_nodes/retained_mode/events/library_events.py,sha256=4NUc3uoLgofo1X9nrCVl2zPX3hsnk06Oo4Op0AQKA5o,36229
130
130
  griptape_nodes/retained_mode/events/logger_events.py,sha256=jYlxzPomgCsJuPtJ0znWBhD8QJfC8qC4xfChDiuVuyg,705
131
- griptape_nodes/retained_mode/events/mcp_events.py,sha256=51OlMZVcabdcIxBb_ojvrHtq2jAzZA31pooPBKaApyg,10734
131
+ griptape_nodes/retained_mode/events/mcp_events.py,sha256=fs83jAQamhwNC9Zt8UNkBKd6iTids8531V_RMnGj__o,11008
132
132
  griptape_nodes/retained_mode/events/model_events.py,sha256=jXm-v-_Uxysn4MJ7a80_uIphrxTHgua3BGgHGyy3T_Y,9232
133
133
  griptape_nodes/retained_mode/events/node_events.py,sha256=vpILjBkgrPzF_KSow2EJCwcU-tDD78WEWM2DAAzhhiE,37720
134
134
  griptape_nodes/retained_mode/events/object_events.py,sha256=cJaqEU73Lzf1RRxJrFqEpl8eTr-gDhKpXKywJ-vVCJQ,2631
@@ -145,7 +145,7 @@ griptape_nodes/retained_mode/events/variable_events.py,sha256=fnl_sY8GWI_R4UJQTE
145
145
  griptape_nodes/retained_mode/events/workflow_events.py,sha256=TFJBYAERYZ6gLGGkLFUNxEkPP0uub7RXubPjvgy0ark,24915
146
146
  griptape_nodes/retained_mode/griptape_nodes.py,sha256=0pv6TmHqcaNPb1Rd4XJzhYMLtxrl7eLQLpZsDSvrhz0,20178
147
147
  griptape_nodes/retained_mode/managers/__init__.py,sha256=OTXysKusqYCQeAYwnVj4PbE3MxvAUTq9xOZT6vUE3JA,24
148
- griptape_nodes/retained_mode/managers/agent_manager.py,sha256=B7O9lczy83AJjRwdHUFgs6I0Pd3ANNbzPYhf70bsg7c,26311
148
+ griptape_nodes/retained_mode/managers/agent_manager.py,sha256=FOKrcHEBw6M-RmfWTWEQmV-9iy9cD1zHiiDUDMqJHE4,28307
149
149
  griptape_nodes/retained_mode/managers/arbitrary_code_exec_manager.py,sha256=LyWzHQKmyDh-2zh2PIahdYyAthf_rMYs4zvhtVo-LsU,3423
150
150
  griptape_nodes/retained_mode/managers/config_manager.py,sha256=74AMeaCS0eOeFbzMk5I54MtB7-SNQbwlx_-O6zBBQRo,26739
151
151
  griptape_nodes/retained_mode/managers/context_manager.py,sha256=eb44_CAZhCg2iYIoodlAPpYc67tG3sHyq9dPNoiq_1s,23031
@@ -203,7 +203,7 @@ griptape_nodes/retained_mode/managers/fitness_problems/workflows/workflow_proble
203
203
  griptape_nodes/retained_mode/managers/fitness_problems/workflows/workflow_schema_version_problem.py,sha256=rUnbBBnGwgq5WTVPt2G4pGP3gVPoX5xvCdTkRPBmP04,1328
204
204
  griptape_nodes/retained_mode/managers/flow_manager.py,sha256=fY0xCXHiualDwVQJnNlPpMUnLz5bYWvr5D1_UvOyNVM,220269
205
205
  griptape_nodes/retained_mode/managers/library_manager.py,sha256=paogGavZj2MDOYvfUklhjORQg16YdpVGBxBncVSxtR0,192265
206
- griptape_nodes/retained_mode/managers/mcp_manager.py,sha256=Ezmn5_48r4JWYe-tFGqmw9dXLvvTiO1rw9b4MNCkw0U,15955
206
+ griptape_nodes/retained_mode/managers/mcp_manager.py,sha256=AEHG1SqFc3g5hOImOHaH7ZjOkmgNAavmQgG9osXVGkE,16018
207
207
  griptape_nodes/retained_mode/managers/model_manager.py,sha256=3lj2X8vIvDSERPtR2VEXNFEWy_D8H6muxRvD-PEx8U8,44845
208
208
  griptape_nodes/retained_mode/managers/node_manager.py,sha256=KbThJ5fvBTuF9EEIqBT37Rop41_7o-irb_-KY8hkXVY,225038
209
209
  griptape_nodes/retained_mode/managers/object_manager.py,sha256=xABsjpE1_HLEIFwYj60zDOLi18EqrYUBuNaj37lUcH4,12921
@@ -222,7 +222,7 @@ griptape_nodes/retained_mode/managers/resource_types/cpu_resource.py,sha256=YHjU
222
222
  griptape_nodes/retained_mode/managers/resource_types/os_resource.py,sha256=HHJ-kgZB2BsnvU0rp-CQlM1xTJm3OZ3Dh-NpB01gGG8,3439
223
223
  griptape_nodes/retained_mode/managers/secrets_manager.py,sha256=knoHlbR-VrkeNULYjq72cHnhbCeupkKjtUT0EfBH8LQ,7743
224
224
  griptape_nodes/retained_mode/managers/session_manager.py,sha256=u3OEir9rjwG7GFM4MA5crKwcwq6F-lCUKlFzxlFU4co,14085
225
- griptape_nodes/retained_mode/managers/settings.py,sha256=BnIOYxsaE834_oIg6C_oRqFz0MDv8qSqLtwEGpiJZvA,12054
225
+ griptape_nodes/retained_mode/managers/settings.py,sha256=UxYA5GzHqBPFMNwKqq2Np4nT8ZciBahpDIFrhQKNMm0,12168
226
226
  griptape_nodes/retained_mode/managers/static_files_manager.py,sha256=rWeI5mO8CCdEHx1odo4z4pxfTy33ggzCcUwkRj67aNM,12408
227
227
  griptape_nodes/retained_mode/managers/sync_manager.py,sha256=dF6nAAy1DLDQydefx7v3EtPCBiCrk4vURMum57WfmK8,21448
228
228
  griptape_nodes/retained_mode/managers/user_manager.py,sha256=JAOOKDhUfIbj0CJ5EHRBcplmxheQTzeogbvGO23VqXQ,4508
@@ -276,7 +276,7 @@ griptape_nodes/version_compatibility/versions/v0_65_5/__init__.py,sha256=4UyspOV
276
276
  griptape_nodes/version_compatibility/versions/v0_65_5/flux_2_removed_parameters.py,sha256=jOlmY5kKHXh8HPzAUtvwMJqzD4bP7pkE--yHUb7jTRA,3305
277
277
  griptape_nodes/version_compatibility/versions/v0_7_0/__init__.py,sha256=IzPPmGK86h2swfGGTOHyVcBIlOng6SjgWQzlbf3ngmo,51
278
278
  griptape_nodes/version_compatibility/versions/v0_7_0/local_executor_argument_addition.py,sha256=Thx8acnbw5OychhwEEj9aFxvbPe7Wgn4V9ZmZ7KRZqc,2082
279
- griptape_nodes-0.68.0.dist-info/WHEEL,sha256=eycQt0QpYmJMLKpE3X9iDk8R04v2ZF0x82ogq-zP6bQ,79
280
- griptape_nodes-0.68.0.dist-info/entry_points.txt,sha256=qvevqd3BVbAV5TcantnAm0ouqaqYKhsRO3pkFymWLWM,82
281
- griptape_nodes-0.68.0.dist-info/METADATA,sha256=N19_zdNWANm20AwShxLGrCdlns7RVwaJ9IoewOOXH1Q,5374
282
- griptape_nodes-0.68.0.dist-info/RECORD,,
279
+ griptape_nodes-0.68.1.dist-info/WHEEL,sha256=eycQt0QpYmJMLKpE3X9iDk8R04v2ZF0x82ogq-zP6bQ,79
280
+ griptape_nodes-0.68.1.dist-info/entry_points.txt,sha256=qvevqd3BVbAV5TcantnAm0ouqaqYKhsRO3pkFymWLWM,82
281
+ griptape_nodes-0.68.1.dist-info/METADATA,sha256=c23iianw-Es7pl0SlHWlsx04xm_T9PMujNlLdfT2jDk,5374
282
+ griptape_nodes-0.68.1.dist-info/RECORD,,