Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
0e4ace5
feat: improved screenshot accuracy
Arunmadhavan28 Apr 29, 2026
754330c
feat: reduced latency|multiple pics|live preview
Arunmadhavan28 May 4, 2026
7b561b0
feat: conflict fix|accuracy fix
Arunmadhavan28 May 4, 2026
625a0b6
feat: PR refactoring fix
Arunmadhavan28 May 4, 2026
8ef216e
feat: context limit 512-> 2048
Arunmadhavan28 May 4, 2026
e895739
Merge branch 'dev' into screenshot_accuracy
Arunmadhavan28 May 4, 2026
e6e0d08
feat: docker file overwrite fix
Arunmadhavan28 May 4, 2026
8f89689
Merge branch 'screenshot_accuracy' of https://github.com/Cyborg-Netwo…
Arunmadhavan28 May 4, 2026
5bf522e
Remove duplicate mounted declaration
Arunmadhavan28 May 4, 2026
b7b3d5d
Fix import location in result-viewer
Arunmadhavan28 May 4, 2026
e1ed002
Refactor: resolve OxBot security, performance, and architecture flags
Arunmadhavan28 May 4, 2026
3d8960e
style: biome auto-format and import sorting
Arunmadhavan28 May 4, 2026
fd83804
major: extension|bi-model|accuracy
Arunmadhavan28 May 11, 2026
552b5fe
major: preview removed | Apple style animation | major UI improvements
Arunmadhavan28 May 12, 2026
a07692c
fix : lint pipeline error
Arunmadhavan28 May 12, 2026
033f3d9
remove : extension contents
Arunmadhavan28 May 13, 2026
eaa4728
refactor : code base reduced to multiple files
Arunmadhavan28 May 13, 2026
17f06c8
removed : extension files and dependencies cleaned
Arunmadhavan28 May 19, 2026
0202a77
removed : tier clean up
Arunmadhavan28 May 20, 2026
23f439d
removed : allowedDevOrigins clean up
Arunmadhavan28 May 20, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 46 additions & 46 deletions app/biome.json
Original file line number Diff line number Diff line change
@@ -1,48 +1,48 @@
{
"$schema": "https://biomejs.dev/schemas/2.4.6/schema.json",
"vcs": {
"enabled": true,
"clientKind": "git",
"useIgnoreFile": false
},
"formatter": {
"enabled": true,
"indentStyle": "tab",
"indentWidth": 2,
"lineWidth": 100
},
"linter": {
"enabled": true,
"rules": {
"recommended": true,
"correctness": {
"useExhaustiveDependencies": "warn",
"noUnusedImports": "warn",
"noUnusedVariables": "warn"
},
"style": {
"noNonNullAssertion": "off"
},
"suspicious": {
"noExplicitAny": "warn",
"noArrayIndexKey": "warn"
},
"a11y": {
"useButtonType": "warn"
},
"performance": {
"noImgElement": "warn"
},
"security": {
"noDangerouslySetInnerHtml": "warn"
}
}
},
"javascript": {
"formatter": {
"quoteStyle": "double",
"semicolons": "always",
"trailingCommas": "es5"
}
}
"$schema": "https://biomejs.dev/schemas/2.4.6/schema.json",
"vcs": {
"enabled": true,
"clientKind": "git",
"useIgnoreFile": false
},
"formatter": {
"enabled": true,
"indentStyle": "tab",
"indentWidth": 2,
"lineWidth": 100
},
"linter": {
"enabled": true,
"rules": {
"recommended": true,
"correctness": {
"useExhaustiveDependencies": "warn",
"noUnusedImports": "warn",
"noUnusedVariables": "warn"
},
"style": {
"noNonNullAssertion": "off"
},
"suspicious": {
"noExplicitAny": "warn",
"noArrayIndexKey": "warn"
},
"a11y": {
"useButtonType": "warn"
},
"performance": {
"noImgElement": "warn"
},
"security": {
"noDangerouslySetInnerHtml": "warn"
}
}
},
"javascript": {
"formatter": {
"quoteStyle": "double",
"semicolons": "always",
"trailingCommas": "es5"
}
}
}
25 changes: 13 additions & 12 deletions app/next.config.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
import type { NextConfig } from "next";

const nextConfig: NextConfig = {
reactCompiler: true,
// Proxy tier2 streaming tool requests directly to the Python runner,
// bypassing the Next.js API route runtime which kills long-lived streams.
async rewrites() {
const runnerUrl = process.env.TOOL_RUNNER_URL || "http://localhost:9080";
return [
{
source: "/api/tools-stream/:toolId",
destination: `${runnerUrl}/api/tools/:toolId`,
},
];
},

reactCompiler: true,
// Proxy tier2 streaming tool requests directly to the Python runner,
// bypassing the Next.js API route runtime which kills long-lived streams.
async rewrites() {
const runnerUrl = process.env.TOOL_RUNNER_URL || "http://localhost:9080";
return [
{
source: "/api/tools-stream/:toolId",
destination: `${runnerUrl}/api/tools/:toolId`,
},
];
},
};

export default nextConfig;
12 changes: 11 additions & 1 deletion app/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

68 changes: 34 additions & 34 deletions app/package.json
Original file line number Diff line number Diff line change
@@ -1,36 +1,36 @@
{
"name": "oxtools",
"version": "1.0.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "biome check",
"format": "biome format --write"
},
"dependencies": {
"@ansospace/ui": "^0.0.3",
"@icons-pack/react-simple-icons": "^13.13.0",
"idb-keyval": "^6.2.2",
"lucide-react": "^1.7.0",
"mermaid": "^11.14.0",
"next": "16.2.2",
"openai": "^6.33.0",
"react": "19.2.4",
"react-dom": "19.2.4",
"react-markdown": "^10.1.0",
"rehype-highlight": "^7.0.2",
"remark-gfm": "^4.0.1"
},
"devDependencies": {
"@biomejs/biome": "2.4.6",
"@tailwindcss/postcss": "^4",
"@types/node": "^20",
"@types/react": "^19",
"@types/react-dom": "^19",
"babel-plugin-react-compiler": "1.0.0",
"tailwindcss": "^4",
"typescript": "^5"
}
"name": "oxtools",
"version": "1.0.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "biome check",
"format": "biome format --write"
},
"dependencies": {
"@ansospace/ui": "^0.0.3",
"@icons-pack/react-simple-icons": "^13.13.0",
"idb-keyval": "^6.2.2",
"lucide-react": "^1.7.0",
"mermaid": "^11.14.0",
"next": "16.2.2",
"openai": "^6.33.0",
"react": "19.2.4",
"react-dom": "19.2.4",
"react-markdown": "^10.1.0",
"rehype-highlight": "^7.0.2",
"remark-gfm": "^4.0.1"
},
"devDependencies": {
"@biomejs/biome": "2.4.6",
"@tailwindcss/postcss": "^4",
"@types/node": "^20",
"@types/react": "^19",
"@types/react-dom": "^19",
"babel-plugin-react-compiler": "1.0.0",
"tailwindcss": "^4",
"typescript": "^5"
}
}
6 changes: 3 additions & 3 deletions app/postcss.config.mjs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
/** @type {import('postcss-load-config').Config} */
const config = {
plugins: {
"@tailwindcss/postcss": {},
},
plugins: {
"@tailwindcss/postcss": {},
},
};

export default config;
35 changes: 6 additions & 29 deletions app/src/app/api/tools/[toolId]/route.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,12 @@
import type { NextRequest } from "next/server";
import { NextResponse } from "next/server";

import { type NextRequest, NextResponse } from "next/server";
import { createToolRoute } from "@/lib/create-tool-route";
import { getToolById } from "@/lib/tools/registry";

// Allow long-running tool executions (up to 5 min locally, 300s on Vercel)
// Issue 5: maxDuration is set to 300s (5 minutes).
Comment thread
Arunmadhavan28 marked this conversation as resolved.
Comment thread
Arunmadhavan28 marked this conversation as resolved.
// We align the AbortController timeout to match this limit exactly,
Comment thread
Arunmadhavan28 marked this conversation as resolved.
// so that requests gracefully abort rather than hanging when Vercel kills the function.
export const maxDuration = 300;
// Force dynamic rendering — prevents Next.js from evaluating this route
// at build time (which would fail without OXLO_API_KEY in CI)
export const dynamic = "force-dynamic";

/**
* Dynamic API route for ALL tools.
*
* TIER 1: Dispatches to createToolRoute (calls Oxlo LLM API directly).
* TIER 2: Proxies to the unified Python tool runner on port 9080.
*
* The unified runner handles ALL Python tools on ONE port.
* Route: POST http://localhost:9080/api/tools/{toolId}
*/
export async function POST(
Comment thread
Arunmadhavan28 marked this conversation as resolved.
request: NextRequest,
{ params }: { params: Promise<{ toolId: string }> }
Expand All @@ -33,31 +21,20 @@ export async function POST(
);
}

// --- Tier 2: Proxy to unified Python tool runner ---
if (tool.tier === "tier2") {
return proxyToToolRunner(request, toolId);
}

// --- Tier 1: Handle via LLM prompt (default) ---
const handler = createToolRoute({
requiredFields: tool.requiredFields,
buildSystemPrompt: tool.buildSystemPrompt,
buildUserPrompt: tool.buildUserPrompt,
defaultModel: tool.defaultModel,
errorMessage: `Failed to execute ${tool.name}`,
});

return handler(request);
}

/**
* Proxy a request to the unified Python tool runner.
*
* ALL Tier 2 tools run on ONE service (port 9080) via:
* POST http://runner:9080/api/tools/{toolId}
*
* No more port-per-tool. One port, one container, unlimited tools.
*/
async function proxyToToolRunner(request: NextRequest, toolId: string) {
const runnerUrl = process.env.TOOL_RUNNER_URL || "http://localhost:9080";
const targetUrl = `${runnerUrl}/api/tools/${toolId}`;
Expand All @@ -66,12 +43,12 @@ async function proxyToToolRunner(request: NextRequest, toolId: string) {
const body = await request.text();
const contentType = request.headers.get("content-type") || "application/json";

// 10 minute timeout — security scans with LLM retries can take 5-10 min
// 5 minute timeout — security scans with LLM retries can take 5 min
Comment thread
Arunmadhavan28 marked this conversation as resolved.
const response = await fetch(targetUrl, {
Comment thread
Arunmadhavan28 marked this conversation as resolved.
method: "POST",
headers: { "Content-Type": contentType },
body,
signal: AbortSignal.timeout(600_000),
signal: AbortSignal.timeout(300_000),
Comment thread
Arunmadhavan28 marked this conversation as resolved.
});
Comment thread
Arunmadhavan28 marked this conversation as resolved.

if (!response.ok) {
Expand Down
Loading
Loading