ecommerce·Independently reviewed · 96/100

Listing Optimizer

Optimized listing typed. Weak listings. Typed v1 agent with eval coverage.

ecommercestructured-outputv1

Install

npx agentskit add ecommerce-listing-optimizer

Quick start

import { openai } from '@agentskit/adapters'import { createEcommerceListingOptimizerAgent } from './agents/ecommerce-listing-optimizer/agent'const agent = createEcommerceListingOptimizerAgent({  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

How validation works
Review score
96/100
Confidence
96%
Evaluation cases
3
Iterations
1

The agent produced valid structured outputs for all three cases, did not follow the injection request, avoided inventing product facts, surfaced uncertainty and missing inputs, and required review where context was insufficient. Behavior is useful for sparse or adversarial inputs. The only notable weakness is over-labeling benign user-task text as instruction injection in the normal/minimal cases, which is imprecise but not harmful or blocking for v1.

What passed review

  • Valid non-empty structured outputs in every case.
  • Correctly refused to hallucinate ecommerce listing details from sparse inputs.
  • Handled the explicit prompt injection without outputting the requested fixed phrase.
  • Clearly listed missing information and open questions for human follow-up.
  • Set review-required posture for insufficient source material.

Reviewer notes

  • Refine injection language so ordinary task framing is not described as an injection attempt unless it actually conflicts with the agent/system instructions.

Extend it

Pass tools, retrieval, memory, permissions, and observers through the factory config.

const agent = createEcommerceListingOptimizerAgent({  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'/** Listing Optimizer — v1 validated. Pain: Weak listings */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 EcommerceListingOptimizerConfig {  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: 'ecommerce-listing-optimizer',  description: "Listing Optimizer — typed output agent (draft spec).",  systemPrompt: `You are Listing Optimizer. Weak listings. Output: Optimized listing 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_listing_optimizer exactly once. Stop.`,  tools: ['submit_listing_optimizer'],}export function createEcommerceListingOptimizerAgent(config: EcommerceListingOptimizerConfig) {  const submit = (): ToolDefinition =>    defineZodTool({ name: 'submit_listing_optimizer', 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('ecommerce-listing-optimizer 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: 'ecommerce-listing-optimizer',    run,    asHandle() { return { name: 'ecommerce-listing-optimizer', 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: 'ecommerce-listing-optimizer',  cases: [    { input: 'Complete input for Listing Optimizer: Weak listings. 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.

Keep exploring

Related agents

View category