From d03825177139e67af7c59030a433817d307f5af4 Mon Sep 17 00:00:00 2001 From: vibegpt Date: Fri, 13 Feb 2026 15:47:14 +0200 Subject: [PATCH 1/2] feat(agentkit): Add PolicyCheck action provider for pre-purchase seller verification Adds a walletless action provider that enables AI agents to verify e-commerce seller policies before making purchases. Analyzes return policies, shipping terms, warranty coverage, and terms of service. Actions: - policycheck_analyze: Full policy analysis from text or URL - policycheck_check_url: Quick URL-based seller check Returns risk level, buyer protection score (0-100), key findings, and purchase recommendation via the PolicyCheck A2A API. Co-Authored-By: Claude Opus 4.6 --- .changeset/add-policycheck-provider.md | 5 + .../agentkit/src/action-providers/index.ts | 1 + .../src/action-providers/policycheck/index.ts | 2 + .../policycheckActionProvider.test.ts | 296 ++++++++++++++++++ .../policycheck/policycheckActionProvider.ts | 203 ++++++++++++ .../action-providers/policycheck/schemas.ts | 37 +++ 6 files changed, 544 insertions(+) create mode 100644 .changeset/add-policycheck-provider.md create mode 100644 typescript/agentkit/src/action-providers/policycheck/index.ts create mode 100644 typescript/agentkit/src/action-providers/policycheck/policycheckActionProvider.test.ts create mode 100644 typescript/agentkit/src/action-providers/policycheck/policycheckActionProvider.ts create mode 100644 typescript/agentkit/src/action-providers/policycheck/schemas.ts diff --git a/.changeset/add-policycheck-provider.md b/.changeset/add-policycheck-provider.md new file mode 100644 index 000000000..dbb1f1897 --- /dev/null +++ b/.changeset/add-policycheck-provider.md @@ -0,0 +1,5 @@ +--- +"@coinbase/agentkit": minor +--- + +Added PolicyCheck action provider for pre-purchase seller policy verification. Enables AI agents to analyze e-commerce seller return policies, shipping terms, warranty coverage, and terms of service before making purchases. Returns risk level, buyer protection score, key findings, and purchase recommendation. Walletless provider — works on all networks. diff --git a/typescript/agentkit/src/action-providers/index.ts b/typescript/agentkit/src/action-providers/index.ts index 7f2b0233a..1231fd5c5 100644 --- a/typescript/agentkit/src/action-providers/index.ts +++ b/typescript/agentkit/src/action-providers/index.ts @@ -22,6 +22,7 @@ export * from "./pyth"; export * from "./moonwell"; export * from "./morpho"; export * from "./opensea"; +export * from "./policycheck"; export * from "./spl"; export * from "./superfluid"; export * from "./sushi"; diff --git a/typescript/agentkit/src/action-providers/policycheck/index.ts b/typescript/agentkit/src/action-providers/policycheck/index.ts new file mode 100644 index 000000000..6b9c30678 --- /dev/null +++ b/typescript/agentkit/src/action-providers/policycheck/index.ts @@ -0,0 +1,2 @@ +export * from "./policycheckActionProvider"; +export * from "./schemas"; diff --git a/typescript/agentkit/src/action-providers/policycheck/policycheckActionProvider.test.ts b/typescript/agentkit/src/action-providers/policycheck/policycheckActionProvider.test.ts new file mode 100644 index 000000000..a9166aea9 --- /dev/null +++ b/typescript/agentkit/src/action-providers/policycheck/policycheckActionProvider.test.ts @@ -0,0 +1,296 @@ +import { policycheckActionProvider, PolicyCheckActionProvider } from "./policycheckActionProvider"; + +// Mock A2A responses +const MOCK_LOW_RISK_RESPONSE = { + jsonrpc: "2.0", + id: "1", + result: { + id: "task_test_1", + status: { state: "completed" }, + artifacts: [ + { + artifactId: "artifact_test_1", + name: "policy_analysis", + parts: [ + { + kind: "data", + data: { + riskLevel: "low", + buyerProtectionScore: 85, + keyFindings: [ + "30-day return policy with free return shipping", + "1-year manufacturer warranty included", + "Full refund to original payment method", + ], + recommendation: "proceed", + }, + mimeType: "application/json", + }, + { + kind: "text", + text: "Low risk seller. Buyer protections are strong with a 30-day return window and free returns.", + }, + ], + }, + ], + messages: [], + }, +}; + +const MOCK_HIGH_RISK_RESPONSE = { + jsonrpc: "2.0", + id: "2", + result: { + id: "task_test_2", + status: { state: "completed" }, + artifacts: [ + { + artifactId: "artifact_test_2", + name: "policy_analysis", + parts: [ + { + kind: "data", + data: { + riskLevel: "high", + buyerProtectionScore: 25, + keyFindings: [ + "No return policy found", + "Binding arbitration clause detected", + "Liability cap limits seller responsibility to purchase price", + ], + recommendation: "caution", + }, + mimeType: "application/json", + }, + { + kind: "text", + text: "High risk seller. Consider purchasing from a different merchant.", + }, + ], + }, + ], + messages: [], + }, +}; + +const MOCK_ERROR_RESPONSE = { + jsonrpc: "2.0", + id: "3", + error: { + code: -32000, + message: "Analysis failed: unable to fetch policy page", + }, +}; + +describe("PolicyCheckActionProvider", () => { + const fetchMock = jest.fn(); + global.fetch = fetchMock; + + let provider: PolicyCheckActionProvider; + + beforeEach(() => { + jest.resetAllMocks().restoreAllMocks(); + provider = policycheckActionProvider(); + }); + + describe("constructor", () => { + it("should use default API URL when no config provided", () => { + const p = policycheckActionProvider(); + expect(p["apiUrl"]).toBe("https://legaleasy.tools/api/a2a"); + }); + + it("should use custom API URL from config", () => { + const p = policycheckActionProvider({ apiUrl: "https://custom.api/a2a" }); + expect(p["apiUrl"]).toBe("https://custom.api/a2a"); + }); + }); + + describe("supportsNetwork", () => { + it("should return true for any network", () => { + expect(provider.supportsNetwork({ protocolFamily: "evm", networkId: "base-mainnet" } as any)).toBe(true); + expect(provider.supportsNetwork({ protocolFamily: "solana", networkId: "mainnet" } as any)).toBe(true); + }); + }); + + describe("analyze", () => { + it("should return low-risk assessment for safe seller policies", async () => { + fetchMock.mockResolvedValueOnce({ + ok: true, + json: async () => MOCK_LOW_RISK_RESPONSE, + }); + + const result = await provider.analyze({ + policyText: + "30-day return policy. Free return shipping. Full refund within 5 business days. 1-year warranty.", + }); + const parsed = JSON.parse(result); + + expect(parsed.success).toBe(true); + expect(parsed.riskLevel).toBe("low"); + expect(parsed.buyerProtectionScore).toBe(85); + expect(parsed.recommendation).toBe("proceed"); + expect(parsed.keyFindings).toHaveLength(3); + expect(parsed.analyzedUrl).toBe("direct text analysis"); + }); + + it("should return high-risk assessment for risky seller policies", async () => { + fetchMock.mockResolvedValueOnce({ + ok: true, + json: async () => MOCK_HIGH_RISK_RESPONSE, + }); + + const result = await provider.analyze({ + policyText: "All sales final. Binding arbitration. Liability capped at $10.", + }); + const parsed = JSON.parse(result); + + expect(parsed.success).toBe(true); + expect(parsed.riskLevel).toBe("high"); + expect(parsed.buyerProtectionScore).toBe(25); + expect(parsed.recommendation).toBe("caution"); + }); + + it("should send seller URL as data part with quick-risk-check skill", async () => { + fetchMock.mockResolvedValueOnce({ + ok: true, + json: async () => MOCK_LOW_RISK_RESPONSE, + }); + + const result = await provider.analyze({ + sellerUrl: "https://example-store.com", + }); + + expect(fetchMock).toHaveBeenCalledTimes(1); + const [url, options] = fetchMock.mock.calls[0]; + expect(url).toBe("https://legaleasy.tools/api/a2a"); + + const body = JSON.parse(options.body); + expect(body.method).toBe("message/send"); + expect(body.params.message.parts[0]).toEqual( + expect.objectContaining({ + kind: "data", + data: { seller_url: "https://example-store.com", skill: "quick-risk-check" }, + }), + ); + + const parsed = JSON.parse(result); + expect(parsed.success).toBe(true); + expect(parsed.analyzedUrl).toBe("https://example-store.com"); + }); + + it("should send policy text as text part", async () => { + fetchMock.mockResolvedValueOnce({ + ok: true, + json: async () => MOCK_LOW_RISK_RESPONSE, + }); + + await provider.analyze({ policyText: "Test policy text" }); + + const [, options] = fetchMock.mock.calls[0]; + const body = JSON.parse(options.body); + expect(body.params.message.parts[0]).toEqual( + expect.objectContaining({ + kind: "text", + text: "Test policy text", + }), + ); + }); + + it("should return error for API error response", async () => { + fetchMock.mockResolvedValueOnce({ + ok: true, + json: async () => MOCK_ERROR_RESPONSE, + }); + + const result = await provider.analyze({ + sellerUrl: "https://broken-site.com", + }); + const parsed = JSON.parse(result); + + expect(parsed.success).toBe(false); + expect(parsed.error).toContain("unable to fetch policy page"); + }); + + it("should return error for HTTP failure", async () => { + fetchMock.mockResolvedValueOnce({ + ok: false, + status: 500, + }); + + const result = await provider.analyze({ + policyText: "Some policy text", + }); + const parsed = JSON.parse(result); + + expect(parsed.success).toBe(false); + expect(parsed.error).toContain("HTTP 500"); + }); + + it("should return error for network failure", async () => { + fetchMock.mockRejectedValueOnce(new Error("Network timeout")); + + const result = await provider.analyze({ + policyText: "Some policy text", + }); + const parsed = JSON.parse(result); + + expect(parsed.success).toBe(false); + expect(parsed.error).toContain("Network timeout"); + }); + + it("should return error when no analysis data in response", async () => { + fetchMock.mockResolvedValueOnce({ + ok: true, + json: async () => ({ + jsonrpc: "2.0", + id: "4", + result: { id: "task_empty", status: { state: "completed" }, artifacts: [], messages: [] }, + }), + }); + + const result = await provider.analyze({ + policyText: "Some policy text", + }); + const parsed = JSON.parse(result); + + expect(parsed.success).toBe(false); + expect(parsed.error).toContain("No analysis data"); + }); + + it("should include summary text when available", async () => { + fetchMock.mockResolvedValueOnce({ + ok: true, + json: async () => MOCK_LOW_RISK_RESPONSE, + }); + + const result = await provider.analyze({ + policyText: "Good policy text", + }); + const parsed = JSON.parse(result); + + expect(parsed.summary).toContain("Low risk seller"); + }); + }); + + describe("checkUrl", () => { + it("should delegate to analyze with sellerUrl", async () => { + fetchMock.mockResolvedValueOnce({ + ok: true, + json: async () => MOCK_LOW_RISK_RESPONSE, + }); + + const result = await provider.checkUrl({ + sellerUrl: "https://example-store.com", + }); + const parsed = JSON.parse(result); + + expect(parsed.success).toBe(true); + expect(parsed.analyzedUrl).toBe("https://example-store.com"); + + // Verify it called the A2A API with quick-risk-check skill + const [, options] = fetchMock.mock.calls[0]; + const body = JSON.parse(options.body); + expect(body.params.message.parts[0].data.skill).toBe("quick-risk-check"); + }); + }); +}); diff --git a/typescript/agentkit/src/action-providers/policycheck/policycheckActionProvider.ts b/typescript/agentkit/src/action-providers/policycheck/policycheckActionProvider.ts new file mode 100644 index 000000000..ad0719b23 --- /dev/null +++ b/typescript/agentkit/src/action-providers/policycheck/policycheckActionProvider.ts @@ -0,0 +1,203 @@ +import { z } from "zod"; +import { ActionProvider } from "../actionProvider"; +import { CreateAction } from "../actionDecorator"; +import { PolicyCheckAnalyzeSchema, PolicyCheckUrlSchema } from "./schemas"; + +const POLICYCHECK_A2A_URL = "https://legaleasy.tools/api/a2a"; + +/** + * Configuration options for the PolicyCheck action provider. + */ +export interface PolicyCheckConfig { + /** + * Override the default PolicyCheck API URL. + */ + apiUrl?: string; +} + +/** + * PolicyCheckActionProvider enables AI agents to verify e-commerce seller policies + * before making purchases. It analyzes return policies, shipping terms, warranty + * coverage, and terms of service to assess buyer protection and risk levels. + * + * This is a walletless action provider — no wallet is required. + */ +export class PolicyCheckActionProvider extends ActionProvider { + private readonly apiUrl: string; + + /** + * Constructs a new PolicyCheckActionProvider. + * + * @param config - Optional configuration. + */ + constructor(config?: PolicyCheckConfig) { + super("policycheck", []); + this.apiUrl = config?.apiUrl || POLICYCHECK_A2A_URL; + } + + /** + * Analyze seller policies to assess buyer protection before a purchase. + * + * @param args - The input arguments (policyText and/or sellerUrl). + * @returns A string containing the risk assessment with score, findings, and recommendation. + */ + @CreateAction({ + name: "policycheck_analyze", + description: `Analyze an e-commerce seller's policies to assess buyer protection risk BEFORE making a purchase. Returns a risk level (low/medium/high/critical), buyer protection score (0-100), key findings about return policy, shipping, warranty, and terms, and a recommendation on whether to proceed. + +Use this action whenever an agent is about to complete a purchase from an online store. Provide either the full policy text or the seller's URL. + +Inputs: +- policyText: The full text of the seller's policy to analyze. Provide this OR sellerUrl. +- sellerUrl: The URL of the e-commerce store. The service will find and analyze policies automatically. Provide this OR policyText. + +Example risk factors detected: +- No return policy or very short return windows +- Binding arbitration clauses that waive right to class action +- Liability caps that limit seller responsibility +- Missing warranty information +- Restocking fees or buyer-pays-return-shipping policies + +Important: If the buyer protection score is below 50, recommend the user reconsider the purchase.`, + schema: PolicyCheckAnalyzeSchema, + }) + async analyze(args: z.infer): Promise { + try { + // Build A2A message parts based on input type + const parts: Array> = []; + + if (args.sellerUrl) { + parts.push({ + kind: "data", + data: { seller_url: args.sellerUrl, skill: "quick-risk-check" }, + mimeType: "application/json", + }); + parts.push({ + kind: "text", + text: `Quick risk check on ${args.sellerUrl}`, + }); + } else if (args.policyText) { + parts.push({ + kind: "text", + text: args.policyText, + }); + } + + const response = await fetch(this.apiUrl, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + jsonrpc: "2.0", + method: "message/send", + params: { + message: { + role: "user", + parts, + }, + }, + id: Date.now().toString(), + }), + }); + + if (!response.ok) { + return JSON.stringify({ + success: false, + error: `PolicyCheck API returned HTTP ${response.status}`, + }); + } + + const data = await response.json(); + + if (data.error) { + return JSON.stringify({ + success: false, + error: data.error.message || "PolicyCheck analysis failed", + }); + } + + // Extract analysis from A2A response artifacts + const result = data.result; + const artifacts = result?.artifacts || []; + let analysisData: Record | null = null; + let summaryText = ""; + + for (const artifact of artifacts) { + for (const part of artifact.parts || []) { + if (part.kind === "data" && part.data) { + analysisData = part.data; + } else if (part.kind === "text" && part.text) { + summaryText = part.text; + } + } + } + + if (analysisData) { + return JSON.stringify({ + success: true, + riskLevel: analysisData.riskLevel, + buyerProtectionScore: analysisData.buyerProtectionScore, + keyFindings: analysisData.keyFindings, + recommendation: analysisData.recommendation, + summary: summaryText || undefined, + analyzedUrl: args.sellerUrl || "direct text analysis", + }); + } + + // Fallback: return text summary if no structured data + if (summaryText) { + return JSON.stringify({ + success: true, + summary: summaryText, + analyzedUrl: args.sellerUrl || "direct text analysis", + }); + } + + return JSON.stringify({ + success: false, + error: "No analysis data returned from PolicyCheck", + }); + } catch (error) { + return JSON.stringify({ + success: false, + error: `PolicyCheck request failed: ${error instanceof Error ? error.message : String(error)}`, + }); + } + } + + /** + * Quick URL-based seller check. + * + * @param args - The seller URL to check. + * @returns A string containing the risk assessment. + */ + @CreateAction({ + name: "policycheck_check_url", + description: `Quick check of an e-commerce seller's URL to assess buyer protection before purchasing. Provide the store URL and the service will find and analyze the seller's policies automatically. Returns risk level, buyer protection score, and key findings. + +Use this as a fast pre-purchase verification step when you have a seller's URL. + +Inputs: +- sellerUrl: The URL of the e-commerce store to check (e.g., 'https://example-store.com').`, + schema: PolicyCheckUrlSchema, + }) + async checkUrl(args: z.infer): Promise { + return this.analyze({ sellerUrl: args.sellerUrl }); + } + + /** + * Checks if this provider supports the given network. + * PolicyCheck is walletless and works on all networks. + * + * @returns Always true. + */ + supportsNetwork = () => true; +} + +/** + * Factory function to create a PolicyCheckActionProvider instance. + * + * @param config - Optional configuration. + * @returns A new PolicyCheckActionProvider instance. + */ +export const policycheckActionProvider = (config?: PolicyCheckConfig) => + new PolicyCheckActionProvider(config); diff --git a/typescript/agentkit/src/action-providers/policycheck/schemas.ts b/typescript/agentkit/src/action-providers/policycheck/schemas.ts new file mode 100644 index 000000000..d94f3f347 --- /dev/null +++ b/typescript/agentkit/src/action-providers/policycheck/schemas.ts @@ -0,0 +1,37 @@ +import { z } from "zod"; + +/** + * Input schema for analyzing seller policies. + */ +export const PolicyCheckAnalyzeSchema = z + .object({ + policyText: z + .string() + .optional() + .describe( + "The full text of the seller's return policy, shipping policy, warranty, or terms of service to analyze. Provide this OR sellerUrl.", + ), + sellerUrl: z + .string() + .optional() + .describe( + "The URL of the e-commerce store to check (e.g., 'https://example-store.com'). The service will find and analyze the seller's policies automatically. Provide this OR policyText.", + ), + }) + .strict() + .refine(data => data.policyText || data.sellerUrl, { + message: "Either policyText or sellerUrl must be provided", + }); + +/** + * Input schema for quick URL-based seller check. + */ +export const PolicyCheckUrlSchema = z + .object({ + sellerUrl: z + .string() + .describe( + "The URL of the e-commerce store to check (e.g., 'https://example-store.com'). The service will find and analyze the seller's policies automatically.", + ), + }) + .strict(); From 2aedca855922f96e2a37c02bfce2e6fb8a992bd0 Mon Sep 17 00:00:00 2001 From: vibegpt Date: Fri, 13 Feb 2026 17:44:24 +0200 Subject: [PATCH 2/2] feat(agentkit): Add PolicyCheck action provider for seller policy risk intelligence Walletless action provider with two actions (policycheck_analyze, policycheck_check_url) that call the PolicyCheck A2A API at policycheck.tools. Returns risk levels, buyer protection scores, key findings, and factual summaries. Co-Authored-By: Claude Opus 4.6 --- .../policycheckActionProvider.test.ts | 18 ++++----- .../policycheck/policycheckActionProvider.ts | 39 +++++++++---------- 2 files changed, 28 insertions(+), 29 deletions(-) diff --git a/typescript/agentkit/src/action-providers/policycheck/policycheckActionProvider.test.ts b/typescript/agentkit/src/action-providers/policycheck/policycheckActionProvider.test.ts index a9166aea9..37be30534 100644 --- a/typescript/agentkit/src/action-providers/policycheck/policycheckActionProvider.test.ts +++ b/typescript/agentkit/src/action-providers/policycheck/policycheckActionProvider.test.ts @@ -22,13 +22,13 @@ const MOCK_LOW_RISK_RESPONSE = { "1-year manufacturer warranty included", "Full refund to original payment method", ], - recommendation: "proceed", + summary: "Strong buyer protections detected. 30-day return window, free return shipping, 1-year manufacturer warranty.", }, mimeType: "application/json", }, { kind: "text", - text: "Low risk seller. Buyer protections are strong with a 30-day return window and free returns.", + text: "Strong buyer protections across all policy categories. 30-day return window, free return shipping, 1-year warranty.", }, ], }, @@ -58,13 +58,13 @@ const MOCK_HIGH_RISK_RESPONSE = { "Binding arbitration clause detected", "Liability cap limits seller responsibility to purchase price", ], - recommendation: "caution", + summary: "High risk indicators detected. 3 of 5 policy categories flagged. Binding arbitration limits dispute resolution. No return policy found.", }, mimeType: "application/json", }, { kind: "text", - text: "High risk seller. Consider purchasing from a different merchant.", + text: "High risk indicators detected. 3 of 5 policy categories flagged. Binding arbitration limits dispute resolution.", }, ], }, @@ -96,7 +96,7 @@ describe("PolicyCheckActionProvider", () => { describe("constructor", () => { it("should use default API URL when no config provided", () => { const p = policycheckActionProvider(); - expect(p["apiUrl"]).toBe("https://legaleasy.tools/api/a2a"); + expect(p["apiUrl"]).toBe("https://policycheck.tools/api/a2a"); }); it("should use custom API URL from config", () => { @@ -128,7 +128,7 @@ describe("PolicyCheckActionProvider", () => { expect(parsed.success).toBe(true); expect(parsed.riskLevel).toBe("low"); expect(parsed.buyerProtectionScore).toBe(85); - expect(parsed.recommendation).toBe("proceed"); + expect(parsed.summary).toContain("Strong buyer protections"); expect(parsed.keyFindings).toHaveLength(3); expect(parsed.analyzedUrl).toBe("direct text analysis"); }); @@ -147,7 +147,7 @@ describe("PolicyCheckActionProvider", () => { expect(parsed.success).toBe(true); expect(parsed.riskLevel).toBe("high"); expect(parsed.buyerProtectionScore).toBe(25); - expect(parsed.recommendation).toBe("caution"); + expect(parsed.summary).toContain("High risk indicators"); }); it("should send seller URL as data part with quick-risk-check skill", async () => { @@ -162,7 +162,7 @@ describe("PolicyCheckActionProvider", () => { expect(fetchMock).toHaveBeenCalledTimes(1); const [url, options] = fetchMock.mock.calls[0]; - expect(url).toBe("https://legaleasy.tools/api/a2a"); + expect(url).toBe("https://policycheck.tools/api/a2a"); const body = JSON.parse(options.body); expect(body.method).toBe("message/send"); @@ -268,7 +268,7 @@ describe("PolicyCheckActionProvider", () => { }); const parsed = JSON.parse(result); - expect(parsed.summary).toContain("Low risk seller"); + expect(parsed.summary).toContain("Strong buyer protections"); }); }); diff --git a/typescript/agentkit/src/action-providers/policycheck/policycheckActionProvider.ts b/typescript/agentkit/src/action-providers/policycheck/policycheckActionProvider.ts index ad0719b23..77b84a4aa 100644 --- a/typescript/agentkit/src/action-providers/policycheck/policycheckActionProvider.ts +++ b/typescript/agentkit/src/action-providers/policycheck/policycheckActionProvider.ts @@ -3,7 +3,7 @@ import { ActionProvider } from "../actionProvider"; import { CreateAction } from "../actionDecorator"; import { PolicyCheckAnalyzeSchema, PolicyCheckUrlSchema } from "./schemas"; -const POLICYCHECK_A2A_URL = "https://legaleasy.tools/api/a2a"; +const POLICYCHECK_A2A_URL = "https://policycheck.tools/api/a2a"; /** * Configuration options for the PolicyCheck action provider. @@ -16,9 +16,13 @@ export interface PolicyCheckConfig { } /** - * PolicyCheckActionProvider enables AI agents to verify e-commerce seller policies - * before making purchases. It analyzes return policies, shipping terms, warranty - * coverage, and terms of service to assess buyer protection and risk levels. + * PolicyCheckActionProvider provides seller policy risk intelligence for AI agents + * involved in e-commerce. It analyzes return policies, shipping terms, warranty + * coverage, and terms of service to produce risk data including risk level + * classifications, buyer protection scores, and key findings. + * + * The agent should use this data alongside other context (purchase amount, buyer + * risk tolerance, item category) to make its own purchase decisions. * * This is a walletless action provider — no wallet is required. */ @@ -36,29 +40,27 @@ export class PolicyCheckActionProvider extends ActionProvider { } /** - * Analyze seller policies to assess buyer protection before a purchase. + * Get seller policy risk data to inform purchase decisions. * * @param args - The input arguments (policyText and/or sellerUrl). - * @returns A string containing the risk assessment with score, findings, and recommendation. + * @returns A string containing the risk data with scores, findings, and factual summary. */ @CreateAction({ name: "policycheck_analyze", - description: `Analyze an e-commerce seller's policies to assess buyer protection risk BEFORE making a purchase. Returns a risk level (low/medium/high/critical), buyer protection score (0-100), key findings about return policy, shipping, warranty, and terms, and a recommendation on whether to proceed. - -Use this action whenever an agent is about to complete a purchase from an online store. Provide either the full policy text or the seller's URL. + description: `Get seller policy risk data to inform purchase decisions. Analyzes return policies, shipping terms, warranty coverage, and terms of service. Returns risk level (low/medium/high/critical), buyer protection score (0-100), key findings about specific policy issues, and a factual summary. The agent should use this data alongside other context (purchase amount, buyer risk tolerance, item category) to make its own purchase decision. Inputs: - policyText: The full text of the seller's policy to analyze. Provide this OR sellerUrl. - sellerUrl: The URL of the e-commerce store. The service will find and analyze policies automatically. Provide this OR policyText. -Example risk factors detected: -- No return policy or very short return windows -- Binding arbitration clauses that waive right to class action -- Liability caps that limit seller responsibility +Risk factors detected include: +- Missing or restrictive return policies +- Binding arbitration clauses affecting dispute resolution options +- Liability caps limiting seller responsibility - Missing warranty information -- Restocking fees or buyer-pays-return-shipping policies +- Restocking fees or buyer-pays-return-shipping terms -Important: If the buyer protection score is below 50, recommend the user reconsider the purchase.`, +A buyer protection score below 50 indicates limited policy protections. Binding arbitration clauses affect dispute resolution options. Missing return policies are notable risk factors.`, schema: PolicyCheckAnalyzeSchema, }) async analyze(args: z.infer): Promise { @@ -137,8 +139,7 @@ Important: If the buyer protection score is below 50, recommend the user reconsi riskLevel: analysisData.riskLevel, buyerProtectionScore: analysisData.buyerProtectionScore, keyFindings: analysisData.keyFindings, - recommendation: analysisData.recommendation, - summary: summaryText || undefined, + summary: (analysisData.summary as string) || summaryText || undefined, analyzedUrl: args.sellerUrl || "direct text analysis", }); } @@ -172,9 +173,7 @@ Important: If the buyer protection score is below 50, recommend the user reconsi */ @CreateAction({ name: "policycheck_check_url", - description: `Quick check of an e-commerce seller's URL to assess buyer protection before purchasing. Provide the store URL and the service will find and analyze the seller's policies automatically. Returns risk level, buyer protection score, and key findings. - -Use this as a fast pre-purchase verification step when you have a seller's URL. + description: `Quick seller policy risk check by URL. Provide the store URL and the service will find and analyze the seller's policies automatically. Returns risk level, buyer protection score, key findings, and a factual summary. Inputs: - sellerUrl: The URL of the e-commerce store to check (e.g., 'https://example-store.com').`,