Ship skills built-in: bundle the catalogue, assign per hire, force humanizer

Skills no longer come from the user's ~/.agents library - most users have
none, and the CEO branch that compiled the entire catalogue into its
prompt overflowed the model context (1.1MB) and failed every CEO run.

- Bundle "built-in skills/" with the app (extraResources) and stage it
  at startup into <profile>/builtin-skills as one dir-per-skill copy -
  both bundle shapes (SKILL.md dirs and flat category .md files)
  normalize into the same importable layout
- Import the staged catalogue per org at startup and inside onboarding,
  so the CEO's first run already carries it
- Forced house style: resolveRuntimeSnapshot unions the humanizer skill
  into every agent's runtime (CEO included) as a resolution rule - no
  binding row to forget, delete, or bypass; revoke_skill refuses it
- CEO staffs hires with skills: hire_agent accepts a skills array,
  grant_skill/revoke_skill adjust later, list_skills now shows
  descriptions from skill frontmatter
- Kill the c_suite compile-all branch; everyone resolves bindings-only,
  capped at 200k chars with omissions named in the prompt
- Remove the Skills settings page and its import/sync/test IPC surface;
  drop ~/.agents discovery and the AGENTCOMPANY_NEW_SKILLS_ROOT seam in
  favor of AGENTCOMPANY_NEW_BUILTIN_SKILLS_DIR
- Tests: staging/import/forced-resolution/cap units, real-bundle CI
  check, e2e asserts the tab is gone and the catalogue self-imports
This commit is contained in:
ZacharyZhang-NY committed 2026-07-08 21:18:50 -04:00
1 parent 55c043f8b4
commit 86aa6fdb29
318 files changed
+77467 -520

No files matched your search

+12 -3
View File
@@ -6,7 +6,7 @@ import type { ChatService } from "./chat-service";
import { canonicalMentionHandle } from "../../shared/mention-handles";
import { readMessagesTool } from "./agent-read-messages";
import { grantConnectorTool, listConnectorsTool } from "./agent-connector-tools";
import { grantSkillTool, listSkillsTool } from "./agent-skill-tools";
import { bindSkillSlugs, grantSkillTool, listSkillsTool } from "./agent-skill-tools";
import { createDocumentTool, writeDeliverableTool } from "./agent-deliverable-tools";
import { describeSend } from "./agent-message-presence";
import { optionalString, optionalStringArray, requireString } from "./agent-tool-args";
@@ -40,7 +40,7 @@ export const AGENT_TOOLS: ToolDefinition[] = [
{
name: "hire_agent",
description:
"Add one direct report to your team. During team building, call this 3-5 times to staff the roles you need before delegating work.",
"Add one direct report to your team. During team building, call this 3-5 times to staff the roles you need before delegating work. Staff every hire with the library skills their role needs (check list_skills; several are fine) — those skills become mandatory practice in the hire's runs.",
parameters: {
type: "object",
additionalProperties: false,
@@ -49,6 +49,11 @@ export const AGENT_TOOLS: ToolDefinition[] = [
role: { type: "string", description: "Their role/title, e.g. 'Growth Marketer'." },
department: { type: "string", enum: [...ORGANIZATION_DEPARTMENTS], description: "The company department the hire belongs to." },
model: { type: "string", description: "Optional model id; defaults to your own model." },
skills: {
type: "array",
items: { type: "string" },
description: "Skill slugs from list_skills this hire must work with, e.g. ['engineering-backend-architect']. Every agent also carries the humanizer house-style skill automatically.",
},
},
required: ["name", "role", "department"],
},
@@ -254,6 +259,7 @@ function hireAgent(deps: AgentToolDeps, ctx: AgentToolContext, args: JsonRecord)
const role = requireString(args.role, "role");
const department = requireString(args.department, "department");
const model = optionalString(args.model) ?? ctx.agent.modelId;
const requestedSkills = optionalStringArray(args.skills, "skills");
const agentId = deps.organization.createAgent({
orgId: ctx.orgId,
name,
@@ -268,7 +274,10 @@ function hireAgent(deps: AgentToolDeps, ctx: AgentToolContext, args: JsonRecord)
heartbeatEnabled: true,
heartbeatIntervalSec: HEARTBEAT_INTERVAL_SEC,
});
return `Hired ${name} as ${role} in ${department} (agent_id=${agentId}).`;
const { granted, unknown } = bindSkillSlugs(deps, ctx.orgId, agentId, requestedSkills);
const skillNote = granted.length > 0 ? ` They carry: ${granted.join(", ")} (plus the automatic humanizer house style).` : "";
const unknownNote = unknown.length > 0 ? ` Unknown skills skipped: ${unknown.join(", ")} — run list_skills and grant_skill to fix.` : "";
return `Hired ${name} as ${role} in ${department} (agent_id=${agentId}).${skillNote}${unknownNote}`;
}
function createTask(deps: AgentToolDeps, ctx: AgentToolContext, args: JsonRecord, options: AgentToolDispatchOptions): string {