Skip to content

feat: ship hosted parsing v1#10

Merged
urjitc merged 22 commits into
mainfrom
codex/hosted-parsing-v1
Jul 22, 2026
Merged

feat: ship hosted parsing v1#10
urjitc merged 22 commits into
mainfrom
codex/hosted-parsing-v1

Conversation

@urjitc

@urjitc urjitc commented Jul 21, 2026

Copy link
Copy Markdown
Member

Summary

  • Ship hosted LiteParse and PDF Inspector execution in private Cloudflare containers.
  • Make hosted document jobs durable, recoverable, observable, and cost-aware.
  • Expose first-class SDK job handles while preserving parse() and compare() convenience APIs.
  • Simplify the dashboard, API-key flow, documentation navigation, and FileRouter brand assets.

Why

FileRouter v1 needs a reliable hosted parsing primitive before it can add intelligent routing. The previous path did not provide first-party hosted native parsers, recoverable SDK job handles, resilient Workflow startup, or production-grade execution telemetry.

This PR establishes those foundations while keeping provider choice explicit and preserving direct/BYOK execution.

Changes

  • Add a dedicated native-parser Worker and private container engines for LiteParse and PDF Inspector, including shared request contracts, option validation, health handling, and structured observability.
  • Add hosted provider adapters, durable source materialization, public-URL validation, result persistence, provider cost reporting, and native parser tests.
  • Add Autumn managed-execution metering and PostHog/browser/server observability boundaries.
  • Reconcile ambiguous Workflow startup, retry only recoverable Workflow steps, and preserve cleanup behavior.
  • Add client.jobs.create(), get(), and wait() with typed recoverable handles, stable idempotency keys, bounded transient retry, status callbacks, and total timeout accounting.
  • Keep FileRouterClient.parse() and compare() as backward-compatible create-and-wait conveniences.
  • Allow unnamed API keys and simplify dashboard onboarding.
  • Refresh docs, processing-mode disclosures, navigation, tech-stack notes, and generated logo assets.

Testing

  • pnpm typecheck
  • pnpm test — 89 tests passed
  • pnpm lint
  • pnpm build:app
  • git diff --check

Review Notes

  • Start with services/native-parsers/ for the execution boundary.
  • Review src/workflows/document-workflow.ts and src/lib/document-jobs.server.ts for lifecycle and retry semantics.
  • Review packages/filerouter/src/jobs.ts and packages/filerouter/src/client.ts for the public SDK contract.
  • The PR intentionally includes all 13 previously local commits as one hosted-parsing v1 release branch.

View with Codesmith Autofix with Codesmith
Need help on this PR? Tag /codesmith with what you need. Autofix is disabled.


Summary by cubic

Ships hosted parsing v1 with private native parsers, durable/recoverable hosted jobs, and account-level hosted credits. Adds curated LiteParse, usage metering, and product analytics for better reliability, billing, and visibility.

  • New Features

    • Adds liteparse and pdf-inspector providers running in private Cloudflare containers behind a native‑parser Worker with caps on bytes, pages, and concurrency; LiteParse supports curated managed OCR, Office conversion, image modes, complexity, and screenshots with explicit failures for unsupported settings.
    • Introduces durable hosted jobs with client.jobs.create(), get(), and wait() (stable idempotency keys, timeouts, bounded transient retry, status callbacks); parse() and compare() remain convenience wrappers.
    • Fetches public‑URL inputs once into temporary storage; rejects private/unsafe URLs; deletes sources when jobs finish; encodes hosted provider options with a 64 KiB limit.
    • Adds hosted credits: 5,000 free credits/month, dashboard balance and checkout via autumn-js; records provider‑reported costs and estimates managed execution; returns 402 Payment Required (insufficient_credits) when depleted and maps to PaymentRequired in the SDK.
    • Observability and UX: structured wide‑event logging, optional analytics/session replay via posthog-js/posthog-node, branded web/API error pages and 404; docs and navigation updated; brand geometry refined.
    • Updates provider catalog and CLI: adds liteparse and pdf-inspector, keeps localProviderIds limited to directly configured providers for local comparisons, allows unnamed API keys; exports selectParseOutputs.
  • Migration

    • No breaking changes. Existing parse() and compare() calls work as before.
    • To adopt recoverable jobs, use client.jobs.create(), client.jobs.get(), and client.jobs.wait() from @file_router/sdk.
    • Optional env vars: AUTUMN_SECRET_KEY for hosted credits and metering; POSTHOG_PROJECT_TOKEN and POSTHOG_HOST for analytics. A 402 Payment Required with insufficient_credits indicates the account needs credits (checkout from the dashboard).

Written for commit 97f7c75. Summary will update on new commits.

Review in cubic

@cursor

cursor Bot commented Jul 21, 2026

Copy link
Copy Markdown

Bugbot is not enabled for your account, so this pull request was not reviewed.

Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs.

@coderabbitai

coderabbitai Bot commented Jul 21, 2026

Copy link
Copy Markdown

Important

Review skipped

Too many files!

This PR contains 110 files, which is 10 over the limit of 100.

To get a review, narrow the scope:
• coderabbit review --committed # exclude uncommitted changes
• coderabbit review --dir # limit to a subdirectory
• coderabbit review --base # compare against a closer base

Upgrade to a paid plan to raise the limit.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: cea60777-e7a1-437b-9432-15b80e53c584

📥 Commits

Reviewing files that changed from the base of the PR and between 9b2c98a and 97f7c75.

⛔ Files ignored due to path filters (17)
  • docs/assets/favicon.svg is excluded by !**/*.svg
  • docs/assets/filerouter-logo.svg is excluded by !**/*.svg
  • docs/assets/filerouter-wordmark-dark.svg is excluded by !**/*.svg
  • docs/assets/filerouter-wordmark-light.svg is excluded by !**/*.svg
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
  • public/app-icon-maskable.svg is excluded by !**/*.svg
  • public/app-icon.svg is excluded by !**/*.svg
  • public/apple-touch-icon.png is excluded by !**/*.png
  • public/favicon.ico is excluded by !**/*.ico
  • public/favicon.svg is excluded by !**/*.svg
  • public/icon-192.png is excluded by !**/*.png
  • public/icon-512.png is excluded by !**/*.png
  • public/icon-maskable-512.png is excluded by !**/*.png
  • public/logo.svg is excluded by !**/*.svg
  • services/native-parsers/engines/liteparse/package-lock.json is excluded by !**/package-lock.json
  • services/native-parsers/engines/pdf-inspector/package-lock.json is excluded by !**/package-lock.json
  • src/logo.svg is excluded by !**/*.svg
📒 Files selected for processing (111)
  • .dev.vars.example
  • README.md
  • docs/api/overview.mdx
  • docs/cli/overview.mdx
  • docs/concepts/how-it-works.mdx
  • docs/concepts/processing-modes.mdx
  • docs/docs.json
  • docs/index.mdx
  • docs/sdk/provider-options.mdx
  • package.json
  • packages/cli/src/commands.ts
  • packages/cli/test/cli.test.ts
  • packages/filerouter/package.json
  • packages/filerouter/src/catalog.ts
  • packages/filerouter/src/client.ts
  • packages/filerouter/src/datalab.ts
  • packages/filerouter/src/errors.ts
  • packages/filerouter/src/hosted.ts
  • packages/filerouter/src/index.ts
  • packages/filerouter/src/internal/http.ts
  • packages/filerouter/src/internal/record.ts
  • packages/filerouter/src/internal/timeout.ts
  • packages/filerouter/src/jobs.ts
  • packages/filerouter/src/llamaparse.ts
  • packages/filerouter/src/mistral.ts
  • packages/filerouter/src/types.ts
  • packages/filerouter/test/catalog.test.ts
  • packages/filerouter/test/client.test.ts
  • packages/filerouter/test/datalab.test.ts
  • packages/filerouter/test/jobs.test.ts
  • packages/filerouter/test/llamaparse.test.ts
  • packages/filerouter/test/mistral.test.ts
  • pnpm-workspace.yaml
  • scripts/generate-logo-assets.mjs
  • services/native-parsers/engines/liteparse/Dockerfile
  • services/native-parsers/engines/liteparse/package.json
  • services/native-parsers/engines/liteparse/server.ts
  • services/native-parsers/engines/liteparse/tsconfig.json
  • services/native-parsers/engines/pdf-inspector/Dockerfile
  • services/native-parsers/engines/pdf-inspector/options.ts
  • services/native-parsers/engines/pdf-inspector/package.json
  • services/native-parsers/engines/pdf-inspector/server.ts
  • services/native-parsers/engines/pdf-inspector/tsconfig.json
  • services/native-parsers/engines/shared/contracts.ts
  • services/native-parsers/engines/shared/http.ts
  • services/native-parsers/engines/shared/observability.ts
  • services/native-parsers/engines/shared/options.ts
  • services/native-parsers/engines/shared/tsconfig.json
  • services/native-parsers/package.json
  • services/native-parsers/src/index.ts
  • services/native-parsers/src/observability.ts
  • services/native-parsers/test/options.test.ts
  • services/native-parsers/tsconfig.json
  • services/native-parsers/vitest.config.ts
  • services/native-parsers/worker-configuration.d.ts
  • services/native-parsers/wrangler.jsonc
  • src/api/app.ts
  • src/api/contracts.ts
  • src/api/problem.ts
  • src/components/api-keys.tsx
  • src/components/dashboard-billing.tsx
  • src/components/dashboard-quickstart.tsx
  • src/components/file-router-logo.tsx
  • src/components/not-found-page.tsx
  • src/components/posthog-bootstrap.tsx
  • src/components/pricing-section.tsx
  • src/components/root-error.tsx
  • src/integrations/autumn/billing.functions.ts
  • src/integrations/autumn/billing.server.test.ts
  • src/integrations/autumn/billing.server.ts
  • src/integrations/autumn/client.server.ts
  • src/integrations/autumn/config.ts
  • src/integrations/autumn/managed-execution-cost.ts
  • src/integrations/autumn/managed-execution.test.ts
  • src/integrations/autumn/managed-execution.ts
  • src/integrations/posthog/browser.ts
  • src/integrations/posthog/config.functions.ts
  • src/integrations/posthog/config.ts
  • src/integrations/posthog/server.ts
  • src/lib/api-auth.server.ts
  • src/lib/auth.functions.ts
  • src/lib/auth.server.ts
  • src/lib/document-job-input.server.test.ts
  • src/lib/document-job-input.server.ts
  • src/lib/document-jobs.server.ts
  • src/lib/document-limits.ts
  • src/lib/document-source.server.test.ts
  • src/lib/document-source.server.ts
  • src/lib/hosted-providers.server.ts
  • src/lib/http.server.ts
  • src/lib/native-parser.server.test.ts
  • src/lib/native-parser.server.ts
  • src/lib/public-url.ts
  • src/lib/record.ts
  • src/observability/log.ts
  • src/routes/__root.tsx
  • src/routes/cookies.tsx
  • src/routes/dashboard.tsx
  • src/routes/device.tsx
  • src/routes/index.tsx
  • src/routes/privacy.tsx
  • src/routes/sign-in.tsx
  • src/server.ts
  • src/workflows/document-results.ts
  • src/workflows/document-source.test.ts
  • src/workflows/document-source.ts
  • src/workflows/document-workflow.ts
  • test/worker/api.test.ts
  • vitest.worker.config.ts
  • worker-configuration.d.ts
  • wrangler.jsonc

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • Review on demand using usage pricing
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/hosted-parsing-v1

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@urjitc

urjitc commented Jul 21, 2026

Copy link
Copy Markdown
Member Author

@greptile-apps @coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 21, 2026

Copy link
Copy Markdown

@urjitc: I’ll review the changes in #10, focusing on the hosted parser boundary, workflow/job lifecycle semantics, and SDK contract.

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@greptile-apps

greptile-apps Bot commented Jul 21, 2026

Copy link
Copy Markdown

Greptile Summary

This PR ships hosted parsing v1 for FileRouter. The main changes are:

  • Native LiteParse and PDF Inspector execution in private Cloudflare containers.
  • Durable hosted document jobs with source materialization, result persistence, cleanup, and metering.
  • SDK job handles through client.jobs.create(), get(), and wait() while keeping parse() and compare() convenience APIs.
  • Hosted provider validation, public URL handling, observability, dashboard onboarding updates, docs, and brand assets.

Confidence Score: 4/5

One contained workflow issue should be fixed before hosted async providers are reliable.

The native parser and SDK changes are broadly coherent. The workflow polling loop can replay stale status because repeated polls use the same step names. The issue is isolated to async provider polling.

src/workflows/document-workflow.ts

T-Rex T-Rex Logs

What T-Rex did

  • Reproduced the workflow polling behavior that reuses step names by running the workflow_step_replay_repro.mjs script in a local harness.
  • Verified that the fake WorkflowStep caches the incomplete status and replays it for identical step.do names, and confirmed the provider’s jobs.get is called only once before the loop times out after 84 checks.
  • Inspected the repro harness output showing duplicate step names and stale status replay.
  • Verified TypeScript typecheck completed with EXIT_CODE 0.
  • Verified the test suite ran successfully with 10 test files and 40 tests passing, exit code 0.

View all artifacts

T-Rex Ran code and verified through T-Rex

Important Files Changed

Filename Overview
services/native-parsers/src/index.ts Adds the native parser Worker router and source materialization boundary; no blocking issues found.
services/native-parsers/engines/liteparse/server.ts Adds LiteParse container execution, option validation, temp-file handling, and normalized native parser output.
services/native-parsers/engines/pdf-inspector/server.ts Adds PDF Inspector container execution with page validation and normalized output.
src/workflows/document-workflow.ts Adds hosted job lifecycle, provider execution, cleanup, result persistence, and metering; async provider polling reuses workflow step names and can replay stale status.
src/lib/document-jobs.server.ts Adds durable hosted job creation, idempotency replay, workflow startup reconciliation, and result streaming.
packages/filerouter/src/jobs.ts Introduces public SDK job handles with create/get/wait, idempotency, retry, and timeout handling.
packages/filerouter/src/client.ts Refactors parse/compare convenience APIs to create hosted jobs and wait within total timeout accounting.
src/lib/native-parser.server.ts Adds hosted native parser provider adapter and response schema validation for LiteParse and PDF Inspector.
src/lib/document-source.server.ts Adds signed source URLs with expiry, range support, and R2 metadata validation for provider access.

Comments Outside Diff (1)

  1. src/workflows/document-workflow.ts, line 401-425 (link)

    P1 Use unique workflow steps
    step.do records results by step name, but every polling iteration reuses check ${provider.id} and wait for ${provider.id}. For async providers, the first non-complete status is replayed on each loop instead of issuing a fresh jobs.get, so a job that completes after the first poll still times out after 14 minutes. Include an attempt counter or provider job id in these step names.

    Artifacts

    Repro: workflow step replay harness

    • Contains supporting evidence from the run (text/javascript; charset=utf-8).

    Repro: harness output showing duplicate step names and stale status replay

    • Keeps the command output available without making the summary code-heavy.

    View artifacts

    T-Rex Ran code and verified through T-Rex

    Fix in Cursor

Fix All in Cursor

Reviews (1): Last reviewed commit: "feat(sdk): expose recoverable hosted job..." | Re-trigger Greptile

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6804d6f73f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +535 to +539
!params.requestId ||
!params.userId ||
params.providers.length === 0 ||
params.outputs.length === 0 ||
!validSource
!params.source.key

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve compatibility with existing workflow payloads

When this is deployed while any pre-change document workflow is still queued/running, its saved payload will not have requestId/userId, and URL-source jobs used the old { kind: "url", url } shape rather than a source.key. This new validation throws before the workflow enters the try block, so those durable instances fail without marking their D1 job failed or complete, leaving clients polling a stuck job. Please accept/upgrade the old payload shape or fail the job inside the existing error path.

Useful? React with 👍 / 👎.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

9 issues found across 109 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="services/native-parsers/src/index.ts">

<violation number="1" location="services/native-parsers/src/index.ts:70">
P3: Unexpected source/container failures return the runtime-generated error response without the assigned `X-Request-Id`, so callers cannot correlate those 5xx responses with `native_parser_request_completed` logs. Return a sanitized 5xx through `responseWithRequestId` after recording `failure`.</violation>
</file>

<file name="packages/filerouter/src/mistral.ts">

<violation number="1" location="packages/filerouter/src/mistral.ts:238">
P2: Successful OCR calls can omit `usage.costUsd` when Mistral returns its `-completion` response model ID, because rate lookup only recognizes request-style IDs. Normalize that suffix (or pass the resolved request model into normalization) before rate lookup.</violation>
</file>

<file name="src/components/api-keys.tsx">

<violation number="1" location="src/components/api-keys.tsx:178">
P3: API-key rows display `undefined...` when Better Auth is configured not to persist `start` (or for older rows). Keep a prefix/friendly fallback so keys remain identifiable.</violation>
</file>

<file name="src/workflows/document-workflow.ts">

<violation number="1" location="src/workflows/document-workflow.ts:122">
P1: A D1 failure while marking a job running now leaves its row `queued` after the workflow deletes its source, so `jobs.wait()` keeps polling a job that cannot recover. Include `queued` in the failure transition (or make the running transition retry/atomic) so this path becomes terminal.</violation>
</file>

<file name="src/workflows/document-source.ts">

<violation number="1" location="src/workflows/document-source.ts:63">
P2: Dead or invalid document URLs are fetched up to four times before the job fails because permanent response errors are ordinary `Error`s inside the retried storage step. Classify known validation/HTTP-response failures as `NonRetryableError` while retaining retries for transient fetch and R2 failures.</violation>
</file>

<file name="services/native-parsers/engines/pdf-inspector/Dockerfile">

<violation number="1" location="services/native-parsers/engines/pdf-inspector/Dockerfile:6">
P2: Build context includes unnecessary files — add a `.dockerignore` to exclude `node_modules/`, `.git/`, `.env`, and editor files from the Docker build context. Without one, the full `engines/` directory is sent to the daemon every build, slowing builds and risking inconsistent cache behavior when local `node_modules/` exists.</violation>
</file>

<file name="services/native-parsers/engines/liteparse/package.json">

<violation number="1" location="services/native-parsers/engines/liteparse/package.json:6">
P2: The `start` script runs `node server.ts` directly, but Node.js requires `--experimental-strip-types` to run `.ts` files before version 24. The project declares `node@>=22.14.0` as a dependency, so developers on Node 22 or 23 will see the server crash with an unrecognized extension/syntax error when running `pnpm start`. Production (Node 24 in Docker) is unaffected, but local dev and CI on <24 will break.

Recommend either: (a) adding `--experimental-strip-types` to the start command, or (b) adding an `.nvmrc`/engines field that signals the expected runtime.</violation>
</file>

<file name="src/api/app.ts">

<violation number="1" location="src/api/app.ts:93">
P3: Rejected API requests such as invalid job IDs and authentication failures omit `error_code` from `api_request_completed` telemetry. Record the `HttpError.code` in `api.onError` before returning its problem response, since Hono handles these errors there rather than propagating them to this middleware catch.</violation>
</file>

<file name="services/native-parsers/engines/shared/observability.ts">

<violation number="1" location="services/native-parsers/engines/shared/observability.ts:18">
P1: `serializeError` drops stack traces from error telemetry, making production debugging harder. Include the stack property when available so operational investigations have the full call path.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread services/native-parsers/engines/pdf-inspector/server.ts Outdated
}

export function serializeError(error: unknown) {
return error instanceof Error

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: serializeError drops stack traces from error telemetry, making production debugging harder. Include the stack property when available so operational investigations have the full call path.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At services/native-parsers/engines/shared/observability.ts, line 18:

<comment>`serializeError` drops stack traces from error telemetry, making production debugging harder. Include the stack property when available so operational investigations have the full call path.</comment>

<file context>
@@ -0,0 +1,21 @@
+}
+
+export function serializeError(error: unknown) {
+  return error instanceof Error
+    ? { error_message: error.message, error_type: error.name }
+    : { error_message: "Unknown error", error_type: "UnknownError" }
</file context>

Comment thread services/native-parsers/engines/liteparse/server.ts Outdated
Comment thread src/lib/public-url.ts Outdated

try {
const configured = providers(this.env)
const startedAt = await step.do("mark job running", async () => {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: A D1 failure while marking a job running now leaves its row queued after the workflow deletes its source, so jobs.wait() keeps polling a job that cannot recover. Include queued in the failure transition (or make the running transition retry/atomic) so this path becomes terminal.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/workflows/document-workflow.ts, line 122:

<comment>A D1 failure while marking a job running now leaves its row `queued` after the workflow deletes its source, so `jobs.wait()` keeps polling a job that cannot recover. Include `queued` in the failure transition (or make the running transition retry/atomic) so this path becomes terminal.</comment>

<file context>
@@ -72,45 +109,71 @@ export class DocumentWorkflow extends WorkflowEntrypoint<
 
     try {
-      const configured = providers(this.env)
+      const startedAt = await step.do("mark job running", async () => {
+        const timestamp = new Date()
+        await createDb(this.env.DB)
</file context>

@@ -0,0 +1,14 @@
FROM node:24-bookworm-slim@sha256:6f7b03f7c2c8e2e784dcf9295400527b9b1270fd37b7e9a7285cf83b6951452d

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Build context includes unnecessary files — add a .dockerignore to exclude node_modules/, .git/, .env, and editor files from the Docker build context. Without one, the full engines/ directory is sent to the daemon every build, slowing builds and risking inconsistent cache behavior when local node_modules/ exists.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At services/native-parsers/engines/pdf-inspector/Dockerfile, line 6:

<comment>Build context includes unnecessary files — add a `.dockerignore` to exclude `node_modules/`, `.git/`, `.env`, and editor files from the Docker build context. Without one, the full `engines/` directory is sent to the daemon every build, slowing builds and risking inconsistent cache behavior when local `node_modules/` exists.</comment>

<file context>
@@ -0,0 +1,14 @@
+WORKDIR /app
+ENV NODE_ENV=production
+
+COPY pdf-inspector/package.json pdf-inspector/package-lock.json ./pdf-inspector/
+RUN cd pdf-inspector && npm ci --omit=dev --no-audit --no-fund
+
</file context>

return responseWithRequestId(response, requestId)
} catch (error) {
failure = error
throw error

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3: Unexpected source/container failures return the runtime-generated error response without the assigned X-Request-Id, so callers cannot correlate those 5xx responses with native_parser_request_completed logs. Return a sanitized 5xx through responseWithRequestId after recording failure.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At services/native-parsers/src/index.ts, line 70:

<comment>Unexpected source/container failures return the runtime-generated error response without the assigned `X-Request-Id`, so callers cannot correlate those 5xx responses with `native_parser_request_completed` logs. Return a sanitized 5xx through `responseWithRequestId` after recording `failure`.</comment>

<file context>
@@ -0,0 +1,197 @@
+      return responseWithRequestId(response, requestId)
+    } catch (error) {
+      failure = error
+      throw error
+    } finally {
+      const status = response?.status ?? 500
</file context>

Comment thread packages/filerouter/src/jobs.ts
Comment thread src/api/app.ts
await next()
} catch (error) {
failure = error
if (error instanceof HttpError) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3: Rejected API requests such as invalid job IDs and authentication failures omit error_code from api_request_completed telemetry. Record the HttpError.code in api.onError before returning its problem response, since Hono handles these errors there rather than propagating them to this middleware catch.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/api/app.ts, line 93:

<comment>Rejected API requests such as invalid job IDs and authentication failures omit `error_code` from `api_request_completed` telemetry. Record the `HttpError.code` in `api.onError` before returning its problem response, since Hono handles these errors there rather than propagating them to this middleware catch.</comment>

<file context>
@@ -43,18 +77,73 @@ export const api = new OpenAPIHono<ApiBindings>({
+    await next()
+  } catch (error) {
+    failure = error
+    if (error instanceof HttpError) {
+      requestEvent.error_code = error.code ?? "http_error"
+    }
</file context>

{key.start ?? key.prefix ?? FILEROUTER_API_KEY_PREFIX}... -
Created {dateFormatter.format(new Date(key.createdAt))}
<p className="truncate font-mono text-xs font-medium">
{key.start}...

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3: API-key rows display undefined... when Better Auth is configured not to persist start (or for older rows). Keep a prefix/friendly fallback so keys remain identifiable.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/components/api-keys.tsx, line 178:

<comment>API-key rows display `undefined...` when Better Auth is configured not to persist `start` (or for older rows). Keep a prefix/friendly fallback so keys remain identifiable.</comment>

<file context>
@@ -168,16 +174,18 @@ export function ApiKeys() {
-                  {key.start ?? key.prefix ?? FILEROUTER_API_KEY_PREFIX}... -
-                  Created {dateFormatter.format(new Date(key.createdAt))}
+                <p className="truncate font-mono text-xs font-medium">
+                  {key.start}...
+                </p>
+                <p className="mt-1 truncate text-xs text-muted-foreground">
</file context>
Suggested change
{key.start}...
{key.start ?? key.prefix ?? "API key"}...

@urjitc
urjitc merged commit 790e8f9 into main Jul 22, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant