coding-client 1.21.2__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.
Files changed (109) hide show
  1. coding_client/__init__.py +1 -0
  2. coding_client/api/__init__.py +19 -0
  3. coding_client/api/exception_handlers.py +158 -0
  4. coding_client/api/logging_setup.py +44 -0
  5. coding_client/api/metrics.py +40 -0
  6. coding_client/api/openapi_config.py +124 -0
  7. coding_client/api/request_logging.py +60 -0
  8. coding_client/api/validation.py +150 -0
  9. coding_client/auth/__init__.py +78 -0
  10. coding_client/auth/_default_tenant.py +132 -0
  11. coding_client/auth/_header_trust.py +98 -0
  12. coding_client/auth/_onbehalf.py +315 -0
  13. coding_client/auth/_trusted_networks.py +94 -0
  14. coding_client/auth/dependencies.py +61 -0
  15. coding_client/auth/middleware.py +445 -0
  16. coding_client/auth/models.py +83 -0
  17. coding_client/auth/outbound.py +137 -0
  18. coding_client/auth/rbac.py +21 -0
  19. coding_client/auth/rbac_coding.py +5 -0
  20. coding_client/auth/tenant.py +650 -0
  21. coding_client/auth/websocket.py +148 -0
  22. coding_client/clients/__init__.py +24 -0
  23. coding_client/clients/base.py +131 -0
  24. coding_client/clients/coding_ai.py +33 -0
  25. coding_client/clients/coding_analysis.py +36 -0
  26. coding_client/clients/coding_containers.py +45 -0
  27. coding_client/clients/coding_github.py +127 -0
  28. coding_client/clients/coding_realtime.py +127 -0
  29. coding_client/clients/coding_security.py +51 -0
  30. coding_client/clients/coding_testing.py +31 -0
  31. coding_client/clients/coding_workspaces.py +265 -0
  32. coding_client/config/__init__.py +12 -0
  33. coding_client/config/base_settings.py +61 -0
  34. coding_client/config/yaml_config_loader.py +172 -0
  35. coding_client/db/__init__.py +42 -0
  36. coding_client/db/db_types.py +122 -0
  37. coding_client/db/exceptions.py +59 -0
  38. coding_client/db/postgres_connection.py +572 -0
  39. coding_client/db/tenant_query_helper.py +417 -0
  40. coding_client/db_init.py +49 -0
  41. coding_client/exceptions/__init__.py +67 -0
  42. coding_client/exceptions/api_exceptions.py +395 -0
  43. coding_client/exceptions/pydantic_ai_exceptions.py +533 -0
  44. coding_client/interfaces/__init__.py +22 -0
  45. coding_client/interfaces/cache_interface.py +179 -0
  46. coding_client/interfaces/container_interface.py +49 -0
  47. coding_client/interfaces/docker_interface.py +283 -0
  48. coding_client/interfaces/graph_interface.py +28 -0
  49. coding_client/interfaces/security_interface.py +72 -0
  50. coding_client/interfaces/webhook_interface.py +67 -0
  51. coding_client/llm/__init__.py +54 -0
  52. coding_client/llm/base_agent.py +195 -0
  53. coding_client/llm/context.py +121 -0
  54. coding_client/llm/responses.py +102 -0
  55. coding_client/llm/routing.py +82 -0
  56. coding_client/llm/settings.py +102 -0
  57. coding_client/models/__init__.py +62 -0
  58. coding_client/models/agent.py +38 -0
  59. coding_client/models/ai_test_failure.py +745 -0
  60. coding_client/models/analysis.py +330 -0
  61. coding_client/models/architecture.py +685 -0
  62. coding_client/models/bug.py +128 -0
  63. coding_client/models/code_graph.py +317 -0
  64. coding_client/models/container.py +241 -0
  65. coding_client/models/core.py +878 -0
  66. coding_client/models/docker_container.py +104 -0
  67. coding_client/models/github.py +293 -0
  68. coding_client/models/logging.py +29 -0
  69. coding_client/models/package_manager.py +257 -0
  70. coding_client/models/pr_validation.py +440 -0
  71. coding_client/models/pydantic_ai.py +395 -0
  72. coding_client/models/repo_scanner.py +249 -0
  73. coding_client/models/responses.py +431 -0
  74. coding_client/models/security.py +185 -0
  75. coding_client/models/static_analysis.py +508 -0
  76. coding_client/models/system.py +48 -0
  77. coding_client/models/test_executor.py +204 -0
  78. coding_client/models/testing.py +673 -0
  79. coding_client/models/testing_config.py +200 -0
  80. coding_client/models/validation.py +127 -0
  81. coding_client/models_init.py +272 -0
  82. coding_client/telemetry.py +195 -0
  83. coding_client/testing.py +180 -0
  84. coding_client/types/__init__.py +130 -0
  85. coding_client/types/constraint_types.py +276 -0
  86. coding_client/types/core_types.py +112 -0
  87. coding_client/types/state_machine.py +443 -0
  88. coding_client/utils/__init__.py +86 -0
  89. coding_client/utils/archive_utils.py +387 -0
  90. coding_client/utils/ast_debug.py +45 -0
  91. coding_client/utils/async_timeout.py +364 -0
  92. coding_client/utils/constants.py +518 -0
  93. coding_client/utils/content_processing.py +326 -0
  94. coding_client/utils/database.py +916 -0
  95. coding_client/utils/encoding_helper.py +222 -0
  96. coding_client/utils/enum_helpers.py +166 -0
  97. coding_client/utils/file_operations.py +177 -0
  98. coding_client/utils/filesystem_ops.py +528 -0
  99. coding_client/utils/http_client.py +562 -0
  100. coding_client/utils/path_utils.py +471 -0
  101. coding_client/utils/profiling.py +421 -0
  102. coding_client/utils/response_builder.py +240 -0
  103. coding_client/utils/retry_helper.py +712 -0
  104. coding_client/utils/security_validation.py +423 -0
  105. coding_client-1.21.2.dist-info/METADATA +234 -0
  106. coding_client-1.21.2.dist-info/RECORD +109 -0
  107. coding_client-1.21.2.dist-info/WHEEL +5 -0
  108. coding_client-1.21.2.dist-info/licenses/LICENSE +201 -0
  109. coding_client-1.21.2.dist-info/top_level.txt +1 -0
@@ -0,0 +1,195 @@
1
+ """OpenTelemetry trace setup for coding-* services.
2
+
3
+ One implementation, called once per service at **application-construction time**.
4
+
5
+ Why this lives in the SDK rather than a per-repo ``telemetry.py``: the wider fleet
6
+ copies a ``src/telemetry.py`` into every repo, and those copies drift. Three
7
+ coding services each grew their own version of this block and **all three emitted
8
+ nothing**, for three different reasons, for months — while logging that tracing
9
+ was enabled.
10
+
11
+ The trap that made them silent is the reason ``setup_tracing`` refuses rather than
12
+ returns:
13
+
14
+ ``FastAPIInstrumentor.instrument_app(app)`` called inside a FastAPI lifespan
15
+ produces **zero spans and raises nothing**. By the time the lifespan runs,
16
+ Starlette has already built the middleware stack, so the instrumentation is
17
+ discarded silently.
18
+
19
+ So a late call is a hard error here, named at the call site. Every other failure
20
+ mode (no endpoint, SDK disabled, packages absent) is a quiet ``False`` — those are
21
+ legitimate local/test configurations, and none of them can be mistaken for
22
+ working tracing, because they emit no success log either.
23
+
24
+ Configuration, matching the fleet convention already provisioned in
25
+ ``clusters/strato``:
26
+
27
+ - ``OTLP_TRACES_ENDPOINT`` — full URL including ``/v1/traces``. Unset ⇒ no exporter.
28
+ - ``OTEL_SDK_DISABLED`` — ``"true"`` ⇒ no tracing at all.
29
+ """
30
+
31
+ from __future__ import annotations
32
+
33
+ import logging
34
+ import os
35
+ from typing import TYPE_CHECKING, Any
36
+
37
+ if TYPE_CHECKING: # pragma: no cover - typing only
38
+ from fastapi import FastAPI
39
+
40
+ logger = logging.getLogger(__name__)
41
+
42
+ #: Probe and scrape paths, excluded so kubelet traffic does not dominate the
43
+ #: trace store. Substring-matched by the instrumentation, not anchored.
44
+ #: Nine services probed every ~10s would otherwise outweigh every real request
45
+ #: the coding fleet serves.
46
+ DEFAULT_EXCLUDED_URLS = "health,healthz,metrics,ready,readyz,live,livez"
47
+
48
+ #: The single span attribute that carries the raw query string. Stripped so a
49
+ #: future ``?token=`` parameter cannot reach the trace store. No coding-*
50
+ #: route declares a sensitive query parameter today (105 scanned across the
51
+ #: fleet); this keeps it that way by construction rather than by review.
52
+ _URL_ATTRIBUTES = ("http.url", "url.full")
53
+
54
+
55
+ def _strip_query(url: str) -> str:
56
+ """Drop everything from the first ``?``, keeping scheme/host/path."""
57
+ head, sep, _ = url.partition("?")
58
+ return head if sep else url
59
+
60
+
61
+ def _server_request_hook(span: Any, scope: dict[str, Any]) -> None:
62
+ """Redact the query string from the server span while it is still writable.
63
+
64
+ Runs inside the instrumentation with a recording span, which is the only
65
+ point where these attributes can still be overwritten — once the span has
66
+ ended its attributes are frozen.
67
+ """
68
+ if span is None or not getattr(span, "is_recording", lambda: False)():
69
+ return
70
+ for key in _URL_ATTRIBUTES:
71
+ value = (span.attributes or {}).get(key)
72
+ if isinstance(value, str) and "?" in value:
73
+ span.set_attribute(key, _strip_query(value))
74
+
75
+
76
+ def _already_started(app: FastAPI) -> bool:
77
+ """True once Starlette has built the middleware stack.
78
+
79
+ After that point ``instrument_app`` is a silent no-op, which is the exact
80
+ failure this module exists to make impossible.
81
+ """
82
+ return getattr(app, "middleware_stack", None) is not None
83
+
84
+
85
+ def _instrument_httpx(provider: Any) -> bool:
86
+ """Instrument outbound httpx calls against ``provider``, best-effort.
87
+
88
+ Client spans are what Tempo's ``service_graphs`` processor turns into edges —
89
+ a server-span-only service appears in the graph as a node nothing points at.
90
+ This SDK's own outbound helpers use httpx, so instrumenting it here covers
91
+ every coding-to-coding call without per-service work.
92
+
93
+ ``HTTPXClientInstrumentor`` is a process-wide singleton that binds its tracer
94
+ at ``instrument()`` time, so the provider is passed explicitly rather than
95
+ resolved from the global — the same reason it is passed to the FastAPI
96
+ instrumentation. Re-instrumenting an already-instrumented process is a no-op
97
+ in OpenTelemetry, so this rebinds first to guarantee spans reach *this*
98
+ service's provider.
99
+ """
100
+ try:
101
+ from opentelemetry.instrumentation.httpx import HTTPXClientInstrumentor
102
+ except ImportError:
103
+ logger.debug("httpx tracing skipped: opentelemetry-instrumentation-httpx not installed")
104
+ return False
105
+
106
+ instrumentor = HTTPXClientInstrumentor()
107
+ if getattr(instrumentor, "is_instrumented_by_opentelemetry", False):
108
+ instrumentor.uninstrument()
109
+ instrumentor.instrument(tracer_provider=provider)
110
+ return True
111
+
112
+
113
+ def setup_tracing(
114
+ app: FastAPI,
115
+ service_name: str,
116
+ *,
117
+ excluded_urls: str | None = None,
118
+ instrument_httpx: bool = True,
119
+ ) -> bool:
120
+ """Install OTLP tracing on ``app``. Returns True only if spans will be exported.
121
+
122
+ Must be called at construction time, before the app serves its first request
123
+ (so: module scope or an app factory — never inside ``lifespan`` or a startup
124
+ handler).
125
+
126
+ Args:
127
+ app: The FastAPI application, not yet started.
128
+ service_name: ``service.name`` in Tempo. Use the Kubernetes service name.
129
+ excluded_urls: Comma-separated substrings; defaults to probe/scrape paths.
130
+ instrument_httpx: Also trace outbound httpx calls, so this service becomes
131
+ a *source* of service-graph edges and not only a target. Best-effort:
132
+ a missing ``opentelemetry-instrumentation-httpx`` is not an error.
133
+
134
+ Returns:
135
+ True when a tracer provider and OTLP exporter were installed. False when
136
+ tracing is deliberately off (``OTEL_SDK_DISABLED``), unconfigured (no
137
+ ``OTLP_TRACES_ENDPOINT``), or the OpenTelemetry packages are absent.
138
+
139
+ Raises:
140
+ RuntimeError: if called after the app has started, because the
141
+ instrumentation would be discarded without any error of its own.
142
+ """
143
+ if _already_started(app):
144
+ raise RuntimeError(
145
+ f"setup_tracing({service_name!r}) was called after the application "
146
+ "started — FastAPIInstrumentor.instrument_app() is a silent no-op at "
147
+ "that point and would export ZERO spans. Move this call to "
148
+ "application-construction time (module scope or the app factory), "
149
+ "not the lifespan or a startup handler."
150
+ )
151
+
152
+ if os.getenv("OTEL_SDK_DISABLED", "false").strip().lower() == "true":
153
+ logger.info("tracing disabled: OTEL_SDK_DISABLED=true")
154
+ return False
155
+
156
+ endpoint = (os.getenv("OTLP_TRACES_ENDPOINT") or "").strip()
157
+ if not endpoint:
158
+ logger.info("tracing disabled: OTLP_TRACES_ENDPOINT is not set")
159
+ return False
160
+
161
+ try:
162
+ from opentelemetry import trace
163
+ from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
164
+ from opentelemetry.instrumentation.fastapi import FastAPIInstrumentor
165
+ from opentelemetry.sdk.resources import Resource
166
+ from opentelemetry.sdk.trace import TracerProvider
167
+ from opentelemetry.sdk.trace.export import BatchSpanProcessor
168
+ except ImportError as exc:
169
+ logger.info("tracing disabled: OpenTelemetry packages not installed (%s)", exc)
170
+ return False
171
+
172
+ provider = TracerProvider(resource=Resource.create({"service.name": service_name}))
173
+ provider.add_span_processor(BatchSpanProcessor(OTLPSpanExporter(endpoint=endpoint)))
174
+
175
+ # Register globally: FastAPIInstrumentor resolves the provider lazily through
176
+ # the global proxy, so an unregistered provider yields non-recording spans and
177
+ # nothing is ever exported.
178
+ trace.set_tracer_provider(provider)
179
+
180
+ FastAPIInstrumentor.instrument_app(
181
+ app,
182
+ tracer_provider=provider,
183
+ excluded_urls=DEFAULT_EXCLUDED_URLS if excluded_urls is None else excluded_urls,
184
+ server_request_hook=_server_request_hook,
185
+ )
186
+
187
+ httpx_traced = _instrument_httpx(provider) if instrument_httpx else False
188
+
189
+ logger.info(
190
+ "tracing enabled: service=%s endpoint=%s httpx=%s",
191
+ service_name,
192
+ endpoint,
193
+ httpx_traced,
194
+ )
195
+ return True
@@ -0,0 +1,180 @@
1
+ """Test-side helpers for neutralising this SDK's identity dependencies.
2
+
3
+ This module is the supported replacement for ``SKIP_AUTH=true``, which was
4
+ deleted in 1.16.0. The two do the same job for a test suite and differ in the
5
+ only way that matters:
6
+
7
+ SKIP_AUTH ambient, global, ENV-triggered, compiled into the
8
+ production wheel. Anything that could set an
9
+ environment variable could disable authentication for
10
+ the whole process, and the branch sat ABOVE every
11
+ credential path in require_tenant.
12
+
13
+ override_tenant_auth per-app-object, explicit, CALL-triggered. There is no
14
+ environment variable, no import-time side effect, and
15
+ no way to reach it except by calling it against a
16
+ specific FastAPI instance.
17
+
18
+ That is the entire security delta, and it is enforced rather than asserted:
19
+ ``tests/unit/test_auth/test_no_auth_bypass.py`` fails if this file ever gains an
20
+ ``os.getenv``/``os.environ`` read or imports ``pytest``.
21
+
22
+ WHY THIS IS SHIPPED HERE RATHER THAN WRITTEN PER REPO
23
+ -----------------------------------------------------
24
+ Because the KEY SET drifts, and it has already drifted. Before 1.16.0,
25
+ ``coding-testing/tests/integration/conftest.py`` hand-rolled overrides for
26
+ ``get_current_user``, ``requires_read_permission`` and
27
+ ``requires_write_permission`` — and NOT ``require_tenant``. That list was
28
+ incomplete and nobody knew, because the same conftest also set
29
+ ``SKIP_AUTH=true`` two lines earlier and covered the gap.
30
+
31
+ Four repos maintaining that list by hand is four chances to miss the next
32
+ dependency this SDK adds. Centralised, adding one is a single edit to
33
+ ``_TENANT_DEPENDENCIES`` that every consumer picks up at its next pin bump. This
34
+ fleet has already been burned twice by forked auth helpers; a third fork, living
35
+ in test code where nobody reviews it as security-relevant, is not a good trade
36
+ for avoiding one import.
37
+
38
+ USAGE
39
+ -----
40
+ from coding_client.testing import override_tenant_auth
41
+
42
+ @pytest.fixture
43
+ def client(app):
44
+ undo = override_tenant_auth(app)
45
+ yield TestClient(app)
46
+ undo() # or use the context manager below
47
+
48
+ # a service whose own dependency objects differ from the SDK's, or which
49
+ # needs a service-specific return shape:
50
+ undo = override_tenant_auth(
51
+ app,
52
+ tenant_id="tenant-a",
53
+ extra={my_module.create_tenant_context: lambda: MyContext("tenant-a")},
54
+ )
55
+
56
+ ``undo()`` restores the PREVIOUS mapping exactly. It does not call
57
+ ``.clear()`` — several suites yield a module-level ``main.app`` singleton, and
58
+ clearing would silently drop overrides the caller installed itself.
59
+ """
60
+
61
+ from __future__ import annotations
62
+
63
+ from collections.abc import Callable, Iterator
64
+ from contextlib import contextmanager
65
+ from typing import Any
66
+
67
+ from .auth.dependencies import get_current_user
68
+ from .auth.models import User
69
+ from .auth.tenant import (
70
+ create_tenant_context,
71
+ get_current_user_with_tenant,
72
+ optional_tenant,
73
+ require_tenant,
74
+ require_tenant_context,
75
+ )
76
+
77
+ __all__ = ["override_tenant_auth", "tenant_auth_override"]
78
+
79
+ # Every identity dependency this SDK exposes. A route that depends on ANY of
80
+ # these must be neutralised, or a suite bypasses auth on some routes and 401s on
81
+ # others — which is exactly the half-configured state that made the old
82
+ # coding-testing conftest look correct.
83
+ #
84
+ # ⚠️ Adding a dependency to auth/tenant.py means adding it HERE. That is the
85
+ # whole point of this tuple existing.
86
+ _TENANT_DEPENDENCIES = (
87
+ require_tenant,
88
+ optional_tenant,
89
+ get_current_user_with_tenant,
90
+ create_tenant_context,
91
+ require_tenant_context,
92
+ get_current_user,
93
+ )
94
+
95
+ DEFAULT_TEST_TENANT = "test-tenant"
96
+ DEFAULT_TEST_USER = "test-user"
97
+
98
+
99
+ def override_tenant_auth(
100
+ app: Any,
101
+ *,
102
+ tenant_id: str = DEFAULT_TEST_TENANT,
103
+ user: User | None = None,
104
+ extra: dict[Callable[..., Any], Callable[..., Any]] | None = None,
105
+ ) -> Callable[[], None]:
106
+ """Neutralise this SDK's identity dependencies on ``app``.
107
+
108
+ Args:
109
+ app: the FastAPI application whose ``dependency_overrides`` to install
110
+ into. Per-app, so two apps in one test session cannot interfere.
111
+ tenant_id: what the tenant-returning dependencies resolve to.
112
+ user: what the user-returning dependencies resolve to. Defaults to a
113
+ ``User`` whose ``tenant_id`` matches ``tenant_id`` — they must agree,
114
+ or a route reading both sees two different tenants.
115
+ extra: additional ``{dependency: replacement}`` pairs, merged last so a
116
+ caller can override one of the defaults. Use for a service's own
117
+ forked dependency object (coding-ai's ``require_tenant`` is a
118
+ different object from this SDK's) or for a service-specific return
119
+ shape (coding-analysis's ``create_tenant_context`` returns its own
120
+ ``TenantContext``, not this SDK's dict).
121
+
122
+ Returns:
123
+ A zero-argument callable that restores the previous overrides exactly.
124
+ """
125
+ resolved_user = user or User(
126
+ sub=DEFAULT_TEST_USER,
127
+ preferred_username=DEFAULT_TEST_USER,
128
+ tenant_id=tenant_id,
129
+ )
130
+
131
+ replacements: dict[Callable[..., Any], Callable[..., Any]] = {
132
+ require_tenant: lambda: tenant_id,
133
+ optional_tenant: lambda: tenant_id,
134
+ get_current_user_with_tenant: lambda: resolved_user,
135
+ create_tenant_context: lambda: {"tenant_id": tenant_id},
136
+ require_tenant_context: lambda: {"tenant_id": tenant_id},
137
+ get_current_user: lambda: resolved_user,
138
+ }
139
+ if extra:
140
+ replacements.update(extra)
141
+
142
+ overrides = app.dependency_overrides
143
+ # Snapshot only the keys we touch. Restoring the whole dict would clobber
144
+ # anything installed between our install and undo.
145
+ previous: dict[Callable[..., Any], Any] = {}
146
+ absent: list[Callable[..., Any]] = []
147
+ for dependency, replacement in replacements.items():
148
+ if dependency in overrides:
149
+ previous[dependency] = overrides[dependency]
150
+ else:
151
+ absent.append(dependency)
152
+ overrides[dependency] = replacement
153
+
154
+ def undo() -> None:
155
+ for dependency, original in previous.items():
156
+ overrides[dependency] = original
157
+ for dependency in absent:
158
+ overrides.pop(dependency, None)
159
+
160
+ return undo
161
+
162
+
163
+ @contextmanager
164
+ def tenant_auth_override(
165
+ app: Any,
166
+ *,
167
+ tenant_id: str = DEFAULT_TEST_TENANT,
168
+ user: User | None = None,
169
+ extra: dict[Callable[..., Any], Callable[..., Any]] | None = None,
170
+ ) -> Iterator[None]:
171
+ """Context-manager form of :func:`override_tenant_auth`.
172
+
173
+ Restores on the way out even when the body raises — which a bare
174
+ ``undo()`` after ``yield`` in a fixture does not.
175
+ """
176
+ undo = override_tenant_auth(app, tenant_id=tenant_id, user=user, extra=extra)
177
+ try:
178
+ yield
179
+ finally:
180
+ undo()
@@ -0,0 +1,130 @@
1
+ """Type definitions for coding-client.
2
+
3
+ Provides:
4
+ - Core Literal types for type safety (SupportedLanguage, ContainerState, etc.)
5
+ - Constraint types with Pydantic Annotated validators (ContainerName, CodeContent, etc.)
6
+ - State machine implementation for lifecycle management
7
+ """
8
+
9
+ from .constraint_types import (
10
+ SAFE_STRING_PATTERN,
11
+ AbsolutePath,
12
+ AnalysisID,
13
+ CodeContent,
14
+ CodeSnippet,
15
+ ColumnNumber,
16
+ Confidence,
17
+ ContainerName,
18
+ CPUCores,
19
+ FileSizeBytes,
20
+ FutureTimestamp,
21
+ GitHubRepoUrl,
22
+ LineNumber,
23
+ MemoryMB,
24
+ Percentage,
25
+ PortNumber,
26
+ RelativePath,
27
+ RequestID,
28
+ SafeCodeString,
29
+ SafeString,
30
+ SafeStringLong,
31
+ SafeStringMedium,
32
+ SafeStringMediumOptional,
33
+ SafeStringOptional,
34
+ SafeStringShort,
35
+ SafeStringShortOptional,
36
+ Score,
37
+ TimeoutSeconds,
38
+ UserIdentifier,
39
+ ValidTimestamp,
40
+ )
41
+ from .core_types import (
42
+ AnalysisState,
43
+ AnalysisType,
44
+ CacheOperationType,
45
+ ContainerState,
46
+ DatabaseState,
47
+ ErrorCategory,
48
+ ExecutionMode,
49
+ ExitCode,
50
+ FileOperationType,
51
+ GitHubEventType,
52
+ GitHubEventTypeEnum,
53
+ HealthState,
54
+ NetworkOperationType,
55
+ PRState,
56
+ QualityLevel,
57
+ ResponseState,
58
+ SecurityLevel,
59
+ SupportedLanguage,
60
+ TestState,
61
+ TestType,
62
+ TransactionState,
63
+ ValidationResult,
64
+ )
65
+ from .state_machine import (
66
+ ContainerStateMachine,
67
+ StateMachine,
68
+ StateTransition,
69
+ )
70
+
71
+ __all__ = [
72
+ # Core Literal types
73
+ "AnalysisState",
74
+ "AnalysisType",
75
+ "CacheOperationType",
76
+ "ContainerState",
77
+ "DatabaseState",
78
+ "ErrorCategory",
79
+ "ExecutionMode",
80
+ "ExitCode",
81
+ "FileOperationType",
82
+ "GitHubEventType",
83
+ "GitHubEventTypeEnum",
84
+ "HealthState",
85
+ "NetworkOperationType",
86
+ "PRState",
87
+ "QualityLevel",
88
+ "ResponseState",
89
+ "SecurityLevel",
90
+ "SupportedLanguage",
91
+ "TestState",
92
+ "TestType",
93
+ "TransactionState",
94
+ "ValidationResult",
95
+ # Constraint types
96
+ "AbsolutePath",
97
+ "AnalysisID",
98
+ "CodeContent",
99
+ "CodeSnippet",
100
+ "ColumnNumber",
101
+ "Confidence",
102
+ "ContainerName",
103
+ "CPUCores",
104
+ "FileSizeBytes",
105
+ "FutureTimestamp",
106
+ "GitHubRepoUrl",
107
+ "LineNumber",
108
+ "MemoryMB",
109
+ "Percentage",
110
+ "PortNumber",
111
+ "RelativePath",
112
+ "RequestID",
113
+ "SAFE_STRING_PATTERN",
114
+ "SafeCodeString",
115
+ "SafeString",
116
+ "SafeStringLong",
117
+ "SafeStringMedium",
118
+ "SafeStringMediumOptional",
119
+ "SafeStringOptional",
120
+ "SafeStringShort",
121
+ "SafeStringShortOptional",
122
+ "Score",
123
+ "TimeoutSeconds",
124
+ "UserIdentifier",
125
+ "ValidTimestamp",
126
+ # State machine
127
+ "ContainerStateMachine",
128
+ "StateMachine",
129
+ "StateTransition",
130
+ ]