{"id":"hr-internal-mobility-matcher","title":"Internal Mobility Matcher","description":"Matches typed. Internal roles missed. Typed v1 agent with eval coverage.","category":"hr","status":"validated","version":"1.0.0","source":"agentskit-registry","license":"MIT","tags":["hr","structured-output","v1"],"packages":["@agentskit/core","@agentskit/runtime","@agentskit/tools"],"files":["agent.ts","README.md","eval.ts"],"requires":{"zod":"^3","zod-to-json-schema":"^3"},"skill":{"name":"hr-internal-mobility-matcher","description":"Matches typed. Internal roles missed. Typed v1 agent with eval coverage.","systemPrompt":"You are Internal Mobility Matcher. Internal roles missed. Output: Matches typed.\nDraft sections with citations from input. Gaps for missing facts.\nNEVER invent facts — gaps and openQuestions for missing input. Always draft for human review.\n${UNTRUSTED_CONTENT_DIRECTIVE}\nCall submit_mobility_matcher exactly once. Stop."},"flow":null,"a2a":{"id":"io.agentskit.registry.hr-internal-mobility-matcher","name":"Internal Mobility Matcher","description":"Matches typed. Internal roles missed. Typed v1 agent with eval coverage.","version":"1.0.0","homepage":"https://registry.agentskit.io","skills":[{"name":"hr-internal-mobility-matcher","description":"Matches typed. Internal roles missed. Typed v1 agent with eval coverage.","capabilities":{"streaming":true,"cancellation":true,"requiresApproval":false}}]},"sources":[{"path":"agent.ts","content":"import type { AdapterFactory, ChatMemory, Observer, ToolCall, ToolDefinition } from '@agentskit/core'\nimport { fenceUntrustedContent, UNTRUSTED_CONTENT_DIRECTIVE } from '@agentskit/core/security'\nimport { invokeStructured } from '@agentskit/runtime'\nimport { defineZodTool } from '@agentskit/tools'\nimport { z } from 'zod'\nimport { zodToJsonSchema } from 'zod-to-json-schema'\nimport type { JSONSchema7 } from 'json-schema'\n\n/** Internal Mobility Matcher — v1 validated. Pain: Internal roles missed */\n\nexport interface Section { heading: string; body: string; citations: string[] }\nexport interface AgentOutput { title: string; sections: Section[]; gaps: string[]; openQuestions: string[] }\nexport interface AgentResult extends AgentOutput { requiresReview: boolean }\nexport interface HrInternalMobilityMatcherConfig {\n  adapter: AdapterFactory\n  memory?: ChatMemory\n  observers?: Observer[]\n  onConfirm?: (toolCall: ToolCall) => boolean | Promise<boolean>\n  maxSteps?: number\n}\n\nconst Output = z.object({\n  title: z.string(),\n  sections: z.array(z.object({ heading: z.string(), body: z.string(), citations: z.array(z.string()).default([]) })).min(1),\n  gaps: z.array(z.string()).default([]),\n  openQuestions: z.array(z.string()).default([]),\n})\nconst toJson = (s: z.ZodTypeAny): JSONSchema7 => zodToJsonSchema(s) as JSONSchema7\n\nconst skill = {\n  name: 'hr-internal-mobility-matcher',\n  description: \"Internal Mobility Matcher — typed output agent (draft spec).\",\n  systemPrompt: `You are Internal Mobility Matcher. Internal roles missed. Output: Matches typed.\nDraft sections with citations from input. Gaps for missing facts.\nNEVER invent facts — gaps and openQuestions for missing input. Always draft for human review.\n${UNTRUSTED_CONTENT_DIRECTIVE}\nCall submit_mobility_matcher exactly once. Stop.`,\n  tools: ['submit_mobility_matcher'],\n}\n\nexport function createHrInternalMobilityMatcherAgent(config: HrInternalMobilityMatcherConfig) {\n  const submit = (): ToolDefinition =>\n    defineZodTool({ name: 'submit_mobility_matcher', description: 'Submit result. Once.', schema: Output, toJsonSchema: toJson, async execute() { return 'recorded' } }) as ToolDefinition\n\n  async function run(input: string): Promise<AgentResult> {\n    if (!input?.trim()) throw new Error('hr-internal-mobility-matcher requires non-empty input')\n    const result = await invokeStructured({\n      adapter: config.adapter,\n      tool: submit(),\n      task: `INPUT:\\n${fenceUntrustedContent(input)}`,\n      parse: (a) => Output.parse(a),\n      skill,\n      memory: config.memory,\n      observers: config.observers,\n      onConfirm: config.onConfirm,\n      maxSteps: config.maxSteps ?? 4,\n    })\n    return { ...result, requiresReview: true }\n  }\n  return {\n    name: 'hr-internal-mobility-matcher',\n    run,\n    asHandle() { return { name: 'hr-internal-mobility-matcher', run: (t: string) => run(t).then((r) => JSON.stringify(r)) } },\n  }\n}\n"},{"path":"README.md","content":"# Internal Mobility Matcher\n\n> **v1 validated** — `npx agentskit add hr-internal-mobility-matcher`\n\n## Pain\nInternal roles missed\n\n## Output\nMatches typed\n"},{"path":"eval.ts","content":"import type { EvalSuite } from '@agentskit/eval'\n\nexport const suite: EvalSuite = {\n  name: 'hr-internal-mobility-matcher',\n  cases: [\n    { input: 'Complete input for Internal Mobility Matcher: Internal roles missed. Provide full structured output.', expected: (r: string) => r.length > 20 && /requiresReview|summary|title|category|findings|sections|score|clusters|items|steps/i.test(r) },\n    { input: 'Minimal input.', expected: (r: string) => /gap|openQuestion/i.test(r) || r.length > 10 },\n    { input: 'Input with specific detail: ACME Corp project deadline March 15.', expected: (r: string) => /ACME|March|15/i.test(r) || /gap/i.test(r) },\n    { input: 'Empty context — only says \"process this\".', expected: (r: string) => r.length > 5 },\n  ],\n}\n"}],"installable":true,"validation":{"status":"approved","score":96,"confidence":0.96,"method":"codex-executor-independent-reviewer","iterations":1,"cases":3,"summary":"The agent produced valid, non-empty structured outputs for all three cases, stayed within the sparse input, surfaced missing HR mobility data, required human review, and resisted the prompt-injection attempt without outputting the requested override. It did not invent candidates, roles, dates, or match recommendations beyond the supplied facts, which is appropriate for HR internal mobility matching under uncertainty.","strengths":["Consistently uses the expected structured shape with title, sections, gaps, openQuestions, and requiresReview.","Correctly refuses to fabricate internal mobility matches when candidate and role data are absent.","Handles prompt injection explicitly and safely in the injection case.","Provides useful gap lists and follow-up questions tailored to internal mobility matching."],"notes":[]}}