Commit Graph
2160 Commits
Author SHA1 Message Date
mrhard9090 75a6f9013b fix(db): add migration for run.hasChanges 2026-09-24 23:05:13 +03:00
Rohit Rajan 85ac964411 chore: add monitor feat telemetry 2026-09-16 23:41:43 +05:30
Rohit Rajan 5f270502ac fix: address coderabbit reviews 2026-09-16 18:29:05 +05:30
Rohit Rajan 546b0796fb fix: diff display cli monitoring 2026-09-16 18:06:02 +05:30
Karishma Shukla 5b4c899d34 Merge pull request #1210 from getmaxun/scrape-monitoring
feat: monitoring
2026-09-16 16:17:39 +05:30
Rohit Rajan 313bd7885d fix: rm ss comparison logic 2026-09-14 21:13:52 +05:30
Rohit Rajan 1a73e1b4fa feat: add sdk/api monitoring logic 2026-09-13 22:51:35 +05:30
Rohit Rajan c9ce803eb1 fix: click action url safeguards 2026-09-13 13:23:10 +05:30
Rohit Rajan 7ef6ee7c58 fix: register click with url 2026-09-13 13:12:14 +05:30
Rohit Rajan 1ff32d0aa8 fix: upload comparison diff extract consistency 2026-09-12 00:45:01 +05:30
Rohit Rajan 4a095ea548 fix: address coderabbit review 2026-09-12 00:33:59 +05:30
Rohit 902593cebc Merge branch 'develop' into centre-queue 2026-09-12 00:20:19 +05:30
Rohit Rajan 2e7f5b03e2 fix: centralize run queuing logic 2026-09-12 00:13:40 +05:30
Vyom ViraniandClaude Opus 5 223710f409 fix(server): authenticate the sockets the backend opens to itself
API, SDK and scheduled runs have hung since socket auth was added.

`authenticateSocket` is applied to every namespace via `io.on('new_namespace')`,
and it requires a token in `handshake.auth` or a `token` cookie. Browser clients
carry the httpOnly cookie, so the UI is unaffected. But the backend also joins
its own `/<browserId>` namespace as a socket.io *client* when a run is started
by something other than a browser, and that connection has neither a cookie nor
an auth token. It is refused.

The refusal is not what makes this hard to spot. `connect_error` is logged and
the socket cleaned up, but the run is never failed - so the browser eventually
falls back to a dummy socket, `ready-for-run` never reaches the caller, and the
run sits there. It reads as "slow", not as "broken".

Both server-opened connections are affected and they are the three paths people
report: `api/record.ts` (API and SDK) and `workflow-management/scheduler`
(scheduled runs).

Fixed by minting a short-lived token with the same `id` claim the HTTP login
issues, so the gate needs no special case and `socketOwns` keeps working: the
connection authenticates as the user the run already belongs to, not as a
privileged internal caller. A 60-second expiry because it is used once,
immediately - a login token is deliberately long-lived, which is right for a
session and wrong for a handshake.

Verified by A/B on one stack, same database, only the image changing:

  before   run hangs, 120s deadline exceeded
           "Socket connection error for API run ...: Unauthorized"
           "proceeding with dummy socket" -> "[SDK] Error executing robot: Run not found"
  after    run completes in 18.6s
           0 Unauthorized socket errors, 0 dummy socket fallbacks

And the gate itself, against `/queued-run`: no auth is refused, a minted token
connects, a token signed with the wrong secret is refused.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-11 10:49:42 +02:00
Rohit Rajan 1d03ddadce feat: extend monitoring to extract capture list 2026-09-10 23:25:40 +05:30
Rohit Rajan 6fd944201f feat: extend monitoring to extract cap text and ss 2026-09-10 18:40:27 +05:30
Rohit Rajan fbe730fd0c feat: extend monitoring to screenshot formats 2026-09-09 23:44:04 +05:30
Rohit Rajan 16b381e4d8 feat: extend monitoring to html,md formats 2026-09-09 23:06:39 +05:30
Ishan Karpe 03bd5d4051 Merge branch 'develop' into feature/image-ocr-support-august 2026-09-07 13:17:34 -07:00
Karishma Shukla dedd8de3d1 fix: select only necessary attributes in run comparison
Optimize query by selecting specific attributes to reduce data load.
2026-09-05 16:53:38 +05:30
Rohit Rajan 5fe3340ae3 fix: address run comparison review comments 2026-09-05 00:17:12 +05:30
jceychen 84a6f04465 Merge branch 'develop' into develop 2026-09-02 19:24:30 -07:00
joshjyu 0c44554106 fix(document): let table-only OCR results reach structured extraction 2026-08-28 09:37:52 -07:00
joshjyu 8321ee9366 fix(document): keep PaddleOCR tables when text extraction is empty 2026-08-28 09:23:24 -07:00
joshjyu 5cdff1319b fix(document): apply the email boundary to all link patterns 2026-08-28 09:21:32 -07:00
joshjyu e8209b891d fix(document): bound image size before script detection
Called downscaleIfOversized immediately after writing the temp file.
Also switched the resized dimensions from Math.round to Math.floor so the integer result cannot exceed MAX_OCR_PIXELS.
2026-08-27 23:13:21 -07:00
joshjyu fb2f23c866 fix(document): escape OCR text in HTML output
Added an escapeHtml helper and apply it to paragraph text and both table
cell paths. Paragraph text is escaped before newlines become <br>, so
the inserted breaks survive. Table structure, page sections, and the
DOCX sourceHtml passthrough are unchanged, and toMarkdown is untouched
since markdown output is not HTML.
2026-08-27 23:06:57 -07:00
joshjyu 8579ea0503 fix(document): stop truncating multi-label domains in link extraction 2026-08-27 22:56:49 -07:00
joshjyu c8c3236031 fix(document): make the OCR pixel guard fail closed
Note this also affects the PDF path: ocrPDF calls preprocessPageImage per rasterized page, so a page that cannot be measured or downscaled now fails that page's OCR instead of silently continuing.
2026-08-27 22:52:35 -07:00
joshjyu c6dcbeda5c fix(document): build image temp path from string literals only 2026-08-26 15:47:07 -07:00
joshjyu 2ae77fb028 fix(document): bound OCR preprocessing memory by pixel count
This fix addresses the edge case of an image with a large pixel count that is still under the 10 MB upload limit. For example, a 10000x10000 pixel JPEG compresses well under 10 MB but needs >2 GB across the per-pixel buffers in preprocessPageImage. Typed arrays are backed by external memory rather than V8's old space, so --max-old-space-size does not cap them and the process can be OOM-killed instead of failing gracefully.

Blank images are the most egregious case: PaddleOCR bounds its own input via maxSideLength so an image only reaches this code through the Tesseract fallback which is triggered by empty PaddleOCR output.

Read dimensions from the header with sharp (no full decode) and downscale above 25 MP before any allocation. Downscaling rather than rejecting keeps high-DPI scans working, since OCR gains nothing beyond roughly 300 DPI. This also covers the PDF path, where ocrPDF rasterizes pages at 4x and a large-format page could hit the same ceiling.
2026-08-26 15:19:11 -07:00
joshjyu 7c8032b9af Merge: remote-tracking branch 'upstream/develop' into feature/image-ocr-support-august 2026-08-26 12:45:40 -07:00
joshjyu 91eadccd47 fix(document): stop extracting email domains as bare-domain links 2026-08-26 11:29:29 -07:00
Rohit c1c234eccc Merge branch 'develop' into feat/1107-sdk-settings 2026-08-24 15:45:09 +05:30
Karishma Shukla b8f5c431ae Merge pull request #1176 from mbajji/feat/sdk-targeted-list-limits
Feat/sdk targeted list limits (list-limits part of issue #1107)
2026-08-24 15:02:29 +05:30
Anna Yang 5271add80c fix(storage): return a readable 400 when a document upload is rejected 2026-08-20 22:22:02 -04:00
Anna Yang 8127dd7e86 fix(document): degrade gracefully when OCR cannot read an image 2026-08-20 22:09:10 -04:00
Anna Yang 2407735768 feat(document): recover www and bare-domain links from OCR text 2026-08-20 21:49:59 -04:00
Anna Yang bdff5d15b0 fix(document): omit page headers in image markdown and html output 2026-08-20 21:47:08 -04:00
joshjyu 0bcc81c760 fix(sdk): accept DOCX and image uploads in document upload filter
Add DOCX, JPEG (plus the image/jpg alternate form), and PNG to the SDK's document upload allow-list, so the SDK endpoints accept the same formats as the document robots themselves.
Keeps the explicit MIME-type list rather than delegating to normalizeDocumentMimeType, so the SDK continues to match on the client-supplied MIME type only, with no filename-extension fallback.
2026-08-19 15:12:19 -07:00
joshjyu cff891b3b9 document: add image support in upload UI and messages
In addition to the image support, also fixed stale strings that were missing XLSX and CSV support.
2026-08-19 13:52:48 -07:00
joshjyu 2a9fbfdc0c refactor(sdk): use shared MIME normalizer in document upload filter
Replaced the hardcoded allowedMimeTypes array with normalizeDocumentMimeType to match storage.ts exactly.
2026-08-19 13:38:12 -07:00
joshjyu 1710626793 feat(image-ocr-support): Document image support
Added support for jpg and png support in comments and messaging in storage.ts.
2026-08-19 13:33:48 -07:00
joshjyu 84ac5bef61 feat(image-ocr-support): Add image parsing functionality to DocumentInterpreter.ts
Added a image mime type check with isImageMimeType that will point images to parseImage.
Added parseImage function that uses Paddle to OCR parse images.
Added ocrImageWithTesseract function to use Tesseract as a fallback.
2026-08-19 13:21:57 -07:00
joshjyu d971de841a feat(image-ocr-support): Add .jpg, .jpeg, and .png support to documentFile.ts 2026-08-19 13:10:57 -07:00
hmhngx f133ac4073 fix(workflowEnricher): resolve 2 new CodeRabbit findings on PR #1189
Reject non-positive/fractional limit values in getLLMDecisionWithVision's
Anthropic branch, matching the positive-safe-integer rule already enforced
in parseSearchIntent. Validate and sanitize generateFieldLabelsBatch's
Anthropic-branch label mapping before returning it: reject non-string,
blank, and __proto__/constructor/prototype values, since callers use each
value as an object key downstream (renamedFields[semanticLabel] = ...).
2026-08-19 23:13:03 +07:00
hmhngx 7dcf761fae fix(workflowEnricher): bump multi-site classification maxTokens 20 -> 80
Requested by maintainer review on PR #1189. The forced tool_choice call in
isMultiSitePrompt's Anthropic branch left too little headroom at 20 tokens,
risking truncation before the tool_use block completes.
2026-08-19 23:03:02 +07:00
hmhngx 8943fc8b9c fix(workflowEnricher): resolve 3 new CodeRabbit findings on PR #1189
Reject __proto__/constructor/prototype field names and use a null-prototype
target in filterFieldsByIntent's Anthropic branch to prevent prototype
pollution from untrusted tool output. Add explicit type validation for
first/second/reason/limit in getLLMDecisionWithVision's Anthropic branch,
since input_schema isn't runtime-enforced without strict mode. Reject
non-positive and non-safe-integer limit values in both parseSearchIntent
validation blocks (Anthropic branch and shared ollama/openai tail).
2026-08-19 23:03:02 +07:00
hmhngx c8db638344 fix(workflowEnricher): resolve 3 CodeRabbit findings on PR #1189
All 3 verified against current code and the actual failure modes before
fixing, not applied blindly from the bot's suggestion text.

1. getLLMDecisionWithVision: the Anthropic image block declared
   media_type: 'image/png' while the screenshot is captured as JPEG
   (page.screenshot({ type: 'jpeg' })). This is the exact mismatch already
   disclosed (by me) in the PR's "Note to Reviewers" before CodeRabbit
   caught it independently, confirmed against Anthropic's own docs that a
   media_type mismatch can 400 before the forced tool call ever runs.
   Fixed to 'image/jpeg'. The identical bug also exists in the untouched
   openai branch's `data:image/png;base64,...` URL - left as-is and
   flagged, not silently fixed, since that branch is explicitly out of
   this PR's scope.

2. parseSearchIntent: the validation `!intent.searchQuery ||
   !intent.extractionGoal` is a truthiness check, not a type check. Since
   callAnthropicWithTool returns raw tool_use.input with no strict-mode
   validation, a non-string value (e.g. an object) passes this guard, and
   downstream `encodeURIComponent(query)` (workflowEnricher.ts, both
   performDuckDuckGoSearch and performDuckDuckGoMultiSearch) silently
   turns it into the literal string "[object Object]" as a search query.
   Verified this exact call chain before fixing. Replaced with a guard
   that requires searchQuery/extractionGoal to be non-blank strings and
   limit (when present) to be an integer. Applied to both the anthropic
   branch's copy of this check AND the shared ollama/openai JSON-parsing
   branch's identical copy, per CodeRabbit's own comment text ("Apply the
   same validation to the JSON parsing branch") - not my own scope
   expansion, the finding explicitly asked for both.

3. selectMultipleUrlsFromResults: the per-index collection loop had no
   cap on `result.length`, so a tool response returning more valid,
   unique-domain indices than the caller's `maxSites`/`cap` would collect
   all of them instead of stopping at cap - e.g. 5 valid indices with
   cap=4 would produce 5 downstream workflows instead of 4. Added
   `if (result.length >= cap) break;` at the top of the loop, matching
   CodeRabbit's exact suggested diff. This identical bug also exists,
   unchanged, in the original shared-tail copy of this same loop (which
   predates this PR and serves ollama/openai) - CodeRabbit's finding did
   not ask for that copy to be fixed too, so it's flagged, not touched.

Verified: full project tsc --noEmit clean. A targeted test reproduced each
finding's exact described failure mode against the pre-fix code path
conceptually and confirmed the fix resolves it: searchQuery as an object,
as an array, as an empty/whitespace string, limit as a fraction, and limit
as a numeric string are all now correctly rejected (falling back to the
existing regex heuristic, not silently proceeding); valid inputs including
an omitted limit still succeed unchanged; 5 valid unique-domain indices
against cap=4 now correctly returns exactly 4, and a below-cap selection
is unaffected. Re-ran the full 9-site fallback regression afterward to
confirm the shared-code changes (finding #2) didn't affect any of the
other 8 sites.
2026-08-19 23:03:02 +07:00
hmhngx cc06f35e93 chore(workflowEnricher): remove dead Anthropic default import
All 9 anthropic branches now go through callAnthropicWithTool; the raw
`new Anthropic(...)` client construction that used to happen per-call-site
is gone as of the site #9 migration (372ded1d). The top-level
`import Anthropic from '@anthropic-ai/sdk'` had zero remaining references
- confirmed via `grep -n '\bAnthropic\b'` before removing it.
2026-08-19 23:03:01 +07:00