mirror of
https://github.com/Alishahryar1/free-claude-code.git
synced 2026-07-09 16:00:45 +00:00
Remove legacy future annotation imports (#982)
## Problem
Python 3.14 provides native lazy annotations, but the codebase still
relied on legacy future annotation imports. Those imports also made
type-only import cycles easier to hide instead of fixing ownership
boundaries.
## Changes
| Before | After |
| --- | --- |
| Python files used `from __future__ import annotations`. | Python files
rely on Python 3.14 native lazy annotations. |
| Some runtime modules used `TYPE_CHECKING` or local imports for
required dependencies. | Runtime modules use top-level owner-module
imports with explicit boundaries. |
| Local and GitHub guardrails only rejected type ignore suppressions. |
Local and GitHub guardrails reject type ignore suppressions and legacy
future annotation imports. |
| Agent docs only documented the no-type-ignore rule. | Agent docs
document the Python 3.14 annotation and import-boundary rules. |
<!-- greptile_comment -->
<details open><summary><h3>Greptile Summary</h3></summary>
This PR moves the codebase to Python 3.14 native lazy annotations. The
main changes are:
- Removed legacy `from __future__ import annotations` imports across
Python modules.
- Promoted selected runtime dependencies from `TYPE_CHECKING` or local
imports to explicit owner-module imports.
- Added local, GitHub, and contract-test guardrails to reject legacy
future annotation imports.
- Updated agent docs with the annotation and import-boundary rules.
- Bumped the package patch version for production-file changes.
</details>
<h3>Confidence Score: 5/5</h3>
Safe to merge with low risk.
The changes are mostly mechanical annotation cleanup with matching CI
and contract-test guardrails. Reviewed import-boundary updates did not
show a confirmed runtime cycle or dependency break.
No files require special attention.
<details><summary><h3><a href="https://www.greptile.com/trex"><img
alt="T-Rex"
src="https://greptile-static-assets.s3.amazonaws.com/trex/trex_green.svg"
height="20" align="absmiddle"></a> T-Rex Logs</h3></summary>
**What T-Rex did**
- Performed an end-to-end validation of the guardrail contract suite: an
environment check confirmed uv availability, a guardrail pytest run used
CPython 3.14.0 with 5 passing contract tests, 3 focused CI-script tests
passed, and the direct CI suppressions guardrail command (including the
legacy future-annotations grep) also passed.
<a
href="https://app.greptile.com/trex/runs/13303335/artifacts"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://greptile-static-assets.s3.amazonaws.com/badges/ViewAllArtifactsDark.svg?v=4"><source
media="(prefers-color-scheme: light)"
srcset="https://greptile-static-assets.s3.amazonaws.com/badges/ViewAllArtifacts.svg?v=4"><img
alt="View all artifacts"
src="https://greptile-static-assets.s3.amazonaws.com/badges/ViewAllArtifacts.svg?v=4"></picture></a>
<sub><a href="https://www.greptile.com/trex"><img alt="T-Rex"
src="https://greptile-static-assets.s3.amazonaws.com/trex/trex_green.svg"
height="14" align="absmiddle"></a> Ran code and verified through
T-Rex</sub>
</details>
<details open><summary><h3>Important Files Changed</h3></summary>
| Filename | Overview |
|----------|----------|
| api/runtime.py | Moves messaging, CLI manager, session, limiter, and
tree dependencies from local/type-checking imports to explicit top-level
owner-module imports. |
| messaging/platforms/telegram.py | Removes future annotations and
promotes Telegram SDK type imports into the existing availability guard.
|
| messaging/platforms/telegram_inbound.py | Removes future annotations
and imports Telegram SDK types at module scope for inbound
normalization. |
| tests/contracts/test_import_boundaries.py | Adds an AST contract that
rejects legacy future annotation imports across Python files. |
| scripts/ci.sh | Extends the local suppression check to reject legacy
future annotation imports alongside type-ignore suppressions. |
| scripts/ci.ps1 | Mirrors the local PowerShell CI suppression check for
legacy future annotations. |
| .github/workflows/tests.yml | Renames and broadens the GitHub
guardrail job to reject both type suppressions and legacy future
annotations. |
| pyproject.toml | Bumps the patch version for production-file changes.
|
</details>
<details open><summary><h3>Sequence Diagram</h3></summary>
<a href="#gh-light-mode-only">
```mermaid
%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
participant Dev as Developer/CI
participant Guard as Suppression guard
participant AST as Import-boundary contract test
participant Py as Python modules
Dev->>Guard: Run local/GitHub suppression check
Guard->>Py: "Scan *.py for type ignores and future annotations"
Guard-->>Dev: Fail if legacy annotation import remains
Dev->>AST: Run pytest contract tests
AST->>Py: Parse imports with ast
AST-->>Dev: Assert no future annotations/import-boundary violations
Py-->>Dev: Use Python 3.14 native lazy annotations
```
</a>
<a href="#gh-dark-mode-only">
```mermaid
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
participant Dev as Developer/CI
participant Guard as Suppression guard
participant AST as Import-boundary contract test
participant Py as Python modules
Dev->>Guard: Run local/GitHub suppression check
Guard->>Py: "Scan *.py for type ignores and future annotations"
Guard-->>Dev: Fail if legacy annotation import remains
Dev->>AST: Run pytest contract tests
AST->>Py: Parse imports with ast
AST-->>Dev: Assert no future annotations/import-boundary violations
Py-->>Dev: Use Python 3.14 native lazy annotations
```
</a>
</details>
<sub>Reviews (2): Last reviewed commit: ["Remove legacy future
annotations
import"](6e6cda69da)
| [Re-trigger
Greptile](https://app.greptile.com/api/retrigger?id=41875785)</sub>
<!-- /greptile_comment -->
This commit is contained in:
parent
dfbff528c6
commit
85b601884d
214 changed files with 87 additions and 492 deletions
12
.github/workflows/tests.yml
vendored
12
.github/workflows/tests.yml
vendored
|
|
@ -1,5 +1,5 @@
|
|||
# Branch protection: require every status check this workflow reports, for example:
|
||||
# Ban type ignore suppressions
|
||||
# Ban suppressions and legacy annotations
|
||||
# ruff-format, ruff-check, ty, pytest
|
||||
# GitHub may prefix with the workflow name (e.g. "CI / ruff-format"); use the names the branch protection UI offers after a run.
|
||||
|
||||
|
|
@ -17,8 +17,8 @@ concurrency:
|
|||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
no-type-ignore-suppressions:
|
||||
name: Ban type ignore suppressions
|
||||
no-suppressions-or-legacy-annotations:
|
||||
name: Ban suppressions and legacy annotations
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 15
|
||||
permissions:
|
||||
|
|
@ -30,10 +30,10 @@ jobs:
|
|||
repository: ${{ github.event.pull_request.head.repo.full_name || github.repository }}
|
||||
fetch-depth: 1
|
||||
|
||||
- name: "Fail on type: ignore (no suppressions allowed)"
|
||||
- name: "Fail on type ignores and legacy future annotations"
|
||||
run: |
|
||||
if grep -rE '# type: ignore|# ty: ignore' --include='*.py' . --exclude-dir=.venv --exclude-dir=.git; then
|
||||
echo "::error::type: ignore / ty: ignore comments are not allowed. Fix the underlying type errors instead."
|
||||
if grep -rE '# type: ignore|# ty: ignore|from __future__ import annotations' --include='*.py' . --exclude-dir=.venv --exclude-dir=.git; then
|
||||
echo "::error::type: ignore / ty: ignore comments and legacy future annotations are not allowed. Fix the underlying type/import issue instead."
|
||||
exit 1
|
||||
fi
|
||||
exit 0
|
||||
|
|
|
|||
|
|
@ -16,10 +16,11 @@
|
|||
- GitHub CI remains check-only for Ruff (`ruff format --check`, `ruff check`) so branch protection verifies committed code.
|
||||
- Fall back to individual repair commands when debugging local failures: `uv run ruff format`, `uv run ruff check --fix`, `uv run ty check`, `uv run pytest -v --tb=short`. Use GitHub-style checks only when verifying enforcement locally: `uv run ruff format --check`, `uv run ruff check`.
|
||||
- Do not add `# type: ignore` or `# ty: ignore`; fix the underlying type issue.
|
||||
- Do not add `from __future__ import annotations`; Python 3.14 native lazy annotations are the project standard.
|
||||
- All 5 check IDs are represented in `scripts/ci.sh` / `scripts/ci.ps1` and enforced in `tests.yml` on push/merge (parallel jobs: suppression grep, ruff-format, ruff-check, ty, pytest).
|
||||
- GitHub CI runs on `push`, `pull_request`, and `merge_group` so required checks validate merge queue candidates before they land.
|
||||
- Repository protection should use rulesets: a non-bypassable main integrity ruleset requires pull requests, merge queue, required checks, and blocks direct/force pushes to `main`; a separate review ruleset may allow `Alishahryar1`/admins to bypass review only.
|
||||
- Required status checks: set **required status checks** to **all** of those statuses (e.g. **Ban type ignore suppressions**, **ruff-format**, **ruff-check**, **ty**, **pytest**—use the exact labels GitHub shows, which may be prefixed with **CI /**). Remove **ci** from required checks if it was previously added for the old gate job.
|
||||
- Required status checks: set **required status checks** to **all** of those statuses (e.g. **Ban suppressions and legacy annotations**, **ruff-format**, **ruff-check**, **ty**, **pytest**—use the exact labels GitHub shows, which may be prefixed with **CI /**). Remove **ci** from required checks if it was previously added for the old gate job.
|
||||
|
||||
## IDENTITY & CONTEXT
|
||||
|
||||
|
|
@ -37,6 +38,8 @@
|
|||
- **Performance**: Use list accumulation for strings (not `+=` in loops), cache env vars at init, prefer iterative over recursive when stack depth matters.
|
||||
- **Platform-agnostic naming**: Use generic names (e.g. `PLATFORM_EDIT`) not platform-specific ones (e.g. `TELEGRAM_EDIT`) in shared code.
|
||||
- **No type ignores**: Do not add `# type: ignore` or `# ty: ignore`. Fix the underlying type issue.
|
||||
- **Python 3.14 annotations**: Do not use `from __future__ import annotations`; rely on native lazy annotations and fix circular import boundaries instead of hiding them with annotation stringization.
|
||||
- **Imports**: Prefer top-level imports. Avoid `TYPE_CHECKING` and local imports for first-party or required dependencies; if a top-level import creates a cycle, move shared types/protocols to a neutral owner.
|
||||
- **Complete migrations**: When moving modules, update imports to the new owner and remove old compatibility shims in the same change unless preserving a published interface is explicitly required.
|
||||
- **Maximum Test Coverage**: There should be maximum test coverage for everything, preferably live smoke test coverage to catch bugs early
|
||||
|
||||
|
|
|
|||
|
|
@ -16,10 +16,11 @@
|
|||
- GitHub CI remains check-only for Ruff (`ruff format --check`, `ruff check`) so branch protection verifies committed code.
|
||||
- Fall back to individual repair commands when debugging local failures: `uv run ruff format`, `uv run ruff check --fix`, `uv run ty check`, `uv run pytest -v --tb=short`. Use GitHub-style checks only when verifying enforcement locally: `uv run ruff format --check`, `uv run ruff check`.
|
||||
- Do not add `# type: ignore` or `# ty: ignore`; fix the underlying type issue.
|
||||
- Do not add `from __future__ import annotations`; Python 3.14 native lazy annotations are the project standard.
|
||||
- All 5 check IDs are represented in `scripts/ci.sh` / `scripts/ci.ps1` and enforced in `tests.yml` on push/merge (parallel jobs: suppression grep, ruff-format, ruff-check, ty, pytest).
|
||||
- GitHub CI runs on `push`, `pull_request`, and `merge_group` so required checks validate merge queue candidates before they land.
|
||||
- Repository protection should use rulesets: a non-bypassable main integrity ruleset requires pull requests, merge queue, required checks, and blocks direct/force pushes to `main`; a separate review ruleset may allow `Alishahryar1`/admins to bypass review only.
|
||||
- Required status checks: set **required status checks** to **all** of those statuses (e.g. **Ban type ignore suppressions**, **ruff-format**, **ruff-check**, **ty**, **pytest**—use the exact labels GitHub shows, which may be prefixed with **CI /**). Remove **ci** from required checks if it was previously added for the old gate job.
|
||||
- Required status checks: set **required status checks** to **all** of those statuses (e.g. **Ban suppressions and legacy annotations**, **ruff-format**, **ruff-check**, **ty**, **pytest**—use the exact labels GitHub shows, which may be prefixed with **CI /**). Remove **ci** from required checks if it was previously added for the old gate job.
|
||||
|
||||
## IDENTITY & CONTEXT
|
||||
|
||||
|
|
@ -37,6 +38,8 @@
|
|||
- **Performance**: Use list accumulation for strings (not `+=` in loops), cache env vars at init, prefer iterative over recursive when stack depth matters.
|
||||
- **Platform-agnostic naming**: Use generic names (e.g. `PLATFORM_EDIT`) not platform-specific ones (e.g. `TELEGRAM_EDIT`) in shared code.
|
||||
- **No type ignores**: Do not add `# type: ignore` or `# ty: ignore`. Fix the underlying type issue.
|
||||
- **Python 3.14 annotations**: Do not use `from __future__ import annotations`; rely on native lazy annotations and fix circular import boundaries instead of hiding them with annotation stringization.
|
||||
- **Imports**: Prefer top-level imports. Avoid `TYPE_CHECKING` and local imports for first-party or required dependencies; if a top-level import creates a cycle, move shared types/protocols to a neutral owner.
|
||||
- **Complete migrations**: When moving modules, update imports to the new owner and remove old compatibility shims in the same change unless preserving a published interface is explicitly required.
|
||||
- **Maximum Test Coverage**: There should be maximum test coverage for everything, preferably live smoke test coverage to catch bugs early
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
"""Admin UI configuration manifest."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Iterable
|
||||
from dataclasses import dataclass
|
||||
from typing import Literal
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
"""Managed env persistence, validation preview, and rendering."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
from collections.abc import Mapping
|
||||
from typing import Any
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
"""Catalog-derived Admin UI provider fields."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any
|
||||
|
||||
from config.provider_catalog import PROVIDER_CATALOG
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
"""Admin config source loading and source precedence."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
from io import StringIO
|
||||
from pathlib import Path
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
"""Provider configuration status for the Admin UI."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Mapping
|
||||
from typing import Any
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
"""Settings-backed Admin UI config validation."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Mapping
|
||||
from typing import Any
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
"""Admin config value state and API response assembly."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
from typing import Any
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
"""Local admin UI routes and APIs."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import inspect
|
||||
import ipaddress
|
||||
from pathlib import Path
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
"""Helpers for presenting local admin URLs."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from config.settings import Settings
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
"""Gateway-safe model id encoding for Claude Code model discovery."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass
|
||||
|
||||
GATEWAY_MODEL_ID_PREFIX = "anthropic"
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
"""Claude Messages API product flow."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import AsyncIterator, Callable
|
||||
from dataclasses import dataclass, replace
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
"""OpenAI Responses API product flow for Codex clients."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Callable
|
||||
|
||||
from fastapi.responses import JSONResponse
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
"""Anthropic token-count API product flow."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import uuid
|
||||
|
||||
from fastapi import HTTPException
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
"""Model-list response construction for Claude-compatible clients."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from config.model_refs import configured_chat_model_refs
|
||||
from config.settings import Settings
|
||||
from providers.runtime import ProviderRuntime
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
"""Model routing for Claude-compatible requests."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass
|
||||
|
||||
from loguru import logger
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
"""Pydantic models for OpenAI Responses-compatible ingress."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any
|
||||
|
||||
from pydantic import BaseModel, ConfigDict
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
"""Shared provider execution primitive for API product handlers."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import uuid
|
||||
from collections.abc import AsyncIterator, Callable
|
||||
from typing import Any
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
"""Shared API request validation and safe error logging."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import traceback
|
||||
from typing import Any
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
"""FastAPI streaming response wrappers for public API wire formats."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import AsyncIterator, Mapping
|
||||
|
||||
from fastapi.responses import StreamingResponse
|
||||
|
|
|
|||
|
|
@ -1,29 +1,30 @@
|
|||
"""Application runtime composition and lifecycle ownership."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
import logging
|
||||
import os
|
||||
import traceback
|
||||
from dataclasses import dataclass, field
|
||||
from typing import TYPE_CHECKING, Any
|
||||
from typing import Any
|
||||
|
||||
from fastapi import FastAPI
|
||||
from loguru import logger
|
||||
|
||||
import cli.managed as cli_managed
|
||||
import messaging.limiter as messaging_limiter
|
||||
import messaging.session as messaging_session
|
||||
import messaging.trees as messaging_trees
|
||||
import messaging.workflow as messaging_workflow_module
|
||||
from api.admin_urls import local_admin_url
|
||||
from config.env_files import ANTHROPIC_AUTH_TOKEN_ENV, process_env_key_is_effective
|
||||
from config.paths import default_claude_workspace_path
|
||||
from config.settings import Settings, get_settings
|
||||
from messaging.platforms import factory as messaging_platform_factory
|
||||
from messaging.platforms.factory import MessagingPlatformOptions
|
||||
from messaging.platforms.ports import MessagingPlatformComponents, MessagingRuntime
|
||||
from providers.exceptions import ServiceUnavailableError
|
||||
from providers.runtime import ProviderRuntime
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from cli.managed import ManagedClaudeSessionManager
|
||||
from messaging.platforms.ports import MessagingPlatformComponents, MessagingRuntime
|
||||
from messaging.session import SessionStore
|
||||
from messaging.workflow import MessagingWorkflow
|
||||
|
||||
_SHUTDOWN_TIMEOUT_S = 5.0
|
||||
|
||||
|
||||
|
|
@ -92,8 +93,8 @@ class AppRuntime:
|
|||
settings: Settings
|
||||
_provider_runtime: ProviderRuntime | None = field(default=None, init=False)
|
||||
messaging_runtime: MessagingRuntime | None = None
|
||||
messaging_workflow: MessagingWorkflow | None = None
|
||||
cli_manager: ManagedClaudeSessionManager | None = None
|
||||
messaging_workflow: messaging_workflow_module.MessagingWorkflow | None = None
|
||||
cli_manager: cli_managed.ManagedClaudeSessionManager | None = None
|
||||
|
||||
@classmethod
|
||||
def for_app(
|
||||
|
|
@ -179,12 +180,7 @@ class AppRuntime:
|
|||
|
||||
async def _start_messaging_if_configured(self) -> None:
|
||||
try:
|
||||
from messaging.platforms.factory import (
|
||||
MessagingPlatformOptions,
|
||||
create_messaging_components,
|
||||
)
|
||||
|
||||
components = create_messaging_components(
|
||||
components = messaging_platform_factory.create_messaging_components(
|
||||
self.settings.messaging_platform,
|
||||
MessagingPlatformOptions(
|
||||
telegram_bot_token=self.settings.telegram_bot_token,
|
||||
|
|
@ -217,8 +213,6 @@ class AppRuntime:
|
|||
except Exception as e:
|
||||
if self.settings.log_api_error_tracebacks:
|
||||
logger.error("Failed to start messaging platform: {}", e)
|
||||
import traceback
|
||||
|
||||
logger.error(traceback.format_exc())
|
||||
else:
|
||||
logger.error(
|
||||
|
|
@ -229,10 +223,6 @@ class AppRuntime:
|
|||
async def _start_messaging_workflow(
|
||||
self, components: MessagingPlatformComponents
|
||||
) -> None:
|
||||
from cli.managed import ManagedClaudeSessionManager
|
||||
from messaging.session import SessionStore
|
||||
from messaging.workflow import MessagingWorkflow
|
||||
|
||||
workspace = (
|
||||
os.path.abspath(self.settings.allowed_dir)
|
||||
if self.settings.allowed_dir
|
||||
|
|
@ -247,7 +237,7 @@ class AppRuntime:
|
|||
allowed_dirs = [workspace] if self.settings.allowed_dir else []
|
||||
plans_dir_abs = os.path.abspath(os.path.join(data_path, "plans"))
|
||||
plans_directory = os.path.relpath(plans_dir_abs, workspace)
|
||||
self.cli_manager = ManagedClaudeSessionManager(
|
||||
self.cli_manager = cli_managed.ManagedClaudeSessionManager(
|
||||
workspace_path=workspace,
|
||||
api_url=api_url,
|
||||
allowed_dirs=allowed_dirs,
|
||||
|
|
@ -257,12 +247,12 @@ class AppRuntime:
|
|||
log_messaging_error_details=self.settings.log_messaging_error_details,
|
||||
)
|
||||
|
||||
session_store = SessionStore(
|
||||
session_store = messaging_session.SessionStore(
|
||||
storage_path=os.path.join(data_path, "sessions.json"),
|
||||
message_log_cap=self.settings.max_message_log_entries_per_chat,
|
||||
)
|
||||
self.messaging_runtime = components.runtime
|
||||
self.messaging_workflow = MessagingWorkflow(
|
||||
self.messaging_workflow = messaging_workflow_module.MessagingWorkflow(
|
||||
platform_name=components.name,
|
||||
outbound=components.outbound,
|
||||
voice_cancellation=components.voice_cancellation,
|
||||
|
|
@ -280,7 +270,9 @@ class AppRuntime:
|
|||
await components.runtime.start()
|
||||
logger.info("{} platform started with messaging workflow", components.name)
|
||||
|
||||
def _restore_tree_state(self, session_store: SessionStore) -> None:
|
||||
def _restore_tree_state(
|
||||
self, session_store: messaging_session.SessionStore
|
||||
) -> None:
|
||||
conversation_snapshot = session_store.load_conversation_snapshot()
|
||||
if conversation_snapshot.is_empty:
|
||||
return
|
||||
|
|
@ -291,10 +283,9 @@ class AppRuntime:
|
|||
"Restoring {} conversation trees...",
|
||||
len(conversation_snapshot.trees),
|
||||
)
|
||||
from messaging.trees import TreeQueueManager
|
||||
|
||||
self.messaging_workflow.replace_tree_queue(
|
||||
TreeQueueManager.from_snapshot(
|
||||
messaging_trees.TreeQueueManager.from_snapshot(
|
||||
conversation_snapshot,
|
||||
queue_update_callback=self.messaging_workflow.update_queue_positions,
|
||||
node_started_callback=self.messaging_workflow.mark_node_processing,
|
||||
|
|
@ -313,24 +304,18 @@ class AppRuntime:
|
|||
async def _shutdown_limiter(self) -> None:
|
||||
verbose = self.settings.log_api_error_tracebacks
|
||||
try:
|
||||
from messaging.limiter import MessagingRateLimiter
|
||||
await best_effort(
|
||||
"MessagingRateLimiter.shutdown_instance",
|
||||
messaging_limiter.MessagingRateLimiter.shutdown_instance(),
|
||||
timeout_s=2.0,
|
||||
log_verbose_errors=verbose,
|
||||
)
|
||||
except Exception as e:
|
||||
if verbose:
|
||||
logger.debug(
|
||||
"Rate limiter shutdown skipped (import failed): {}: {}",
|
||||
type(e).__name__,
|
||||
e,
|
||||
"Rate limiter shutdown skipped: {}: {}", type(e).__name__, e
|
||||
)
|
||||
else:
|
||||
logger.debug(
|
||||
"Rate limiter shutdown skipped (import failed): exc_type={}",
|
||||
type(e).__name__,
|
||||
"Rate limiter shutdown skipped: exc_type={}", type(e).__name__
|
||||
)
|
||||
return
|
||||
|
||||
await best_effort(
|
||||
"MessagingRateLimiter.shutdown_instance",
|
||||
MessagingRateLimiter.shutdown_instance(),
|
||||
timeout_s=2.0,
|
||||
log_verbose_errors=verbose,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
"""Safe metadata summaries for HTTP 422 validation logging (no raw text content)."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
"""Compatibility re-exports for :mod:`api.web_tools` (web_search / web_fetch)."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import httpx
|
||||
|
||||
from api.web_tools.egress import (
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
"""Egress policy for user-controlled web_fetch URLs (SSRF guard)."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import ipaddress
|
||||
import socket
|
||||
from dataclasses import dataclass
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
"""Outbound HTTP for web_search / web_fetch (client, body caps, logging)."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
import socket
|
||||
from collections.abc import AsyncIterator
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
"""HTML parsing for web_search / web_fetch."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import html
|
||||
import re
|
||||
from html.parser import HTMLParser
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
"""Detect forced Anthropic web server tool requests."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from api.models.anthropic import MessagesRequest, Tool
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
"""SSE streaming for local web_search / web_fetch server tool results."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import uuid
|
||||
from collections.abc import AsyncIterator
|
||||
from datetime import UTC, datetime
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
"""Shared Claude Code environment policy for FCC client surfaces."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
CLAUDE_CODE_AUTO_COMPACT_WINDOW = "190000"
|
||||
CLAUDE_BINARY_NAME = "claude"
|
||||
CLAUDE_NO_AUTH_SENTINEL = "fcc-no-auth"
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
"""CLI entry points for the installed package."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
import shutil
|
||||
import threading
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
"""Installed `fcc-claude` launcher."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
import sys
|
||||
from collections.abc import Mapping, Sequence
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
"""Installed `fcc-codex` launcher."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
"""Build Codex model catalogs from the FCC model-list route."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import uuid
|
||||
from collections.abc import Mapping
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
"""Shared process helpers for installed client CLI launchers."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
"""Managed Claude Code task command, environment, and stdout parsing."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
from collections.abc import Iterable, Mapping
|
||||
from dataclasses import dataclass, field
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
"""Managed Claude Code diagnostic classification."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass
|
||||
|
||||
_BENIGN_STDERR_MARKERS = ("claude.ai connectors are disabled",)
|
||||
|
|
|
|||
|
|
@ -5,8 +5,6 @@ FastAPI lifespan cleanup doesn't run to completion. We only track processes we
|
|||
spawn so we don't accidentally kill unrelated system processes.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import atexit
|
||||
import os
|
||||
import signal
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
"""Dotenv file discovery and explicit dotenv override helpers."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
from collections.abc import Mapping
|
||||
from pathlib import Path
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
"""Canonical env template loading for init and Admin UI defaults."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import importlib.resources
|
||||
from pathlib import Path
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
"""Provider-prefixed model reference helpers."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass
|
||||
from typing import Protocol
|
||||
|
||||
|
|
|
|||
|
|
@ -4,8 +4,6 @@ Adapter factories live in :mod:`providers.runtime.factory`; this module stays fr
|
|||
provider implementation imports (see contract tests).
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass
|
||||
from typing import Literal
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
"""Canonical provider id tuple (re-exported from the provider catalog)."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from .provider_catalog import SUPPORTED_PROVIDER_IDS
|
||||
|
||||
__all__ = ("SUPPORTED_PROVIDER_IDS",)
|
||||
|
|
|
|||
|
|
@ -3,8 +3,6 @@
|
|||
Provider adapters supply policy via parameters (defaults, OpenRouter post-steps).
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Sequence
|
||||
from typing import Any
|
||||
|
||||
|
|
|
|||
|
|
@ -4,8 +4,6 @@ Used by :class:`OpenRouterProvider` and line-mode
|
|||
:class:`providers.transports.anthropic_messages.AnthropicMessagesTransport` providers.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import copy
|
||||
import json
|
||||
from dataclasses import dataclass, field
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
"""Canonical Anthropic-style SSE sequence for provider-side streaming errors."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import uuid
|
||||
from collections.abc import Iterator
|
||||
from typing import Any
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
"""Shared Anthropic request serialization helpers."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
from typing import Any
|
||||
|
||||
|
|
|
|||
|
|
@ -3,8 +3,6 @@
|
|||
Shared by :mod:`api.web_tools` and stream contract tests to avoid drift.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Final
|
||||
|
||||
SERVER_TOOL_USE: Final = "server_tool_use"
|
||||
|
|
|
|||
|
|
@ -7,8 +7,6 @@ back the same shape the real Anthropic API returns for a non-streaming
|
|||
``messages.create()`` call.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import uuid
|
||||
from collections.abc import AsyncIterator
|
||||
|
|
|
|||
|
|
@ -3,8 +3,6 @@
|
|||
Used by default CI contract tests and by opt-in live smoke scenarios.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
from collections.abc import Iterable
|
||||
from dataclasses import dataclass
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
"""Anthropic SSE serialization helpers."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
from typing import Any
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
"""Anthropic stream state ledger."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import hashlib
|
||||
import json
|
||||
import uuid
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
"""Shared retry and recovery policy for Anthropic streams."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import time
|
||||
from collections.abc import Callable
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
"""Provider-neutral transient upstream error classification."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
from collections.abc import Mapping
|
||||
from contextlib import suppress
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
"""Facade for OpenAI Responses protocol adaptation."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import AsyncIterable, AsyncIterator, Mapping
|
||||
from typing import Any, ClassVar
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
"""Anthropic SSE parsing used by the Responses stream adapter."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
from collections.abc import AsyncIterable, AsyncIterator
|
||||
from dataclasses import dataclass
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
"""Errors and error envelopes for OpenAI Responses compatibility."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
"""OpenAI Responses SSE event formatting."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
from collections.abc import Mapping
|
||||
from typing import Any
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
"""Identifier helpers for OpenAI Responses payloads."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import uuid
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
"""Convert OpenAI Responses requests into Anthropic Messages payloads."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Mapping
|
||||
from typing import Any
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
"""Responses object and output item builders."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
"""Reasoning and thinking conversion helpers for OpenAI Responses."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Mapping
|
||||
from typing import Any
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
"""Translate Anthropic SSE streams into OpenAI Responses SSE streams."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import AsyncIterable, AsyncIterator, Mapping
|
||||
from typing import Any
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
"""Anthropic SSE to OpenAI Responses stream assembly."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import time
|
||||
import uuid
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
"""Block state for OpenAI Responses streaming assembly."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass, field
|
||||
from typing import Literal
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
"""Block finalization for OpenAI Responses streams."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Callable
|
||||
|
||||
from ..errors import ResponsesConversionError
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
"""Responses stream error mapping."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Mapping
|
||||
from typing import Any
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
"""OpenAI Responses SSE event builders."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any
|
||||
|
||||
from ..events import format_response_sse_event
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
"""Output ledger for OpenAI Responses streaming assembly."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Mapping
|
||||
from typing import Any
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
"""Tool conversion helpers for the OpenAI Responses adapter."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import hashlib
|
||||
import json
|
||||
import re
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
"""Usage helpers for OpenAI Responses payloads."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Protocol
|
||||
|
||||
_DISALLOWED_SPECIAL: tuple[str, ...] = ()
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
"""Shared strict sliding-window rate limiting primitives."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
import time
|
||||
from collections import deque
|
||||
|
|
|
|||
|
|
@ -5,8 +5,6 @@ Conversation and Claude Code prompts are logged verbatim unless values live unde
|
|||
sanitized credential keys (e.g. ``api_key``, ``authorization``).
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
from collections.abc import AsyncGenerator, AsyncIterator, Mapping
|
||||
from typing import Any
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
"""Typed dependency surface for messaging slash commands."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Protocol
|
||||
|
||||
from .managed_protocols import ManagedClaudeSessionManagerProtocol
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
"""Command parsing and dispatch for messaging handlers."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from .command_context import MessagingCommandContext
|
||||
from .commands import handle_clear_command, handle_stats_command, handle_stop_command
|
||||
from .models import IncomingMessage
|
||||
|
|
|
|||
|
|
@ -3,16 +3,10 @@
|
|||
Commands depend on MessagingCommandContext instead of the concrete workflow.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from loguru import logger
|
||||
|
||||
from .command_context import MessagingCommandContext
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from messaging.models import IncomingMessage
|
||||
from .models import IncomingMessage
|
||||
|
||||
|
||||
async def handle_stop_command(
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
"""Protocols for messaging-owned managed Claude sessions."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import AsyncGenerator
|
||||
from typing import Any, Protocol, runtime_checkable
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
"""CLI event handling for a single queued node (transcript + session + errors)."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Awaitable, Callable
|
||||
from typing import Any
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
"""Run queued messaging nodes through a managed CLI session."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
from collections.abc import Callable
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
"""Discord messaging runtime."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
import contextlib
|
||||
from collections.abc import Awaitable, Callable
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
"""Discord inbound event normalization."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any
|
||||
|
||||
from loguru import logger
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
"""Discord outbound delivery."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Awaitable, Callable
|
||||
from typing import Any, cast
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
"""Messaging platform component factory."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass
|
||||
|
||||
from loguru import logger
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
"""Shared queued delivery helper for messaging platforms."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
from collections.abc import Awaitable, Callable
|
||||
from typing import Any, cast
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
"""Messaging platform ports used by the customer-facing workflow."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Awaitable, Callable
|
||||
from dataclasses import dataclass
|
||||
from typing import Any, Protocol, runtime_checkable
|
||||
|
|
|
|||
|
|
@ -1,12 +1,10 @@
|
|||
"""Telegram messaging runtime."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
import contextlib
|
||||
import os
|
||||
from collections.abc import Awaitable, Callable
|
||||
from typing import TYPE_CHECKING, Any
|
||||
from typing import Any
|
||||
|
||||
# Opt-in to future behavior for python-telegram-bot (retry_after as timedelta).
|
||||
os.environ["PTB_TIMEDELTA"] = "1"
|
||||
|
|
@ -25,11 +23,8 @@ from .telegram_inbound import (
|
|||
from .telegram_io import TelegramMessenger
|
||||
from .voice_flow import VoiceNoteFlow
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from telegram import Update
|
||||
from telegram.ext import ContextTypes
|
||||
|
||||
try:
|
||||
from telegram import Update
|
||||
from telegram.ext import (
|
||||
Application,
|
||||
CommandHandler,
|
||||
|
|
|
|||
|
|
@ -1,19 +1,13 @@
|
|||
"""Telegram inbound event normalization."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from loguru import logger
|
||||
from telegram import Update
|
||||
from telegram.ext import ContextTypes
|
||||
|
||||
from ..models import IncomingMessage
|
||||
from ..rendering.telegram_markdown import format_status
|
||||
from .voice_flow import VoiceNoteRequest, audio_suffix_from_metadata
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from telegram import Update
|
||||
from telegram.ext import ContextTypes
|
||||
|
||||
|
||||
def telegram_text_message_from_update(
|
||||
update: Update,
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
"""Telegram outbound delivery."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
from collections.abc import Awaitable, Callable
|
||||
from datetime import timedelta
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
"""Shared voice-note flow for messaging platform adapters."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import contextlib
|
||||
import tempfile
|
||||
from collections.abc import Awaitable, Callable
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
"""Shared Markdown table pre-normalization for platform renderers."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
|
||||
_TABLE_SEP_RE = re.compile(r"^\s*\|?\s*:?-{3,}:?\s*(\|\s*:?-{3,}:?\s*)+\|?\s*$")
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
"""Platform rendering profiles for messaging transcripts and status text."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Callable
|
||||
from dataclasses import dataclass
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
"""Helpers for redacting user-derived content from log lines."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
|
||||
def format_exception_for_log(exc: BaseException, *, log_full_message: bool) -> str:
|
||||
"""Return exception type and optionally ``str(exc)`` for operator diagnostics."""
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
"""Per-chat message ID log used by messaging clear commands."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from datetime import UTC, datetime
|
||||
from typing import Any
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
"""Atomic JSON persistence for messaging session state."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import contextlib
|
||||
import json
|
||||
import os
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
"""Persistent messaging conversation state store."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import threading
|
||||
|
||||
from loguru import logger
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
"""Transcript event application and open-block tracking."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any
|
||||
|
||||
from .context import RenderCtx
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
"""Rendering context used by transcript segments."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Callable
|
||||
from dataclasses import dataclass
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
"""Render and truncate ordered transcript segments."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from collections import deque
|
||||
from collections.abc import Iterable
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
"""Transcript segment types for messaging UI output."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
from abc import ABC, abstractmethod
|
||||
from dataclasses import dataclass, field
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue