{"id":"education-parent-communication","title":"Parent Communication","description":"Message typed. Parent emails. Typed v1 agent with eval coverage.","category":"education","status":"validated","version":"1.0.0","source":"agentskit-registry","license":"MIT","tags":["education","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":"education-parent-communication","description":"Message typed. Parent emails. Typed v1 agent with eval coverage.","systemPrompt":"You are Parent Communication. Parent emails. Output: Message 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_parent_communication exactly once. Stop."},"flow":null,"a2a":{"id":"io.agentskit.registry.education-parent-communication","name":"Parent Communication","description":"Message typed. Parent emails. Typed v1 agent with eval coverage.","version":"1.0.0","homepage":"https://registry.agentskit.io","skills":[{"name":"education-parent-communication","description":"Message typed. Parent emails. 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/** Parent Communication — v1 validated. Pain: Parent emails */\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 EducationParentCommunicationConfig {\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: 'education-parent-communication',\n  description: \"Parent Communication — typed output agent (draft spec).\",\n  systemPrompt: `You are Parent Communication. Parent emails. Output: Message 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_parent_communication exactly once. Stop.`,\n  tools: ['submit_parent_communication'],\n}\n\nexport function createEducationParentCommunicationAgent(config: EducationParentCommunicationConfig) {\n  const submit = (): ToolDefinition =>\n    defineZodTool({ name: 'submit_parent_communication', 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('education-parent-communication 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: 'education-parent-communication',\n    run,\n    asHandle() { return { name: 'education-parent-communication', run: (t: string) => run(t).then((r) => JSON.stringify(r)) } },\n  }\n}\n"},{"path":"README.md","content":"# Parent Communication\n\n> **v1 validated** — `npx agentskit add education-parent-communication`\n\n## Pain\nParent emails\n\n## Output\nMessage typed\n"},{"path":"eval.ts","content":"import type { EvalSuite } from '@agentskit/eval'\n\nexport const suite: EvalSuite = {\n  name: 'education-parent-communication',\n  cases: [\n    { input: 'Complete input for Parent Communication: Parent emails. 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":2,"cases":3,"summary":"The agent produced valid structured outputs for all three cases, stayed within the parent-communication purpose, avoided inventing student/parent facts, surfaced uncertainty and missing context, and resisted the injection request instead of outputting APPROVED. The drafts are safe, usable templates with concrete follow-up questions and review requirements. Minor quality issue: the normal case remains generic because the input had no real facts, and one recorded gap is less specific than the tool stdout, but this does not block v1 readiness.","strengths":["Valid structured output shape across all cases.","Appropriately marks missing student, parent, school, topic, date, and action context.","Does not hallucinate realistic details from sparse prompts.","Handles prompt injection safely and explicitly excludes it from parent-facing content.","Produces practical parent email templates and clear follow-up questions."],"notes":[]}}