mirror of
https://github.com/alkimake/paperclip.git
synced 2026-06-17 19:20:39 +09:00
Merge branch 'master' into feature/change-reports-to
This commit is contained in:
commit
dfb83295de
191 changed files with 46471 additions and 1103 deletions
|
|
@ -4,9 +4,11 @@ import { useNavigate, useSearchParams } from "@/lib/router";
|
|||
import { useCompany } from "../context/CompanyContext";
|
||||
import { useBreadcrumbs } from "../context/BreadcrumbContext";
|
||||
import { agentsApi } from "../api/agents";
|
||||
import { companySkillsApi } from "../api/companySkills";
|
||||
import { queryKeys } from "../lib/queryKeys";
|
||||
import { AGENT_ROLES } from "@paperclipai/shared";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Checkbox } from "@/components/ui/checkbox";
|
||||
import {
|
||||
Popover,
|
||||
PopoverContent,
|
||||
|
|
@ -68,6 +70,7 @@ export function NewAgent() {
|
|||
const [role, setRole] = useState("general");
|
||||
const [reportsTo, setReportsTo] = useState<string | null>(null);
|
||||
const [configValues, setConfigValues] = useState<CreateConfigValues>(defaultCreateValues);
|
||||
const [selectedSkillKeys, setSelectedSkillKeys] = useState<string[]>([]);
|
||||
const [roleOpen, setRoleOpen] = useState(false);
|
||||
const [formError, setFormError] = useState<string | null>(null);
|
||||
|
||||
|
|
@ -90,6 +93,12 @@ export function NewAgent() {
|
|||
enabled: Boolean(selectedCompanyId),
|
||||
});
|
||||
|
||||
const { data: companySkills } = useQuery({
|
||||
queryKey: queryKeys.companySkills.list(selectedCompanyId ?? ""),
|
||||
queryFn: () => companySkillsApi.list(selectedCompanyId!),
|
||||
enabled: Boolean(selectedCompanyId),
|
||||
});
|
||||
|
||||
const isFirstAgent = !agents || agents.length === 0;
|
||||
const effectiveRole = isFirstAgent ? "ceo" : role;
|
||||
|
||||
|
|
@ -172,7 +181,8 @@ export function NewAgent() {
|
|||
name: name.trim(),
|
||||
role: effectiveRole,
|
||||
...(title.trim() ? { title: title.trim() } : {}),
|
||||
...(reportsTo != null ? { reportsTo } : {}),
|
||||
...(reportsTo ? { reportsTo } : {}),
|
||||
...(selectedSkillKeys.length > 0 ? { desiredSkills: selectedSkillKeys } : {}),
|
||||
adapterType: configValues.adapterType,
|
||||
adapterConfig: buildAdapterConfig(),
|
||||
runtimeConfig: {
|
||||
|
|
@ -188,6 +198,17 @@ export function NewAgent() {
|
|||
});
|
||||
}
|
||||
|
||||
const availableSkills = (companySkills ?? []).filter((skill) => !skill.key.startsWith("paperclipai/paperclip/"));
|
||||
|
||||
function toggleSkill(key: string, checked: boolean) {
|
||||
setSelectedSkillKeys((prev) => {
|
||||
if (checked) {
|
||||
return prev.includes(key) ? prev : [...prev, key];
|
||||
}
|
||||
return prev.filter((value) => value !== key);
|
||||
});
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="mx-auto max-w-2xl space-y-6">
|
||||
<div>
|
||||
|
|
@ -266,6 +287,44 @@ export function NewAgent() {
|
|||
adapterModels={adapterModels}
|
||||
/>
|
||||
|
||||
<div className="border-t border-border px-4 py-4">
|
||||
<div className="space-y-3">
|
||||
<div>
|
||||
<h2 className="text-sm font-medium">Company skills</h2>
|
||||
<p className="mt-1 text-xs text-muted-foreground">
|
||||
Optional skills from the company library. Built-in Paperclip runtime skills are added automatically.
|
||||
</p>
|
||||
</div>
|
||||
{availableSkills.length === 0 ? (
|
||||
<p className="text-xs text-muted-foreground">
|
||||
No optional company skills installed yet.
|
||||
</p>
|
||||
) : (
|
||||
<div className="space-y-3">
|
||||
{availableSkills.map((skill) => {
|
||||
const inputId = `skill-${skill.id}`;
|
||||
const checked = selectedSkillKeys.includes(skill.key);
|
||||
return (
|
||||
<div key={skill.id} className="flex items-start gap-3">
|
||||
<Checkbox
|
||||
id={inputId}
|
||||
checked={checked}
|
||||
onCheckedChange={(next) => toggleSkill(skill.key, next === true)}
|
||||
/>
|
||||
<label htmlFor={inputId} className="grid gap-1 leading-none">
|
||||
<span className="text-sm font-medium">{skill.name}</span>
|
||||
<span className="text-xs text-muted-foreground">
|
||||
{skill.description ?? skill.key}
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Footer */}
|
||||
<div className="border-t border-border px-4 py-3">
|
||||
{isFirstAgent && (
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue