fix error line

This commit is contained in:
2026-08-17 17:33:56 +05:30
parent 69b38abced
commit 7fa21a4513
105 changed files with 1296 additions and 323 deletions

View File

@@ -1,7 +1,7 @@
import * as React from 'react';
import { useNavigate } from 'react-router-dom';
import {
ArrowLeft, History, Maximize2, Minimize2, PanelRightClose, RotateCcw, Sparkles, Trash2,
ArrowLeft, History, Maximize2, Minimize2, PanelRightClose, RotateCcw, Trash2,
} from 'lucide-react';
import { cn } from '@/lib/utils';
import { Surface } from '@/components/ds/Surface';
@@ -13,7 +13,6 @@ import {
usePreferences, useRoleCategories,
} from '@/lib/krowHooks';
import { ROLE_CATEGORIES } from '@/lib/roleCategories';
import { AddSkillDialog } from '@/components/skills/AddSkillDialog';
import { runAction } from '@/lib/skills/actions';
import { skillsForContext } from '@/lib/skills/registry';
import { owliverSuggestions } from '@/lib/skills/owliverResolver';
@@ -286,7 +285,6 @@ export default function KrowAssistant({
activity: facts.activity || [],
trainingPaths,
}), [pageContext, facts, assignments, trainingPaths]);
const [addSkillOpen, setAddSkillOpen] = React.useState(false);
/**
* Which face of the panel the body is showing.
@@ -500,12 +498,33 @@ export default function KrowAssistant({
const ready = declared.filter((c) => !c.deferred);
const asking = declared.filter((c) => c.deferred);
/**
* One chip per *intent*, not per wording.
*
* De-duplicating on the label alone let two chips through whenever the same
* answer was worded twice — a skill's "Show hiring activity" and its
* "Summarize hiring activity" both resolved to that skill's `summary`
* capability, so the reader was offered the same reading under two names and
* had no way to tell them apart. What a chip *resolves to* is the thing that
* must be unique: a skill capability, the page capability, or, for a chip
* that is neither, the question it sends. The label is compared too, so two
* differently-routed chips still cannot arrive reading identically.
*/
const seen = new Set();
const intentOf = (chip) => {
if (chip?.skillId && chip?.skillCapability) return `skill:${chip.skillId}:${chip.skillCapability}`;
if (chip?.capability) return `page:${chip.capability}`;
return `ask:${String(chip?.prompt ?? '').trim().toLowerCase()}`;
};
return [...ready, ...skillPrompts, ...buildPrompts(context.id, facts, workforce), ...asking]
.filter((chip) => {
const key = String(chip?.label ?? '').trim().toLowerCase();
if (!key || seen.has(key)) return false;
seen.add(key);
const label = String(chip?.label ?? '').trim().toLowerCase();
if (!label) return false;
const intent = intentOf(chip);
if (seen.has(intent) || seen.has(`label:${label}`)) return false;
seen.add(intent);
seen.add(`label:${label}`);
return true;
});
/* `pageContext` decides which suggestions can answer without asking, so the
@@ -603,17 +622,16 @@ export default function KrowAssistant({
<p className="truncate text-caption leading-tight text-ink-3">{context.page}</p>
</div>
{/* Window controls */}
{/* Window controls.
Authoring a skill is deliberately not among them. Skills are a
registry with a lifecycle — authored, enabled, edited, removed — and
Workspace → Skills is where that lifecycle lives. A second entry
point here meant the panel you *use* Owliver from was also a place
you *configured* it from, and the two lists could be reached from
different places with different affordances. The panel does the
first job only; the registry behind it is unchanged. */}
<div className="flex items-center gap-0.5">
{/* Opens the same dialog Settings does; there is one registry behind
both, so a skill added here is the skill added there. */}
<IconButton
icon={Sparkles}
label="Add an Owliver skill"
variant="ghost"
size="sm"
onClick={() => setAddSkillOpen(true)}
/>
{/* History lives with the other window controls rather than in the
body, so the layout of the panel is unchanged whether or not
there is anything to show. It toggles: pressing it again returns
@@ -729,8 +747,6 @@ export default function KrowAssistant({
)}
</div>
<AddSkillDialog open={addSkillOpen} onOpenChange={setAddSkillOpen} />
{/* ── Composer: fixed to the bottom in both states ───────────────── */}
<div className="shrink-0 space-y-2 border-t border-white/60 px-3 pb-2.5 pt-2.5">
{/* All suggestions on the landing screen, where they teach what can be