lm-deluge 0.0.67__py3-none-any.whl → 0.0.88__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 lm-deluge might be problematic. Click here for more details.

Files changed (92) hide show
  1. lm_deluge/__init__.py +25 -2
  2. lm_deluge/api_requests/anthropic.py +92 -17
  3. lm_deluge/api_requests/base.py +47 -11
  4. lm_deluge/api_requests/bedrock.py +7 -4
  5. lm_deluge/api_requests/chat_reasoning.py +4 -0
  6. lm_deluge/api_requests/gemini.py +138 -18
  7. lm_deluge/api_requests/openai.py +114 -21
  8. lm_deluge/client.py +282 -49
  9. lm_deluge/config.py +15 -3
  10. lm_deluge/mock_openai.py +643 -0
  11. lm_deluge/models/__init__.py +12 -1
  12. lm_deluge/models/anthropic.py +17 -2
  13. lm_deluge/models/arcee.py +16 -0
  14. lm_deluge/models/deepseek.py +36 -4
  15. lm_deluge/models/google.py +29 -0
  16. lm_deluge/models/grok.py +24 -0
  17. lm_deluge/models/kimi.py +36 -0
  18. lm_deluge/models/minimax.py +10 -0
  19. lm_deluge/models/openai.py +100 -0
  20. lm_deluge/models/openrouter.py +86 -8
  21. lm_deluge/models/together.py +11 -0
  22. lm_deluge/models/zai.py +1 -0
  23. lm_deluge/pipelines/gepa/__init__.py +95 -0
  24. lm_deluge/pipelines/gepa/core.py +354 -0
  25. lm_deluge/pipelines/gepa/docs/samples.py +696 -0
  26. lm_deluge/pipelines/gepa/examples/01_synthetic_keywords.py +140 -0
  27. lm_deluge/pipelines/gepa/examples/02_gsm8k_math.py +261 -0
  28. lm_deluge/pipelines/gepa/examples/03_hotpotqa_multihop.py +300 -0
  29. lm_deluge/pipelines/gepa/examples/04_batch_classification.py +271 -0
  30. lm_deluge/pipelines/gepa/examples/simple_qa.py +129 -0
  31. lm_deluge/pipelines/gepa/optimizer.py +435 -0
  32. lm_deluge/pipelines/gepa/proposer.py +235 -0
  33. lm_deluge/pipelines/gepa/util.py +165 -0
  34. lm_deluge/{llm_tools → pipelines}/score.py +2 -2
  35. lm_deluge/{llm_tools → pipelines}/translate.py +5 -3
  36. lm_deluge/prompt.py +224 -40
  37. lm_deluge/request_context.py +7 -2
  38. lm_deluge/tool/__init__.py +1118 -0
  39. lm_deluge/tool/builtin/anthropic/__init__.py +300 -0
  40. lm_deluge/tool/builtin/gemini.py +59 -0
  41. lm_deluge/tool/builtin/openai.py +74 -0
  42. lm_deluge/tool/cua/__init__.py +173 -0
  43. lm_deluge/tool/cua/actions.py +148 -0
  44. lm_deluge/tool/cua/base.py +27 -0
  45. lm_deluge/tool/cua/batch.py +215 -0
  46. lm_deluge/tool/cua/converters.py +466 -0
  47. lm_deluge/tool/cua/kernel.py +702 -0
  48. lm_deluge/tool/cua/trycua.py +989 -0
  49. lm_deluge/tool/prefab/__init__.py +45 -0
  50. lm_deluge/tool/prefab/batch_tool.py +156 -0
  51. lm_deluge/tool/prefab/docs.py +1119 -0
  52. lm_deluge/tool/prefab/email.py +294 -0
  53. lm_deluge/tool/prefab/filesystem.py +1711 -0
  54. lm_deluge/tool/prefab/full_text_search/__init__.py +285 -0
  55. lm_deluge/tool/prefab/full_text_search/tantivy_index.py +396 -0
  56. lm_deluge/tool/prefab/memory.py +458 -0
  57. lm_deluge/tool/prefab/otc/__init__.py +165 -0
  58. lm_deluge/tool/prefab/otc/executor.py +281 -0
  59. lm_deluge/tool/prefab/otc/parse.py +188 -0
  60. lm_deluge/tool/prefab/random.py +212 -0
  61. lm_deluge/tool/prefab/rlm/__init__.py +296 -0
  62. lm_deluge/tool/prefab/rlm/executor.py +349 -0
  63. lm_deluge/tool/prefab/rlm/parse.py +144 -0
  64. lm_deluge/tool/prefab/sandbox.py +1621 -0
  65. lm_deluge/tool/prefab/sheets.py +385 -0
  66. lm_deluge/tool/prefab/subagents.py +233 -0
  67. lm_deluge/tool/prefab/todos.py +342 -0
  68. lm_deluge/tool/prefab/tool_search.py +169 -0
  69. lm_deluge/tool/prefab/web_search.py +199 -0
  70. lm_deluge/tracker.py +16 -13
  71. lm_deluge/util/schema.py +412 -0
  72. lm_deluge/warnings.py +8 -0
  73. {lm_deluge-0.0.67.dist-info → lm_deluge-0.0.88.dist-info}/METADATA +22 -9
  74. lm_deluge-0.0.88.dist-info/RECORD +117 -0
  75. lm_deluge/built_in_tools/anthropic/__init__.py +0 -128
  76. lm_deluge/built_in_tools/openai.py +0 -28
  77. lm_deluge/presets/cerebras.py +0 -17
  78. lm_deluge/presets/meta.py +0 -13
  79. lm_deluge/tool.py +0 -849
  80. lm_deluge-0.0.67.dist-info/RECORD +0 -72
  81. lm_deluge/{llm_tools → pipelines}/__init__.py +1 -1
  82. /lm_deluge/{llm_tools → pipelines}/classify.py +0 -0
  83. /lm_deluge/{llm_tools → pipelines}/extract.py +0 -0
  84. /lm_deluge/{llm_tools → pipelines}/locate.py +0 -0
  85. /lm_deluge/{llm_tools → pipelines}/ocr.py +0 -0
  86. /lm_deluge/{built_in_tools → tool/builtin}/anthropic/bash.py +0 -0
  87. /lm_deluge/{built_in_tools → tool/builtin}/anthropic/computer_use.py +0 -0
  88. /lm_deluge/{built_in_tools → tool/builtin}/anthropic/editor.py +0 -0
  89. /lm_deluge/{built_in_tools → tool/builtin}/base.py +0 -0
  90. {lm_deluge-0.0.67.dist-info → lm_deluge-0.0.88.dist-info}/WHEEL +0 -0
  91. {lm_deluge-0.0.67.dist-info → lm_deluge-0.0.88.dist-info}/licenses/LICENSE +0 -0
  92. {lm_deluge-0.0.67.dist-info → lm_deluge-0.0.88.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,144 @@
1
+ """
2
+ RLM (Recursive Language Model) code parsing and validation.
3
+
4
+ Extends OTC's security model with additional modules for context analysis.
5
+ """
6
+
7
+ import ast
8
+ import collections
9
+ import json
10
+ import math
11
+ import re
12
+
13
+ # Import OTC's base security definitions
14
+ from ..otc.parse import (
15
+ FORBIDDEN_CALLS,
16
+ SAFE_BUILTINS,
17
+ ASTValidator,
18
+ OTCSecurityError,
19
+ )
20
+
21
+ # RLM uses the same builtins as OTC
22
+ RLM_SAFE_BUILTINS = SAFE_BUILTINS.copy()
23
+
24
+ # Modules available in RLM - imports of these are stripped (no-ops)
25
+ RLM_ALLOWED_IMPORTS = {"re", "math", "collections", "json"}
26
+
27
+ # Modules and common imports available in RLM (injected into globals)
28
+ RLM_MODULES = {
29
+ # Full modules
30
+ "re": re,
31
+ "math": math,
32
+ "collections": collections,
33
+ "json": json,
34
+ # Common imports from collections
35
+ "Counter": collections.Counter,
36
+ "defaultdict": collections.defaultdict,
37
+ "deque": collections.deque,
38
+ "namedtuple": collections.namedtuple,
39
+ "OrderedDict": collections.OrderedDict,
40
+ }
41
+
42
+
43
+ class RLMSecurityError(OTCSecurityError):
44
+ """Raised when RLM code violates security constraints."""
45
+
46
+ pass
47
+
48
+
49
+ class RLMExecutionError(Exception):
50
+ """Raised when RLM code execution fails."""
51
+
52
+ pass
53
+
54
+
55
+ class RLMASTValidator(ASTValidator):
56
+ """Validates RLM code with additional checks.
57
+
58
+ Import statements for allowed modules are stripped (no-ops).
59
+ Imports of disallowed modules raise errors.
60
+ """
61
+
62
+ def __init__(self, allowed_names: set[str] | None = None):
63
+ super().__init__(allowed_tool_names=set())
64
+ self.allowed_names = allowed_names or set()
65
+
66
+ def visit(self, node: ast.AST) -> None:
67
+ # Check imports - allowed ones will be stripped later, disallowed ones error
68
+ if isinstance(node, ast.Import):
69
+ for alias in node.names:
70
+ if alias.name not in RLM_ALLOWED_IMPORTS:
71
+ self.errors.append(
72
+ f"Forbidden import: {alias.name} at line {node.lineno}. "
73
+ f"Available modules: {', '.join(sorted(RLM_ALLOWED_IMPORTS))}"
74
+ )
75
+ self.generic_visit(node)
76
+ return
77
+
78
+ if isinstance(node, ast.ImportFrom):
79
+ if node.module not in RLM_ALLOWED_IMPORTS:
80
+ self.errors.append(
81
+ f"Forbidden import: from {node.module} at line {node.lineno}. "
82
+ f"Available modules: {', '.join(sorted(RLM_ALLOWED_IMPORTS))}"
83
+ )
84
+ self.generic_visit(node)
85
+ return
86
+
87
+ # For all other nodes, use parent validation
88
+ super().visit(node)
89
+
90
+ def visit_Call(self, node: ast.Call) -> None:
91
+ if isinstance(node.func, ast.Name):
92
+ if node.func.id in FORBIDDEN_CALLS:
93
+ self.errors.append(
94
+ f"Forbidden function call: {node.func.id} at line {node.lineno}"
95
+ )
96
+ self.generic_visit(node)
97
+
98
+
99
+ class ImportStripper(ast.NodeTransformer):
100
+ """Strips import statements for allowed modules from the AST."""
101
+
102
+ def visit_Import(self, node: ast.Import) -> ast.AST | None:
103
+ # Keep only imports of non-allowed modules (which will error at validation)
104
+ remaining = [
105
+ alias for alias in node.names if alias.name not in RLM_ALLOWED_IMPORTS
106
+ ]
107
+ if not remaining:
108
+ return None # Remove the entire import statement
109
+ node.names = remaining
110
+ return node
111
+
112
+ def visit_ImportFrom(self, node: ast.ImportFrom) -> ast.AST | None:
113
+ # Strip imports from allowed modules
114
+ if node.module in RLM_ALLOWED_IMPORTS:
115
+ return None # Remove the entire import statement
116
+ return node
117
+
118
+
119
+ def validate_rlm_code(code: str) -> ast.Module:
120
+ """Parse and validate RLM code, returning AST if valid.
121
+
122
+ Import statements for allowed modules (re, math, collections, json) are
123
+ stripped from the AST since these modules are already in the namespace.
124
+ """
125
+ try:
126
+ tree = ast.parse(code)
127
+ except SyntaxError as e:
128
+ raise RLMSecurityError(f"Syntax error: {e}")
129
+
130
+ # Validate first (before stripping)
131
+ validator = RLMASTValidator()
132
+ errors = validator.validate(tree)
133
+
134
+ if errors:
135
+ raise RLMSecurityError(
136
+ "Security violations:\n" + "\n".join(f" - {e}" for e in errors)
137
+ )
138
+
139
+ # Strip allowed imports (they're no-ops since modules are pre-loaded)
140
+ stripper = ImportStripper()
141
+ tree = stripper.visit(tree)
142
+ ast.fix_missing_locations(tree)
143
+
144
+ return tree