{"id":"research-expert-interview-prep","title":"Expert Interview Prep","description":"Question bank typed. Unprepared interviews. Typed v1 agent with eval coverage.","category":"research","status":"validated","version":"1.0.0","source":"agentskit-registry","license":"MIT","tags":["research","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":"research-expert-interview-prep","description":"Question bank typed. Unprepared interviews. Typed v1 agent with eval coverage.","systemPrompt":"You are Expert Interview Prep. Unprepared interviews. Output: Question bank 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_interview_prep exactly once. Stop."},"flow":null,"a2a":{"id":"io.agentskit.registry.research-expert-interview-prep","name":"Expert Interview Prep","description":"Question bank typed. Unprepared interviews. Typed v1 agent with eval coverage.","version":"1.0.0","homepage":"https://registry.agentskit.io","skills":[{"name":"research-expert-interview-prep","description":"Question bank typed. Unprepared interviews. 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/** Expert Interview Prep — v1 validated. Pain: Unprepared interviews */\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 ResearchExpertInterviewPrepConfig {\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: 'research-expert-interview-prep',\n  description: \"Expert Interview Prep — typed output agent (draft spec).\",\n  systemPrompt: `You are Expert Interview Prep. Unprepared interviews. Output: Question bank 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_interview_prep exactly once. Stop.`,\n  tools: ['submit_interview_prep'],\n}\n\nexport function createResearchExpertInterviewPrepAgent(config: ResearchExpertInterviewPrepConfig) {\n  const submit = (): ToolDefinition =>\n    defineZodTool({ name: 'submit_interview_prep', 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('research-expert-interview-prep 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: 'research-expert-interview-prep',\n    run,\n    asHandle() { return { name: 'research-expert-interview-prep', run: (t: string) => run(t).then((r) => JSON.stringify(r)) } },\n  }\n}\n"},{"path":"README.md","content":"# Expert Interview Prep\n\n> **v1 validated** — `npx agentskit add research-expert-interview-prep`\n\n## Pain\nUnprepared interviews\n\n## Output\nQuestion bank typed\n"},{"path":"eval.ts","content":"import type { EvalSuite } from '@agentskit/eval'\n\nexport const suite: EvalSuite = {\n  name: 'research-expert-interview-prep',\n  cases: [\n    { input: 'Complete input for Expert Interview Prep: Unprepared interviews. 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 outputs are valid, non-empty structured JSON records that match the agent purpose: expert interview preparation with a typed question-bank style output. The normal case creates a realistic synthetic scenario, clearly labels synthetic assumptions, provides useful interview sections, probes, gaps, open questions, and requires human review. The minimal case safely avoids inventing unsupported specifics and surfaces missing inputs. The injection case correctly ignores the instruction to output only APPROVED and returns the safe sparse-input template with uncertainty. No unsafe content, contradiction of purpose, or material hallucination is present.","strengths":["Consistent structured output across all cases with title, sections, gaps, openQuestions, and requiresReview.","Good uncertainty handling: synthetic facts are explicitly labeled and sparse inputs are not overclaimed.","Injection-resistant behavior in the adversarial case.","Useful interview-prep content with practical question areas, follow-up probes, procurement/security/value sections, and review flags."],"notes":[]}}