Skip to content

Ai and feedback#1

Open
mewHacks wants to merge 6 commits into
mainfrom
ai-and-feedback
Open

Ai and feedback#1
mewHacks wants to merge 6 commits into
mainfrom
ai-and-feedback

Conversation

@mewHacks

Copy link
Copy Markdown
Owner

No description provided.

mewHacks added 3 commits May 16, 2026 18:01
…th scoring, and dynamic match weighting system
…engine, and update UI components with viewer session awareness.

Copilot AI 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.

Pull request overview

Implements a feedback loop around AI matching by introducing an in-memory relationship/feedback store, profile “strength” scoring, and weight overrides derived from completed sessions; wires this into new API routes and UI components (AI match cards + dashboard).

Changes:

  • Added relationship/feedback data model (store.ts) plus strength and weight calculation utilities.
  • Added API routes for matches, relationships, feedback submission, and profile strength.
  • Added UI: AI match cards, relationship dashboard/cards, feedback widget, and a hook to fetch AI matches; added Node test runner setup + tests for deterministic matching/exclusions.

Reviewed changes

Copilot reviewed 22 out of 23 changed files in this pull request and generated 13 comments.

Show a summary per file
File Description
tests/match-engine.test.ts Adds deterministic matcher + exclusion tests.
src/lib/store.ts In-memory relationships/feedback store with seeded demo data.
src/lib/strength-calculator.ts Computes profile strength score and label.
src/lib/weight-engine.ts Computes dimension weight multipliers from historical feedback.
src/lib/match-engine.ts Adds AI matching via Ollama with deterministic fallback + weighting/context support.
src/app/api/match/route.ts Match endpoint that applies exclusion + weight overrides + prompt context note.
src/app/api/relationships/route.ts Relationships GET/POST endpoints.
src/app/api/feedback/[id]/route.ts Feedback submission endpoint for a relationship side.
src/app/api/profile-strength/[id]/route.ts Profile strength endpoint.
src/hooks/use-ai-matches.ts Client hook to fetch matches for a viewer.
src/components/audience-browse-page.tsx Switches “AI Recommended” section to show AI picks when available.
src/components/ai-match-card.tsx Displays an AI-picked profile + rationale tooltip and creates relationships.
src/components/rationale-card.tsx Renders score breakdown + flags for a match.
src/components/relationship-dashboard.tsx Fetches and displays strength + relationships list.
src/components/relationship-card.tsx Renders a relationship row with optional feedback flow.
src/components/feedback-widget.tsx Star rating + optional comment submission UI.
src/components/profile-strength-badge.tsx Renders strength score bar + label.
src/app/dashboard/page.tsx Adds /dashboard page to display relationship dashboard.
src/app/page.tsx Adds a Dashboard link to the home header.
package.json Adds a test script using Node’s test runner + jiti.
docs/superpowers/plans/2026-05-16-feedback-loop.md Adds implementation plan doc for the feedback loop work.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/lib/match-engine.ts
Comment on lines +164 to +174
function applyWeights(
base: MatchBreakdown,
weights: WeightOverrides
): MatchBreakdown {
return {
domain_fit: clamp(Math.round(base.domain_fit * weights.domain_fit), 0, DIMENSION_MAXES.domain_fit),
stage_fit: clamp(Math.round(base.stage_fit * weights.stage_fit), 0, DIMENSION_MAXES.stage_fit),
geography: clamp(Math.round(base.geography * weights.geography), 0, DIMENSION_MAXES.geography),
history: clamp(Math.round(base.history * weights.history), 0, DIMENSION_MAXES.history),
availability: clamp(Math.round(base.availability * weights.availability), 0, DIMENSION_MAXES.availability),
};

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

@copilot apply changes based on this feedback

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Addressed in 68cbc6c. The deterministic matcher now clamps weighted dimensions against weighted maxes, so boosts above 1.0 can increase the breakdown, and the final returned score is normalized back to /100. I also added a regression test for the boosted-weight path.

Comment thread src/lib/match-engine.ts Outdated
Comment on lines +2 to +12
import type { Relationship } from "./store";
import type { WeightOverrides } from "./weight-engine";
import { DEFAULT_WEIGHTS } from "./weight-engine";

export type MatchBreakdown = {
domain_fit: number;
stage_fit: number;
geography: number;
history: number;
availability: number;
};
Comment on lines +18 to +31
async function submit() {
if (selected === 0) return;
setSubmitting(true);

await fetch(`/api/feedback/${relationshipId}`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ side, rating: selected, comment }),
});

setSubmitting(false);
setDone(true);
onSubmitted?.(selected);
}
Comment on lines +46 to +58
{[1, 2, 3, 4, 5].map((star) => (
<button
key={star}
type="button"
className={`text-2xl transition-transform hover:scale-110 ${
star <= (hovered || selected) ? "text-[var(--color-google-yellow)]" : "text-muted"
}`}
onMouseEnter={() => setHovered(star)}
onMouseLeave={() => setHovered(0)}
onClick={() => setSelected(star)}
>
</button>
Comment on lines +22 to +33
export function ProfileStrengthBadge({ strength, size = "md" }: ProfileStrengthBadgeProps) {
const pct = strength.total;
const isLg = size === "lg";

return (
<div className={`space-y-${isLg ? "4" : "2"}`}>
<div className="flex items-center justify-between">
<span className="text-xs font-semibold uppercase tracking-[0.2em] text-muted">
Profile Strength
</span>
<span className={`font-bold tabular-nums ${labelColors[strength.label]} ${isLg ? "text-2xl" : "text-base"}`}>
{strength.total}
Comment on lines +7 to +9
{ params }: { params: Promise<{ id: string }> }
) {
const { id } = await params;
Comment on lines +9 to +11
{ params }: { params: Promise<{ id: string }> }
) {
const { id } = await params;
Comment on lines +18 to +33
useEffect(() => {
let cancelled = false;

fetch("/api/match", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ viewerId }),
})
.then((r) => {
if (!r.ok) throw new Error(`${r.status}`);
return r.json();
})
.then((data) => {
if (!cancelled) setMatches(data.matches ?? []);
})
.catch((err: unknown) => {
Comment on lines +60 to +76
const response = await fetch("/api/relationships", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
viewerId,
matchedId: match.id,
matchScore: match.score,
rationale: match.rationale,
breakdown: match.breakdown,
}),
});
if (!response.ok) {
setConnecting(false);
return;
}
setConnecting(false);
setConnected(true);
Comment thread src/lib/weight-engine.ts
Comment on lines +45 to +53
const maxes: Record<keyof MatchBreakdown, number> = {
domain_fit: 30, stage_fit: 25, geography: 15, history: 20, availability: 10,
};

const overrides = { ...DEFAULT_WEIGHTS };

for (const key of keys) {
const avgAll = avg(completed.map((r) => (r.breakdown![key] / maxes[key]) * 100));
const avgHigh = avg(highRated.map((r) => (r.breakdown![key] / maxes[key]) * 100));
Agent-Logs-Url: https://github.com/mewHacks/myhack26/sessions/6c6fc861-aa69-457c-beb0-4f4baa7a4f5a

Co-authored-by: mewHacks <201765265+mewHacks@users.noreply.github.com>

Copilot AI commented May 16, 2026

Copy link
Copy Markdown

Just as a heads up, I was blocked by some firewall rules while working on your feedback. Expand below for details.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • registry.npmmirror.com
    • Triggering command: /usr/local/bin/node node /usr/local/bin/npm install (dns block)
    • Triggering command: /usr/local/bin/node node /usr/local/bin/npm ci (dns block)
    • Triggering command: /usr/local/bin/node node /usr/local/bin/npm ci --include=dev (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

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.

3 participants