autobots-devtools-shared-lib 0.5.1__tar.gz → 0.5.3__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 (68) hide show
  1. {autobots_devtools_shared_lib-0.5.1 → autobots_devtools_shared_lib-0.5.3}/PKG-INFO +1 -1
  2. {autobots_devtools_shared_lib-0.5.1 → autobots_devtools_shared_lib-0.5.3}/pyproject.toml +1 -1
  3. {autobots_devtools_shared_lib-0.5.1 → autobots_devtools_shared_lib-0.5.3}/src/autobots_devtools_shared_lib/dynagent/utils/schema_directive_resolver.py +109 -20
  4. {autobots_devtools_shared_lib-0.5.1 → autobots_devtools_shared_lib-0.5.3}/README.md +0 -0
  5. {autobots_devtools_shared_lib-0.5.1 → autobots_devtools_shared_lib-0.5.3}/src/autobots_devtools_shared_lib/__init__.py +0 -0
  6. {autobots_devtools_shared_lib-0.5.1 → autobots_devtools_shared_lib-0.5.3}/src/autobots_devtools_shared_lib/common/__init__.py +0 -0
  7. {autobots_devtools_shared_lib-0.5.1 → autobots_devtools_shared_lib-0.5.3}/src/autobots_devtools_shared_lib/common/config/__init__.py +0 -0
  8. {autobots_devtools_shared_lib-0.5.1 → autobots_devtools_shared_lib-0.5.3}/src/autobots_devtools_shared_lib/common/config/jenkins_config.py +0 -0
  9. {autobots_devtools_shared_lib-0.5.1 → autobots_devtools_shared_lib-0.5.3}/src/autobots_devtools_shared_lib/common/config/jenkins_constants.py +0 -0
  10. {autobots_devtools_shared_lib-0.5.1 → autobots_devtools_shared_lib-0.5.3}/src/autobots_devtools_shared_lib/common/config/jenkins_loader.py +0 -0
  11. {autobots_devtools_shared_lib-0.5.1 → autobots_devtools_shared_lib-0.5.3}/src/autobots_devtools_shared_lib/common/observability/__init__.py +0 -0
  12. {autobots_devtools_shared_lib-0.5.1 → autobots_devtools_shared_lib-0.5.3}/src/autobots_devtools_shared_lib/common/observability/logging_utils.py +0 -0
  13. {autobots_devtools_shared_lib-0.5.1 → autobots_devtools_shared_lib-0.5.3}/src/autobots_devtools_shared_lib/common/observability/otel_fastapi.py +0 -0
  14. {autobots_devtools_shared_lib-0.5.1 → autobots_devtools_shared_lib-0.5.3}/src/autobots_devtools_shared_lib/common/observability/trace_metadata.py +0 -0
  15. {autobots_devtools_shared_lib-0.5.1 → autobots_devtools_shared_lib-0.5.3}/src/autobots_devtools_shared_lib/common/observability/trace_propagation.py +0 -0
  16. {autobots_devtools_shared_lib-0.5.1 → autobots_devtools_shared_lib-0.5.3}/src/autobots_devtools_shared_lib/common/observability/tracing.py +0 -0
  17. {autobots_devtools_shared_lib-0.5.1 → autobots_devtools_shared_lib-0.5.3}/src/autobots_devtools_shared_lib/common/servers/__init__.py +0 -0
  18. {autobots_devtools_shared_lib-0.5.1 → autobots_devtools_shared_lib-0.5.3}/src/autobots_devtools_shared_lib/common/servers/fileserver/README.md +0 -0
  19. {autobots_devtools_shared_lib-0.5.1 → autobots_devtools_shared_lib-0.5.3}/src/autobots_devtools_shared_lib/common/servers/fileserver/__init__.py +0 -0
  20. {autobots_devtools_shared_lib-0.5.1 → autobots_devtools_shared_lib-0.5.3}/src/autobots_devtools_shared_lib/common/servers/fileserver/app.py +0 -0
  21. {autobots_devtools_shared_lib-0.5.1 → autobots_devtools_shared_lib-0.5.3}/src/autobots_devtools_shared_lib/common/servers/fileserver/config.py +0 -0
  22. {autobots_devtools_shared_lib-0.5.1 → autobots_devtools_shared_lib-0.5.3}/src/autobots_devtools_shared_lib/common/servers/fileserver/models.py +0 -0
  23. {autobots_devtools_shared_lib-0.5.1 → autobots_devtools_shared_lib-0.5.3}/src/autobots_devtools_shared_lib/common/services/__init__.py +0 -0
  24. {autobots_devtools_shared_lib-0.5.1 → autobots_devtools_shared_lib-0.5.3}/src/autobots_devtools_shared_lib/common/services/context/README.md +0 -0
  25. {autobots_devtools_shared_lib-0.5.1 → autobots_devtools_shared_lib-0.5.3}/src/autobots_devtools_shared_lib/common/services/context/__init__.py +0 -0
  26. {autobots_devtools_shared_lib-0.5.1 → autobots_devtools_shared_lib-0.5.3}/src/autobots_devtools_shared_lib/common/services/context/cache_backed.py +0 -0
  27. {autobots_devtools_shared_lib-0.5.1 → autobots_devtools_shared_lib-0.5.3}/src/autobots_devtools_shared_lib/common/services/context/db_repository.py +0 -0
  28. {autobots_devtools_shared_lib-0.5.1 → autobots_devtools_shared_lib-0.5.3}/src/autobots_devtools_shared_lib/common/services/context/factory.py +0 -0
  29. {autobots_devtools_shared_lib-0.5.1 → autobots_devtools_shared_lib-0.5.3}/src/autobots_devtools_shared_lib/common/services/context/in_memory.py +0 -0
  30. {autobots_devtools_shared_lib-0.5.1 → autobots_devtools_shared_lib-0.5.3}/src/autobots_devtools_shared_lib/common/services/context/redis_store.py +0 -0
  31. {autobots_devtools_shared_lib-0.5.1 → autobots_devtools_shared_lib-0.5.3}/src/autobots_devtools_shared_lib/common/services/context/store.py +0 -0
  32. {autobots_devtools_shared_lib-0.5.1 → autobots_devtools_shared_lib-0.5.3}/src/autobots_devtools_shared_lib/common/tools/__init__.py +0 -0
  33. {autobots_devtools_shared_lib-0.5.1 → autobots_devtools_shared_lib-0.5.3}/src/autobots_devtools_shared_lib/common/tools/context_tools.py +0 -0
  34. {autobots_devtools_shared_lib-0.5.1 → autobots_devtools_shared_lib-0.5.3}/src/autobots_devtools_shared_lib/common/tools/format_tools.py +0 -0
  35. {autobots_devtools_shared_lib-0.5.1 → autobots_devtools_shared_lib-0.5.3}/src/autobots_devtools_shared_lib/common/tools/fserver_client_tools.py +0 -0
  36. {autobots_devtools_shared_lib-0.5.1 → autobots_devtools_shared_lib-0.5.3}/src/autobots_devtools_shared_lib/common/tools/jenkins_builtin_tools.py +0 -0
  37. {autobots_devtools_shared_lib-0.5.1 → autobots_devtools_shared_lib-0.5.3}/src/autobots_devtools_shared_lib/common/tools/jenkins_pipeline_tools.py +0 -0
  38. {autobots_devtools_shared_lib-0.5.1 → autobots_devtools_shared_lib-0.5.3}/src/autobots_devtools_shared_lib/common/utils/__init__.py +0 -0
  39. {autobots_devtools_shared_lib-0.5.1 → autobots_devtools_shared_lib-0.5.3}/src/autobots_devtools_shared_lib/common/utils/context_utils.py +0 -0
  40. {autobots_devtools_shared_lib-0.5.1 → autobots_devtools_shared_lib-0.5.3}/src/autobots_devtools_shared_lib/common/utils/format_utils.py +0 -0
  41. {autobots_devtools_shared_lib-0.5.1 → autobots_devtools_shared_lib-0.5.3}/src/autobots_devtools_shared_lib/common/utils/fserver_client_utils.py +0 -0
  42. {autobots_devtools_shared_lib-0.5.1 → autobots_devtools_shared_lib-0.5.3}/src/autobots_devtools_shared_lib/common/utils/jenkins_builtin_utils.py +0 -0
  43. {autobots_devtools_shared_lib-0.5.1 → autobots_devtools_shared_lib-0.5.3}/src/autobots_devtools_shared_lib/common/utils/jenkins_http_utils.py +0 -0
  44. {autobots_devtools_shared_lib-0.5.1 → autobots_devtools_shared_lib-0.5.3}/src/autobots_devtools_shared_lib/common/utils/jenkins_pipeline_utils.py +0 -0
  45. {autobots_devtools_shared_lib-0.5.1 → autobots_devtools_shared_lib-0.5.3}/src/autobots_devtools_shared_lib/dynagent/__init__.py +0 -0
  46. {autobots_devtools_shared_lib-0.5.1 → autobots_devtools_shared_lib-0.5.3}/src/autobots_devtools_shared_lib/dynagent/agents/__init__.py +0 -0
  47. {autobots_devtools_shared_lib-0.5.1 → autobots_devtools_shared_lib-0.5.3}/src/autobots_devtools_shared_lib/dynagent/agents/agent_config_utils.py +0 -0
  48. {autobots_devtools_shared_lib-0.5.1 → autobots_devtools_shared_lib-0.5.3}/src/autobots_devtools_shared_lib/dynagent/agents/agent_meta.py +0 -0
  49. {autobots_devtools_shared_lib-0.5.1 → autobots_devtools_shared_lib-0.5.3}/src/autobots_devtools_shared_lib/dynagent/agents/base_agent.py +0 -0
  50. {autobots_devtools_shared_lib-0.5.1 → autobots_devtools_shared_lib-0.5.3}/src/autobots_devtools_shared_lib/dynagent/agents/batch.py +0 -0
  51. {autobots_devtools_shared_lib-0.5.1 → autobots_devtools_shared_lib-0.5.3}/src/autobots_devtools_shared_lib/dynagent/agents/invocation_utils.py +0 -0
  52. {autobots_devtools_shared_lib-0.5.1 → autobots_devtools_shared_lib-0.5.3}/src/autobots_devtools_shared_lib/dynagent/agents/middleware.py +0 -0
  53. {autobots_devtools_shared_lib-0.5.1 → autobots_devtools_shared_lib-0.5.3}/src/autobots_devtools_shared_lib/dynagent/config/__init__.py +0 -0
  54. {autobots_devtools_shared_lib-0.5.1 → autobots_devtools_shared_lib-0.5.3}/src/autobots_devtools_shared_lib/dynagent/config/dynagent_settings.py +0 -0
  55. {autobots_devtools_shared_lib-0.5.1 → autobots_devtools_shared_lib-0.5.3}/src/autobots_devtools_shared_lib/dynagent/llm/__init__.py +0 -0
  56. {autobots_devtools_shared_lib-0.5.1 → autobots_devtools_shared_lib-0.5.3}/src/autobots_devtools_shared_lib/dynagent/llm/llm.py +0 -0
  57. {autobots_devtools_shared_lib-0.5.1 → autobots_devtools_shared_lib-0.5.3}/src/autobots_devtools_shared_lib/dynagent/models/__init__.py +0 -0
  58. {autobots_devtools_shared_lib-0.5.1 → autobots_devtools_shared_lib-0.5.3}/src/autobots_devtools_shared_lib/dynagent/models/state.py +0 -0
  59. {autobots_devtools_shared_lib-0.5.1 → autobots_devtools_shared_lib-0.5.3}/src/autobots_devtools_shared_lib/dynagent/services/__init__.py +0 -0
  60. {autobots_devtools_shared_lib-0.5.1 → autobots_devtools_shared_lib-0.5.3}/src/autobots_devtools_shared_lib/dynagent/services/structured_converter.py +0 -0
  61. {autobots_devtools_shared_lib-0.5.1 → autobots_devtools_shared_lib-0.5.3}/src/autobots_devtools_shared_lib/dynagent/tools/__init__.py +0 -0
  62. {autobots_devtools_shared_lib-0.5.1 → autobots_devtools_shared_lib-0.5.3}/src/autobots_devtools_shared_lib/dynagent/tools/state_tools.py +0 -0
  63. {autobots_devtools_shared_lib-0.5.1 → autobots_devtools_shared_lib-0.5.3}/src/autobots_devtools_shared_lib/dynagent/tools/tool_registry.py +0 -0
  64. {autobots_devtools_shared_lib-0.5.1 → autobots_devtools_shared_lib-0.5.3}/src/autobots_devtools_shared_lib/dynagent/ui/__init__.py +0 -0
  65. {autobots_devtools_shared_lib-0.5.1 → autobots_devtools_shared_lib-0.5.3}/src/autobots_devtools_shared_lib/dynagent/ui/default_ui.py +0 -0
  66. {autobots_devtools_shared_lib-0.5.1 → autobots_devtools_shared_lib-0.5.3}/src/autobots_devtools_shared_lib/dynagent/ui/ui_utils.py +0 -0
  67. {autobots_devtools_shared_lib-0.5.1 → autobots_devtools_shared_lib-0.5.3}/src/autobots_devtools_shared_lib/dynagent/utils/__init__.py +0 -0
  68. {autobots_devtools_shared_lib-0.5.1 → autobots_devtools_shared_lib-0.5.3}/src/autobots_devtools_shared_lib/py.typed +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: autobots-devtools-shared-lib
3
- Version: 0.5.1
3
+ Version: 0.5.3
4
4
  Summary: Shared library functions to be used for all autobots projects
5
5
  License: MIT
6
6
  Author: Pralhad
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "autobots-devtools-shared-lib"
3
- version = "0.5.1"
3
+ version = "0.5.3"
4
4
  description = "Shared library functions to be used for all autobots projects"
5
5
  readme = "README.md"
6
6
  authors = [
@@ -29,10 +29,9 @@ def _resolve_json_pointer(document: Any, pointer: str) -> Any:
29
29
  if pointer == "":
30
30
  return document
31
31
  if pointer == "/":
32
- # RFC 6901: "/" means the key "" (empty string) in the root object
33
- if isinstance(document, dict) and "" in document:
34
- return document[""]
35
- raise ValueError("JSON Pointer '/' targets empty-string key, but document has no such key")
32
+ # Directive convention: "/" means the root document, not the RFC 6901 empty-string key.
33
+ # Schemas in this codebase never have an empty-string key, so treat "/" as root.
34
+ return document
36
35
 
37
36
  if not pointer.startswith("/"):
38
37
  raise ValueError(f"Invalid JSON Pointer (must start with '/'): {pointer}")
@@ -92,9 +91,10 @@ def _retrieve_from_path(base_dir: Path):
92
91
 
93
92
  def _retrieve(uri: str) -> Resource:
94
93
  from urllib.parse import unquote, urlparse
94
+ from urllib.request import url2pathname
95
95
 
96
96
  parsed = urlparse(uri)
97
- path = Path(unquote(parsed.path))
97
+ path = Path(url2pathname(unquote(parsed.path)))
98
98
  if not path.is_absolute():
99
99
  path = base_dir / path
100
100
  contents = json.loads(path.read_text())
@@ -144,6 +144,99 @@ def _merge_parent_schemas(parent_docs: list[dict]) -> dict:
144
144
  return merged
145
145
 
146
146
 
147
+ def _flatten_directive_entries(
148
+ entries: list[dict],
149
+ directive_dir: Path,
150
+ link_target: str = "",
151
+ _seen: frozenset[str] = frozenset(),
152
+ _sources: list[dict] | None = None,
153
+ ) -> list[tuple[str, dict, str | None]]:
154
+ """Flatten directive entries, resolving ``$ref`` links recursively.
155
+
156
+ Entries with ``$ref`` load the referenced directive file and rebase its entries
157
+ under the linking entry's ``target``. Recursion is guarded by ``_seen``.
158
+
159
+ Rebasing rule:
160
+ - Referenced ``/`` → ``link_target`` (or ``/`` at top level)
161
+ - Referenced ``/properties/x`` → ``link_target + /properties/x``
162
+
163
+ Args:
164
+ entries: The ``directives`` list from a directive document.
165
+ directive_dir: Directory for resolving relative ``$ref`` paths.
166
+ link_target: JSON Pointer prefix for all targets in ``entries``.
167
+ Empty string means no rebasing (top-level call).
168
+ _seen: Resolved directive file paths — guards against circular references.
169
+ _sources: Optional list; each loaded directive file appends its metadata here.
170
+
171
+ Returns:
172
+ Flat list of ``(pointer, pragma_obj, description)`` tuples.
173
+ """
174
+ result: list[tuple[str, dict, str | None]] = []
175
+
176
+ for entry in entries:
177
+ if not isinstance(entry, dict):
178
+ raise TypeError(f"Directive entries must be objects, got {type(entry)!r}")
179
+
180
+ has_ref = "$ref" in entry
181
+ has_pragmas = "x-fbp-pragmas" in entry
182
+
183
+ if not has_ref and not has_pragmas:
184
+ raise ValueError(
185
+ f"Directive entry must have 'x-fbp-pragmas' or '$ref' "
186
+ f"(target={entry.get('target')!r}): {entry}"
187
+ )
188
+
189
+ entry_target: str = entry.get("target", "/")
190
+
191
+ # Compute the absolute JSON Pointer for this entry.
192
+ if entry_target == "/":
193
+ abs_target = link_target if link_target else "/"
194
+ else:
195
+ abs_target = (link_target + entry_target) if link_target else entry_target
196
+
197
+ # Emit this entry's own x-fbp-pragmas at abs_target.
198
+ if has_pragmas:
199
+ result.append((abs_target, entry["x-fbp-pragmas"], entry.get("description")))
200
+
201
+ # Resolve $ref: load the referenced directive file and rebase its entries.
202
+ if has_ref:
203
+ ref: str = entry["$ref"]
204
+ ref_path = (directive_dir / ref).resolve()
205
+ ref_uri = str(ref_path)
206
+
207
+ if ref_uri in _seen:
208
+ raise ValueError(f"Circular $ref in directives detected: {ref!r}")
209
+
210
+ try:
211
+ ref_doc = json.loads(ref_path.read_text())
212
+ except (OSError, json.JSONDecodeError) as e:
213
+ raise ValueError(f"Failed to load directive $ref {ref!r}: {e}") from e
214
+
215
+ if _sources is not None:
216
+ _sources.append(
217
+ {
218
+ "id": ref_doc.get("id", ref_path.stem),
219
+ "title": ref_doc.get("title", ref_path.stem),
220
+ }
221
+ )
222
+
223
+ sub_entries = ref_doc.get("directives", [])
224
+ if not isinstance(sub_entries, list):
225
+ raise TypeError(f"'directives' in {ref!r} must be a list")
226
+
227
+ result.extend(
228
+ _flatten_directive_entries(
229
+ sub_entries,
230
+ ref_path.parent,
231
+ abs_target,
232
+ _seen | {ref_uri},
233
+ _sources,
234
+ )
235
+ )
236
+
237
+ return result
238
+
239
+
147
240
  def resolve_parent_with_directives(parent_paths: list[Path], directive_path: None | Path) -> dict:
148
241
  """Load parent schema(s), merge common+domain, then apply directives.
149
242
 
@@ -211,16 +304,18 @@ def resolve_parent_with_directives(parent_paths: list[Path], directive_path: Non
211
304
  }
212
305
  sources.append(directive_source)
213
306
 
214
- for entry in entries:
215
- if not isinstance(entry, dict):
216
- raise TypeError(f"Directive entries must be objects in '{directive_path.name}'")
217
- if "target" not in entry or "x-fbp-pragmas" not in entry:
218
- raise ValueError(
219
- f"Directive entry in '{directive_path.name}' is missing 'target' or 'x-fbp-pragmas': {entry}"
307
+ transitive_sources: list[dict] = []
308
+ flat_entries = _flatten_directive_entries(
309
+ entries, directive_path.parent, _sources=transitive_sources
310
+ )
311
+ sources.extend(transitive_sources)
312
+
313
+ for pointer, pragma_obj, description in flat_entries:
314
+ if not isinstance(pragma_obj, dict):
315
+ raise TypeError(
316
+ f"'x-fbp-pragmas' must be an object in directive '{directive_path.name}' "
317
+ f"for target '{pointer}', got {type(pragma_obj)!r}"
220
318
  )
221
- pointer = entry["target"]
222
- pragma_obj = entry["x-fbp-pragmas"]
223
- description = entry.get("description")
224
319
 
225
320
  try:
226
321
  target_node = _resolve_json_pointer(merged, pointer)
@@ -229,12 +324,6 @@ def resolve_parent_with_directives(parent_paths: list[Path], directive_path: Non
229
324
  logger.exception(error_msg)
230
325
  raise ValueError(error_msg) from e
231
326
 
232
- if not isinstance(pragma_obj, dict):
233
- raise TypeError(
234
- f"'x-fbp-pragmas' must be an object in directive '{directive_path.name}' "
235
- f"for target '{pointer}', got {type(pragma_obj)!r}"
236
- )
237
-
238
327
  _merge_pragmas(target_node, pragma_obj, description)
239
328
 
240
329
  return merged