Skip to content

feat: Add opportunity-legitimacy-screener bundle#266

Open
m-hamza-n wants to merge 2 commits into
Lamatic:mainfrom
m-hamza-n:feat/opportunity-legitimacy-screener
Open

feat: Add opportunity-legitimacy-screener bundle#266
m-hamza-n wants to merge 2 commits into
Lamatic:mainfrom
m-hamza-n:feat/opportunity-legitimacy-screener

Conversation

@m-hamza-n

@m-hamza-n m-hamza-n commented Jul 18, 2026

Copy link
Copy Markdown

What this adds

A two-flow AgentKit bundle (kits/opportunity-legitimacy-screener/) that screens job postings, recruiter emails, and freelance briefs for legitimacy — extracting structured signals, running live web research, and returning a risk tier with a plain-English explanation.

Flows

  • gather-signals: Extracts structured signals from raw text via LLM, enriched with live Serper web search filtered to results actually mentioning the company.
  • score-and-explain: Scores signals for red flags with negation-aware keyword detection, maps to a low/medium/high risk tier, and generates a tier-specific explanation and recommended action.

Testing

Both flows tested end-to-end across all three risk tiers plus the fallback path. See README.md for details.

Tradeoffs

Documented in README.md, including why the two flows are deployed independently rather than chained via flowNode, and known limitations of the keyword-based scam-signal detection.

Note on PR checklist

This repo's PR template checklist (config.json, bundles/<name>/, per-flow inputs.json/meta.json) appears to describe an earlier version of the contribution structure. This submission follows the structure currently documented in CONTRIBUTING.md (kits/<name>/, lamatic.config.ts, flows/<name>.ts with externalized prompts//scripts//model-configs/), which matches the existing reference bundle kits/knowledge-chatbot/.

  • Added the opportunity-legitimacy-screener AgentKit bundle under kits/opportunity-legitimacy-screener/:

    • lamatic.config.ts (bundle config with the two required steps: gather-signals, score-and-explain)
    • .env.example (Lamatic + API key placeholders)
    • .gitignore (ignore local Lamatic data, node_modules, and env files)
    • README.md (deployment notes, manual chaining approach, output shape, and limitations/tradeoffs)
    • agent.md + constitutions/default.md (agent/pipeline description and baseline assistant guardrails)
    • Flow definitions:
      • flows/gather-signals.ts
      • flows/score-and-explain.ts
    • Model configs:
      • model-configs/gather-signals_llmnode-390_generative-model-name.ts
      • model-configs/score-and-explain_llmnode-353_generative-model-name.ts
      • model-configs/score-and-explain_llmnode-419_generative-model-name.ts
      • model-configs/score-and-explain_llmnode-645_generative-model-name.ts
    • Prompts:
      • prompts/gather-signals_llmnode-390_system_0.md
      • prompts/gather-signals_llmnode-390_user_1.md
      • prompts/score-and-explain_llmnode-353_system_0.md
      • prompts/score-and-explain_llmnode-353_user_1.md
      • prompts/score-and-explain_llmnode-419_system_0.md
      • prompts/score-and-explain_llmnode-419_user_1.md
      • prompts/score-and-explain_llmnode-645_system_0.md
      • prompts/score-and-explain_llmnode-645_user_1.md
    • Supporting scripts:
      • scripts/gather-signals_code-node-139_code.ts
      • scripts/gather-signals_code-node-512_code.ts
      • scripts/score-and-explain_code-node-396_code.ts
      • scripts/score-and-explain_code-node-529_code.ts
      • scripts/score-and-explain_code-node-905_code.ts
  • gather-signals flow (flows/gather-signals.ts)

    • Node types used: triggerNode, model, select, dynamicNode, responseNode (plus edge routing)
    • High-level behavior:
      • Trigger receives unstructured input plus source_type/raw_text
      • LLM extracts a fixed-schema structured signal object (normalized to empty strings)
      • Code step sanitizes/normalizes LLM JSON output (strips optional ```json fences; falls back with parse_error and nulls if parsing fails)
      • Serper web search runs against the claimed company
      • Code filters/merges search results into a compact search_results string (attempts company-name relevance matching; falls back to unfiltered results)
      • Returns consolidated signals including extracted fields and enriched search_results
  • score-and-explain flow (flows/score-and-explain.ts)

    • Node types used: triggerNode, model, conditionNode, dynamicNode, responseNode (plus edge routing)
    • High-level behavior:
      • Trigger ingests signals produced by gather-signals
      • Code computes legitimacy signals/risk inputs:
        • parses sender/contact domains and flags generic providers
        • estimates “verifiable web presence” using company-name overlap in search results
        • performs negation-aware scam/fraud/complaint detection by sanitizing negated mentions before flagging negative reports
        • maps red-flag count to risk_tier (high / medium / low)
      • conditionNode routes to tier-specific LLM prompts:
        • low: recommends "proceed"
        • medium: recommends "verify_further"
        • high: recommends "avoid"
      • Code finalizer selects the executed tier’s model output, cleans HTML/entities + code fences, extracts the JSON payload, validates required fields, and applies fallback handling for skipped/missing/invalid outputs
      • Returns final JSON with risk_tier, explanation, and recommended_action

@github-actions

Copy link
Copy Markdown
Contributor

:robot_face: AgentKit Structural Validation

New Contributions Detected

  • Bundle: kits/opportunity-legitimacy-screener

Check Results

Check Status
No edits to existing kits ✅ Pass
Required root files present ✅ Pass
Flow .ts files present ✅ Pass
lamatic.config.ts valid ✅ Pass
No changes outside kits/ ✅ Pass

🎉 All checks passed! This contribution follows the AgentKit structure.

@coderabbitai

coderabbitai Bot commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI (base), Organization UI (inherited)

Review profile: ASSERTIVE

Plan: Pro

Run ID: d0085fbf-9d28-4c67-946a-5dbf1af77254

📥 Commits

Reviewing files that changed from the base of the PR and between f72a9b3 and 5a158b1.

📒 Files selected for processing (8)
  • kits/opportunity-legitimacy-screener/prompts/score-and-explain_llmnode-353_system_0.md
  • kits/opportunity-legitimacy-screener/prompts/score-and-explain_llmnode-353_user_1.md
  • kits/opportunity-legitimacy-screener/prompts/score-and-explain_llmnode-419_system_0.md
  • kits/opportunity-legitimacy-screener/prompts/score-and-explain_llmnode-419_user_1.md
  • kits/opportunity-legitimacy-screener/prompts/score-and-explain_llmnode-645_system_0.md
  • kits/opportunity-legitimacy-screener/prompts/score-and-explain_llmnode-645_user_1.md
  • kits/opportunity-legitimacy-screener/scripts/score-and-explain_code-node-396_code.ts
  • kits/opportunity-legitimacy-screener/scripts/score-and-explain_code-node-529_code.ts

Walkthrough

Changes

Adds the Opportunity Legitimacy Screener kit with configuration, documentation, signal gathering, web-search enrichment, heuristic risk scoring, tier-specific LLM explanations, and normalized verdict responses.

Opportunity Legitimacy Screener

Layer / File(s) Summary
Kit configuration and operating contract
kits/opportunity-legitimacy-screener/.env.example, kits/opportunity-legitimacy-screener/.gitignore, kits/opportunity-legitimacy-screener/lamatic.config.ts, kits/opportunity-legitimacy-screener/constitutions/default.md, kits/opportunity-legitimacy-screener/README.md, kits/opportunity-legitimacy-screener/agent.md
Defines kit metadata, local configuration placeholders, guardrails, the two workflow steps, expected outputs, setup instructions, and documented limitations.
Signal extraction and web enrichment
kits/opportunity-legitimacy-screener/flows/gather-signals.ts, kits/opportunity-legitimacy-screener/model-configs/gather-signals_*, kits/opportunity-legitimacy-screener/prompts/gather-signals_*, kits/opportunity-legitimacy-screener/scripts/gather-signals_*
Extracts structured opportunity fields, normalizes LLM output, searches the web, filters results by company name, and returns consolidated signals.
Risk scoring and verdict generation
kits/opportunity-legitimacy-screener/flows/score-and-explain.ts, kits/opportunity-legitimacy-screener/model-configs/score-and-explain_*, kits/opportunity-legitimacy-screener/prompts/score-and-explain_*, kits/opportunity-legitimacy-screener/scripts/score-and-explain_*
Counts legitimacy flags, routes low/medium/high tiers to dedicated prompts, parses model responses, handles fallbacks, and maps the final verdict to the API response.

Suggested reviewers: amanintech, d-pamneja

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise and clearly states the main change: adding the opportunity-legitimacy-screener bundle.
Description check ✅ Passed The description covers purpose, flows, testing, and tradeoffs, and is mostly complete despite not mirroring the template exactly.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 Biome (2.5.3)
kits/opportunity-legitimacy-screener/scripts/score-and-explain_code-node-396_code.ts

File contains syntax errors that prevent linting: Line 1: Expected a property, a shorthand property, a getter, a setter, or a method but instead found '{triggerNode_1.output.comp; Line 1: Expected a statement but instead found '}'.; Line 2: Expected a property, a shorthand property, a getter, a setter, or a method but instead found '{triggerNode_1.output.clai; Line 2: Expected a statement but instead found '}'.; Line 3: Expected a property, a shorthand property, a getter, a setter, or a method but instead found '{triggerNode_1.output.send; Line 3: Expected a statement but instead found '}'.; Line 4: Expected a property, a shorthand property, a getter, a setter, or a method but instead found '{triggerNode_1.output.stat; Line 4: Expected a statement but instead found '}'.; Line 5: Expected a property, a shorthand property, a getter, a setter, or a method but instead found '{triggerNode_1.output.role; Line 5: Expected a statement but instead found '}'.; Line 6: Expected a property, a shorthand property, a getter, a setter, or a method but instead found '{triggerNode_1.output.cont; Line 6: Expected a statement but instead found '}'.; Line 7: Expected a property, a shorthand property, a getter, a setter, or a method but instead found '{triggerNode_1.output.sear; Line 7: Expected a statement but instead found '}'.

kits/opportunity-legitimacy-screener/scripts/score-and-explain_code-node-529_code.ts

File contains syntax errors that prevent linting: Line 38: Illegal return statement outside of a function; Line 41: Illegal return statement outside of a function; Line 43: Illegal return statement outside of a function; Line 49: Illegal return statement outside of a function; Line 53: Illegal return statement outside of a function


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.

@m-hamza-n

Copy link
Copy Markdown
Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 18, 2026

Copy link
Copy Markdown
Contributor
✅ 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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 7

🤖 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/opportunity-legitimacy-screener/prompts/score-and-explain_llmnode-353_system_0.md`:
- Around line 3-6: Update the JSON schema examples so the explanation value is a
quoted string placeholder, preserving valid JSON syntax. Apply this change in
kits/opportunity-legitimacy-screener/prompts/score-and-explain_llmnode-353_system_0.md
lines 3-6,
kits/opportunity-legitimacy-screener/prompts/score-and-explain_llmnode-419_system_0.md
lines 3-6, and
kits/opportunity-legitimacy-screener/prompts/score-and-explain_llmnode-645_system_0.md
lines 3-6; keep the recommended_action values unchanged.

In
`@kits/opportunity-legitimacy-screener/prompts/score-and-explain_llmnode-353_user_1.md`:
- Around line 1-7: Harden both prompt files by clearly delimiting all
interpolated signal values as untrusted data and instructing the model to ignore
any instructions embedded within them. Apply this change to
kits/opportunity-legitimacy-screener/prompts/score-and-explain_llmnode-353_user_1.md
lines 1-7 and
kits/opportunity-legitimacy-screener/prompts/score-and-explain_llmnode-419_user_1.md
lines 1-7, preserving the existing signal fields and scoring context.

In
`@kits/opportunity-legitimacy-screener/prompts/score-and-explain_llmnode-645_user_1.md`:
- Around line 1-4: Update the four template references in the prompt from
codeNode_709 to the existing codeNode_396 output signals, preserving the
company_name, role_title, stated_compensation, and contact_method fields so the
scoring prompt receives the required context.

In
`@kits/opportunity-legitimacy-screener/scripts/gather-signals_code-node-139_code.ts`:
- Around line 1-2: Replace the workflow-object accesses in the script’s results
and companyName initialization with Lamatic template variables using the
{{nodeId.output.x}} format, referencing webSearchNode_810.output.output.organic
and codeNode_512.output.company_name respectively. Preserve the existing
empty-array fallback and lowercase normalization.

In
`@kits/opportunity-legitimacy-screener/scripts/score-and-explain_code-node-396_code.ts`:
- Around line 9-14: The generic-email check in the score-and-explain flow should
evaluate the actual email hostname rather than substring-matching contact or
email text. Update the logic around genericEmailDomains and emailDomainIsGeneric
to parse sender_email, extract its domain, and compare it against exact provider
domains, so domains such as gmail.company.com are not classified as generic.

In
`@kits/opportunity-legitimacy-screener/scripts/score-and-explain_code-node-529_code.ts`:
- Around line 37-43: Reconcile the fallback behavior in the score evaluation
flow so every returned risk_tier conforms to the published low/medium/high
contract. Update both the non-skipped elseNode branch and the final “Nothing ran
at all” fallback to use a supported tier and the corresponding verify-further
action, or consistently extend the documented/API contract to include unknown.
- Around line 27-34: Validate the value returned by JSON.parse in the raw-output
handling path before reading its fields. Require a non-null object with string
explanation and recommended_action properties; otherwise return the same
malformed-output fallback used for parse failures. Keep the valid payload
response unchanged.
🪄 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: 69b14555-21d3-4260-9e9e-13197c24dcce

📥 Commits

Reviewing files that changed from the base of the PR and between 0ada432 and f72a9b3.

📒 Files selected for processing (25)
  • kits/opportunity-legitimacy-screener/.env.example
  • kits/opportunity-legitimacy-screener/.gitignore
  • kits/opportunity-legitimacy-screener/README.md
  • kits/opportunity-legitimacy-screener/agent.md
  • kits/opportunity-legitimacy-screener/constitutions/default.md
  • kits/opportunity-legitimacy-screener/flows/gather-signals.ts
  • kits/opportunity-legitimacy-screener/flows/score-and-explain.ts
  • kits/opportunity-legitimacy-screener/lamatic.config.ts
  • kits/opportunity-legitimacy-screener/model-configs/gather-signals_llmnode-390_generative-model-name.ts
  • kits/opportunity-legitimacy-screener/model-configs/score-and-explain_llmnode-353_generative-model-name.ts
  • kits/opportunity-legitimacy-screener/model-configs/score-and-explain_llmnode-419_generative-model-name.ts
  • kits/opportunity-legitimacy-screener/model-configs/score-and-explain_llmnode-645_generative-model-name.ts
  • kits/opportunity-legitimacy-screener/prompts/gather-signals_llmnode-390_system_0.md
  • kits/opportunity-legitimacy-screener/prompts/gather-signals_llmnode-390_user_1.md
  • kits/opportunity-legitimacy-screener/prompts/score-and-explain_llmnode-353_system_0.md
  • kits/opportunity-legitimacy-screener/prompts/score-and-explain_llmnode-353_user_1.md
  • kits/opportunity-legitimacy-screener/prompts/score-and-explain_llmnode-419_system_0.md
  • kits/opportunity-legitimacy-screener/prompts/score-and-explain_llmnode-419_user_1.md
  • kits/opportunity-legitimacy-screener/prompts/score-and-explain_llmnode-645_system_0.md
  • kits/opportunity-legitimacy-screener/prompts/score-and-explain_llmnode-645_user_1.md
  • kits/opportunity-legitimacy-screener/scripts/gather-signals_code-node-139_code.ts
  • kits/opportunity-legitimacy-screener/scripts/gather-signals_code-node-512_code.ts
  • kits/opportunity-legitimacy-screener/scripts/score-and-explain_code-node-396_code.ts
  • kits/opportunity-legitimacy-screener/scripts/score-and-explain_code-node-529_code.ts
  • kits/opportunity-legitimacy-screener/scripts/score-and-explain_code-node-905_code.ts

@m-hamza-n

Copy link
Copy Markdown
Author

@amanintech @d-pamneja — pushed a fix for all 7 CodeRabbit findings from the initial review (stale codeNode_709 reference in the tier prompts, generic-email-domain substring matching, JSON.parse("null") crash, unquoted JSON example, prompt-injection hardening on the two user prompts, and mapping the fallback path to a documented risk_tier). Re-tested all three tiers + the fallback path against the fix.

CodeRabbit's re-review came back clean — no actionable comments, review approved.

One item I intentionally left as-is: the suggestion on gather-signals_code-node-139_code.ts to use {{nodeId.output.x}} template syntax instead of workflow.X.output.Y — replied on that thread with the reasoning (confirmed via testing that {{...}} inside a Code node body resolves to a literal path-string in Studio, not the actual value).

Ready for another look whenever you get a chance.

@github-actions

Copy link
Copy Markdown
Contributor

Hi @m-hamza-n! 👋

Before this PR can be reviewed by maintainers, please resolve all comments and requested changes from the CodeRabbit automated review.

Steps to follow:

  1. Read through all CodeRabbit comments carefully
  2. Address each issue raised (or reply explaining why you disagree)
  3. Push your fixes as new commits
  4. Once all issues are resolved, comment here so we can re-review

This helps keep the review process efficient for everyone. Thank you! 🙏

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant