Prompt: This is a JavaScript code from the AO documentation repository. Filename: config.js Path: ../ao-cookbook/src/.vitepress/config.js

Response:
import { defineConfig } from "vitepress";

import { languages } from "../../languages/def.js";
import { localeConfig } from "./locales.js";

// https://vitepress.dev/reference/site-config
const config = defineConfig({
  themeConfig: {
    /**
     * Enable Search
     */
    search: {
      provider: "local",
    },
  },
  head: [
    ["meta", { name: "apple-mobile-web-app-capable", content: "yes" }],
    [
      "meta",
      {
        name: "apple-mobile-web-app-status-bar-style",
        content: "black",
      },
    ],
    [
      "link",
      {
        rel: "icon",
        type: "image/svg+xml",
        href: "/ao_pictograph_lightmode.svg",
      },
    ],
    ["link", { rel: "preconnect", href: "https://fonts.googleapis.com" }],
    ["link", { rel: "preconnect", href: "https://fonts.gstatic.com" }],
    [
      "link",
      {
        rel: "stylesheet",
        href: "https://fonts.googleapis.com/css2?family=Inter:wght@100;200;300;400;500;600&display=swap",
      },
    ],
  ],

  markdown: {
    lineNumbers: false,
  },

  /**
   * The copy that comprises the layout and theme of the site
   * must also be internationalized, so we create a locale configuration
   * for each language we support
   *
   * See https://vitepress.dev/guide/i18n#internationalization
   */
  locales: languages.reduce(
    (locales, { code }) => {
      locales[code] = localeConfig(code);
      return locales;
    },
    { root: localeConfig("en") },
  ),

  transformPageData: (pageData) => {
    return {
      i18n: languages[pageData.frontmatter.locale || "en"],
    };
  },
  /**
   * Needed for shim for
   */
  vite: {
    build: {
      rollupOptions: {
        output: {
          chunkFileNames: "assets/chunks/[name].js",
        },
      },
    },
  },
});

export default config;


Prompt:
This is a JavaScript code from the AO documentation repository. Filename: locales.js Path: ../ao-cookbook/src/.vitepress/locales.js
Note: This content continues in the next part.

Response:
import { get_i18n_str } from "../../languages/def.js";

const get_i18n_link = (code, link) =>
  `${code === "en" ? "" : "/" + code}${link}`;

/**
 * @type {import('vitepress').LocaleSpecificConfig<import('vitepress').DefaultTheme.Config>}
 */
export const localeConfig = (langCode) => ({
  label: get_i18n_str(langCode, "label"),
  lang: get_i18n_str(langCode, "lang"),
  title: get_i18n_str(langCode, "title"),
  description: get_i18n_str(langCode, "description"),
  themeConfig: {
    logo: {
      light: { src: "/ao_pictograph_lightmode.svg", height: 26, width: 26 },
      dark: { src: "/ao_pictograph_darkmode.svg", height: 26, width: 26 },
    },
    socialLinks: [
      { icon: "discord", link: "https://discord.gg/qWgGxJKwNJ" },
      { icon: "github", link: "https://github.com/permaweb/ao-cookbook" },
    ],
    nav: [
      {
        text: get_i18n_str(langCode, "docs"),
        link: get_i18n_link(langCode, "/welcome/index"),
      },
      {
        text: "LLMs.txt",
        link: get_i18n_link(langCode, "/llms-explanation"),
      },
    ],
    sidebar: [
      {
        text: get_i18n_str(langCode, "mainnet"),
        link: get_i18n_link(langCode, "/mainnet/index"),
        items: [
          {
            text: get_i18n_str(langCode, "mainnet-ao-core-relay"),
            link: get_i18n_link(langCode, "/mainnet/ao-core-relay"),
          },
        ],
      },
      {
        text: get_i18n_str(langCode, "welcome"),
        link: get_i18n_link(langCode, "/welcome/index"),
        items: [
          {
            text: get_i18n_str(langCode, "welcome-getting-started"),
            link: get_i18n_link(langCode, "/welcome/getting-started"),
          },
          {
            text: get_i18n_str(langCode, "welcome-legacynet-info"),
            link: get_i18n_link(langCode, "/welcome/legacynet-info/index"),
            items: [],
          },
        ],
      },
      {
        text: get_i18n_str(langCode, "tutorials"),
        link: get_i18n_link(langCode, "/tutorials/index"),
        items: [
          {
            text: get_i18n_str(langCode, "tutorials-begin"),
            link: get_i18n_link(langCode, "/tutorials/begin/index"),
            collapsed: true,
            items: [
              {
                text: get_i18n_str(langCode, "tutorials-begin-preparations"),
                link: get_i18n_link(langCode, "/tutorials/begin/preparations"),
              },
              {
                text: get_i18n_str(langCode, "tutorials-begin-messaging"),
                link: get_i18n_link(langCode, "/tutorials/begin/messaging"),
              },
              {
                text: get_i18n_str(langCode, "tutorials-begin-chatroom"),
                link: get_i18n_link(langCode, "/tutorials/begin/chatroom"),
              },
              {
                text: get_i18n_str(langCode, "tutorials-begin-token"),
                link: get_i18n_link(langCode, "/tutorials/begin/token"),
              },
              {
                text: get_i18n_str(langCode, "tutorials-begin-tokengating"),
                link: get_i18n_link(langCode, "/tutorials/begin/tokengating"),
              },
              {
                text: get_i18n_str(langCode, "tutorials-begin-dao"),
                link: get_i18n_link(langCode, "/tutorials/begin/dao"),
              },
            ],
          },
          {
            text: get_i18n_str(langCode, "tutorials-bots-and-games"),
            link: get_i18n_link(langCode, "/tutorials/bots-and-games/index"),
            collapsed: true,
            items: [
              {
                text: get_i18n_str(
                  langCode,
                  "tutorials-bots-and-games-ao-effect",
                ),
                link: get_i18n_link(
                  langCode,
                  "/tutorials/bots-and-games/ao-effect",
                ),
              },
              {
                text: get_i18n_str(
                  langCode,
                  "tutorials-bots-and-games-announcements",
                ),
                link: get_i18n_link(
                  langCode,
                  "/tutorials/bots-and-games/announcements",
                ),
              },
              {
                text: get_i18n_str(
                  langCode,
                  "tutorials-bots-and-games-game-state",
                ),
                link: get_i18n_link(
                  langCode,
                  "/tutorials/bots-and-games/game-state",
                ),
              },
              {
                text: get_i18n_str(
                  langCode,
                  "tutorials-bots-and-games-decisions",
                ),
                link: get_i18n_link(
                  langCode,
                  "/tutorials/bots-and-games/decisions",
                ),
              },
              {
                text: get_i18n_str(
                  langCode,
                  "tutorials-bots-and-games-attacking",
                ),
                link: get_i18n_link(
                  langCode,
                  "/tutorials/bots-and-games/attacking",
                ),
              },
              {
                text: get_i18n_str(
                  langCode,
                  "tutorials-bots-and-games-bringing-together",
                ),
                link: get_i18n_link(
                  langCode,
                  "/tutorials/bots-and-games/bringing-together",
                ),
              },
              {
                text: get_i18n_str(
                  langCode,
                  "tutorials-bots-and-games-arena-mechanics",
                ),
                link: get_i18n_link(
                  langCode,
                  "/tutorials/bots-and-games/arena-mechanics",
                ),
              },
              {
                text: get_i18n_str(
                  langCode,
                  "tutorials-bots-and-games-build-game",
                ),
                link: get_i18n_link(
                  langCode,
                  "/tutorials/bots-and-games/build-game",
                ),
              },
            ],
          },
        ],
      },
      {
        text: get_i18n_str(langCode, "guides"),
        link: get_i18n_link(langCode, "/guides/index"),
        items: [
          {
            text: get_i18n_str(langCode, "guides-aos"),
            link: get_i18n_link(langCode, "/guides/aos/index"),
            collapsed: true,
            items: [
              {
                text: get_i18n_str(langCode, "guides-aos-intro"),
                link: get_i18n_link(langCode, "/guides/aos/intro"),
              },
              {
                text: get_i18n_str(langCode, "guides-aos-installing"),
                link: get_i18n_link(langCode, "/guides/aos/installing"),
              },
              {
                text: get_i18n_str(langCode, "guides-aos-cli"),
                link: get_i18n_link(langCode, "/guides/aos/cli"),
              },
              {
                text: get_i18n_str(langCode, "guides-aos-prompt"),
                link: get_i18n_link(langCode, "/guides/aos/prompt"),
              },
              {
                text: get_i18n_str(langCode, "guides-aos-load"),
                link: get_i18n_link(langCode, "/guides/aos/load"),
              },
              {
                text: get_i18n_str(langCode, "guides-aos-pingpong"),
                link: get_i18n_link(langCode, "/guides/aos/pingpong"),
              },
              {
                text: get_i18n_str(langCode, "guides-aos-editor"),
                link: get_i18n_link(langCode, "/guides/aos/editor"),
              },
              {
                text: get_i18n_str(langCode, "guides-aos-inbox-and-handlers"),
                link: get_i18n_link(langCode, "/guides/aos/inbox-and-handlers"),
              },
              {
                text: get_i18n_str(langCode, "guides-aos-troubleshooting"),
                link: get_i18n_link(langCode, "/guides/aos/troubleshooting"),
              },
              {
                text: get_i18n_str(langCode, "guides-aos-faq"),
                link: get_i18n_link(langCode, "/guides/aos/faq"),
              },
              {
                text: get_i18n_str(langCode, "guides-aos-token"),
                link: get_i18n_link(langCode, "/guides/aos/token"),
              },
              {
                text: get_i18n_str(langCode, "guides-aos-blueprints"),
                link: get_i18n_link(langCode, "/guides/aos/blueprints/index"),
                collapsed: true,
                items: [
                  {
                    text: get_i18n_str(
                      langCode,
                      "guides-aos-blueprints-chatroom",
                    ),
                    link: get_i18n_link(
                      langCode,
                      "/guides/aos/blueprints


Prompt:
This is a JavaScript code from the AO documentation repository. This is a continuation from the previous part. Filename: locales.js Path: ../ao-cookbook/src/.vitepress/locales.js
Note: This content continues in the next part.

Response:
-aos-troubleshooting"),
                link: get_i18n_link(langCode, "/guides/aos/troubleshooting"),
              },
              {
                text: get_i18n_str(langCode, "guides-aos-faq"),
                link: get_i18n_link(langCode, "/guides/aos/faq"),
              },
              {
                text: get_i18n_str(langCode, "guides-aos-token"),
                link: get_i18n_link(langCode, "/guides/aos/token"),
              },
              {
                text: get_i18n_str(langCode, "guides-aos-blueprints"),
                link: get_i18n_link(langCode, "/guides/aos/blueprints/index"),
                collapsed: true,
                items: [
                  {
                    text: get_i18n_str(
                      langCode,
                      "guides-aos-blueprints-chatroom",
                    ),
                    link: get_i18n_link(
                      langCode,
                      "/guides/aos/blueprints/chatroom",
                    ),
                  },
                  {
                    text: get_i18n_str(
                      langCode,
                      "guides-aos-blueprints-cred-utils",
                    ),
                    link: get_i18n_link(
                      langCode,
                      "/guides/aos/blueprints/cred-utils",
                    ),
                  },
                  {
                    text: get_i18n_str(
                      langCode,
                      "guides-aos-blueprints-staking",
                    ),
                    link: get_i18n_link(
                      langCode,
                      "/guides/aos/blueprints/staking",
                    ),
                  },
                  {
                    text: get_i18n_str(langCode, "guides-aos-blueprints-token"),
                    link: get_i18n_link(
                      langCode,
                      "/guides/aos/blueprints/token",
                    ),
                  },
                  {
                    text: get_i18n_str(
                      langCode,
                      "guides-aos-blueprints-voting",
                    ),
                    link: get_i18n_link(
                      langCode,
                      "/guides/aos/blueprints/voting",
                    ),
                  },
                ],
              },
              {
                text: get_i18n_str(langCode, "guides-aos-modules"),
                link: get_i18n_link(langCode, "/guides/aos/modules/index"),
                collapsed: true,
                items: [
                  {
                    text: get_i18n_str(langCode, "guides-aos-modules-json"),
                    link: get_i18n_link(langCode, "/guides/aos/modules/json"),
                  },
                  {
                    text: get_i18n_str(langCode, "guides-aos-modules-ao"),
                    link: get_i18n_link(langCode, "/guides/aos/modules/ao"),
                  },
                  {
                    text: get_i18n_str(langCode, "guides-aos-modules-crypto"),
                    link: get_i18n_link(langCode, "/guides/aos/modules/crypto"),
                  },
                  {
                    text: get_i18n_str(langCode, "guides-aos-modules-base64"),
                    link: get_i18n_link(langCode, "/guides/aos/modules/base64"),
                  },
                  {
                    text: get_i18n_str(langCode, "guides-aos-modules-pretty"),
                    link: get_i18n_link(langCode, "/guides/aos/modules/pretty"),
                  },
                  {
                    text: get_i18n_str(langCode, "guides-aos-modules-utils"),
                    link: get_i18n_link(langCode, "/guides/aos/modules/utils"),
                  },
                ],
              },
            ],
          },
          {
            text: get_i18n_str(langCode, "guides-aoconnect"),
            link: get_i18n_link(langCode, "/guides/aoconnect/aoconnect"),
            collapsed: true,
            items: [
              {
                text: get_i18n_str(langCode, "guides-installing-connect"),
                link: get_i18n_link(
                  langCode,
                  "/guides/aoconnect/installing-connect",
                ),
              },
              {
                text: get_i18n_str(langCode, "guides-connecting"),
                link: get_i18n_link(langCode, "/guides/aoconnect/connecting"),
              },
              {
                text: get_i18n_str(langCode, "guides-sending-messages"),
                link: get_i18n_link(
                  langCode,
                  "/guides/aoconnect/sending-messages",
                ),
              },
              {
                text: get_i18n_str(langCode, "guides-reading-results"),
                link: get_i18n_link(
                  langCode,
                  "/guides/aoconnect/reading-results",
                ),
              },
              {
                text: get_i18n_str(langCode, "guides-spawning-processes"),
                link: get_i18n_link(
                  langCode,
                  "/guides/aoconnect/spawning-processes",
                ),
              },
              {
                text: get_i18n_str(langCode, "guides-calling-dryrun"),
                link: get_i18n_link(
                  langCode,
                  "/guides/aoconnect/calling-dryrun",
                ),
              },
              {
                text: get_i18n_str(langCode, "guides-monitoring-cron"),
                link: get_i18n_link(
                  langCode,
                  "/guides/aoconnect/monitoring-cron",
                ),
              },
              {
                text: get_i18n_str(langCode, "guides-assign-data"),
                link: get_i18n_link(langCode, "/guides/aoconnect/assign-data"),
              },
              {
                text: get_i18n_str(langCode, "guides-signers"),
                link: get_i18n_link(langCode, "/guides/aoconnect/signers"),
              },
            ],
          },
          {
            text: "Additional Technologies",
            collapsed: true,
            items: [
              {
                text: get_i18n_str(langCode, "guides-dev-cli"),
                link: get_i18n_link(langCode, "/guides/dev-cli/index"),
              },
              {
                text: get_i18n_str(langCode, "guides-sqlite"),
                link: get_i18n_link(langCode, "/guides/snacks/sqlite"),
              },
              {
                text: get_i18n_str(langCode, "guides-weavedrive"),
                link: get_i18n_link(langCode, "/guides/snacks/weavedrive"),
              },
              {
                text: get_i18n_str(langCode, "guides-0rbit"),
                link: get_i18n_link(langCode, "/guides/snacks/0rbit/index"),
                collapsed: true,
                items: [
                  {
                    text: get_i18n_str(langCode, "guides-0rbit-get-request"),
                    link: get_i18n_link(
                      langCode,
                      "/guides/snacks/0rbit/get-request",
                    ),
                  },
                  {
                    text: get_i18n_str(langCode, "guides-0rbit-post-request"),
                    link: get_i18n_link(
                      langCode,
                      "/guides/snacks/0rbit/post-request",
                    ),
                  },
                ],
              },
            ],
          },
        ],
      },
      {
        text: get_i18n_str(langCode, "concepts"),
        link: get_i18n_link(langCode, "/concepts/index"),
        items: [
          {
            text: "AO System Architecture",
            collapsed: true,
            items: [
              {
                text: get_i18n_str(langCode, "concepts-how-it-works"),
                link: get_i18n_link(langCode, "/concepts/how-it-works"),
              },
              {
                text: get_i18n_str(langCode, "concepts-processes"),
                link: get_i18n_link(langCode, "/concepts/processes"),
              },
              {
                text: get_i18n_str(langCode, "concepts-messages"),
                link: get_i18n_link(langCode, "/concepts/messages"),
              },
              {
                text: get_i18n_str(langCode, "concepts-eval"),
                link: get_i18n_link(langCode, "/concepts/eval"),
              },
              {
                text: get_i18n_str(langCode, "concepts-units"),
                link: get_i18n_link(langCode, "/concepts/units"),
              },
              {
                text: get_i18n_str(langCode, "concepts-specs"),
                link: get_i18n_link(langCode, "/concepts/specs"),
              },
            ],
          },
          {
            text: "Programming Environment",
            collapsed: true,
            items: [
              {
                text: get_i18n_str(langCode, "concepts-tour"),
                link: get_i18n_link(langCode, "/concepts/tour"),
              },
              {
                text: get_i18n_str(langCode, "concepts-meet-lua"),
                link: get_i18n_link(langCode, "/concepts/lua"),
              },
            ],
          },
        ],
      },
      {
        text: get_i18n_str(langCode, "references"),
        link: get_i18n_link(langCode, "/references/index"),
        items: [
          {
            text: "Programming Languages",
            collapsed: true,
            items: [
              {
                text: get_i18n_str(langCode, "references-lua"),
                link: get_i18n_link(langCode, "/references/lua"),
              },
              {
                text: get_i18n_str(langCode, "references-wasm"),
                link: get_i18n_link(langCode, "/references/wasm"),
              },
              {
                text:


Prompt: This is a JavaScript code from the AO documentation repository. This is a continuation from the previous part. Filename: locales.js Path: ../ao-cookbook/src/.vitepress/locales.js

Response:
, "concepts-tour"),
                link: get_i18n_link(langCode, "/concepts/tour"),
              },
              {
                text: get_i18n_str(langCode, "concepts-meet-lua"),
                link: get_i18n_link(langCode, "/concepts/lua"),
              },
            ],
          },
        ],
      },
      {
        text: get_i18n_str(langCode, "references"),
        link: get_i18n_link(langCode, "/references/index"),
        items: [
          {
            text: "Programming Languages",
            collapsed: true,
            items: [
              {
                text: get_i18n_str(langCode, "references-lua"),
                link: get_i18n_link(langCode, "/references/lua"),
              },
              {
                text: get_i18n_str(langCode, "references-wasm"),
                link: get_i18n_link(langCode, "/references/wasm"),
              },
              {
                text: get_i18n_str(langCode, "references-lua-optimization"),
                link: get_i18n_link(langCode, "/references/lua-optimization"),
              },
            ],
          },
          {
            text: "AO API Reference",
            collapsed: true,
            items: [
              {
                text: get_i18n_str(langCode, "references-ao"),
                link: get_i18n_link(langCode, "/references/ao"),
              },
              {
                text: get_i18n_str(langCode, "references-messaging"),
                link: get_i18n_link(langCode, "/references/messaging"),
              },
              {
                text: get_i18n_str(langCode, "references-handlers"),
                link: get_i18n_link(langCode, "/references/handlers"),
              },
              {
                text: get_i18n_str(langCode, "references-token"),
                link: get_i18n_link(langCode, "/references/token"),
              },
              {
                text: get_i18n_str(langCode, "references-data"),
                link: get_i18n_link(langCode, "/references/data"),
              },
              {
                text: get_i18n_str(langCode, "references-cron"),
                link: get_i18n_link(langCode, "/references/cron"),
              },
            ],
          },
          {
            text: "Development Environment",
            collapsed: true,
            items: [
              {
                text: get_i18n_str(langCode, "references-editor-setup"),
                link: get_i18n_link(langCode, "/references/editor-setup"),
              },
              {
                text: get_i18n_str(langCode, "guides-betteridea"),
                link: get_i18n_link(langCode, "/references/betteridea/index"),
              },
            ],
          },
          {
            text: get_i18n_str(langCode, "references-community"),
            link: get_i18n_link(langCode, "/references/community"),
          },
          {
            text: get_i18n_str(langCode, "references-glossary"),
            link: get_i18n_link(langCode, "/references/glossary"),
          },
        ],
      },
      {
        text: get_i18n_str(langCode, "releasenotes"),
        link: get_i18n_link(langCode, "/releasenotes/index"),
        items: [],
      },
    ],
  },
});


Prompt: This is a JavaScript code from the AO documentation repository. Filename: index.js Path: ../ao-cookbook/src/.vitepress/theme/index.js

Response:
// https://vitepress.dev/guide/custom-theme

import { h } from "vue";
import DefaultTheme from "vitepress/theme-without-fonts";
import "./style.css";

/** @type {import('vitepress').Theme} */
export default {
  extends: DefaultTheme,
  Layout: () => {
    return h(DefaultTheme.Layout, null, {
      // https://vitepress.dev/guide/extending-default-theme#layout-slots
    });
  },
  enhanceApp({ app, router, siteData }) {
    /**
     * Original issue: https://github.com/permaweb/ao-cookbook/issues/17
     *
     * The path manifest for the site will contain mappings to index.html pages like
     * '/getting-started/index.html' 👍
     *
     * But the Vue Router seems to be tranparently removing the 'index.html'
     * bit from the url on navigation (presumably to make it 'prettier') eg:
     *
     * nav to '/getting-started/index.html' will work but then url will be
     * '/getting-started/' 👎
     *
     * This causes a subsequent refresh of the page to not be resolved by the Gateway --
     * the path manifest doesn't contain a mapping for it, so the Gateway reasonbly
     * returns a 404
     *
     * To get around ths, we use a Vue Router onAfterRouteChanged() lifecycle hook
     * to check if the url ends with a '/'. If it does, then we update the url to include 'index.html'.
     *
     * This way, on page refresh, the Gateway can correctly resolve the asset from the path manifest
     */
    router.onAfterRouteChanged = (to) => {
      /**
       * Should not run when building
       */
      if (import.meta.env.SSR) return;

      if (to.endsWith("/") && to !== "/") {
        history.replaceState({}, null, `${to}index.html`);
      }
    };
  },
};


Prompt: This is a CSS from the AO documentation repository. Filename: style.css Path: ../ao-cookbook/src/.vitepress/theme/style.css

Response:
/**
 * Customize default theme styling by overriding CSS variables:
 * https://github.com/vuejs/vitepress/blob/main/src/client/theme-default/styles/vars.css
 */

/**
 * Colors
 *
 * Each colors have exact same color scale system with 3 levels of solid
 * colors with different brightness, and 1 soft color.
 *
 * - `XXX-1`: The most solid color used mainly for colored text. It must
 *   satisfy the contrast ratio against when used on top of `XXX-soft`.
 *
 * - `XXX-2`: The color used mainly for hover state of the button.
 *
 * - `XXX-3`: The color for solid background, such as bg color of the button.
 *   It must satisfy the contrast ratio with pure white (#ffffff) text on
 *   top of it.
 *
 * - `XXX-soft`: The color used for subtle background such as custom container
 *   or badges. It must satisfy the contrast ratio when putting `XXX-1` colors
 *   on top of it.
 *
 *   The soft color must be semi transparent alpha channel. This is crucial
 *   because it allows adding multiple "soft" colors on top of each other
 *   to create a accent, such as when having inline code block inside
 *   custom containers.
 *
 * - `default`: The color used purely for subtle indication without any
 *   special meanings attched to it such as bg color for menu hover state.
 *
 * - `brand`: Used for primary brand colors, such as link text, button with
 *   brand theme, etc.
 *
 * - `tip`: Used to indicate useful information. The default theme uses the
 *   brand color for this by default.
 *
 * - `warning`: Used to indicate warning to the users. Used in custom
 *   container, badges, etc.
 *
 * - `danger`: Used to show error, or dangerous message to the users. Used
 *   in custom container, badges, etc.
 * -------------------------------------------------------------------------- */

:root {
  --vp-c-cyan-1: #3485b1;
  --vp-c-cyan-2: #3a98cc;
  --vp-c-cyan-3: #55a3cd;
  --vp-c-cyan-soft: rgba(99, 172, 255, 0.14);

  --vp-c-default-1: var(--vp-c-gray-1);
  --vp-c-default-2: var(--vp-c-gray-2);
  --vp-c-default-3: var(--vp-c-gray-3);
  --vp-c-default-soft: var(--vp-c-gray-soft);

  --vp-c-brand-1: var(--nav-background-color);
  --vp-c-brand-2: var(--accent-color);
  --vp-c-brand-3: var(--background-color);
  --vp-c-brand-soft: var(--table-accent-color);

  --vp-c-tip-1: var(--vp-c-brand-1);
  --vp-c-tip-2: var(--vp-c-brand-2);
  --vp-c-tip-3: var(--vp-c-brand-3);
  --vp-c-tip-soft: var(--vp-c-brand-soft);

  --vp-c-warning-1: var(--vp-c-yellow-1);
  --vp-c-warning-2: var(--vp-c-yellow-2);
  --vp-c-warning-3: var(--vp-c-yellow-3);
  --vp-c-warning-soft: var(--vp-c-yellow-soft);

  --vp-c-danger-1: var(--vp-c-red-1);
  --vp-c-danger-2: var(--vp-c-red-2);
  --vp-c-danger-3: var(--vp-c-red-3);
  --vp-c-danger-soft: var(--vp-c-red-soft);

  --nav-background-color: #a1a1a1;
  --background-color: #f2f2f2;
  --faded-accent-color: #0a0705;
  --table-accent-color: #feeee5;
  --accent-color: #e77b40;
  --slate-gray: slateGray;
}

/**
  * Component: Button
  * -------------------------------------------------------------------------- */

:root {
  --vp-button-brand-border: transparent;
  --vp-button-brand-text: #3c3c43;
  --vp-button-brand-bg: var(--vp-c-brand-3);
  --vp-button-brand-active-border: var(--vp-c-brand-2);
  --vp-button-brand-hover-text: var(--vp-c-brand-2);
  --vp-button-brand-hover-bg: var(--vp-c-brand-3);
  --vp-button-brand-hover-border: var(--vp-c-brand-2);
  --vp-button-brand-active-text: var(--vp-c-text-1);
  --vp-button-brand-active-bg: var(--vp-c-brand-3);
}

/**
  * Component: Home
  * -------------------------------------------------------------------------- */

:root {
  --vp-home-hero-name-color: transparent;
  --vp-home-hero-name-background: var(--vp-c-text-1);

  --vp-home-hero-image-background-image: linear-gradient(-45deg,
      #bd34fe 50%,
      #47caff 50%);
  --vp-home-hero-image-filter: blur(44px);
}

@media (min-width: 640px) {
  :root {
    --vp-home-hero-image-filter: blur(56px);
  }
}

@media (min-width: 960px) {
  :root {
    --vp-home-hero-image-filter: blur(68px);
  }
}

/**
  * Component: Custom Block
  * -------------------------------------------------------------------------- */

:root {
  --vp-custom-block-tip-border: transparent;
  --vp-custom-block-tip-text: var(--vp-c-text-1);
  --vp-custom-block-tip-bg: var(--vp-c-green-soft);
  --vp-custom-block-tip-code-bg: var(--vp-c-green-soft);

  --vp-custom-block-note-border: transparent;
  --vp-custom-block-note-text: var(--vp-c-text-1);
  --vp-custom-block-note-bg: var(--vp-c-cyan-soft);
  --vp-custom-block-note-code-bg: var(--vp-c-cyan-soft);
}

/**
  * Component: Algolia
  * -------------------------------------------------------------------------- */

.DocSearch {
  --docsearch-primary-color: var(--vp-c-brand-1) !important;
}


Prompt: This is a Markdown documentation from the AO documentation repository. Filename: ao-core-relay.md Path: ../ao-cookbook/src/mainnet/ao-core-relay.md

Response:
# AO Core Payment Relays

Mainnet AO Core is a foundational framework designed for developers to build decentralized, permanent applications on blockchain infrastructure. It provides tools and APIs to interact with the mainnet and manage onchain data efficiently. Phase 1 of Mainnet AO Core is processing payments, this is available today in relay mode via HyperBEAM nodes, which act as payment gateways to AO.

## Prerequisites

1. Install **Node.js** (version 20+ recommended).
2. Install **npm** or **yarn** for package management.

## Installation

Install the **Mainnet AO Core** and its CLI tool globally by running:

```bash
npm install -g https://get_ao.g8way.io
```

This will install the **AOS Console**, a command-line tool for managing and interacting with Mainnet AO Core.

## Usage

#### Using a relay

The AOS Console allows you to configure and use a relay for sending messages through Mainnet AO Core.

To use a relay, use the following command in the AOS Console:

```bash
aos <name or process_id> --wallet <path_to_wallet> --relay <relay_url>
```

Replace:

- `<name or process_id>`: A human-readable name for the new process you want to spawn, or an existing process ID that you want to connect to.
- `<path_to_wallet>`: Path to the wallet that owns or will own this process.
- `<relay_url>`: The URL of your relay node (e.g., `http://relay.ao-hb.xyz`).

#### Payments

Relays will charge for usage of the node. If you are attempting to access a node that does not hold funds transferred from you, then you will be prompted to top up before continuing.

When you access AOS in relay mode, `--relay <relay_url>` you will be able to see the associated wallet address. If this wallet address does not hold any of the tokens needed to access this node (by default AO), you will have to transfer some to them. Only a small amount is needed to send messages through the relayer.

1. Transfer some AO (0.0000001 is enough) to the wallet that you will use in AOS.

   - `Send({ Target = AO_TOKEN, Action = 'Transfer', Quantity = '1000000', Recipient = WALLET_ADDRESS })`

2. Spawn a new process or connect to an existing one in relay mode.
   - `aos my-new-process --wallet wallet.json --relay http://relay.ao-hb.xyz`
3. If you have not yet topped up with this node, AOS will prompt you to transfer some tokens to the relay. In order to continue you must enter **Yes** and then choose an amount (0.0000001 AO is the default and is enough to get started, but you can enter more to top up less frequently).
4. At this point AOS will handle the transfer to the relay and you will now be able to start sending messages.

::: info
Note that `Quantity` is the amount of Armstrongs to send, not $AO. One AO is one trillion Armstrongs, so 1,000,000 Armstrongs = 0.000001 AO.
:::


Prompt: This is a Markdown documentation from the AO documentation repository. Filename: index.md Path: ../ao-cookbook/src/mainnet/index.md

Response:
---
next:
  text: "AO Core Relay"
  link: "./ao-core-relay"
---

# AO Mainnet

AO Mainnet is here, marking a major step toward a decentralized, open-access supercomputer directly connected to the internet. It enables confidential, decentralized computation without reliance on centralized Web2 infrastructure, expanding access to information and opportunity.

This documentation is an evolving resource. More guides and references will be added soon.

## Get Started

Learn how to start interacting with HyperBEAM allowing you to send messages and handle payments directly from the command line.

- [AO Core Relay](ao-core-relay)

## Launch Video

<iframe width="560" height="315" src="https://www.youtube.com/embed/3LxPt0EuFvU?si=Uf7QtUgj5twWJtNd" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>


Prompt: This is a Markdown documentation from the AO documentation repository. Filename: cron.md Path: ../ao-cookbook/src/references/cron.md

Response:
# Cron Messages

ao has the ability to generate messages on a specified interval, this interval could be seconds, minutes, hours, or blocks. These messages automatically get evaluated by a monitoring process to inform the Process to evaluate these messages over time. The result is a real-time Process that can communicate with the full ao network or oracles in the outside network.

## Setting up cron in a process

The easiest way to create these cron messages is by spawning a new process in the aos console and defining the time interval.

```sh
aos [myProcess] --cron 5-minutes
```

When spawning a new process, you can pass a cron argument in your command line followed by the interval you would like the cron to tick. By default, cron messages are lazily evaluated, meaning they will not be evaluated until the next scheduled message. To initiate these scheduled cron messages, call `.monitor` in aos - this kicks off a worker process on the `mu` that triggers the cron messages from the `cu`. Your Process will then receive cron messages every `x-interval`.

```lua
.monitor
```

If you wish to stop triggering the cron messages simply call `.unmonitor` and this will stop the triggering process, but the next time you send a message, the generated cron messages will still get created and processed.

## Handling cron messages

Every cron message has an `Action` tag with the value `Cron`. [Handlers](handlers.md) can be defined to perform specific tasks autonomously, each time a cron message is received.

```lua
Handlers.add(
  "CronTick", -- Handler name
  Handlers.utils.hasMatchingTag("Action", "Cron"), -- Handler pattern to identify cron message
  function () -- Handler task to execute on cron message
    -- Do something
  end
)
```

Cron messages are a powerful utility that can be used to create "autonomous agents" with expansive capabilities.


Prompt:
This is a Markdown documentation from the AO documentation repository. Filename: token.md Path: ../ao-cookbook/src/references/token.md
Note: This content continues in the next part.

Response:
# ao Token and Subledger Specification

**Status:** DRAFT-1
**Targeting Network:** ao.TN.1

This specification describes the necessary message handlers and functionality required for a standard ao token process. Implementations of this standard typically offer users the ability to control a transferrable asset, whose scarcity is maintained by the process.

Each compliant process will likely implement a ledger of balances in order to encode ownership of the asset that the process represents. Compliant processes have a set of methods that allow for the modification of this ledger, typically with safe-guards to ensure the scarcity of ownership of the token represented by the process.

Additionally, this specification describes a 'subledger' process type which, when implemented, offers the ability to split move a number of the tokens from the parent into a child process that implements the same token interface specification. If the `From-Module` of the subledger process is trusted by the participants, these subledgers can be used to transact in the 'source' token, without directly exchanging messages with it. This allows participants to use the tokens from a process, even if that process is congested. Optionally, if the participants trust the `Module` a subledger process is running, they are able to treat balances across these processes as _fungible_. The result of this is that an arbitrary numbers of parallel processes -- and thus, transactions -- can be processed by a single token at any one time.

# Token Processes

A specification-compliant token process responds to a number of different forms of messages, with each form specified in an `Action` tag. The full set of `Action` messages that the token must support are as follows:

| Name     | Description                                                                                | Read-Only          |
| -------- | ------------------------------------------------------------------------------------------------------ | ------------------ |
| Balance  | get the balance of an identifier                                                                       | :heavy_check_mark: |
| Balances | get a list of all ledger/account balances                                                              | :heavy_check_mark: |
| Transfer | send 1 or more units from the callers balance to one or move targets with the option to notify targets | :x:                |
| Mint     | if the ledger process is the root and you would like to increase token supply                          | :x:                |

In the remainder of this section the tags necessary to spawn a compliant token process, along with the form of each of the `Action` messages and their results is described.

## Spawning Parameters

Every compliant token process must carry the following immutable parameters upon its spawning message:

| Tag          | Description                                                                                | Optional?          |
| ------------ | -------------------------------------------------------------------------------------------------------------------- | ------------------ |
| Name         | The title of the token, as it should be displayed to users.                                                          | :heavy_check_mark: |
| Ticker       | A suggested shortened name for the token, such that it can be referenced quickly.                                    | :heavy_check_mark: |
| Logo         | An image that applications may desire to show next to the token, in order to make it quickly visually identifiable.  | :heavy_check_mark: |
| Denomination | The number of the token that should be treated as a single unit when quantities and balances are displayed to users. | :x:                |

## Messaging Protocol

### Balance(Target? : string)

- Returns the balance of a target, if a target is not supplied then the balance of the sender of the message must be returned.

**Example `Action` message:**

```lua
ao.send({
    Target = "{TokenProcess Identifier}",
    Tags = {
        ["Action"] = "Balance",
        ["Target"] = "{IDENTIFIER}"
    }
})
```

**Example response message:**

```lua
{
    Tags = {
        ["Balance"] = "50",
        ["Target"] = "LcldyO8wwiGDzC3iXzGofdO8JdR4S1_2A6Qtz-o33-0",
        ["Ticker"] = "FUN"
    }
}
```

### Balances()

- Returns the balance of all participants in the token.

```lua
ao.send({
    Target = "[TokenProcess Identifier]",
    Tags = {
        ["Action"] = "Balances",
        ["Limit"] = 1000, # TODO: Is this necessary if the user is paying for the compute and response?
        ["Cursor"] = "BalanceIdentifier"
    }
})
```

**Example response message:**

```lua
{
    Data = {
        "MV8B3MAKTsUOqyCzQ0Tsa2AR3TiWTBU1Dx0xM4MO-f4": 100,
        "LcldyO8wwiGDzC3iXzGofdO8JdR4S1_2A6Qtz-o33-0": 50
    }
}
```

### Transfer(Target, Quantity)

If the sender has a sufficient balance, send the `Quantity` to the `Target`, issuing a `Credit-Notice` to the recipient and a `Debit-Notice` to the sender. The `Credit-` and `Debit-Notice` should forward any and all tags from the original `Transfer` message with the `X-` prefix. If the sender has an insufficient balance, fail and notify the sender.

```lua
ao.send({
    Target = "[TokenProcess Identifier]",
    Tags = {
        ["Action"] = "Transfer",
        ["Recipient"] = "[ADDRESS]",
        ["Quantity"] = "100",
        ["X-[Forwarded Tag(s) Name]"] = "[VALUE]"
    }
})
```

If a successful transfer occurs a notification message should be sent if `Cast` is not set.

```lua
ao.send({
    Target = "[Recipient Address]",
    Tags = {
        ["Action"] = "Credit-Notice",
        ["Sender"] = "[ADDRESS]",
        ["Quantity"] = "100",
        ["X-[Forwarded Tag(s) Name]"] = "[VALUE]"
    }
})
```

Recipients will infer from the `From-Process` tag of the message which tokens they have received.

### Get-Info()

```lua
ao.send({
    Target = "{Token}",
    Tags = {
        ["Action"] = "Info"
    }
})
```

### Mint() [optional]

Implementing a `Mint` action gives the process a way of allowing valid participants to create new tokens.

```lua
ao.send({
    Target ="{Token Process}",
    Tags = {
        ["Action"] = "Mint",
        ["Quantity"] = "1000"
    }
})
```

# Subledger Processes

In order to function appropriately, subledgers must implement the full messaging protocol of token contracts (excluding the `Mint` action). Subledgers must also implement additional features and spawn parameters for their processes. These modifications are described in the following section.

### Spawning Parameters

Every compliant subledger process must carry the following immutable parameters upon its spawning message:

| Tag          | Description                                                        | Optional? |
| ------------ | ------------------------------------------------------------------ | --------- |
| Source-Token | The `ID` of the top-most process that this subledger represents.   | :x:       |
| Parent-Token | The `ID` of the parent process that this subledger is attached to. | :x:       |

### `Credit-Notice` Handler

Upon receipt of a `Credit-Notice` message, a compliant subledger process must check if the process in question is the `Parent-Token`. If it is, the subledger must increase the balance of the `Sender` by the specified quantity.

### Transfer(Target, Quantity)

In addition to the normal tags that are passed in the `Credit-Notice` message to the recipient of tokens, a compliant subledger process must also provide both of the `Source-Token` and `Parent-Token` values. This allows the recipient of the `Transfer` message -- if they trust the `Module` of the subledger process -- to credit a receipt that is analogous (fungible with) deposits from the `Source-Token`.

The modified `Credit-Notice` should be structured as follows:

```lua
ao.send({
    Target = "[Recipient Address]",
    Tags = {
        ["Action"] = "Credit-Notice",
        ["Quantity"] = "100",
        ["Source-Token"] = "[ADDRESS]",
        ["Parent-Token"] = "[ADDRESS]",
        ["X-[Forwarded Tag(s) Name]"] = "[VALUE]"
    }
})
```

### Withdraw(Target?, Quantity)

All subledgers must allow balance holders to withdraw their tokens to the parent ledger. Upon receipt of an `Action: Withdraw` message, the subledger must send an `Action` message to its `Parent-Ledger`, transferring the requested tokens to the caller's address, while debiting their account locally. This transfer will result in a `Credit-Notice` from the `Parent-Ledger` for the caller.

```lua
ao.send({
    Target = "[TokenProcess Identifier]",
    Tags = {
        ["Action"] = "Withdraw",
        ["Recipient"] = "[ADDRESS]",
        ["Quantity"] = "100"
    }
})
```

# Token Example

> NOTE: When implementing a token it is important to remember that all Tags on a message MUST be "string"s. Using the`tostring` function you can convert simple types to strings.

```lua
if not balances then
  balances = { [ao.id] = 100000000000000 }
end

if name ~= "Fun Coin" then
  name = "Fun Coin"
end

if ticker ~= "Fun" then
  ticker = "fun"
end

if denomination ~= 6 then
  denomination = 6
end

-- handlers that handler incoming msg
Handlers.add(
  "Transfer",
  Handlers.utils.hasMatchingTag("Action", "Transfer"),
  function (msg)
    assert(type(msg.Tags.Recipient) == 'string', '


Prompt: This is a Markdown documentation from the AO documentation repository. This is a continuation from the previous part. Filename: token.md Path: ../ao-cookbook/src/references/token.md

Response:
({
    Target = "[TokenProcess Identifier]",
    Tags = {
        ["Action"] = "Withdraw",
        ["Recipient"] = "[ADDRESS]",
        ["Quantity"] = "100"
    }
})
```

# Token Example

> NOTE: When implementing a token it is important to remember that all Tags on a message MUST be "string"s. Using the`tostring` function you can convert simple types to strings.

```lua
if not balances then
  balances = { [ao.id] = 100000000000000 }
end

if name ~= "Fun Coin" then
  name = "Fun Coin"
end

if ticker ~= "Fun" then
  ticker = "fun"
end

if denomination ~= 6 then
  denomination = 6
end

-- handlers that handler incoming msg
Handlers.add(
  "Transfer",
  Handlers.utils.hasMatchingTag("Action", "Transfer"),
  function (msg)
    assert(type(msg.Tags.Recipient) == 'string', 'Recipient is required!')
    assert(type(msg.Tags.Quantity) == 'string', 'Quantity is required!')

    if not balances[msg.From] then
      balances[msg.From] = 0
    end

    if not balances[msg.Tags.Recipient] then
      balances[msg.Tags.Recipient] = 0
    end

    local qty = tonumber(msg.Tags.Quantity)
    assert(type(qty) == 'number', 'qty must be number')
    -- handlers.utils.reply("Transferring qty")(msg)
    if balances[msg.From] >= qty then
      balances[msg.From] = balances[msg.From] - qty
      balances[msg.Tags.Recipient] = balances[msg.Tags.Recipient] + qty
      ao.send({
        Target = msg.From,
        Tags = {
          ["Action"] = "Debit-Notice",
          ["Quantity"] = tostring(qty)
        }
      })
      ao.send({
        Target = msg.Tags.Recipient,
        Tags = {
          ["Action"] = "Credit-Notice",
          ["Quantity"] = tostring(qty)
        }
      })
      -- if msg.Tags.Cast and msg.Tags.Cast == "true" then
      --   return
      -- end

    end
  end
)

Handlers.add(
  "Balance",
  Handlers.utils.hasMatchingTag("Action", "Balance"),
  function (msg)
    assert(type(msg.Tags.Target) == "string", "Target Tag is required!")
    local bal = "0"
    if balances[msg.Tags.Target] then
      bal = tostring(balances[msg.Tags.Target])
    end
    ao.send({
      Target = msg.From,
      Tags = {
        ["Balance"] = bal,
        ["Ticker"] = ticker or ""
      }
    })
  end
)

local json = require("json")

Handlers.add(
  "Balances",
  Handlers.utils.hasMatchingTag("Action", "Balances"),
  function (msg)
    ao.send({
      Target = msg.From,
      Data = json.encode(balances)
    })
  end

)

Handlers.add(
  "Info",
  Handlers.utils.hasMatchingTag("Action", "Info"),
  function (msg)
    ao.send({
      Target = msg.From,
      Tags = {
        ["Name"] = name,
        ["Ticker"] = ticker,
        ["Denomination"] = tostring(denomination)
      }
    })
  end
)
```


Prompt: This is a Markdown documentation from the AO documentation repository. Filename: wasm.md Path: ../ao-cookbook/src/references/wasm.md

Response:
# Meet Web Assembly

WebAssembly (often abbreviated as Wasm) is a modern binary instruction format providing a portable compilation target for high-level languages like C, C++, and Rust. It enables deployment on the web for client and server applications, offering a high level of performance and efficiency. WebAssembly is designed to maintain the security and sandboxing features of web browsers, making it a suitable choice for web-based applications. It's a key technology for web developers, allowing them to write code in multiple languages and compile it into bytecode that runs in the browser at near-native speed.

The significance of WebAssembly lies in its ability to bridge the gap between web and native applications. It allows complex applications and games, previously limited to desktop environments, to run in the browser with comparable performance. This opens up new possibilities for web development, including the creation of high-performance web apps, games, and even the porting of existing desktop applications to the web. WebAssembly operates alongside JavaScript, complementing it by enabling performance-critical components to be written in languages better suited for such tasks, thereby enhancing the capabilities and performance of web applications.


Prompt: This is a Markdown documentation from the AO documentation repository. Filename: community.md Path: ../ao-cookbook/src/references/community.md

Response:
---
prev:
  text: "ao Editor Setup"
  link: "/references/editor-setup.md"
---

# Community Resources

This page provides a comprehensive list of community resources, tools, guides, and links for the AO ecosystem.

## Core Resources

[Autonomous Finance](https://www.autonomous.finance/)

- Autonomous Finance is a dedicated research and technology entity, focusing on the intricacies of financial infrastructure within the ao network.

[BetterIdea](https://betteridea.dev/)

- Build faster, smarter, and more efficiently with BetterIDEa, the ultimate native web IDE for AO development

[0rbit](https://www.0rbit.co/)

- 0rbit provides any data from the web to an ao process
  by utilizing the power of ao, and 0rbit nodes.
  The user sends a message to the 0rbit ao, 0rbit nodes fetches the data and the user process receives the data.

[ArweaveHub](https://arweavehub.com/)

- A community platform for the Arweave ecosystem featuring events, developer resources, and discovery tools.

[AR.IO](https://ar.io/)

- The first permanent cloud network built on Arweave, providing infrastructure for the permaweb with no 404s, no lost dependencies, and reliable access to applications and data through gateways, domains, and deployment tools.

## Developer Tools

- [AO Package Manager](https://apm_betteridea.arweave.net)

## Contributing

> Not seeing an AO Community Member or resource? Create an issue or submit a pull request to add it to this page: https://github.com/permaweb/ao-cookbook


Prompt: This is a Markdown documentation from the AO documentation repository. Filename: lua.md Path: ../ao-cookbook/src/references/lua.md

Response:
# Meet Lua

## Understanding Lua

- **Background**: Lua is a lightweight, high-level, multi-paradigm programming language designed primarily for embedded systems and clients. It's known for its efficiency, simplicity, and flexibility.
- **Key Features**: Lua offers powerful data description constructs, dynamic typing, efficient memory management, and good support for object-oriented programming.

## Setting Up

1. **Installation**: Visit [Lua's official website](http://www.lua.org/download.html) to download and install Lua.
2. **Environment**: You can use a simple text editor and command line, or an IDE like ZeroBrane Studio or Eclipse with a Lua plugin.

## Basic Syntax and Concepts (in aos)

- **Hello World**:
  ```lua
  "Hello, World!"
  ```
- **Variables and Types**: Lua is dynamically typed. Basic types include `nil`, `boolean`, `number`, `string`, `function`, `userdata`, `thread`, and `table`.
- **Control Structures**: Includes `if`, `while`, `repeat...until`, and `for`.
- **Functions**: First-class citizens in Lua, supporting closures and higher-order functions.
- **Tables**: The only data structuring mechanism in Lua, which can be used to represent arrays, sets, records, etc.

## Hands-On Practice

- **Experiment with Lua's Interactive Mode**: Run `aos` in your terminal and start experimenting with Lua commands.
- **Write Simple Scripts**: Create `.lua` files and run them using the Lua interpreter. Use `.load file.lua` feature to upload lua code on your `aos` process.

## Resources

- **Official Documentation**: [Lua 5.3 Reference Manual](https://www.lua.org/manual/5.3/)
- **Online Tutorials**: Websites like [Learn Lua](https://www.learn-lua.org/) are great for interactive learning.
- **Books**: "Programming in Lua" (first edition available [online](http://www.lua.org/pil/contents.html)) is a comprehensive resource.
- **Community**: Join forums or communities like [Lua Users](http://lua-users.org/) for support and discussions.

## Best Practices

- **Keep It Simple**: Lua is designed to be simple and flexible. Embrace this philosophy in your code.
- **Performance**: Learn about Lua's garbage collection and efficient use of tables.
- **Integration**: Consider how Lua can be embedded into other applications, particularly C/C++ projects.

## Conclusion

Lua is a powerful language, especially in the context of embedded systems and game development. Its simplicity and efficiency make it a great choice for specific use cases. Enjoy your journey into Lua programming!


Prompt: This is a Markdown documentation from the AO documentation repository. Filename: messaging.md Path: ../ao-cookbook/src/references/messaging.md

Response:
# Messaging Patterns in ao

This reference guide explains the messaging patterns available in ao and when to use each one.

## Quick Reference: Choosing the Right Pattern

| If you need to...                                  | Process Flow        | Key function(s)                                                                                |
| -------------------------------------------------- | ------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| Send a message without waiting for a response      | **_A → B_**         | [`ao.send`](#ao-send-asynchronous-message-sending)                                                                                |
| Send a message and wait for a response             | **_A → B → A_**     | [`ao.send().receive()`](#ao-send-receive-lowercase-r-blocking-reference-matcher)                                                    |
| Process messages and respond to the sender         | **_B → A_**         | [`Handlers.add`](#msg-reply-asynchronous-response-sending) + [`msg.reply`](#msg-reply-asynchronous-response-sending)                |
| Create a chain of processing services              | **_A → B → C → A_** | [`msg.forward`](#msg-forward-message-forwarding) + [`ao.send().receive()`](#ao-send-receive-lowercase-r-blocking-reference-matcher) |
| Wait for any matching message regardless of sender | **_Any → A_**       | [`Receive`](#receive-capital-r-blocking-pattern-matcher) (capital R)                                                                |
| Create a standard automated response               | **_B → A_**         | [`Handlers.utils.reply`](#handlers-utils-reply-simple-reply-handler-creation)                                                       |

## Sending Messages

### `ao.send`: Asynchronous Message Sending

Non-blocking direct **_A → B_** messaging that returns immediately after sending.

- Use for fire-and-forget notifications or starting async conversations
- Returns a promise-like object that can be chained with [`.receive()`](#ao-send-receive-lowercase-r-blocking-reference-matcher) if needed
- Good for parallel processing since it doesn't block execution

```
Client (A) → Service (B)
   ↓           ↓
Continues    Processes
 execution    message
```

**Basic Send Example:**

```lua
-- Non-blocking send example
local serviceId = "process-789" -- Process ID of the target service

ao.send({
  Target = serviceId,
  Data = "Hello!",
  Action = "Greeting"
})
-- Code here runs immediately after sending
```

### `msg.reply`: Asynchronous Response Sending

Non-blocking **_B → A_** response with automatic reference tracking. Used within handlers to respond to incoming messages.

- Automatically links response to original message via [`X-Reference`](#message-properties)
- Enables asynchronous request-response patterns
- Automatically sets `Target` to the original sender or [`Reply-To`](#message-properties) address if specified

```
Client (A) → Service (B)
          ←
Response tagged with X-Reference
```

**Handler Reply Example:**

```lua
-- Non-blocking reply in a handler
Handlers.add("greeting-handler",
  { Action = "Greeting" },
  function(msg)
    msg.reply({ Data = "Hi back!" }) -- Returns immediately
    -- Handler continues executing here
  end
)
```

### `msg.forward`: Message Forwarding

Non-blocking multi-process routing for **_A → B → C → A_** patterns. Creates a sanitized copy of the original message.

- Takes a `target` and a partial message to overwrite forwarded message fields
- Preserves [`Reply-To`](#message-properties) and [`X-Reference`](#message-properties) properties for complete message tracking
- Sets [`X-Origin`](#message-properties) to original sender, enabling final service to reply directly to originator

```
Client (A) → Service (B) → Backend (C)
       ↖                       ↙
    Response with X-Reference
```

**Multi-Process Pipeline Example:**

```lua
-- In client process
local middlewareProcessId = "process-123"
local finalProcessId = "process-456"

-- Send to middleware and wait for response from final service
local response = ao.send({
  Target = middlewareProcessId,
  Action = "Transform",
  Data = "raw-data"
}).receive(finalProcessId)  -- Explicitly wait for response from final service

-- In middleware service
Handlers.add("transform-middleware",
  { Action = "Transform" },
  function(msg)
    local finalProcessId = "process-456"

    msg.forward(finalProcessId, {
      Data = msg.Data .. " (pre-processed)",
      Action = "Transform-Processed"
    })
  end
)

-- In final service
Handlers.add("final-processor",
  { Action = "Transform-Processed" },
  function(msg)
    -- No need to know the client ID - it's stored in X-Origin
    msg.forward(msg['X-Origin'], {
      Data = msg.Data .. " (final processing complete)",
      Action = "Transform-Complete"
    })
  end
)
```

### `Handlers.utils.reply`: Simple Reply Handler Creation

Creates a handler function that automatically replies with a fixed response. A wrapper around [`msg.reply`](#msg-reply-asynchronous-response-sending) for common use cases.

**Simple String Response Example:**

```lua
-- Simple string response handler
Handlers.add("echo-handler",
  { Action = "Echo" },
  Handlers.utils.reply("Echo reply!")
)

-- Equivalent to:
Handlers.add("echo-handler",
  { Action = "Echo" },
  function(msg)
    msg.reply({ Data = "Echo reply!" })
  end
)
```

**Message Table Response Example:**

```lua
-- Message table response handler
Handlers.add("status-handler",
  { Action = "Status" },
  Handlers.utils.reply({
    Data = "OK",
    Action = "Status-Response"
  })
)
```

## Receiving Messages

### `Receive` (Capital R): Blocking Pattern Matcher

Blocks execution until any matching message arrives from any sender. Under the hood, this is implemented using `Handlers.once`, making it a one-time pattern matcher that automatically removes itself after execution.

- Waits for any message matching the pattern, regardless of origin
- Use for synchronous message processing flows or event listening
- Automatically removes the handler after first match (using `Handlers.once` internally)

```
        Process (A)
            ↓
Blocks until match received
            ↓
    Continues execution
```

**Message Pattern Matching Example:**

```lua
-- Blocks until matching message received
local msg = Receive({
  Action = "Update"
})

if msg then
  -- Process message
end
```

### `ao.send().receive` (Lowercase r): Blocking Reference Matcher

Blocks execution until a specific reply arrives, enabling **_A → B → A_** and **_A → B → C → A_** request-response cycles.

- Only matches messages linked by [`X-Reference`](#message-properties)
- Can specify a target process ID to indicate which process will reply
- Implicitly waits for the proper response based on message reference chains
- For **_A → B → A_** flows, process B uses [`msg.reply`](#msg-reply-asynchronous-response-sending)
- For **_A → B → C → A_** flows, processes B and C use [`msg.forward`](#msg-forward-message-forwarding)

**Basic Request-Response Example:**

```lua
-- Basic usage: wait for reply from target
local serviceId = "process-789"

local reply = ao.send({
  Target = serviceId,
  Action = "Query",
  Data = { query: "select" }
}).receive() -- Blocks until response received
```

## Message Properties

The following properties track message chains and ensure proper routing:

- `Reference`: Unique identifier automatically assigned to each message.
- `Reply-To`: Specifies the destination for responses.
- `X-`: Any property starting with `X-` denotes a 'forwarded' tag and is automatically managed by the system.
  - `X-Reference`: Maintains the conversation chain across replies and forwards.
  - `X-Origin`: Tracks the conversation originator.

The system automatically manages these properties when using `msg.reply` and `msg.forward`. Check
out the [source code](https://github.com/permaweb/aos/blob/e9fc10c54b4f21302ee8d084d31f3383b46857b2/process/process.lua#L377-L406) to see exactly how these
properties are managed.

## Blocking vs. Non-Blocking

Functions either pause your code or let it continue running:

- **Non-blocking** ([`ao.send`](#ao-send-asynchronous-message-sending), [`msg.reply`](#msg-reply-asynchronous-response-sending), [`msg.forward`](#msg-forward-message-forwarding)): Send and continue execution
- **Blocking** ([`Receive`](#receive-capital-r-blocking-pattern-matcher), [`.receive()`](#ao-send-receive-lowercase-r-blocking-reference-matcher)): Pause until response arrives


Prompt:
This is a Markdown documentation from the AO documentation repository. Filename: ao.md Path: ../ao-cookbook/src/references/ao.md
Note: This content continues in the next part.

Response:
# ao Module

version: 0.0.3

`ao` process communication is handled by messages, each process receives messages in the form of [ANS-104 DataItems](https://specs.arweave.net/view/xwOgX-MmqN5_-Ny_zNu2A8o-PnTGsoRb_3FrtiMAkuw), and needs to be able to do the following common operations.

- [ao.send(msg)](#ao-send-msg-message) - send message to another process
- [ao.spawn(module, msg)](#ao-spawn-module-string-spawn-spawn) - spawn a process

The goal of this library is to provide this core functionality in the box of the `ao` developer toolkit. As a developer you have the option to leverage this library or not, but it integrated by default.

## Properties

| Name               | Description                                                                                | Type     |
| ------------------ | ------------------------------------------------------------------------------------------------------------ | -------- |
| id                 | Process Identifier (TxID)                                                                                | string   |
| \_module           | Module Identifier (TxID)                                                                                | string   |
| authorities        | Set of Trusted TXs                                                                                | string   |
| Authority          | Identifiers that the process is able to accept transactions from that are not the owner or the process (0-n) | string   |
| \_version          | The version of the library                                                                                | string   |
| reference          | Reference number of the process                                                                              | number   |
| env                | Evaluation Environment                                                                                | object   |
| outbox             | Holds Messages and Spawns for response                                                                       | object   |
| assignables        | List of assignables of the process                                                                           | list     |
| nonExtractableTags | List of non-extractable tags of the process                                                                  | list     |
| nonForwardableTags | List of non-forwardable tags of the process                                                                  | list     |
| init               | Initializes the AO environment                                                                               | function |
| send               | Sends a message to a target process                                                                          | function |
| assign             | Assigns a message to the process                                                                             | function |
| spawn              | Spawns a process                                                                                | function |
| result             | Returns the result of a message                                                                              | function |
| isTrusted          | Checks if a message is trusted                                                                               | function |
| isAssignment       | Checks if a message is an assignment                                                                         | function |
| isAssignable       | Checks if a message is assignable                                                                            | function |
| addAssignable      | Adds an assignable to the assignables list                                                                   | function |
| removeAssignable   | Removes an assignable from the assignables list                                                              | function |
| clearOutbox        | Clears the outbox                                                                                | function |
| normalize          | Normalizes a message by extracting tags                                                                      | function |
| sanitize           | Sanitizes a message by removing non-forwardable tags                                                         | function |
| clone              | Clones a table recursively                                                                                | function |

### Environment Schema

The `ao.env` variable contains information about the initializing message of the process. It follows this schema:

```lua
ao.env = {
  Process = {
    Id = string,      -- Process ID
    Owner = string,   -- Process owner
    TagArray = {      -- Array of name-value pairs
      { name = string, value = string }
    },
    Tags = {          -- Tags as key-value pairs
      [string] = string
    }
  }
}
```

#### Example

```lua
{
  Process = {
    Id = "A1b2C3d4E5f6G7h8I9j0K1L2M3N4O5P6Q7R8S9T0",
    Owner = "Xy9PqW3vR5sT8uB1nM6dK0gF2hL4jC7iE9rV3wX5",
    TagArray = {
      { name = "App-Name", value = "aos" }
    },
    Tags = {
      ["App-Name"] = "aos"
    }
  }
}
```

## Methods

### `ao.send(msg: Message)`

Takes a [Message](#message) as input. The function adds `ao`-specific tags and stores the message in `ao.outbox.Messages`.

#### Example

```lua
local message = ao.send({
    Target = msg.From,
    Data = "ping",
    Tags = {
        ["Content-Type"] = "text/plain",
        ["Action"] = "Ping"
    }
})

-- or

local message = ao.send({
    Target = msg.From,
    Data = "ping",
    Action = "Ping",               -- will be converted to Tags
    ["Content-Type"] = "text/plain"  -- will be converted to Tags
})
```

### `ao.spawn(module: string, spawn: Spawn)`

Takes a module ID string and [Spawn](#spawn) as input. Returns a Spawn table with a generated `Ref_` tag.

#### Example

```lua
local process = ao.spawn("processId", {
    Data = { initial = "state" },
    Tags = {
        ["Process-Type"] = "calculator"
    }
})
```

### `ao.assign(assignment: Assignment)`

Takes an [Assignment](#assignment) as input. Adds the assignment to `ao.outbox.Assignments`.

#### Example

```lua
ao.assign({
    Processes = {"process-1", "process-2"},
    Message = "sample-message-id"
})
```

### `ao.result(result: Result)`

Takes a [Result](#result) as input. Returns the final process execution result.

#### Example

```lua
local process_result = ao.result({
    Output = "Process completed successfully",
    Messages = {
        { Target = "ProcessY", Data = "Result data", Tags = { ["Status"] = "Success" } }
    },
    Spawns = { "spawned-process-1" },
    Assignments = { {Processes = { "process-1" }, Message = "assignment-message-id"} }
})
```

### `ao.isAssignable(msg: Message)`

Takes a [Message](#message) as input. Returns `true` if the message matches a pattern in `ao.assignables`.

#### Example

```lua
local can_be_assigned = ao.isAssignable({
    Target = "ProcessA",
    Data = "Some content",
    Tags = {
         ["Category"] = "Info"
    }
})
```

### `ao.isAssignment(msg: Message)`

Takes a [Message](#message) as input. Returns `true` if the message is assigned to a different process.

#### Example

```lua
local is_assigned_elsewhere = ao.isAssignment({
    Target = "AnotherProcess"
})
```

### `ao.addAssignable(name: string, condition: function)`

Adds a named condition function to the process's list of assignables. Messages matching any condition will be accepted when assigned.

> **Note:** The `condition` parameter uses a similar pattern matching approach as the `pattern` parameter in `Handlers.add()`. For more advanced pattern matching techniques, see the [Handlers Pattern Matching documentation](../references/handlers.md#pattern-matching-tables).

#### Example

```lua
-- Allow transactions from ArDrive
ao.addAssignable("allowArDrive", function (msg)
    return msg.Tags["App-Name"] == "ArDrive-App"
end)

-- Allow transactions with specific content type
ao.addAssignable("allowJson", function (msg)
    return msg.Tags["Content-Type"] == "application/json"
end)
```

### `ao.removeAssignable(name: string)`

Removes a previously added assignable condition from the process's list of assignables.

#### Example

```lua
ao.removeAssignable("allowArDrive")
```

### `ao.isTrusted(msg: Message)`

Takes a [Message](#message) as input. Returns `true` if the message is from a trusted source.

#### Example

```lua
if ao.isTrusted(msg) then
    -- Process trusted message
else
    -- Handle untrusted message
end
```

## Custom `ao` Table Structures

### Tags

Used by: `ao.send()`, `ao.spawn()`, `ao.normalize()`, `ao.sanitize()`

All of the below syntaxes are valid, but each syntax gets converted to `{ name = string, value = string }` tables behind the scenes. We use **alternative 1** throughout the documentation for brevity and consistency.

```lua
-- Default: Array of name-value pair tables
Tags = {
    { name = "Content-Type", value = "text/plain" },
    { name = "Action", value = "Ping" }
}

-- Alternative 1: Direct key-value pairs in Tags table using string keys
Tags = {
    ["Content-Type"] = "text/plain",
    ["Action"] = "Ping"
}

-- Alternative 2: Direct key-value pairs in Tags table using dot notation
Tags = {
    Category = "Info",
    Action = "Ping"
}
```

::: info Root-level Tag Conversion
Any keys in the root message object that are not one of: `Target`, `Data`, `Anchor`, `Tags`, or `From` will automatically be converted into Tags using the key as the tag name and its value as the tag value.

```lua
-- These root-level keys will be automatically converted to Tags
{
    Target = "process-id",
    Data = "Hello",
    ["Content-Type"] = "text/plain",  -- Will become a Tag
    Action = "Ping"                   -- Will become a Tag
}
```

:::

### Message

Used by: `ao.send()`, `ao.isTrusted()`,


Prompt: This is a Markdown documentation from the AO documentation repository. This is a continuation from the previous part. Filename: ao.md Path: ../ao-cookbook/src/references/ao.md

Response:
 pairs in Tags table using string keys
Tags = {
    ["Content-Type"] = "text/plain",
    ["Action"] = "Ping"
}

-- Alternative 2: Direct key-value pairs in Tags table using dot notation
Tags = {
    Category = "Info",
    Action = "Ping"
}
```

::: info Root-level Tag Conversion
Any keys in the root message object that are not one of: `Target`, `Data`, `Anchor`, `Tags`, or `From` will automatically be converted into Tags using the key as the tag name and its value as the tag value.

```lua
-- These root-level keys will be automatically converted to Tags
{
    Target = "process-id",
    Data = "Hello",
    ["Content-Type"] = "text/plain",  -- Will become a Tag
    Action = "Ping"                   -- Will become a Tag
}
```

:::

### Message

Used by: `ao.send()`, `ao.isTrusted()`, `ao.isAssignment()`, `ao.isAssignable()`, `ao.normalize()`, `ao.sanitize()`

```lua
-- Message structure
{
    Target = string,     -- Required: Process/wallet address
    Data = any,          -- Required: Message payload
    Tags = Tag<table>
}
```

### Spawn

Used by: `ao.spawn()`

```lua
-- Spawn structure
{
    Data = any,          -- Required: Initial process state
    Tags = Tag<table>    -- Required: Process tags
}
```

### Assignment

Used by: `ao.assign()`, `ao.result()`

```lua
-- Assignment configuration table structure
{
    Processes = { string }, -- Required: List of target process ID strings
    Message = string       -- Required: Message to assign
}
```

### Result

Used by: `ao.result()`

```lua
-- Process result structure
{
    Output = string,           -- Optional: Process output
    Messages = Message<table>,   -- Optional: Generated messages
    Spawns = Spawn<table>,        -- Optional: Spawned processes
    Assignments = Assignment<table>,    -- Optional: Process assignments
    Error = string         -- Optional: Error information
}
```


Prompt: This is a Markdown documentation from the AO documentation repository. Filename: index.md Path: ../ao-cookbook/src/references/index.md

Response:
---
prev:
  text: "The aos interface"
  link: "/concepts/tour"
next:
  text: "Lua"
  link: "./lua"
---

# References

This section provides detailed technical references for AO components, languages, and tools. Use these resources to find specific information when implementing your AO projects.

## Programming Languages

Resources for the programming languages used in AO:

- [Lua](./lua) - Reference for the Lua programming language, the primary language used in AO
- [WebAssembly (WASM)](./wasm) - Information about using WebAssembly modules in AO
- [Lua Optimization](./lua-optimization) - Techniques and best practices for optimizing Lua code in AO

## AO API Reference

Documentation for AO's core APIs and functionality:

- [AO Core](./ao) - Core `ao` module and API reference
- [Messaging](./messaging) - Comprehensive guide to the AO messaging system patterns
- [Handlers](./handlers) - Reference for event handlers and message processing
- [Token](./token) - Information about token creation and management
- [Arweave Data](./data) - Guide to data handling and storage in AO
- [Cron](./cron) - Documentation for scheduling and managing timed events

## Development Environment

Tools and setup for AO development:

- [Editor Setup](./editor-setup) - Guide to setting up your development environment for AO
- [BetterIDEa](./betteridea/index) - The ultimate native web IDE for AO development

## Community Resources

Connect with the AO community:

- [Community Resources](./community) - Information about AO community resources and support

## Navigation

Use the sidebar to navigate between reference topics. References are organized by category to help you find the information you need quickly.


Prompt:
This is a Markdown documentation from the AO documentation repository. Filename: handlers.md Path: ../ao-cookbook/src/references/handlers.md
Note: This content continues in the next part.

Response:
# Handlers (Version 0.0.5)

## Overview

The Handlers library provides a flexible way to manage and execute a series of process functions based on pattern matching. An AO process responds based on receiving Messages, these messages are defined using the Arweave DataItem specification which consists of Tags, and Data. Using the Handlers library, you can define a pipeline of process evaluation based on the attributes of the AO Message. Each Handler is instantiated with a name, a pattern matching function, and a function to execute on the incoming message. This library is suitable for scenarios where different actions need to be taken based on varying input criteria.

## Concepts

### Handler Arguments Overview

When adding a handler using `Handlers.add()`, you provide three main arguments:

1. `name` (string): The identifier for your handler
2. `pattern` (table or function): Defines how to match incoming messages
3. `handler` (function or resolver table): Defines what to do with matched messages

### Pattern Matching Tables

Pattern Matching Tables provide a declarative way to match incoming messages based on their attributes. This is used as the second argument in `Handlers.add()` to specify which messages your handler should process.

#### Basic Pattern Matching Rules

1. **Simple Tag Matching**

   ```lua
   { "Action" = "Do-Something" }  -- Match messages that have an exact Action tag value
   ```

2. **Wildcard Matching**

   ```lua
   { "Recipient" = '_' }  -- Match messages with any Recipient tag value
   ```

3. **Pattern Matching**

   ```lua
   { "Quantity" = "%d+" }  -- Match using Lua string patterns (similar to regex)
   ```

4. **Function-based Matching**
   ```lua
   { "Quantity" = function(v) return tonumber(v) ~= nil end }  -- Custom validation function
   ```

#### Common Pattern Examples

1. **Balance Action Handler**

   ```lua
   { Action = "Balance" }  -- Match messages with Action = "Balance"
   ```

2. **Numeric Quantity Handler**
   ```lua
   { Quantity = "%d+" }  -- Match messages where Quantity is a number
   ```

### Default Action Handlers (AOS 2.0+)

AOS 2.0 introduces simplified syntax for Action-based handlers. Instead of writing explicit pattern functions, you can use these shorthand forms:

```lua
-- Traditional syntax
Handlers.add("Get-Balance", function (msg) return msg.Action == "Balance", doBalance)

-- Simplified syntax options:
Handlers.add("Balance", "Balance", doBalance)  -- Explicit action matching
Handlers.add("Balance", doBalance)             -- Implicit action matching
```

### Resolvers

Resolvers are special tables that can be used as the third argument in `Handlers.add()` to enable conditional execution of functions based on additional pattern matching. Each key in a resolver table is a pattern matching table, and its corresponding value is a function that executes when that pattern matches.

```lua
Handlers.add("Update",
  {
    [{ Status = "Ready" }] = function (msg) print("Ready") end,
    [{ Status = "Pending" }] = function (msg) print("Pending") end,
    [{ Status = "Failed" }] = function (msg) print("Failed") end
  }
)
```

This structure allows developers to create switch/case-like statements where different functions are triggered based on which pattern matches the incoming message. Resolvers are particularly useful when you need to handle a group of related messages differently based on additional criteria.

## Module Structure

- `Handlers._version`: String representing the version of the Handlers library.
- `Handlers.list`: Table storing the list of registered handlers.

## Common Handler Function Parameters

| Parameter            | Type                             | Description                                                                                |
| -------------------- | -------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `name`               | `string`                         | The identifier of the handler item in the handlers list.                                                                                |
| `pattern`            | `table` or `function`            | Specifies how to match messages. As a table, defines required message tags with string values (e.g. `{ Action = "Balance", Recipient = "_" }` requires an "Action" tag with string value "Balance" and any string "Recipient" tag value). As a function, takes a message DataItem and returns: "true" (invoke handler and exit pipeline), "false" (skip handler), or "continue" (invoke handler and continue pipeline). |
| `handler`            | (Resolver) `table` or `function` | Either a resolver table containing pattern-function pairs for conditional execution, or a single function that processes the message. When using a resolver table, each key is a pattern matching table and its value is the function to execute when that pattern matches. When using a function, it takes the message DataItem as an argument and executes business logic.                                            |
| `maxRuns` (optional) | number                           | As of 0.0.5, each handler function takes an optional function to define the amount of times the handler should match before it is removed. The default is infinity.                                                                                |

## Functions

### `Handlers.add(name, pattern, handler)`

Adds a new handler or updates an existing handler by name

### `Handlers.append(name, pattern, handler)`

Appends a new handler to the end of the handlers list.

### `Handlers.once(name, pattern, handler)`

Only runs once when the pattern is matched. Equivalent to setting `maxRuns = 1`. This is the underlying implementation used by the `Receive` function in the messaging system.

### `Handlers.prepend(name, pattern, handler)`

Prepends a new handler to the beginning of the handlers list.

### `Handlers.before(handleName)`

Returns an object that allows adding a new handler before a specified handler.

### `Handlers.after(handleName)`

Returns an object that allows adding a new handler after a specified handler.

### `Handlers.remove(name)`

Removes a handler from the handlers list by name.

## Handler Execution Notes

### Execution Order

- Handlers are executed in the order they appear in `Handlers.list`.
- When a message arrives, each handler's pattern function is called sequentially to determine if it should process the message.

### Pattern Function Return Values

Pattern functions determine the message handling flow based on their return values:

1. **Skip Handler (No Match)**

   - **Return**: `0`, `false`, or any string except "continue" or "break"
   - **Effect**: Skips current handler and proceeds to the next one in the list

2. **Handle and Continue**

   - **Return**: `1` or `"continue"`
   - **Effect**: Processes the message and continues checking subsequent handlers
   - **Use Case**: Ideal for handlers that should always execute (e.g., logging)

3. **Handle and Stop**
   - **Return**: `-1`, `true`, or `"break"`
   - **Effect**: Processes the message and stops checking further handlers
   - **Use Case**: Most common scenario where a handler exclusively handles its matched message

### Practical Examples

- **Logging Handler**: Place at the start of the list and return `"continue"` to log all messages while allowing other handlers to process them.
- **Specific Message Handler**: Return `"break"` to handle matched messages exclusively and prevent further processing by other handlers.

## Handlers.utils

The `Handlers.utils` module provides two functions that are common matching patterns and one function that is a common handle function.

- `hasMatchingData(data: string)`
- `hasMatchingTag(name: string, value: string)`
- `reply(text: string)`

### `Handlers.utils.hasMatchingData(data: string)`

- This helper function returns a pattern matching function that takes a message as input. The returned function checks if the message's `Data` field contains the specified string. You can use this helper directly as the pattern argument when adding a new handler.

  ```lua
  Handlers.add("ping",
      Handlers.utils.hasMatchingData("ping"),
      ...
  )
  ```

### `Handlers.utils.hasMatchingTag(name: string, value: string)`

- This helper function returns a pattern matching function that takes a message as input. The returned function checks if the message has a tag with the specified `name` and `value`. If they match exactly, the pattern returns true and the handler function will be invoked. This helper can be used directly as the pattern argument when adding a new handler.

  ```lua
  Handlers.add("ping",
      Handlers.utils.hasMatchingTag("Action", "Ping"),
      ...
  )
  ```

### `Handlers.utils.reply(text: string)`

- This helper is a simple handle function, it basically places the text value in to the `Data` property of the outbound message.

  ```lua
  Handlers.add("ping",
      Handlers.utils.hasMatchingData("ping"),
      Handlers.utils.reply("pong")
  )
  ```

## Example Handlers

### Pattern Matching Table

```lua
Handlers.add("Ping",    -- Name of the handler
  { Action = "Ping" },  -- Matches messages with Action = "Ping" tag
  function(msg)         -- Business logic to execute on Message
    print("ping")
    msg.reply({ Data = "pong" })
  end
)
```

### Resolver Table Handler

```lua
Handlers.add("Foobarbaz",  -- Name of the handler
  { Action = "Speak" },    -- Matches messages with Action = "Speak" tag
  {
    -- Resolver with pattern-function pairs
    [{ Status = "foo" }] = function(msg) print("foo") end,
    [{ Status = "bar" }] = function(msg) print("bar") end,
    [{ Status = "baz" }]


Prompt: This is a Markdown documentation from the AO documentation repository. This is a continuation from the previous part. Filename: handlers.md Path: ../ao-cookbook/src/references/handlers.md

Response:
 ```lua
  Handlers.add("ping",
      Handlers.utils.hasMatchingData("ping"),
      Handlers.utils.reply("pong")
  )
  ```

## Example Handlers

### Pattern Matching Table

```lua
Handlers.add("Ping",    -- Name of the handler
  { Action = "Ping" },  -- Matches messages with Action = "Ping" tag
  function(msg)         -- Business logic to execute on Message
    print("ping")
    msg.reply({ Data = "pong" })
  end
)
```

### Resolver Table Handler

```lua
Handlers.add("Foobarbaz",  -- Name of the handler
  { Action = "Speak" },    -- Matches messages with Action = "Speak" tag
  {
    -- Resolver with pattern-function pairs
    [{ Status = "foo" }] = function(msg) print("foo") end,
    [{ Status = "bar" }] = function(msg) print("bar") end,
    [{ Status = "baz" }] = function(msg) print("baz") end
  }
)
```

### Function-Based Pattern Matching & Handler

```lua
Handlers.add("Example",    -- Name of the handler
  function(msg)           -- Pattern function matches messages with Action = "Speak" tag
    return msg.Action == "Speak"
  end,
  function(msg)           -- Handler function that executes business logic
    print(msg.Status)
  end
)
```


Prompt: This is a Markdown documentation from the AO documentation repository. Filename: editor-setup.md Path: ../ao-cookbook/src/references/editor-setup.md

Response:
---
next:
  text: "Community"
  link: "/references/community"
---

# Editor setup

Remembering all the built in ao functions and utilities can sometimes be hard. To enhance your developer experience, it is recommended to install the [Lua Language Server](https://luals.github.io) extension into your favorite text editor and add the [ao addon](https://github.com/martonlederer/ao-definitions). It supports all built in aos [modules](../guides/aos/modules/index.md) and [globals](../guides/aos/intro.md#globals).

## VS Code

Install the [sumneko.lua](https://marketplace.visualstudio.com/items?itemName=sumneko.lua) extension:

1. Search for "Lua" by sumneko in the extension marketplace
2. Download and install the extension
3. Open the VS Code command palette with `Shift + Command + P` (Mac) / `Ctrl + Shift + P` (Windows/Linux) and run the following command:

```
> Lua: Open Addon Manager
```

4. In the Addon Manager, search for "ao", it should be the first result. Click "Enable" and enjoy autocomplete!

## Other editors

1. Verify that your editor supports the [language server protocol](https://microsoft.github.io/language-server-protocol/implementors/tools/)
2. Install Lua Language Server by following the instructions at [luals.github.io](https://luals.github.io/#install)
3. Install the "ao" addon to the language server

## BetterIDEa

[BetterIDEa](https://ide.betteridea.dev) is a custom web based IDE for developing on ao.

It offers a built in Lua language server with ao definitions, so you don't need to install anything. Just open the IDE and start coding!

Features include:

- Code completion
- Cell based notebook ui for rapid development
- Easy process management
- Markdown and Latex cell support
- Share projects with anyone through ao processes
- Tight integration with [ao package manager](https://apm.betteridea.dev)

Read detailed information about the various features and integrations of the IDE in the [documentation](https://docs.betteridea.dev).


Prompt: This is a Markdown documentation from the AO documentation repository. Filename: glossary.md Path: ../ao-cookbook/src/references/glossary.md

Response:
<style>
  .glossary-iframe {
    height: 500px;
    width: 100%;
    border: none;
  }

  html:not(.dark) .dark-mode-iframe {
    display: none;
  }

  html.dark .light-mode-iframe {
    display: none;
  }
</style>

<iframe class="glossary-iframe light-mode-iframe" src="https://glossary.permagate.io/"></iframe>
<iframe class="glossary-iframe dark-mode-iframe" src="https://glossary.permagate.io/?link-color=%2334d399&bg-color=%231b1b1f&text-color=%23e0e0e0&border-color=%23444444&hover-bg=%23222222&heading-color=%23ffffff&button-bg=%23444444&button-text=%23ffffff&section-bg=%23333333&section-color=%23ffffff&category-bg=%23333333&category-text=%23ffffff&tag-bg=%233a3a3a&tag-text=%23e0e0e0&secondary-text=%23a0a0a0&result-bg=%231e1e1e&result-hover=%23333333"></iframe>