AkurAI Build
Menu

popagent

public

Latest change 6edc7e928c57dab23c0973ed3f7ee70b3ebb72d5 - Initial popagent baseline by AkurAI Build

import { createTool } from "@mastra/core/tools";
import { z } from "zod";
import { secrets } from "../secrets";

const name = z.string()
  .min(1)
  .max(128)
  .regex(/^[a-zA-Z0-9][a-zA-Z0-9._/-]*$/, "Use letters, digits, dots, slashes, underscores, or hyphens");
const value = z.string().min(1).max(32_768);

function resourceId(context: { requestContext?: { get(key: string): unknown } }) {
  const id = context.requestContext?.get("popagent.resourceId");
  if (typeof id !== "string" || !id) throw new Error("Secret context is unavailable");
  return id;
}

export const storeSecret = createTool({
  id: "store-secret",
  description: "Securely store a new secret for the current user. The value is encrypted before database storage. Never use this to replace an existing secret; use update-secret instead.",
  inputSchema: z.object({ name, value }),
  outputSchema: z.object({ stored: z.literal(true), name }),
  execute: async ({ name, value }, context) => {
    if (!await secrets.store(resourceId(context), name, value)) {
      throw new Error(`Secret ${name} already exists; use update-secret`);
    }
    return { stored: true as const, name };
  },
});

export const recallSecret = createTool({
  id: "recall-secret",
  description: "Recall one secret by its exact name for the current user. Use only when the secret value is required to complete the user's request, and never repeat the value unless the user explicitly asks to see it.",
  inputSchema: z.object({ name }),
  outputSchema: z.object({ name, value }),
  execute: async ({ name }, context) => {
    const secret = await secrets.recall(resourceId(context), name);
    if (secret === undefined) throw new Error(`Secret ${name} was not found`);
    return { name, value: secret };
  },
});

export const updateSecret = createTool({
  id: "update-secret",
  description: "Replace the value of an existing secret for the current user. The new value is encrypted before database storage.",
  inputSchema: z.object({ name, value }),
  outputSchema: z.object({ updated: z.literal(true), name }),
  execute: async ({ name, value }, context) => {
    if (!await secrets.update(resourceId(context), name, value)) {
      throw new Error(`Secret ${name} was not found; use store-secret`);
    }
    return { updated: true as const, name };
  },
});