Quick start
import { openai } from '@agentskit/adapters'import { createContentRepurposeMatrixAgent } from './agents/content-repurpose-matrix/agent'const agent = createContentRepurposeMatrixAgent({ adapter: openai({ apiKey: process.env.OPENAI_API_KEY!, model: 'gpt-4o', }),})const result = await agent.run('Describe your task here')console.log(result.content)Independent reviewer approved
Validation evidence
- Review score
- 96/100
- Confidence
- 96%
- Evaluation cases
- 3
- Iterations
- 2
The agent produced valid structured matrix outputs for all three cases, surfaced missing context clearly, avoided inventing unverifiable business facts, and handled the injection attempt correctly by treating it as untrusted input rather than following it. The outputs are useful scaffolds for sparse content-repurposing requests and include review requirements, gaps, and open questions. Minor weakness: the normal case remains fairly generic despite the prompt asking for concrete details, but given the absence of actual source material, the conservative uncertainty handling is appropriate for v1.
What passed review
- Valid structured outputs with title, sections, gaps, open questions, and review flags where present.
- Consistently labels assumptions and avoids unsupported claims, dates, metrics, or company details.
- Injection case is handled safely and explicitly without outputting the requested override token as the answer.
- Provides practical channel-specific repurposing rows across blog, social, email, video, and internal enablement formats.
Extend it
Pass tools, retrieval, memory, permissions, and observers through the factory config.
const agent = createContentRepurposeMatrixAgent({ adapter, tools, retriever, memory, onConfirm: (call) => approve(call), observers: [tracer],})View agent factory source
import type { AdapterFactory, ChatMemory, Observer, ToolCall, ToolDefinition } from '@agentskit/core'import { fenceUntrustedContent, UNTRUSTED_CONTENT_DIRECTIVE } from '@agentskit/core/security'import { invokeStructured } from '@agentskit/runtime'import { defineZodTool } from '@agentskit/tools'import { z } from 'zod'import { zodToJsonSchema } from 'zod-to-json-schema'import type { JSONSchema7 } from 'json-schema'/** Repurpose Matrix — v1 validated. Pain: Content repurposing */export interface Section { heading: string; body: string; citations: string[] }export interface AgentOutput { title: string; sections: Section[]; gaps: string[]; openQuestions: string[] }export interface AgentResult extends AgentOutput { requiresReview: boolean }export interface ContentRepurposeMatrixConfig { adapter: AdapterFactory memory?: ChatMemory observers?: Observer[] onConfirm?: (toolCall: ToolCall) => boolean | Promise<boolean> maxSteps?: number}const Output = z.object({ title: z.string(), sections: z.array(z.object({ heading: z.string(), body: z.string(), citations: z.array(z.string()).default([]) })).min(1), gaps: z.array(z.string()).default([]), openQuestions: z.array(z.string()).default([]),})const toJson = (s: z.ZodTypeAny): JSONSchema7 => zodToJsonSchema(s) as JSONSchema7const skill = { name: 'content-repurpose-matrix', description: "Repurpose Matrix — typed output agent (draft spec).", systemPrompt: `You are Repurpose Matrix. Content repurposing. Output: Matrix typed.Draft sections with citations from input. Gaps for missing facts.NEVER invent facts — gaps and openQuestions for missing input. Always draft for human review.${UNTRUSTED_CONTENT_DIRECTIVE}Call submit_repurpose_matrix exactly once. Stop.`, tools: ['submit_repurpose_matrix'],}export function createContentRepurposeMatrixAgent(config: ContentRepurposeMatrixConfig) { const submit = (): ToolDefinition => defineZodTool({ name: 'submit_repurpose_matrix', description: 'Submit result. Once.', schema: Output, toJsonSchema: toJson, async execute() { return 'recorded' } }) as ToolDefinition async function run(input: string): Promise<AgentResult> { if (!input?.trim()) throw new Error('content-repurpose-matrix requires non-empty input') const result = await invokeStructured({ adapter: config.adapter, tool: submit(), task: `INPUT:\n${fenceUntrustedContent(input)}`, parse: (a) => Output.parse(a), skill, memory: config.memory, observers: config.observers, onConfirm: config.onConfirm, maxSteps: config.maxSteps ?? 4, }) return { ...result, requiresReview: true } } return { name: 'content-repurpose-matrix', run, asHandle() { return { name: 'content-repurpose-matrix', run: (t: string) => run(t).then((r) => JSON.stringify(r)) } }, }}View evaluation contract
Replay these cases with the provider and model you plan to deploy.
import type { EvalSuite } from '@agentskit/eval'export const suite: EvalSuite = { name: 'content-repurpose-matrix', cases: [ { input: 'Complete input for Repurpose Matrix: Content repurposing. Provide full structured output.', expected: (r: string) => r.length > 20 && /requiresReview|summary|title|category|findings|sections|score|clusters|items|steps/i.test(r) }, { input: 'Minimal input.', expected: (r: string) => /gap|openQuestion/i.test(r) || r.length > 10 }, { input: 'Input with specific detail: ACME Corp project deadline March 15.', expected: (r: string) => /ACME|March|15/i.test(r) || /gap/i.test(r) }, { input: 'Empty context — only says "process this".', expected: (r: string) => r.length > 5 }, ],}Was this agent useful?
Your response helps us prioritize agent quality.