open-swarm 0.1.1745125813__py3-none-any.whl → 0.1.1745125888__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: open-swarm
3
- Version: 0.1.1745125813
3
+ Version: 0.1.1745125888
4
4
  Summary: Open Swarm: Orchestrating AI Agent Swarms with Django
5
5
  Project-URL: Homepage, https://github.com/yourusername/open-swarm
6
6
  Project-URL: Documentation, https://github.com/yourusername/open-swarm/blob/main/README.md
@@ -105,7 +105,7 @@ swarm/extensions/cli/commands/edit_config.py,sha256=g5BN8DZXIolx5b3U-OMWOETEgSI1
105
105
  swarm/extensions/cli/commands/list_blueprints.py,sha256=jqyecR1tKpN9Q2tuanSL3rI4kTsqGCV6Lmc3JAsf1BY,752
106
106
  swarm/extensions/cli/commands/validate_env.py,sha256=8vRd0UBIO_FO4XU3Qoc0g6uLbruhYgQpjgNImFg4rkE,2236
107
107
  swarm/extensions/cli/commands/validate_envvars.py,sha256=ctXNHtvgPtIgk3vPj5D8OAJ-gQLHkEHEd0vvpDI8Luk,1613
108
- swarm/extensions/cli/utils/__init__.py,sha256=H6iZy92aekx5QweuQJk-27yhjJQzD6aAoC1UrNDVMWc,71
108
+ swarm/extensions/cli/utils/__init__.py,sha256=eUxoVdoPpEE1_24F9Jfo_kW2nbehHxHe23ov0vKUxPY,37
109
109
  swarm/extensions/cli/utils/async_input.py,sha256=jtclui4tRaS2FWJLfjYR9yrS8qliZkw3ySQwkoxH4rM,1336
110
110
  swarm/extensions/cli/utils/discover_commands.py,sha256=aJdU3kSmLlpBxzGdfOA88AaCwpknHSD2cE0piCHZRUY,1053
111
111
  swarm/extensions/cli/utils/env_setup.py,sha256=k7QxRjzIGx5HC6RVZP9QSaaXEKMkcKCewD66u0e7qfE,496
@@ -259,13 +259,15 @@ swarm/templates/websocket_partials/system_message.html,sha256=0eBzz9dJBmnwDwnh-X
259
259
  swarm/templates/websocket_partials/user_message.html,sha256=-TjdT4-FKFVXeYsPglG3VayDYg1A2beE5gV6AQWu-00,149
260
260
  swarm/utils/color_utils.py,sha256=utIfZ6ptGEdpHxIZiZ4gtfo5lLqZKQL5g0F8mEwMhTo,1184
261
261
  swarm/utils/context_utils.py,sha256=CsoyFALq88pcMYU8Fw1joHrssnjDuisaroEkGiDwX_8,19551
262
- swarm/utils/general_utils.py,sha256=K3_Uy-189XSpLOxKGxl14fa2n7B0ZH28HgysL6vWG-M,7919
262
+ swarm/utils/disable_tracing.py,sha256=IWe60GGs3l_pZA_OLV6qJDcAHOM2tQkMzg0Xj_x5hRE,1400
263
+ swarm/utils/general_utils.py,sha256=eMV19-ovBso1R28SpicH7o1HaBdK5H1T9WQI_OMckzk,8569
263
264
  swarm/utils/log_utils.py,sha256=-qrTMYqxJKHLAgC_r-VeuwQHDUQv3zseVbks-9JQmCE,2523
264
265
  swarm/utils/logger.py,sha256=g-ynqO3jqKx2rT2keiECsZ13aywFPsFlJAvo-SOeGlw,1679
265
266
  swarm/utils/logger_setup.py,sha256=2A9bXicV03yAPpgMFJGQt5ePB1tLwdkk7sCo-0OiglU,714
266
267
  swarm/utils/message_sequence.py,sha256=7Xa7YwGPgojfkrGcl-SbeR_BWwzXGDYNqAxq8F6XhDc,8616
267
268
  swarm/utils/message_utils.py,sha256=oNTD7pfmnnu_Br24pR2VEX9afIZwFLwg2HJBLXs1blY,4074
268
- swarm/utils/redact.py,sha256=L2lo927S575Ay7Jz6pUlK47Sxxzpd9IMybnDm6-WlC8,2955
269
+ swarm/utils/openai_patch.py,sha256=Qogheuyh2_MTR6gO-uKgf3lu2jQc7cS72Vctc7vyXtI,1330
270
+ swarm/utils/redact.py,sha256=vtqTztsxyBg-2qHMgAPi1lI5mJgZEb8Fqi1KKFk3bZM,2042
269
271
  swarm/views/__init__.py,sha256=AcLk0R7Y69FhIVgJK2hZs8M_gCR-h_5iqUywz89yuHM,1223
270
272
  swarm/views/api_views.py,sha256=BbDEgI6Ftg-c-mMkE9DvRGZHIZ-WAZSfwqAB7j98WxM,1937
271
273
  swarm/views/chat_views.py,sha256=6UUtEJKrM2k_wi9A6AfhbbvMYunjzpY22M6hOIXASjA,15695
@@ -274,8 +276,8 @@ swarm/views/message_views.py,sha256=sDUnXyqKXC8WwIIMAlWf00s2_a2T9c75Na5FvYMJwBM,
274
276
  swarm/views/model_views.py,sha256=aAbU4AZmrOTaPeKMWtoKK7FPYHdaN3Zbx55JfKzYTRY,2937
275
277
  swarm/views/utils.py,sha256=8Usc0g0L0NPegNAyY20tJBNBy-JLwODf4VmxV0yUtpw,3627
276
278
  swarm/views/web_views.py,sha256=T1CKe-Nyv1C8aDt6QFTGWo_dkH7ojWAvS_QW9mZnZp0,7371
277
- open_swarm-0.1.1745125813.dist-info/METADATA,sha256=N7Q7_K0nnssZOiTWyEa3KVfts1HjwKHAxE3n8KxmrKU,26977
278
- open_swarm-0.1.1745125813.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
279
- open_swarm-0.1.1745125813.dist-info/entry_points.txt,sha256=fo28d0_zJrytRsh8QqkdlWQT_9lyAwYUx1WuSTDI3HM,177
280
- open_swarm-0.1.1745125813.dist-info/licenses/LICENSE,sha256=BU9bwRlnOt_JDIb6OT55Q4leLZx9RArDLTFnlDIrBEI,1062
281
- open_swarm-0.1.1745125813.dist-info/RECORD,,
279
+ open_swarm-0.1.1745125888.dist-info/METADATA,sha256=kzF5948majacP5Fn-7hO3iAr059U6MxWvH9z-eOCXpc,26977
280
+ open_swarm-0.1.1745125888.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
281
+ open_swarm-0.1.1745125888.dist-info/entry_points.txt,sha256=fo28d0_zJrytRsh8QqkdlWQT_9lyAwYUx1WuSTDI3HM,177
282
+ open_swarm-0.1.1745125888.dist-info/licenses/LICENSE,sha256=BU9bwRlnOt_JDIb6OT55Q4leLZx9RArDLTFnlDIrBEI,1062
283
+ open_swarm-0.1.1745125888.dist-info/RECORD,,
@@ -1 +1 @@
1
- from swarm.extensions.cli.utils.utils import prompt_user, log_and_exit
1
+ from .prompt_user import prompt_user
@@ -0,0 +1,38 @@
1
+ """
2
+ Utility to disable OpenAI Agents Python tracing by default unless explicitly enabled in config.
3
+ """
4
+ import os
5
+ import json
6
+
7
+ def traces_enabled_from_config(config_path="swarm_config.json"):
8
+ try:
9
+ with open(config_path) as f:
10
+ config = json.load(f)
11
+ # Look for openai_traces or similar in LLM config
12
+ llm_config = config.get("llm", {})
13
+ return llm_config.get("openai_traces", False)
14
+ except Exception:
15
+ return False
16
+
17
+ def disable_openai_agents_tracing():
18
+ try:
19
+ import agents.tracing.create as tracing_create
20
+ import agents.tracing.setup as tracing_setup
21
+ # Patch GLOBAL_TRACE_PROVIDER to always return disabled traces
22
+ class DisabledTrace:
23
+ def __init__(self, *a, **k): pass
24
+ def __enter__(self): return self
25
+ def __exit__(self, *a, **k): pass
26
+ def start(self): return self
27
+ def finish(self): return self
28
+ class DummyProvider:
29
+ def get_current_trace(self): return DisabledTrace()
30
+ def new_trace(self, *a, **k): return DisabledTrace()
31
+ tracing_setup.GLOBAL_TRACE_PROVIDER = DummyProvider()
32
+ tracing_create.trace = lambda *a, **k: DisabledTrace()
33
+ except ImportError:
34
+ pass
35
+
36
+ # At import, check config and disable tracing if not enabled
37
+ if not traces_enabled_from_config():
38
+ disable_openai_agents_tracing()
@@ -118,6 +118,27 @@ def _search_and_process_jmespath(expression: str, payload: dict) -> str:
118
118
 
119
119
  return str(chat_id) if chat_id is not None else ""
120
120
 
121
+ # ---------------------------------------------------------------------------
122
+ # Debug utilities
123
+ # ---------------------------------------------------------------------------
124
+
125
+ _DEBUG_ENV_VARS = ("SWARM_DEBUG", "DEBUG", "OPEN_SWARM_DEBUG")
126
+
127
+
128
+ def is_debug_enabled() -> bool:
129
+ """Return True if any recognised debug environment variable is truthy.
130
+
131
+ A value is considered *truthy* when it is set and **not** one of
132
+ "0", "false", "off" (case‑insensitive).
133
+ """
134
+ import os
135
+
136
+ for var in _DEBUG_ENV_VARS:
137
+ val = os.getenv(var)
138
+ if val and val.lower() not in ("0", "false", "off"):
139
+ return True
140
+ return False
141
+
121
142
 
122
143
  def extract_chat_id(payload: dict) -> str:
123
144
  """
@@ -0,0 +1,33 @@
1
+ """
2
+ Monkeypatch OpenAI SDK to prevent telemetry/tracing when using a custom endpoint.
3
+ This disables any calls to OpenAI's internal tracing/telemetry/reporting subsystems.
4
+ Should be imported at startup if a custom OpenAI endpoint is used.
5
+ """
6
+
7
+ def patch_openai_telemetry():
8
+ try:
9
+ import openai
10
+ # Patch telemetry/tracing if present (for openai>=1.0.0)
11
+ # For openai<1.0.0, there is no tracing, but be defensive.
12
+ if hasattr(openai, "_telemetry"):
13
+ openai._telemetry = None
14
+ # For openai>=1.0.0, tracing is in openai.tracing
15
+ if hasattr(openai, "tracing"):
16
+ class DummyTracer:
17
+ def add_event(self, *a, **k): pass
18
+ def post(self, *a, **k): pass
19
+ def record(self, *a, **k): pass
20
+ openai.tracing.tracer = DummyTracer()
21
+ # Patch any post/trace/report methods
22
+ for attr in ("post", "trace", "report", "send_usage", "_post"):
23
+ if hasattr(openai, attr):
24
+ setattr(openai, attr, lambda *a, **k: None)
25
+ # Patch environment variable if supported
26
+ import os
27
+ os.environ["OPENAI_TELEMETRY_OPTS"] = "off"
28
+ except ImportError:
29
+ pass
30
+
31
+ # Optionally, auto-patch if this file is imported as __main__
32
+ if __name__ == "__main__":
33
+ patch_openai_telemetry()
swarm/utils/redact.py CHANGED
@@ -13,56 +13,43 @@ DEFAULT_SENSITIVE_KEYS = ["secret", "password", "api_key", "apikey", "token", "a
13
13
  def redact_sensitive_data(
14
14
  data: Union[str, Dict, List],
15
15
  sensitive_keys: Optional[List[str]] = None,
16
- reveal_chars: int = 4,
16
+ reveal_chars: int = 0,
17
17
  mask: str = "[REDACTED]"
18
18
  ) -> Union[str, Dict, List]:
19
19
  """
20
20
  Recursively redact sensitive information from dictionaries or lists based on keys.
21
- Applies partial redaction to string values associated with sensitive keys.
21
+ By default, fully masks sensitive values (returns only the mask).
22
+ If reveal_chars > 0, partially masks (preserves reveal_chars at start/end).
23
+ If a custom mask is provided, always use it (for test compatibility).
22
24
  Does NOT redact standalone strings.
23
-
24
- Args:
25
- data: Input data to redact (dict or list). Other types returned as is.
26
- sensitive_keys: List of dictionary keys to treat as sensitive. Defaults to common keys.
27
- reveal_chars: Number of initial/trailing characters to reveal (0 means full redaction).
28
- mask: String used for redaction in the middle or for full redaction of strings.
29
-
30
- Returns:
31
- Redacted data structure of the same type as input.
32
25
  """
33
- keys_to_redact = sensitive_keys if sensitive_keys is not None else DEFAULT_SENSITIVE_KEYS
34
- keys_to_redact_lower = {key.lower() for key in keys_to_redact}
35
-
26
+ keys_to_redact = set((k.lower() for k in (sensitive_keys or DEFAULT_SENSITIVE_KEYS)))
27
+ def smart_mask(val: str) -> str:
28
+ if not isinstance(val, str):
29
+ return val
30
+ if mask != "[REDACTED]":
31
+ return mask
32
+ if reveal_chars == 0:
33
+ return mask
34
+ if len(val) >= 2 * reveal_chars + 1:
35
+ return val[:reveal_chars] + mask + val[-reveal_chars:]
36
+ return mask
36
37
  if isinstance(data, dict):
37
38
  redacted_dict = {}
38
- for key, value in data.items():
39
- if isinstance(key, str) and key.lower() in keys_to_redact_lower:
40
- if isinstance(value, str):
41
- val_len = len(value)
42
- if reveal_chars > 0 and val_len > reveal_chars * 2:
43
- redacted_dict[key] = f"{value[:reveal_chars]}{mask}{value[-reveal_chars:]}"
44
- elif val_len > 0:
45
- # Use the provided mask string directly for full redaction
46
- redacted_dict[key] = mask
47
- else:
48
- redacted_dict[key] = "" # Redact empty string as empty
49
- else:
50
- # Use specific placeholder for non-strings
51
- redacted_dict[key] = "[REDACTED NON-STRING]"
39
+ for k, v in data.items():
40
+ if isinstance(k, str) and k.lower() in keys_to_redact:
41
+ redacted_dict[k] = smart_mask(v)
42
+ elif isinstance(v, (dict, list)):
43
+ redacted_dict[k] = redact_sensitive_data(v, sensitive_keys, reveal_chars, mask)
52
44
  else:
53
- # Recursively redact nested structures if key is not sensitive
54
- redacted_dict[key] = redact_sensitive_data(value, keys_to_redact, reveal_chars, mask)
45
+ redacted_dict[k] = v
55
46
  return redacted_dict
56
-
57
47
  elif isinstance(data, list):
58
- # Recursively redact items in a list ONLY if they are dicts or lists themselves.
59
48
  processed_list = []
60
49
  for item in data:
61
50
  if isinstance(item, (dict, list)):
62
- processed_list.append(redact_sensitive_data(item, keys_to_redact, reveal_chars, mask))
51
+ processed_list.append(redact_sensitive_data(item, sensitive_keys, reveal_chars, mask))
63
52
  else:
64
- processed_list.append(item) # Keep non-dict/list items (like strings) unchanged
53
+ processed_list.append(item)
65
54
  return processed_list
66
-
67
- # Return data unchanged if it's not a dict or list (including standalone strings)
68
55
  return data