feat: add SMC bias agent#264
Conversation
|
adding SMC agnet |
:robot_face: AgentKit Structural ValidationNew Contributions Detected
Check Results
❌ Errors
|
|
Failure recorded at 2026-07-20T10:34:25Z UTC. If this PR is not fixed within 4 weeks it will be automatically closed. |
WalkthroughChangesThe pull request adds a complete Next.js SMC Bias Agent kit: Binance candle retrieval, SMC/ICT analysis, Lamatic or fallback narrative generation, an analysis API, and a chart-based frontend with setup documentation. SMC Bias Agent
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 8
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@kits/smc-bias-agent/.env.example`:
- Around line 1-4: Replace the credential-like values in the .env.example
entries LAMATIC_API_KEY, LAMATIC_GRAPHQL_URL, LAMATIC_PROJECT_ID, and
LAMATIC_WORKFLOW_ID with clearly fake placeholders, and rotate or revoke the
exposed Lamatic credentials separately.
In `@kits/smc-bias-agent/app/api/analyze/route.ts`:
- Around line 22-32: Update the error handling in the analyze route’s catch
block to distinguish client-input/validation failures, such as unsupported
interval or insufficient candles, from upstream fetch or analysis failures.
Return HTTP 400 for client errors and retain 502 for upstream failures, using
the existing error information and route flow without changing successful
responses.
In `@kits/smc-bias-agent/components/PriceChart.tsx`:
- Line 32: Remove the unused localIndexOf function definition from the
PriceChart component, leaving the surrounding chart logic and start value
unchanged.
In `@kits/smc-bias-agent/lamatic.config.ts`:
- Around line 1-15: Update the config object exported by lamatic.config.ts to
include the required author, steps, and links metadata, matching the structure
and values used by an existing sibling kit configuration. Set links.github to
reference kits/smc-bias-agent while preserving the current name, slug, type,
description, and tags.
In `@kits/smc-bias-agent/lib/binance.ts`:
- Around line 16-42: Both outbound requests lack cancellation and can hang the
analysis request indefinitely. In kits/smc-bias-agent/lib/binance.ts:16-42,
update fetchCandles to create an AbortController, enforce the shared timeout
pattern, pass its signal to fetch, and clean up the timer; apply the same change
to getBiasNarrative’s fetch in
kits/smc-bias-agent/lib/lamatic-client.ts:101-110, preserving existing response
and error handling.
- Around line 29-41: Validate each row in the Binance response before mapping it
in the surrounding fetch/parser function: require the expected six fields,
verify the timestamp and OHLCV values are present and finite after conversion,
and reject malformed rows with a clear error instead of returning NaN. Remove
the unchecked tuple cast and raw parseFloat flow while preserving the existing
normalized output for valid rows.
In `@kits/smc-bias-agent/lib/lamatic-client.ts`:
- Around line 92-98: Align the Lamatic configuration contract so
getBiasNarrative uses the variables provided by the example or the example
defines the single LAMATIC_FLOW_ENDPOINT contract; update
kits/smc-bias-agent/lib/lamatic-client.ts lines 92-98 and
kits/smc-bias-agent/.env.example lines 1-4 consistently, ensuring the example
enables the Lamatic narrative path instead of falling back silently.
In `@kits/smc-bias-agent/lib/smc.ts`:
- Around line 12-14: Update findOrderBlocks to enforce the impulse-strength
threshold when selecting the opposite-colored origin candle, requiring its
absolute body range to meet IMPULSE_MIN_RANGE_MULT times the relevant average
range before accepting it; otherwise continue searching or reject the candidate.
If this filter is not intended, remove the unused IMPULSE_MIN_RANGE_MULT
constant instead.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI (base), Organization UI (inherited)
Review profile: ASSERTIVE
Plan: Pro
Run ID: ea41a1d0-2522-4683-abba-7dd749c7bc38
⛔ Files ignored due to path filters (1)
kits/smc-bias-agent/package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (20)
kits/smc-bias-agent/.env.examplekits/smc-bias-agent/.gitignorekits/smc-bias-agent/README.mdkits/smc-bias-agent/app/api/analyze/route.tskits/smc-bias-agent/app/globals.csskits/smc-bias-agent/app/layout.tsxkits/smc-bias-agent/app/page.tsxkits/smc-bias-agent/components/BiasCard.tsxkits/smc-bias-agent/components/PriceChart.tsxkits/smc-bias-agent/lamatic.config.tskits/smc-bias-agent/lib/binance.tskits/smc-bias-agent/lib/lamatic-client.tskits/smc-bias-agent/lib/smc.tskits/smc-bias-agent/lib/types.tskits/smc-bias-agent/next-env.d.tskits/smc-bias-agent/next.config.jskits/smc-bias-agent/package.jsonkits/smc-bias-agent/postcss.config.jskits/smc-bias-agent/tailwind.config.tskits/smc-bias-agent/tsconfig.json
| LAMATIC_API_KEY=lt-a37857b83dd6f993e9d327b9a9f68bba | ||
| LAMATIC_GRAPHQL_URL=https://ayushsorganization263-ayushsproject211.lamatic.dev/graphql | ||
| LAMATIC_PROJECT_ID=3bffc6da-08d8-4f1a-af0c-f654bca169e6 | ||
| LAMATIC_WORKFLOW_ID=8ba7821c-251d-4d58-827b-bb5d627a3d57 No newline at end of file |
There was a problem hiding this comment.
🔒 Security & Privacy | 🔴 Critical | ⚡ Quick win
Abort, abort — this tape is self-destructing for a reason, and these credentials should too.
These values look like real, issued credentials (API key, project ID, workflow ID, and a personal Lamatic subdomain in the GraphQL URL), not placeholders. Static analysis flags a generic API key here. Committing real secrets into a .env.example template exposes them to anyone who clones the repo.
Rotate this key/workflow immediately and replace all four values with clearly fake placeholders (e.g. LAMATIC_API_KEY=your-lamatic-api-key).
🧰 Tools
🪛 Betterleaks (1.6.1)
[high] 1-1: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.
(generic-api-key)
🪛 dotenv-linter (4.0.0)
[warning] 4-4: [EndingBlankLine] No blank line at the end of the file
(EndingBlankLine)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@kits/smc-bias-agent/.env.example` around lines 1 - 4, Replace the
credential-like values in the .env.example entries LAMATIC_API_KEY,
LAMATIC_GRAPHQL_URL, LAMATIC_PROJECT_ID, and LAMATIC_WORKFLOW_ID with clearly
fake placeholders, and rotate or revoke the exposed Lamatic credentials
separately.
Source: Linters/SAST tools
| try { | ||
| const candles = await fetchCandles(symbol, interval); | ||
| const analysis = analyzeSMC(symbol, interval, candles); | ||
| const narrative = await getBiasNarrative(analysis); | ||
|
|
||
| return NextResponse.json({ analysis, narrative }); | ||
| } catch (err) { | ||
| const message = err instanceof Error ? err.message : "Unexpected error while analyzing the symbol."; | ||
| return NextResponse.json({ error: message }, { status: 502 }); | ||
| } | ||
| } |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
One-size-fits-all disguise won't fool every checkpoint.
Every thrown error — including client-input problems like an unsupported interval or "not enough candles" — is mapped to 502. That's a Bad-Gateway code reserved for upstream failures; input-validation failures should surface as 400.
🎯 Proposed fix: distinguish client vs upstream errors
} catch (err) {
const message = err instanceof Error ? err.message : "Unexpected error while analyzing the symbol.";
- return NextResponse.json({ error: message }, { status: 502 });
+ const isClientError = message.includes("Unsupported interval") || message.includes("Not enough candles");
+ return NextResponse.json({ error: message }, { status: isClientError ? 400 : 502 });
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| try { | |
| const candles = await fetchCandles(symbol, interval); | |
| const analysis = analyzeSMC(symbol, interval, candles); | |
| const narrative = await getBiasNarrative(analysis); | |
| return NextResponse.json({ analysis, narrative }); | |
| } catch (err) { | |
| const message = err instanceof Error ? err.message : "Unexpected error while analyzing the symbol."; | |
| return NextResponse.json({ error: message }, { status: 502 }); | |
| } | |
| } | |
| try { | |
| const candles = await fetchCandles(symbol, interval); | |
| const analysis = analyzeSMC(symbol, interval, candles); | |
| const narrative = await getBiasNarrative(analysis); | |
| return NextResponse.json({ analysis, narrative }); | |
| } catch (err) { | |
| const message = err instanceof Error ? err.message : "Unexpected error while analyzing the symbol."; | |
| const isClientError = message.includes("Unsupported interval") || message.includes("Not enough candles"); | |
| return NextResponse.json({ error: message }, { status: isClientError ? 400 : 502 }); | |
| } | |
| } |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@kits/smc-bias-agent/app/api/analyze/route.ts` around lines 22 - 32, Update
the error handling in the analyze route’s catch block to distinguish
client-input/validation failures, such as unsupported interval or insufficient
candles, from upstream fetch or analysis failures. Return HTTP 400 for client
errors and retain 502 for upstream failures, using the existing error
information and route flow without changing successful responses.
| const xAt = (localIndex: number) => PAD_LEFT + localIndex * slot + slot / 2; | ||
| const yAt = (price: number) => PAD_TOP + (1 - (price - minPrice) / span) * plotH; | ||
|
|
||
| const localIndexOf = (globalIndex: number) => globalIndex - start; |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value
Eliminate unused function.
Agent, your mission, should you choose to accept it, is to eliminate this dead code to keep our operation's footprint clean. localIndexOf is defined here but never utilized in the field.
🕶️ Proposed fix
- const localIndexOf = (globalIndex: number) => globalIndex - start;📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const localIndexOf = (globalIndex: number) => globalIndex - start; |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@kits/smc-bias-agent/components/PriceChart.tsx` at line 32, Remove the unused
localIndexOf function definition from the PriceChart component, leaving the
surrounding chart logic and start value unchanged.
| // NOTE: field names here are my best inference from the public repo structure | ||
| // (every kit is typed via this file's `type` field: "template" | "bundle" | "kit"). | ||
| // Confirm this against an existing sibling kit's lamatic.config.ts after forking | ||
| // and adjust field names if the actual schema differs. | ||
|
|
||
| const config = { | ||
| name: "SMC Bias Agent", | ||
| slug: "smc-bias-agent", | ||
| type: "kit" as const, | ||
| description: | ||
| "Detects Smart Money Concepts structure (order blocks, fair value gaps, break of structure / change of character) on a crypto pair and returns a plain-English directional bias with key levels to watch.", | ||
| tags: ["crypto", "trading", "smc", "ict", "technical-analysis"], | ||
| }; | ||
|
|
||
| export default config; |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Locate kit config files and inspect the target plus a sibling example.
git ls-files 'kits/*/lamatic.config.ts' | sed -n '1,80p'
echo '--- target ---'
cat -n kits/smc-bias-agent/lamatic.config.ts
echo '--- sibling list with line counts ---'
for f in $(git ls-files 'kits/*/lamatic.config.ts' | grep -v '^kits/smc-bias-agent/lamatic.config.ts$' | head -n 5); do
echo "FILE: $f"
wc -l "$f"
doneRepository: Lamatic/AgentKit
Length of output: 4871
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Read a representative sibling config to compare required fields and schema.
sibling=$(git ls-files 'kits/*/lamatic.config.ts' | grep -v '^kits/smc-bias-agent/lamatic.config.ts$' | head -n 1)
echo "SIBLING=$sibling"
cat -n "$sibling"Repository: Lamatic/AgentKit
Length of output: 158
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Check for the repo's validation workflow mention of links.github and kit naming.
rg -n "links\.github|kits/<name>|lamatic\.config\.ts|author|steps|links" .github kits -g '!**/node_modules/**' -g '!**/dist/**' -g '!**/build/**'Repository: Lamatic/AgentKit
Length of output: 50373
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo '## kit config files'
git ls-files 'kits/*/lamatic.config.ts' | sort
echo
echo '## target file'
cat -n kits/smc-bias-agent/lamatic.config.ts
echo
echo '## first sibling'
sibling=$(git ls-files 'kits/*/lamatic.config.ts' | grep -v '^kits/smc-bias-agent/lamatic.config.ts$' | sort | head -n 1)
echo "SIBLING: $sibling"
cat -n "$sibling"
echo
echo '## schema references'
rg -n "links\.github|author:|steps:|type:|slug:|tags:" .github kits -g '!**/node_modules/**' -g '!**/dist/**' -g '!**/build/**'Repository: Lamatic/AgentKit
Length of output: 50372
Restore the required kit metadata.
kits/smc-bias-agent/lamatic.config.ts is missing author, steps, and links; this kit config needs to match the repo’s metadata contract, and links.github should point to kits/smc-bias-agent.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@kits/smc-bias-agent/lamatic.config.ts` around lines 1 - 15, Update the config
object exported by lamatic.config.ts to include the required author, steps, and
links metadata, matching the structure and values used by an existing sibling
kit configuration. Set links.github to reference kits/smc-bias-agent while
preserving the current name, slug, type, description, and tags.
Source: Coding guidelines
| export async function fetchCandles(symbol: string, interval: string, limit = 150): Promise<Candle[]> { | ||
| if (!isValidInterval(interval)) { | ||
| throw new Error(`Unsupported interval "${interval}". Use one of: ${[...ALLOWED_INTERVALS].join(", ")}`); | ||
| } | ||
|
|
||
| const url = `${BINANCE_BASE}?symbol=${encodeURIComponent(symbol.toUpperCase())}&interval=${interval}&limit=${limit}`; | ||
| const res = await fetch(url, { next: { revalidate: 30 } }); | ||
|
|
||
| if (!res.ok) { | ||
| const body = await res.text().catch(() => ""); | ||
| throw new Error(`Binance request failed (${res.status}): ${body || res.statusText}`); | ||
| } | ||
|
|
||
| const raw = (await res.json()) as unknown[]; | ||
|
|
||
| return raw.map((row) => { | ||
| const r = row as [number, string, string, string, string, string, ...unknown[]]; | ||
| return { | ||
| time: Math.floor(r[0] / 1000), | ||
| open: parseFloat(r[1]), | ||
| high: parseFloat(r[2]), | ||
| low: parseFloat(r[3]), | ||
| close: parseFloat(r[4]), | ||
| volume: parseFloat(r[5]), | ||
| }; | ||
| }); | ||
| } |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
Two unfused fetches in the same mission — patch both before this op goes live. Both outbound fetch calls run synchronously inside the POST /api/analyze request path with no timeout or AbortController, so either external service stalling can hang the request indefinitely.
kits/smc-bias-agent/lib/binance.ts#L16-L42: wrap the Binancefetchcall infetchCandleswith anAbortController-based timeout.kits/smc-bias-agent/lib/lamatic-client.ts#L101-L110: wrap the Lamatic flowfetchcall ingetBiasNarrativewith the same timeout pattern.
📍 Affects 2 files
kits/smc-bias-agent/lib/binance.ts#L16-L42(this comment)kits/smc-bias-agent/lib/lamatic-client.ts#L101-L110
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@kits/smc-bias-agent/lib/binance.ts` around lines 16 - 42, Both outbound
requests lack cancellation and can hang the analysis request indefinitely. In
kits/smc-bias-agent/lib/binance.ts:16-42, update fetchCandles to create an
AbortController, enforce the shared timeout pattern, pass its signal to fetch,
and clean up the timer; apply the same change to getBiasNarrative’s fetch in
kits/smc-bias-agent/lib/lamatic-client.ts:101-110, preserving existing response
and error handling.
| const raw = (await res.json()) as unknown[]; | ||
|
|
||
| return raw.map((row) => { | ||
| const r = row as [number, string, string, string, string, string, ...unknown[]]; | ||
| return { | ||
| time: Math.floor(r[0] / 1000), | ||
| open: parseFloat(r[1]), | ||
| high: parseFloat(r[2]), | ||
| low: parseFloat(r[3]), | ||
| close: parseFloat(r[4]), | ||
| volume: parseFloat(r[5]), | ||
| }; | ||
| }); |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
No safe-house for malformed Binance rows.
The row as [number, string, ...] cast plus raw parseFloat trusts the response shape entirely — an API change or unexpected row (missing element, empty string) silently yields NaN, which then propagates through swing/OB/FVG math without a loud failure.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@kits/smc-bias-agent/lib/binance.ts` around lines 29 - 41, Validate each row
in the Binance response before mapping it in the surrounding fetch/parser
function: require the expected six fields, verify the timestamp and OHLCV values
are present and finite after conversion, and reject malformed rows with a clear
error instead of returning NaN. Remove the unchecked tuple cast and raw
parseFloat flow while preserving the existing normalized output for valid rows.
| export async function getBiasNarrative(analysis: SMCAnalysis): Promise<BiasNarrative> { | ||
| const apiKey = process.env.LAMATIC_API_KEY; | ||
| const endpoint = process.env.LAMATIC_FLOW_ENDPOINT; | ||
|
|
||
| if (!apiKey || !endpoint) { | ||
| return { reasoning: localFallbackNarrative(analysis), source: "fallback" }; | ||
| } |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
The dead-drop location and the pickup instructions don't match. getBiasNarrative requires LAMATIC_FLOW_ENDPOINT, but .env.example never defines it (it ships LAMATIC_GRAPHQL_URL, LAMATIC_PROJECT_ID, LAMATIC_WORKFLOW_ID instead), so following the example as-is silently disables the Lamatic narrative path.
kits/smc-bias-agent/lib/lamatic-client.ts#L92-L98: either read the endpoint from the vars actually shipped in.env.example(build it fromLAMATIC_GRAPHQL_URL/LAMATIC_PROJECT_ID/LAMATIC_WORKFLOW_ID) or standardize on a singleLAMATIC_FLOW_ENDPOINTcontract.kits/smc-bias-agent/.env.example#L1-L4: addLAMATIC_FLOW_ENDPOINT(or rename to match whatever contractlamatic-client.tssettles on) so the example is actually functional out of the box.
📍 Affects 2 files
kits/smc-bias-agent/lib/lamatic-client.ts#L92-L98(this comment)kits/smc-bias-agent/.env.example#L1-L4
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@kits/smc-bias-agent/lib/lamatic-client.ts` around lines 92 - 98, Align the
Lamatic configuration contract so getBiasNarrative uses the variables provided
by the example or the example defines the single LAMATIC_FLOW_ENDPOINT contract;
update kits/smc-bias-agent/lib/lamatic-client.ts lines 92-98 and
kits/smc-bias-agent/.env.example lines 1-4 consistently, ensuring the example
enables the Lamatic narrative path instead of falling back silently.
| const SWING_LOOKBACK = 2; | ||
| const IMPULSE_LOOKAHEAD = 4; | ||
| const IMPULSE_MIN_RANGE_MULT = 1.5; |
There was a problem hiding this comment.
🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win
Agent, this gadget was packed but never deployed.
IMPULSE_MIN_RANGE_MULT is declared but never used — findOrderBlocks accepts the first opposite-colored candle before a structure event regardless of its range, so the intended impulse-strength filter implied by this constant's name isn't actually enforced.
Either wire it into the origin-candle search (e.g. require Math.abs(origin.close - origin.open) >= IMPULSE_MIN_RANGE_MULT * avgRange) or remove the dead constant if it's not needed.
Also applies to: 67-115
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@kits/smc-bias-agent/lib/smc.ts` around lines 12 - 14, Update findOrderBlocks
to enforce the impulse-strength threshold when selecting the opposite-colored
origin candle, requiring its absolute body range to meet IMPULSE_MIN_RANGE_MULT
times the relevant average range before accepting it; otherwise continue
searching or reject the candidate. If this filter is not intended, remove the
unused IMPULSE_MIN_RANGE_MULT constant instead.
|
Hi @Ayush441-python! 👋 Before this PR can be reviewed by maintainers, please resolve all comments and requested changes from the CodeRabbit automated review. Steps to follow:
This helps keep the review process efficient for everyone. Thank you! 🙏 |
PR Checklist
1. Select Contribution Type
kits/<category>/<kit-name>/)bundles/<bundle-name>/)templates/<template-name>/)2. General Requirements
kebab-caseand matches the flow IDREADME.md(purpose, setup, usage)3. File Structure (Check what applies)
config.jsonpresent with valid metadata (name, description, tags, steps, author, env keys)flows/<flow-name>/(where applicable) include:config.json(Lamatic flow export)inputs.jsonmeta.jsonREADME.md.env.examplewith placeholder values only (kits only)config.jsonnode graphs (changes via Lamatic Studio export)4. Validation
npm install && npm run devworks locally (kits: UI runs; bundles/templates: flows are valid)[kit] Add <name> for <use case>)kits/smc-bias-agentNext.js kit with:lamatic.config.ts.flow.jsonwas not present in the available repository files, so no flow node types or flow execution details could be verified.