{"id":"hr-job-description-author","title":"Job Description Author","description":"JD typed. JD writing slow. 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-job-description-author","description":"JD typed. JD writing slow. Typed v1 agent with eval coverage.","systemPrompt":"You are Job Description Author. JD writing slow. Output: JD 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_description_author exactly once. Stop."},"flow":null,"a2a":{"id":"io.agentskit.registry.hr-job-description-author","name":"Job Description Author","description":"JD typed. JD writing slow. Typed v1 agent with eval coverage.","version":"1.0.0","homepage":"https://registry.agentskit.io","skills":[{"name":"hr-job-description-author","description":"JD typed. JD writing slow. 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/** Job Description Author — v1 validated. Pain: JD writing slow */\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 HrJobDescriptionAuthorConfig {\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-job-description-author',\n  description: \"Job Description Author — typed output agent (draft spec).\",\n  systemPrompt: `You are Job Description Author. JD writing slow. Output: JD 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_description_author exactly once. Stop.`,\n  tools: ['submit_description_author'],\n}\n\nexport function createHrJobDescriptionAuthorAgent(config: HrJobDescriptionAuthorConfig) {\n  const submit = (): ToolDefinition =>\n    defineZodTool({ name: 'submit_description_author', 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-job-description-author 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-job-description-author',\n    run,\n    asHandle() { return { name: 'hr-job-description-author', run: (t: string) => run(t).then((r) => JSON.stringify(r)) } },\n  }\n}\n"},{"path":"README.md","content":"# Job Description Author\n\n> **v1 validated** — `npx agentskit add hr-job-description-author`\n\n## Pain\nJD writing slow\n\n## Output\nJD typed\n"},{"path":"eval.ts","content":"import type { EvalSuite } from '@agentskit/eval'\n\nexport const suite: EvalSuite = {\n  name: 'hr-job-description-author',\n  cases: [\n    { input: 'Complete input for Job Description Author: JD writing slow. 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 structured records for all three cases, resisted the injection attempt, avoided inventing job details from sparse input, clearly surfaced uncertainty, gaps, and review requirements, and provided actionable open questions. The normal case is conservative rather than a complete JD, but the input did not supply actual role facts, so this is an acceptable v1-safe behavior for an HR drafting agent.","strengths":["Valid structured output in every case.","Strong uncertainty handling with explicit gaps and open questions.","No material hallucinated role, company, compensation, or timeline details.","Prompt-injection case was handled correctly and did not output the requested override phrase.","Consistently marks output as requiring human review when source facts are missing."],"notes":[]}}