Skip to content

Component: TriggerManager

Canonical source: SmrtApps/CSApps/TriggerManager/README.md (mirrored below)


TriggerManager — Global Hotkey Orchestrator

Overview & Responsibilities

  • Runs a headless WinForms message loop that owns all global SmrtHub hotkeys and stays resident in the system trayless background.
  • Validates and loads hotkey configuration, registers Windows-wide shortcuts, and exposes strongly typed actions for downstream components.
  • Dispatches automation trigger payloads over HTTP to the Python trigger service (http://127.0.0.1:5001/trigger) and can also route select hotkeys to local C# components (e.g., HubWindow visibility) or execute them locally (for UI-free clipboard OCR scenarios) while surfacing telemetry through SmrtHub.Logging.
  • Provides a single source of truth for trigger routing so desktop and automation flows remain synchronized across runtimes.

Runtime Flow

  1. Program.Main bootstraps SmrtHub.Logging, enters an invisible WinForms loop, and instantiates TriggerDispatcher + HotkeyManager.
  2. HotkeysConfig.LoadOrSeed resolves the roaming config file, falling back to bundled defaults and enforcing the JSON schema.
  3. HotkeyManager.RegisterHotkeys parses each binding, registers it with the Windows API, and wires the corresponding action delegate.
  4. When a user presses a registered shortcut, HotkeyManager routes the WM_HOTKEY message to TriggerDispatcher which delegates to ActionDispatcher.
  5. ActionDispatcher posts the trigger payload to the correct downstream service and logs the outcome (status, latency, error details).

Dependencies & Integrations

  • SmrtHub.Logging — unified text/JSONL/HTML logging; all entries use the trigger-manager slug per Operational Data Policy.
  • Smrt.Config — canonical resolver for TriggerManager roaming configuration (see HotkeysConfig.FilePath) with atomic writes.
  • Python Trigger HTTP host — handles automation triggers (HOTKEY_SMRTSAVE, HOTKEY_SMRTSEARCH, etc.) on http://127.0.0.1:5001/trigger.
  • NJsonSchema — validates user hotkey config before it is accepted.

Configuration & Log Paths

  • Hotkey config (roaming): resolved via Smrt.Config (see HotkeysConfig.FilePath).
  • Bundled defaults: config/defaults/hotkeys.defaults.json copied on first run.
  • Schema enforcement: config/schema/hotkeys.schema.json shipped with the app, optional but applied when present.
  • Logs: %LocalAppData%/SmrtHub/Logs/trigger-manager/trigger-manager-log*.{txt,json} (managed by SmrtHub.Logging with HTML export on demand).

Hotkey Registry

Hotkey Default Binding Route Target Notes
HOTKEY_SMRTSAVE Ctrl+Shift+S Python trigger service Persists active clipboard content.
HOTKEY_SMRTSEARCH Ctrl+Shift+C Python trigger service Launches Smart Web capture routine.
HUBWINDOW_TOGGLE Ctrl+Shift+H HubWindow (local IPC) Cycles HubWindow top-panel state via HubWindow single-instance IPC (action:toggle-top-panel). Best-effort fallback: restore event or launching HubWindow when staged alongside TriggerManager.
HOTKEY_EXTRACT_TEXT Ctrl+Shift+O TriggerManager (local) OCRs clipboard image/file and copies extracted text to clipboard.
HOTKEY_EXTRACT_STRUCTURED_TEXT Ctrl+Shift+Alt+O TriggerManager (local) OCRs clipboard image/file, copies structured JSON to clipboard, and best-effort POSTs it to the Python bridge (POST /structured-output) so it is persisted under the active SmrtSpace in Structured Data Output/<YYYY-MM-DD>/.
HOTKEY_EXTRACT_STRUCTURED_TEXT_FROM_DOCUMENTS Ctrl+Shift+Alt+P TriggerManager (local) Prompts to pick files or a folder (optional subfolder recursion), runs local structured OCR per input, and persists results via POST /structured-output/batch when enabled (fallback to POST /structured-output per item). Copies JSON to clipboard only when a single file is selected.

Local OCR Inputs (TriggerManager)

TriggerManager’s OCR hotkeys use local Windows OCR executors (Windows AI OCR when available/ready, else Windows legacy OCR). The local path accepts inputs that can be decoded/rendered into a Windows.Graphics.Imaging.SoftwareBitmap.

Supported Inputs

  • Raster images (file-drop or picker): commonly .png, .jpg/.jpeg, .bmp, .gif, .tif/.tiff.
  • PDF scans (picker / file-drop): .pdf (application/pdf) is supported by rendering each page via Windows.Data.Pdf and running OCR per page.

Current Limitations

  • Password-protected/encrypted PDFs are not supported.
  • Non-image office/document formats (DOCX, PPTX, HTML, etc.) are not supported by the local OCR hotkeys.
  • Very large PDFs can be slow; prefer cloud providers for high-volume or long-document extraction.

Safety Limits (Bulk Runs)

To keep bulk folder runs safe and predictable, TriggerManager enforces best-effort limits for the documents hotkey. Configure via environment variables:

  • SMRTHUB_LOCAL_OCR_MAX_FILES_PER_RUN (default: 250) — maximum number of documents processed per hotkey run (extra files are truncated).
  • SMRTHUB_LOCAL_OCR_MAX_FILE_BYTES (default: 52428800 / 50 MiB) — maximum file size per document (oversize files are skipped).
  • SMRTHUB_LOCAL_OCR_MAX_PDF_PAGES_PER_DOCUMENT (optional) — when set to a positive integer, caps how many PDF pages are rendered/OCR’d per document.
  • SMRTHUB_LOCAL_OCR_TIMEOUT_SECONDS (default: 180) — per-document timeout for local OCR (and file read). Timed-out documents are marked failed and the run continues.

Persistence Optimizations (Bulk Runs)

To reduce HTTP overhead when persisting many structured outputs, TriggerManager can buffer multiple extracted JSON payloads and flush them to the Python bridge in batches.

  • SMRTHUB_STRUCTURED_OUTPUT_BATCH_ENABLED (default: true) — enables POST /structured-output/batch for multi-item flushes.
  • SMRTHUB_STRUCTURED_OUTPUT_BATCH_MAX_ITEMS (default: 25) — maximum items per batch flush.
  • SMRTHUB_STRUCTURED_OUTPUT_BATCH_MAX_JSON_BYTES (default: 2097152) — best-effort cap on buffered JSON bytes per flush.

If a batch POST fails, TriggerManager logs a warning and falls back to individual POST /structured-output requests.

Persistence Reliability (Retries)

TriggerManager treats loopback HTTP persistence as best-effort. To improve resiliency for transient failures, it retries failed persistence POSTs (batch and per-item) using exponential backoff with jitter.

  • SMRTHUB_STRUCTURED_OUTPUT_HTTP_MAX_ATTEMPTS (default: 3) — total attempts per POST (1 initial + retries).
  • SMRTHUB_STRUCTURED_OUTPUT_HTTP_RETRY_BASE_DELAY_MS (default: 250) — base backoff delay.
  • SMRTHUB_STRUCTURED_OUTPUT_HTTP_RETRY_MAX_DELAY_MS (default: 2000) — upper cap for backoff delay.

Retries apply only to transient failures (timeouts, network errors, and HTTP 408/429/5xx). Non-transient failures (e.g., 400 validation errors) are not retried.

What You’ll See In Logs

TriggerManager intentionally logs metadata only (counts, filenames, sizes, page counts, provider status) — never document bytes or extracted content. Typical entries for the documents hotkey:

  • Selection + truncation:
    • ExtractStructuredText-from-documents hotkey: selected files (count=1234) exceeds limit (max=250); truncating list.
    • ExtractStructuredText-from-documents hotkey: selected files (count=250)
  • Skips (guardrails):
    • ExtractStructuredText-from-documents failed for <file>: File is too large for local OCR (bytes=..., max=...).
    • ExtractStructuredText-from-documents failed for <file>: Local OCR timed out after 180 seconds.
  • Success (per file):
    • ExtractStructuredText-from-documents succeeded for <file> (chars=..., pages=...)
    • If SMRTHUB_LOCAL_OCR_MAX_PDF_PAGES_PER_DOCUMENT is set and the output hits the cap: ... (PDF page limit reached ...; output may be truncated)
  • Run summary:
    • ExtractStructuredText-from-documents finished (runId=...): succeeded=..., failed=..., total=...

Structured-output persistence telemetry (structured JSONL):

  • TriggerManager emits standardized event names with shared fields so operators can correlate TriggerManager ↔ python-net ↔ python-runtime.
  • Canonical schema reference: README.Files/System/Policies/SmrtHub-StructuredOutput-Telemetry-v1.0.README.md.
  • Common fields:
    • kind: structured-output
    • eventVersion: 1
    • runId (always) and requestId (per-item when applicable)
    • route (e.g., /structured-output, /structured-output/batch), status, attempt, maxAttempts, responseLength
    • outcome (success, failed, retry-scheduled, fallback, summary) and outcomeKind
  • Event names:
    • structured-output.post.retry-scheduled
    • structured-output.post.completed
    • structured-output.post.failed
    • structured-output.post.exception
    • structured-output.batch.fallback
    • structured-output.persist.summary

Correlation IDs (runId + requestId)

  • Each documents hotkey run generates a single runId (GUID) and includes it on all persistence requests and summary logs.
  • Each persisted item also has its own requestId (GUID) so individual saves can be traced end-to-end.
  • Both IDs are safe to log and are used for cross-component correlation (TriggerManager ↔ python-net ↔ python-runtime) without logging content.

Diagnostics & Support

  • Logs follow SmrtHub’s Operational Data Policy; use the Support Bundle exporter or Logger.ExportUnifiedHtmlLogs("trigger-manager") to collect artifacts.
  • Hotkey registration warnings (collisions, parse failures) and dispatch errors are captured in both text and JSON logs with correlation IDs.
  • For field issues, capture the user hotkey config and relevant log segment, then reference README.Files/Reference-Guides/Smrt.SupportBundle.README.md.

Support bundle

  • Include TriggerManager logs and the active hotkey configuration when generating a support bundle.
  • Not documented yet: any TriggerManager-specific non-log artifacts that should be captured.

Testing & Validation

  1. Build: Tools/Clean-Build/BuildApps.ps1 -Scope CSharpApps -Configuration Debug -RuntimeIdentifier win-x64.
  2. Run: execute TriggerManager.exe from Apps/Debug/win-x64/TriggerManager/ (ensure the Python trigger host is reachable if testing end-to-end).
  3. Trigger: use the default hotkey set or modify the roaming hotkey config file, then press each shortcut to confirm dispatch and observe log entries.
  4. Schema: intentionally break the config (e.g., duplicate binding) to verify validation logs an error and the defaults remain intact.

Build & Deployment

  • Packaged via the central build pipeline; staged output lives under Apps/<Configuration>/<RID>/TriggerManager/ alongside defaults and schema files.
  • Dedicated script: Build-TriggerManager.ps1 (wrapper around the centralized build script) is available for local smoke testing.
  • README.Files/Reference-Guides/SmrtHub.Logging.README.md
  • README.Files/System/Policies/SmrtHub-Operational-Data-Policy-v1.0.README.md
  • README.Files/System/Policies/SmrtHub-Documentation-Policy-v1.0.README.md