Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
12 changes: 8 additions & 4 deletions public/runbook-embed.js
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,13 @@
description: (el.getAttribute("data-runbook-description") || "").trim()
});
}
function handleOut() {
function handleOut(evt) {
var from = evt.target instanceof Element ? evt.target : null;
var to = evt.relatedTarget instanceof Element ? evt.relatedTarget : null;
if (!from) return;
var fromFeature = from.closest("[data-runbook-feature],[data-runbook-title],[data-runbook-description]");
if (!fromFeature) return;
if (to && fromFeature.contains(to)) return;
updateHoveredFeature(null);
}
document.addEventListener("pointerover", handleOver, true);
Expand Down Expand Up @@ -406,8 +412,6 @@
}

function pageContext() {
var t = document.title || "";
var u = location.href || "";
var meta = "";
var m = document.querySelector('meta[name="description"]');
if (m) meta = m.getAttribute("content") || "";
Expand Down Expand Up @@ -445,7 +449,7 @@
bodyText = "";
}
}
return [u, t, meta, headings, bodyText].filter(Boolean).join("\n");
return [meta, headings, bodyText].filter(Boolean).join("\n");
}

function addBot(html) {
Expand Down
13 changes: 9 additions & 4 deletions src/app/api/embed/chat/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,6 @@ function normalizePageContext(body: ChatBody): string {
return [
`Page URL: ${body.pageUrl || "n/a"}`,
`Page title: ${body.pageTitle || "n/a"}`,
hovered ? `Hovered feature: ${hovered}` : "",
body.pageContext.trim()
]
.filter(Boolean)
Expand All @@ -124,9 +123,15 @@ function normalizePageContext(body: ChatBody): string {
function sanitizeHoveredFeature(raw: unknown): string {
if (!raw || typeof raw !== "object") return "";
const obj = raw as Record<string, unknown>;
const feature = String(obj.feature || "").trim();
const title = String(obj.title || "").trim();
const description = String(obj.description || "").trim().slice(0, 400);
const asStr = (v: unknown, limit: number): string =>
(typeof v === "string" ? v : "")
.replace(/[\u0000-\u001f]/g, " ")
.replace(/\s+/g, " ")
.trim()
.slice(0, limit);
const feature = asStr(obj.feature, 120);
const title = asStr(obj.title, 120);
const description = asStr(obj.description, 400);
const joined = [title || feature, description].filter(Boolean).join(" — ");
return joined.slice(0, 520);
}
Expand Down
6 changes: 1 addition & 5 deletions src/components/EmbeddedRunbookAssistant.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -213,11 +213,7 @@ export function EmbeddedRunbookAssistant({
typeof document !== "undefined"
? document.body.innerText.replace(/\s+/g, " ").trim().slice(0, 10_000)
: "";
const pageContext =
pageContextOverride ||
(typeof window !== "undefined"
? [window.location.href, document.title, pageBody].filter(Boolean).join("\n")
: pageBody);
const pageContext = pageContextOverride || pageBody;
const res = await fetch(`${base}/api/embed/chat`, {
method: "POST",
headers: { "Content-Type": "application/json" },
Expand Down
45 changes: 43 additions & 2 deletions src/lib/embedDemoKnowledge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,46 @@ function extractLocationTarget(text: string): string {
return "the relevant action button";
}

function pageLooksLikeDashboard(ctx: string): boolean {
return /(workflow|integration|api key|deployment|settings|onboarding|template|dashboard)/i.test(ctx);
}

function inferActionsFromContext(ctx: string, hovered: string): { bullets: string[]; steps: string[] } {
if (hovered) {
const hoverTitle = hovered.split("—")[0]?.trim() || hovered;
return {
bullets: [
`Explore ${hoverTitle}`,
"Use the highlighted feature first",
"Follow page prompts for next action"
],
steps: [
"Start with the hovered feature on this page.",
"Complete one action in that section.",
"Ask What next? for step-by-step guidance."
]
};
}
if (pageLooksLikeDashboard(ctx)) {
return {
bullets: ["Create a workflow", "Connect integrations", "Set up API keys"],
steps: [
"Start with the primary CTA on this page.",
"Complete one setup action.",
"Ask What next? for guided progression."
]
};
}
return {
bullets: ["Use the primary CTA", "Open navigation to key sections", "Follow visible setup hints"],
steps: [
"Look for the most prominent action button.",
"Open the related section from page navigation.",
"Complete one visible setup task, then ask for next steps."
]
};
}

/** Deterministic demo responses for hackathon reliability. */
export function buildNorthstarDemoResponse(message: string, pageContext: string, hoveredFeature?: string): DemoChatResult {
const m = message.toLowerCase().trim();
Expand All @@ -112,11 +152,12 @@ export function buildNorthstarDemoResponse(message: string, pageContext: string,
}

if (m.includes("what can i do here")) {
const inferred = inferActionsFromContext(ctx, hovered);
return createResult({
answer: "Here are the key actions available on this page.",
bullets: ["Create a workflow", "Connect integrations", "Set up API keys"],
bullets: inferred.bullets,
sources: product ? [{ title: product.title, excerpt: excerptFromContent(product.content), url: undefined }] : [],
steps: ["Start with the primary CTA on this page.", "Complete one setup action.", "Ask What next? for guided progression."]
steps: inferred.steps
});
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.

Expand Down
Loading