Skip to content

Conversation

@devin-ai-integration
Copy link
Contributor

@devin-ai-integration devin-ai-integration bot commented Sep 3, 2025

Add Mastra using-a-tool example with Agentuity wrapper

Summary

Converts the Mastra "Using a Tool" example to an Agentuity agent wrapper following established patterns. The example creates a London weather assistant that uses Mastra's tool system to fetch historical weather data from the Open-Meteo API.

Key components:

  • london-weather-tool.ts - Mastra tool that fetches year-to-date London weather data
  • london-weather-agent - Agentuity-wrapped Mastra agent with tool integration
  • Standard project structure following other framework examples

Preserves original framework functionality while wrapping with Agentuity SDK interfaces (AgentRequest, AgentResponse, AgentContext).

Review & Testing Checklist for Human

  • Install dependencies and verify compilation - Code shows TypeScript errors due to missing packages. Verify npm install works and code compiles without errors.
  • Test the weather tool functionality - The tool fetches from archive-api.open-meteo.com with hardcoded London coordinates. Verify the API endpoint works and returns expected data structure.
  • Deploy and test in Agentuity platform - Verify the agent can be deployed with agentuity dev and responds correctly to weather queries in the console.
  • Validate request handling - The agent uses req.text() instead of req.data.text() like other examples. Verify this works correctly with the Agentuity request handling.

Notes

  • This code was not tested locally due to missing dependencies, so compilation and runtime behavior need verification
  • The weather tool relies on external API availability and could fail if the service is down
  • Example follows the established Agentuity wrapper pattern from other framework examples

Link to Devin run: https://app.devin.ai/sessions/5c8de41d0cf04b7f901a0ad6f7946064
Requested by: Dhilan Fye (dfye@agentuity.com)

Summary by CodeRabbit

  • New Features

    • Introduces a Mastra “Using a Tool” example powered by Agentuity.
    • Adds a runnable agent that answers London year-to-date weather questions using an integrated weather data tool.
    • Provides simple startup via build/bundle/start scripts.
  • Documentation

    • New README with setup steps, sample prompts, and project overview.
    • Added guidelines for authoring agents and configuration.
  • Chores

    • Added project configuration, TypeScript settings, ignore rules, and package scripts.
    • Included runtime entrypoint and agent configuration for development and deployment.

- Convert Mastra tool example from https://mastra.ai/en/examples/agents/using-a-tool
- Preserve all original Mastra framework functionality
- Wrap with Agentuity SDK interfaces (AgentRequest, AgentResponse, AgentContext)
- Include London weather tool with historical data access
- Follow established Agentuity wrapper patterns from existing examples
- Add welcome() function with weather-specific prompts
- Include proper error handling with ctx.logger
- Complete project structure with package.json, tsconfig.json, README

Co-Authored-By: Dhilan Fye <dfye@agentuity.com>
@devin-ai-integration
Copy link
Contributor Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment and CI monitoring

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 3, 2025

Walkthrough

Adds a new Mastra-based “Using a Tool” example wrapped with Agentuity SDK, including project config, entrypoint, TypeScript setup, docs, and a London weather agent that uses a Mastra tool to fetch year-to-date weather data from Open-Meteo and respond to user prompts.

Changes

Cohort / File(s) Summary
Cursor rules documentation
frameworks/mastra/using-a-tool/.cursorrules/agent.mdc, frameworks/mastra/using-a-tool/.cursorrules/agentuity.mdc
Adds editor rules/guidelines for Agentuity agents and configuration files with YAML front matter targeting agent files and agentuity.yaml.
Project scaffolding & runtime
frameworks/mastra/using-a-tool/agentuity.yaml, frameworks/mastra/using-a-tool/package.json, frameworks/mastra/using-a-tool/index.ts, frameworks/mastra/using-a-tool/tsconfig.json, frameworks/mastra/using-a-tool/.gitignore, frameworks/mastra/using-a-tool/README.md
Introduces Agentuity project config, npm scripts, serve entrypoint, strict TS config, ignore rules, and README describing the example and setup.
Agent implementation
frameworks/mastra/using-a-tool/src/agents/london-weather-agent/index.ts
Adds agent with welcome() and default handler using Mastra Agent and OpenAI model; integrates tool, processes prompt, returns text; logs errors.
Tool implementation
frameworks/mastra/using-a-tool/src/tools/london-weather-tool.ts
Adds Mastra tool to fetch year-to-date London weather from Open-Meteo; defines output schema and execute logic; returns parsed arrays.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor U as User
  participant S as Agentuity Server (serve)
  participant A as LondonWeatherAgent
  participant M as Mastra Agent (GPT-4o)
  participant T as londonWeatherTool
  participant W as Open‑Meteo API

  U->>S: HTTP request (prompt)
  S->>A: AgentRequest/Response/Context
  A->>M: generate(prompt, tools=[T])
  M->>T: invoke execute(startDate..endDate)
  T->>W: GET /archive (London coords, daily metrics)
  W-->>T: JSON daily data
  T-->>M: {date[], temp_max[], ...}
  M-->>A: result.text
  A-->>S: resp.text(result.text)
  S-->>U: HTTP 200 (text)

  rect rgba(255,230,230,0.4)
    note over A,S: On error
    A->>S: resp.text("I'm sorry, ...")
    S-->>U: HTTP 200 (apology)
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • rblalock
  • nnance

Poem

A rabbit taps the weather vane,
London’s clouds in tidy chain—
Tools fetch winds and rains-to-date,
Agents stitch a terse update.
Data hops from sky to screen,
Year-to-now in charts so clean.
Thump! Another forecast seen. 🌦️🐇

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch devin/1756860060-mastra-tool-example

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore or @coderabbit ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@coderabbitai coderabbitai bot requested review from nnance and rblalock September 3, 2025 00:45
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (14)
frameworks/mastra/using-a-tool/.gitignore (1)

1-9: Add a few common Node/TS artefacts to ignore.

Covers noisy build/test files that often slip in.

 node_modules/
 .env
 .env.local
 .env.development
 .env.production
 .agentuity/
 dist/
 *.log
+.npmrc
+npm-debug.log*
+yarn-debug.log*
+pnpm-debug.log*
+coverage/
+*.tsbuildinfo
+.eslintcache
 .DS_Store
frameworks/mastra/using-a-tool/.cursorrules/agentuity.mdc (1)

9-9: Capitalize product name.

Minor copy fix.

-This file is used by agentuity to configure the AI Agent project.  You should NOT suggest edits to this file.
+This file is used by Agentuity to configure the AI Agent project. You should NOT suggest edits to this file.
frameworks/mastra/using-a-tool/tsconfig.json (1)

2-19: Enable Node types and sturdier module detection.

Prevents missing types for process/env and avoids heuristic mis-detection with ESM.

   "compilerOptions": {
     "target": "ES2022",
     "lib": ["ES2022"],
     "module": "ESNext",
     "moduleResolution": "bundler",
     "allowImportingTsExtensions": true,
     "noEmit": true,
     "strict": true,
     "noUnusedLocals": true,
     "noUnusedParameters": true,
     "noFallthroughCasesInSwitch": true,
     "skipLibCheck": true,
     "allowSyntheticDefaultImports": true,
     "esModuleInterop": true,
     "forceConsistentCasingInFileNames": true,
     "resolveJsonModule": true,
     "isolatedModules": true,
-    "verbatimModuleSyntax": true
+    "verbatimModuleSyntax": true,
+    "moduleDetection": "force",
+    "types": ["node"]
   },
frameworks/mastra/using-a-tool/README.md (2)

22-29: Specify a language for the fenced code block.

Fixes MD040 and improves rendering.

-```
+```text
 src/
 ├── agents/
 │   └── london-weather-agent/
 │       └── index.ts          # Main agent implementation
 └── tools/
     └── london-weather-tool.ts # Weather data tool definition
-```
+```

54-57: Document npx path for running without a global CLI.

Reduces setup friction.

    ```bash
-   agentuity dev
+   agentuity dev
+   # If you don't have the CLI installed:
+   npx agentuity@latest dev
    ```
frameworks/mastra/using-a-tool/.cursorrules/agent.mdc (2)

28-28: Minor grammar fix.

-The AgentRequest interface provides a set of helper methods and public variables which can be used for working with data has been passed to the Agent.
+The AgentRequest interface provides helper methods and public variables for working with data that has been passed to the Agent.

9-15: Call out the correct text accessor

All existing TypeScript agents still use the old req.data.text() accessor—update examples to use the top-level req.text() method on AgentRequest.

- Use the provided logger from the `AgentContext` interface such as `ctx.logger.info("my message: %s", "hello")`
+ Use the provided logger from the `AgentContext` interface such as `ctx.logger.info("my message: %s", "hello")`
+ For text inputs, prefer `await req.text()` instead of `await req.data.text()`.
frameworks/mastra/using-a-tool/package.json (3)

5-5: Remove or align the "main" entry to avoid confusion.

This package runs via Agentuity bundling (.agentuity/index.js). "main": "index.js" is misleading and unused.

Apply:

-  "main": "index.js",
+  // "main" not needed for this example; removed to avoid confusion

7-12: Add a typecheck script for CI.

Quick safety net for TS errors without building.

   "scripts": {
     "build": "agentuity build",
     "prestart": "agentuity bundle",
     "start": "node --env-file .env .agentuity/index.js",
-    "test": "echo \"Error: no test specified\" && exit 1"
+    "test": "echo \"Error: no test specified\" && exit 1",
+    "typecheck": "tsc --noEmit"
   },

1-12: Pin required Node version (supports --env-file and global fetch).

Make runtime expectations explicit.

 {
   "name": "mastra-using-a-tool",
   "description": "Mastra agent with London weather tool wrapped in Agentuity SDK",
   "version": "0.0.1",
-  "type": "module",
+  "type": "module",
+  "engines": { "node": ">=22" },

Verify your deployment Node version matches this constraint.

frameworks/mastra/using-a-tool/index.ts (1)

1-3: Handle potential serve() rejection (optional).

Tiny hardening: avoid unhandled promise rejections.

-import { serve } from "@agentuity/sdk";
-
-serve();
+import { serve } from "@agentuity/sdk";
+void serve().catch((err) => {
+  // eslint-disable-next-line no-console
+  console.error("Agentuity serve failed:", err);
+  process.exitCode = 1;
+});
frameworks/mastra/using-a-tool/src/tools/london-weather-tool.ts (2)

7-14: Consider nullable numbers in the schema (API can emit nulls).

Open‑Meteo occasionally returns nulls for some aggregates (e.g., snowfall). Either normalize to 0 (as above) or allow nullable numbers.

   outputSchema: z.object({
-    date: z.array(z.string()),
-    temp_max: z.array(z.number()),
-    temp_min: z.array(z.number()),
-    rainfall: z.array(z.number()),
-    windspeed: z.array(z.number()),
-    snowfall: z.array(z.number()),
+    date: z.array(z.string()),
+    temp_max: z.array(z.number()),
+    temp_min: z.array(z.number()),
+    rainfall: z.array(z.number()),
+    windspeed: z.array(z.number()),
+    snowfall: z.array(z.number()),
   }),

If you keep the normalization, the current non-nullable schema is fine.


16-17: Optional: use yesterday for a stable “year-to-date” cutoff.

Daily aggregates for “today” may be partial. Using yesterday avoids partial-day artifacts.

-    const endDate = now.toISOString().split("T")[0];
+    const end = new Date(now);
+    end.setDate(end.getDate() - 1);
+    const endDate = end.toISOString().split("T")[0];
frameworks/mastra/using-a-tool/src/agents/london-weather-agent/index.ts (1)

37-37: Optional: model via env for easier switching.

Allow overriding the model with an env var, defaulting to gpt-4o.

-      model: openai("gpt-4o"),
+      model: openai(process.env.OPENAI_MODEL ?? "gpt-4o"),

Happy to wire a small config helper if you prefer.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 61337c0 and 039c33a.

📒 Files selected for processing (10)
  • frameworks/mastra/using-a-tool/.cursorrules/agent.mdc (1 hunks)
  • frameworks/mastra/using-a-tool/.cursorrules/agentuity.mdc (1 hunks)
  • frameworks/mastra/using-a-tool/.gitignore (1 hunks)
  • frameworks/mastra/using-a-tool/README.md (1 hunks)
  • frameworks/mastra/using-a-tool/agentuity.yaml (1 hunks)
  • frameworks/mastra/using-a-tool/index.ts (1 hunks)
  • frameworks/mastra/using-a-tool/package.json (1 hunks)
  • frameworks/mastra/using-a-tool/src/agents/london-weather-agent/index.ts (1 hunks)
  • frameworks/mastra/using-a-tool/src/tools/london-weather-tool.ts (1 hunks)
  • frameworks/mastra/using-a-tool/tsconfig.json (1 hunks)
🧰 Additional context used
🧠 Learnings (37)
📓 Common learnings
Learnt from: CR
PR: agentuity/examples#0
File: frameworks/mastra/basic/.cursor/rules/sdk.mdc:0-0
Timestamp: 2025-06-23T17:15:21.314Z
Learning: For best practices in Agentuity SDK projects, use TypeScript for type safety, import types from agentuity/sdk, use structured error handling with try/catch, leverage the provided logger, use storage APIs for data persistence, and consider agent communication for complex workflows.
Learnt from: CR
PR: agentuity/examples#0
File: patterns/llmAsJury/.cursor/rules/sdk.mdc:0-0
Timestamp: 2025-06-23T17:17:19.027Z
Learning: Use TypeScript for better type safety and IDE support when developing with the Agentuity SDK.
Learnt from: CR
PR: agentuity/examples#0
File: frameworks/vercel/basic/.cursor/rules/sdk.mdc:0-0
Timestamp: 2025-06-23T17:16:58.079Z
Learning: Use TypeScript for better type safety and IDE support when developing with the Agentuity SDK.
Learnt from: CR
PR: agentuity/examples#0
File: frameworks/langgraph/basic/.cursor/rules/sdk.mdc:0-0
Timestamp: 2025-06-23T17:14:46.802Z
Learning: The Agentuity JavaScript SDK provides core interfaces such as AgentHandler, AgentRequest, AgentResponse, and AgentContext for building AI agents in TypeScript or JavaScript.
📚 Learning: 2025-06-23T17:15:21.314Z
Learnt from: CR
PR: agentuity/examples#0
File: frameworks/mastra/basic/.cursor/rules/sdk.mdc:0-0
Timestamp: 2025-06-23T17:15:21.314Z
Learning: For best practices in Agentuity SDK projects, use TypeScript for type safety, import types from agentuity/sdk, use structured error handling with try/catch, leverage the provided logger, use storage APIs for data persistence, and consider agent communication for complex workflows.

Applied to files:

  • frameworks/mastra/using-a-tool/README.md
  • frameworks/mastra/using-a-tool/index.ts
  • frameworks/mastra/using-a-tool/package.json
  • frameworks/mastra/using-a-tool/.cursorrules/agent.mdc
📚 Learning: 2025-07-17T13:39:44.988Z
Learnt from: CR
PR: agentuity/examples#0
File: agents/composio/.cursor/rules/sdk.mdc:0-0
Timestamp: 2025-07-17T13:39:44.988Z
Learning: Applies to agents/composio/src/agents/**/*.ts : Use TypeScript for better type safety and IDE support

Applied to files:

  • frameworks/mastra/using-a-tool/tsconfig.json
📚 Learning: 2025-07-17T13:39:31.143Z
Learnt from: CR
PR: agentuity/examples#0
File: agents/agent-riza/.cursor/rules/sdk.mdc:0-0
Timestamp: 2025-07-17T13:39:31.143Z
Learning: Applies to agents/agent-riza/src/agents/**/*.ts : Use TypeScript for better type safety and IDE support

Applied to files:

  • frameworks/mastra/using-a-tool/tsconfig.json
📚 Learning: 2025-07-17T13:39:37.133Z
Learnt from: CR
PR: agentuity/examples#0
File: agents/composio/.cursor/rules/agent.mdc:0-0
Timestamp: 2025-07-17T13:39:37.133Z
Learning: Applies to agents/composio/**/src/agents/**/index.ts : The file should export a default function

Applied to files:

  • frameworks/mastra/using-a-tool/index.ts
📚 Learning: 2025-07-17T13:40:37.445Z
Learnt from: CR
PR: agentuity/examples#0
File: agentuity/sdk-js/streaming/.cursor/rules/agent.mdc:0-0
Timestamp: 2025-07-17T13:40:37.445Z
Learning: Applies to agentuity/sdk-js/streaming/**/src/agents/**/index.ts : The file should export a default function

Applied to files:

  • frameworks/mastra/using-a-tool/index.ts
📚 Learning: 2025-07-17T13:39:55.775Z
Learnt from: CR
PR: agentuity/examples#0
File: agents/deep-research-js/.cursor/rules/agent.mdc:0-0
Timestamp: 2025-07-17T13:39:55.775Z
Learning: Applies to agents/deep-research-js/**/src/agents/**/index.ts : The file should export a default function

Applied to files:

  • frameworks/mastra/using-a-tool/index.ts
📚 Learning: 2025-07-17T13:38:58.657Z
Learnt from: CR
PR: agentuity/examples#0
File: agents/Startup_News_Scraper/.cursor/rules/agent.mdc:0-0
Timestamp: 2025-07-17T13:38:58.657Z
Learning: Applies to agents/Startup_News_Scraper/**/src/agents/**/index.ts : The file should export a default function

Applied to files:

  • frameworks/mastra/using-a-tool/index.ts
📚 Learning: 2025-07-17T13:39:18.709Z
Learnt from: CR
PR: agentuity/examples#0
File: agents/agent-riza/.cursor/rules/agent.mdc:0-0
Timestamp: 2025-07-17T13:39:18.709Z
Learning: Applies to agents/agent-riza/**/src/agents/**/index.ts : The file should export a default function

Applied to files:

  • frameworks/mastra/using-a-tool/index.ts
📚 Learning: 2025-06-23T17:14:46.802Z
Learnt from: CR
PR: agentuity/examples#0
File: frameworks/langgraph/basic/.cursor/rules/sdk.mdc:0-0
Timestamp: 2025-06-23T17:14:46.802Z
Learning: The Agentuity JavaScript SDK provides core interfaces such as AgentHandler, AgentRequest, AgentResponse, and AgentContext for building AI agents in TypeScript or JavaScript.

Applied to files:

  • frameworks/mastra/using-a-tool/index.ts
  • frameworks/mastra/using-a-tool/src/agents/london-weather-agent/index.ts
📚 Learning: 2025-07-17T13:39:44.988Z
Learnt from: CR
PR: agentuity/examples#0
File: agents/composio/.cursor/rules/sdk.mdc:0-0
Timestamp: 2025-07-17T13:39:44.988Z
Learning: Applies to agents/composio/src/agents/**/*.ts : Import types from `agentuity/sdk`

Applied to files:

  • frameworks/mastra/using-a-tool/index.ts
📚 Learning: 2025-06-23T17:16:58.079Z
Learnt from: CR
PR: agentuity/examples#0
File: frameworks/vercel/basic/.cursor/rules/sdk.mdc:0-0
Timestamp: 2025-06-23T17:16:58.079Z
Learning: Import types from agentuity/sdk to ensure consistency and leverage type definitions.

Applied to files:

  • frameworks/mastra/using-a-tool/index.ts
📚 Learning: 2025-07-17T13:39:11.850Z
Learnt from: CR
PR: agentuity/examples#0
File: agents/Startup_News_Scraper/.cursor/rules/sdk.mdc:0-0
Timestamp: 2025-07-17T13:39:11.850Z
Learning: Applies to agents/Startup_News_Scraper/src/agents/**/*.ts : Import types from `agentuity/sdk`

Applied to files:

  • frameworks/mastra/using-a-tool/index.ts
📚 Learning: 2025-07-17T13:39:31.143Z
Learnt from: CR
PR: agentuity/examples#0
File: agents/agent-riza/.cursor/rules/sdk.mdc:0-0
Timestamp: 2025-07-17T13:39:31.143Z
Learning: Applies to agents/agent-riza/src/agents/**/*.ts : Import types from `agentuity/sdk`

Applied to files:

  • frameworks/mastra/using-a-tool/index.ts
📚 Learning: 2025-07-17T13:40:05.817Z
Learnt from: CR
PR: agentuity/examples#0
File: agents/deep-research-js/.cursor/rules/sdk.mdc:0-0
Timestamp: 2025-07-17T13:40:05.817Z
Learning: Applies to agents/deep-research-js/src/agents/**/*.ts : Import types from `agentuity/sdk`

Applied to files:

  • frameworks/mastra/using-a-tool/index.ts
📚 Learning: 2025-06-23T17:16:16.519Z
Learnt from: CR
PR: agentuity/examples#0
File: frameworks/openai/from-oai/.cursor/rules/agentuity.mdc:0-0
Timestamp: 2025-06-23T17:16:16.519Z
Learning: The Agentuity configuration file (agentuity.yaml) is reserved for configuring the AI Agent project and should not be edited or suggested for edits during code review.

Applied to files:

  • frameworks/mastra/using-a-tool/.cursorrules/agentuity.mdc
  • frameworks/mastra/using-a-tool/agentuity.yaml
📚 Learning: 2025-06-23T17:16:33.550Z
Learnt from: CR
PR: agentuity/examples#0
File: frameworks/pydantic/basic/.cursor/rules/agentuity.mdc:0-0
Timestamp: 2025-06-23T17:16:33.550Z
Learning: The agentuity.yaml file is a configuration file used by Agentuity to configure the AI Agent project and should not be edited or suggested for edits during code review.

Applied to files:

  • frameworks/mastra/using-a-tool/.cursorrules/agentuity.mdc
  • frameworks/mastra/using-a-tool/agentuity.yaml
📚 Learning: 2025-07-17T13:41:01.314Z
Learnt from: CR
PR: agentuity/examples#0
File: frameworks/agno/from_agno/.cursor/rules/agentuity.mdc:0-0
Timestamp: 2025-07-17T13:41:01.314Z
Learning: Applies to frameworks/agno/from_agno/**/agentuity.yaml : Do not suggest edits to the Agentuity AI Configuration file (agentuity.yaml)

Applied to files:

  • frameworks/mastra/using-a-tool/.cursorrules/agentuity.mdc
  • frameworks/mastra/using-a-tool/agentuity.yaml
📚 Learning: 2025-06-23T17:13:52.368Z
Learnt from: CR
PR: agentuity/examples#0
File: frameworks/crewai/socialagent/.cursor/rules/agentuity.mdc:0-0
Timestamp: 2025-06-23T17:13:52.368Z
Learning: The 'agentuity.yaml' file is a configuration file used by Agentuity to configure the AI Agent project and should not be edited or suggested for edits.

Applied to files:

  • frameworks/mastra/using-a-tool/.cursorrules/agentuity.mdc
  • frameworks/mastra/using-a-tool/agentuity.yaml
📚 Learning: 2025-06-23T17:15:46.735Z
Learnt from: CR
PR: agentuity/examples#0
File: frameworks/miscellaneous/mem0/mem0demo/.cursor/rules/agentuity.mdc:0-0
Timestamp: 2025-06-23T17:15:46.735Z
Learning: The Agentuity configuration file (agentuity.yaml) is used to configure the AI Agent project and should not be edited or suggested for edits.

Applied to files:

  • frameworks/mastra/using-a-tool/.cursorrules/agentuity.mdc
  • frameworks/mastra/using-a-tool/agentuity.yaml
📚 Learning: 2025-06-23T17:15:30.804Z
Learnt from: CR
PR: agentuity/examples#0
File: frameworks/miscellaneous/grokLiveSearch/.cursor/rules/agentuity.mdc:0-0
Timestamp: 2025-06-23T17:15:30.804Z
Learning: In the context of Agentuity AI projects, the 'agentuity.yaml' file is a configuration file that should not be edited or suggested for edits during code review.

Applied to files:

  • frameworks/mastra/using-a-tool/.cursorrules/agentuity.mdc
  • frameworks/mastra/using-a-tool/agentuity.yaml
📚 Learning: 2025-06-23T17:14:18.092Z
Learnt from: CR
PR: agentuity/examples#0
File: frameworks/langchain/basic/.cursor/rules/agentuity.mdc:0-0
Timestamp: 2025-06-23T17:14:18.092Z
Learning: The file 'agentuity.yaml' is used to configure the Agentuity AI Agent project and should not be edited or suggested for edits.

Applied to files:

  • frameworks/mastra/using-a-tool/.cursorrules/agentuity.mdc
  • frameworks/mastra/using-a-tool/agentuity.yaml
📚 Learning: 2025-07-17T13:39:39.665Z
Learnt from: CR
PR: agentuity/examples#0
File: agents/composio/.cursor/rules/agentuity.mdc:0-0
Timestamp: 2025-07-17T13:39:39.665Z
Learning: Applies to agents/composio/**/agentuity.yaml : Do NOT suggest edits to the Agentuity AI Configuration file (agentuity.yaml)

Applied to files:

  • frameworks/mastra/using-a-tool/.cursorrules/agentuity.mdc
📚 Learning: 2025-06-23T17:16:02.063Z
Learnt from: CR
PR: agentuity/examples#0
File: frameworks/openai/from-oai-typescript/.cursor/rules/agentuity.mdc:0-0
Timestamp: 2025-06-23T17:16:02.063Z
Learning: The Agentuity AI Configuration file (agentuity.yaml) is used to configure the AI Agent project and should not be edited or suggested for edits.

Applied to files:

  • frameworks/mastra/using-a-tool/.cursorrules/agentuity.mdc
  • frameworks/mastra/using-a-tool/agentuity.yaml
📚 Learning: 2025-06-23T17:17:12.992Z
Learnt from: CR
PR: agentuity/examples#0
File: patterns/llmAsJury/.cursor/rules/agentuity.mdc:0-0
Timestamp: 2025-06-23T17:17:12.992Z
Learning: In the context of Agentuity AI projects, the agentuity.yaml file is a configuration file that should not be edited or suggested for edits during code review.

Applied to files:

  • frameworks/mastra/using-a-tool/.cursorrules/agentuity.mdc
  • frameworks/mastra/using-a-tool/agentuity.yaml
📚 Learning: 2025-07-17T13:39:23.010Z
Learnt from: CR
PR: agentuity/examples#0
File: agents/agent-riza/.cursor/rules/agentuity.mdc:0-0
Timestamp: 2025-07-17T13:39:23.010Z
Learning: Applies to agents/agent-riza/**/agentuity.yaml : Do not suggest edits to the Agentuity AI Configuration file (agentuity.yaml)

Applied to files:

  • frameworks/mastra/using-a-tool/.cursorrules/agentuity.mdc
📚 Learning: 2025-07-17T13:38:58.657Z
Learnt from: CR
PR: agentuity/examples#0
File: agents/Startup_News_Scraper/.cursor/rules/agent.mdc:0-0
Timestamp: 2025-07-17T13:38:58.657Z
Learning: Applies to agents/Startup_News_Scraper/**/src/agents/**/index.ts : Prefer loading types from the node modules package `agentuity/sdk` in the node_modules folder

Applied to files:

  • frameworks/mastra/using-a-tool/package.json
📚 Learning: 2025-06-23T17:15:12.561Z
Learnt from: CR
PR: agentuity/examples#0
File: frameworks/mastra/basic/.cursor/rules/agent.mdc:0-0
Timestamp: 2025-06-23T17:15:12.561Z
Learning: In Agentuity AI Agent files (`**/src/agents/**/index.ts`), the default export should be an async function that handles the agent logic, typically accepting parameters `(req: AgentRequest, resp: AgentResponse, ctx: AgentContext)`.

Applied to files:

  • frameworks/mastra/using-a-tool/src/agents/london-weather-agent/index.ts
  • frameworks/mastra/using-a-tool/.cursorrules/agent.mdc
📚 Learning: 2025-06-23T17:16:49.315Z
Learnt from: CR
PR: agentuity/examples#0
File: frameworks/vercel/basic/.cursor/rules/agent.mdc:0-0
Timestamp: 2025-06-23T17:16:49.315Z
Learning: When writing an Agent in TypeScript for Agentuity, always use the types provided by the `agentuity/sdk` package for AgentRequest, AgentResponse, and AgentContext to ensure type safety and compatibility.

Applied to files:

  • frameworks/mastra/using-a-tool/src/agents/london-weather-agent/index.ts
  • frameworks/mastra/using-a-tool/.cursorrules/agent.mdc
📚 Learning: 2025-06-23T17:14:39.393Z
Learnt from: CR
PR: agentuity/examples#0
File: frameworks/langgraph/basic/.cursor/rules/agent.mdc:0-0
Timestamp: 2025-06-23T17:14:39.393Z
Learning: In Agentuity AI Agent files (`**/src/agents/**/index.ts`), import types such as `AgentRequest`, `AgentResponse`, and `AgentContext` from the `agentuity/sdk` package to ensure type safety and consistency.

Applied to files:

  • frameworks/mastra/using-a-tool/src/agents/london-weather-agent/index.ts
  • frameworks/mastra/using-a-tool/.cursorrules/agent.mdc
📚 Learning: 2025-06-23T17:16:58.079Z
Learnt from: CR
PR: agentuity/examples#0
File: frameworks/vercel/basic/.cursor/rules/sdk.mdc:0-0
Timestamp: 2025-06-23T17:16:58.079Z
Learning: In the Agentuity JavaScript SDK, the main handler for an agent should implement the AgentHandler type: (request: AgentRequest, response: AgentResponse, context: AgentContext) => Promise<AgentResponseType>.

Applied to files:

  • frameworks/mastra/using-a-tool/src/agents/london-weather-agent/index.ts
📚 Learning: 2025-06-23T17:15:21.314Z
Learnt from: CR
PR: agentuity/examples#0
File: frameworks/mastra/basic/.cursor/rules/sdk.mdc:0-0
Timestamp: 2025-06-23T17:15:21.314Z
Learning: In the Agentuity JavaScript SDK, the main handler for an agent should implement the AgentHandler type: a function that takes (request: AgentRequest, response: AgentResponse, context: AgentContext) and returns a Promise of AgentResponseType.

Applied to files:

  • frameworks/mastra/using-a-tool/src/agents/london-weather-agent/index.ts
📚 Learning: 2025-06-23T17:14:39.393Z
Learnt from: CR
PR: agentuity/examples#0
File: frameworks/langgraph/basic/.cursor/rules/agent.mdc:0-0
Timestamp: 2025-06-23T17:14:39.393Z
Learning: In Agentuity AI Agent files (`**/src/agents/**/index.ts`), always use the provided logger from the `AgentContext` interface (e.g., `ctx.logger.info(...)`) for logging, rather than custom or external logging solutions.

Applied to files:

  • frameworks/mastra/using-a-tool/.cursorrules/agent.mdc
📚 Learning: 2025-06-23T17:15:59.829Z
Learnt from: CR
PR: agentuity/examples#0
File: frameworks/openai/from-oai-typescript/.cursor/rules/agent.mdc:0-0
Timestamp: 2025-06-23T17:15:59.829Z
Learning: In TypeScript AI Agent files located at '**/src/agents/**/index.ts', use the provided logger from the `AgentContext` interface (e.g., `ctx.logger.info(...)`) for logging, rather than custom or external logging solutions.

Applied to files:

  • frameworks/mastra/using-a-tool/.cursorrules/agent.mdc
📚 Learning: 2025-07-17T13:39:18.709Z
Learnt from: CR
PR: agentuity/examples#0
File: agents/agent-riza/.cursor/rules/agent.mdc:0-0
Timestamp: 2025-07-17T13:39:18.709Z
Learning: Applies to agents/agent-riza/**/src/agents/**/index.ts : Prefer naming the default function Agent or the name of the Agent based on the context of the Agent description

Applied to files:

  • frameworks/mastra/using-a-tool/.cursorrules/agent.mdc
📚 Learning: 2025-06-23T17:17:10.338Z
Learnt from: CR
PR: agentuity/examples#0
File: patterns/llmAsJury/.cursor/rules/agent.mdc:0-0
Timestamp: 2025-06-23T17:17:10.338Z
Learning: In TypeScript AI Agent files located at '**/src/agents/**/index.ts', always use the provided logger from the `AgentContext` interface (e.g., `ctx.logger.info(...)`) for logging, rather than custom logging solutions.

Applied to files:

  • frameworks/mastra/using-a-tool/.cursorrules/agent.mdc
📚 Learning: 2025-07-17T13:41:25.437Z
Learnt from: CR
PR: agentuity/examples#0
File: frameworks/crewai/basic/.cursor/rules/agentuity.mdc:0-0
Timestamp: 2025-07-17T13:41:25.437Z
Learning: Applies to frameworks/crewai/basic/**/agentuity.yaml : Do not suggest edits to the agentuity.yaml configuration file

Applied to files:

  • frameworks/mastra/using-a-tool/agentuity.yaml
🪛 LanguageTool
frameworks/mastra/using-a-tool/README.md

[grammar] ~15-~15: There might be a mistake here.
Context: ...r-to-date weather information for London - Tool Integration: Uses Mastra's `creat...

(QB_NEW_EN)


[grammar] ~16-~16: There might be a mistake here.
Context: ...function to define the weather data tool - Agentuity Wrapper: Wrapped with Agentu...

(QB_NEW_EN)


[grammar] ~17-~17: There might be a mistake here.
Context: ...h Agentuity SDK for seamless integration - Error Handling: Proper error logging u...

(QB_NEW_EN)


[grammar] ~33-~33: There might be a mistake here.
Context: ...ality The londonWeatherTool provides: - Daily temperature maximums and minimums ...

(QB_NEW_EN)


[grammar] ~34-~34: There might be a mistake here.
Context: ... Daily temperature maximums and minimums - Precipitation/rainfall data - Wind speed...

(QB_NEW_EN)


[grammar] ~35-~35: There might be a mistake here.
Context: ...d minimums - Precipitation/rainfall data - Wind speed measurements - Snowfall amoun...

(QB_NEW_EN)


[grammar] ~36-~36: There might be a mistake here.
Context: .../rainfall data - Wind speed measurements - Snowfall amounts - Data from January 1st...

(QB_NEW_EN)


[grammar] ~37-~37: There might be a mistake here.
Context: ...nd speed measurements - Snowfall amounts - Data from January 1st of current year to...

(QB_NEW_EN)


[grammar] ~38-~38: There might be a mistake here.
Context: ...nowfall amounts - Data from January 1st of current year to present ## Usage Examp...

(QB_NEW_EN)


[grammar] ~38-~38: There might be a mistake here.
Context: ...- Data from January 1st of current year to present ## Usage Examples - "How many...

(QB_NEW_EN)


[grammar] ~63-~63: There might be a mistake here.
Context: ...ra framework for agent and tool creation - @ai-sdk/openai: OpenAI integration for...

(QB_NEW_EN)


[grammar] ~64-~64: There might be a mistake here.
Context: ...penAI integration for the language model - @agentuity/sdk: Agentuity SDK for requ...

(QB_NEW_EN)


[grammar] ~65-~65: There might be a mistake here.
Context: ...ntuity SDK for request/response handling - zod: Schema validation for tool inputs...

(QB_NEW_EN)

🪛 markdownlint-cli2 (0.17.2)
frameworks/mastra/using-a-tool/README.md

22-22: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🪛 Biome (2.1.2)
frameworks/mastra/using-a-tool/src/agents/london-weather-agent/index.ts

[error] 18-18: Shouldn't redeclare 'Agent'. Consider to delete it or rename it.

'Agent' is defined here:

(lint/suspicious/noRedeclare)

🔇 Additional comments (5)
frameworks/mastra/using-a-tool/package.json (1)

16-25: Double-check Mastra package consistency. You depend on both mastra (devDependencies; ^0.2.9-alpha.4) and @mastra/core (dependencies; ^0.5.0-alpha.4). Verify compatibility by running in the subpackage:

cd frameworks/mastra/using-a-tool
npm ci
npm run typecheck

Ensure there are no type errors when importing Agent/Tool APIs from both packages.

frameworks/mastra/using-a-tool/agentuity.yaml (1)

1-18: Configuration file acknowledged. No review suggestions per project rules.

frameworks/mastra/using-a-tool/src/agents/london-weather-agent/index.ts (3)

24-24: Good: using req.text() matches the Agentuity request API.


44-51: Solid error handling and user-facing fallback.


37-39: Confirm Mastra tools registration shape
Depending on your Mastra version, the tools option may need to be an array ([londonWeatherTool]) instead of an object ({ londonWeatherTool }). Run your TypeScript typecheck to verify and update accordingly.

- Prefer loading types from the node modules package `@agentuity/sdk` in the node_modules folder
- The file should export a default function
- Prefer naming the default function Agent or the name of the Agent based on the context of the Agent description
- All code should be in Typescript format
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Spell “TypeScript” correctly.

User-facing docs should use the correct casing.

-- All code should be in Typescript format
+- All code should be in TypeScript format
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- All code should be in Typescript format
- All code should be in TypeScript format
🤖 Prompt for AI Agents
frameworks/mastra/using-a-tool/.cursorrules/agent.mdc around line 13: the
document currently spells "Typescript" incorrectly; update the text to use the
correct casing "TypeScript" wherever it appears (line 13 and any other
occurrences in this file) so user-facing docs use the proper, consistent
branding.

Comment on lines +1 to +4
import type { AgentRequest, AgentResponse, AgentContext } from "@agentuity/sdk";
import { openai } from "@ai-sdk/openai";
import { Agent } from "@mastra/core";
import { londonWeatherTool } from "../../tools/london-weather-tool";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix fatal name collision: local function shadows imported Mastra Agent.

export default async function Agent(...) shadows the imported Agent class. new Agent({...}) will throw “Agent is not a constructor” at runtime (async functions aren’t constructible). Rename one side.

-import type { AgentRequest, AgentResponse, AgentContext } from "@agentuity/sdk";
-import { openai } from "@ai-sdk/openai";
-import { Agent } from "@mastra/core";
+import type { AgentRequest, AgentResponse, AgentContext } from "@agentuity/sdk";
+import { openai } from "@ai-sdk/openai";
+import { Agent as MastraAgent } from "@mastra/core";
@@
-export default async function Agent(
+export default async function handler(
   req: AgentRequest,
   resp: AgentResponse,
   ctx: AgentContext,
 ) {
@@
-    const londonWeatherAgent = new Agent({
+    const londonWeatherAgent = new MastraAgent({
       name: "london-weather-agent",

This also resolves the Biome “noRedeclare” warning.

Also applies to: 18-41

🤖 Prompt for AI Agents
In frameworks/mastra/using-a-tool/src/agents/london-weather-agent/index.ts
around lines 1-4 and 18-41, the module declares an async function named Agent
which collides with the imported Agent class and causes a runtime “Agent is not
a constructor” and a noRedeclare warning; rename the exported async function to
something like createLondonWeatherAgent (or buildAgent) and update its export
default accordingly, and update any internal references/usages within the file
to call the new function name so the imported Agent class remains available for
instantiation (e.g., keep using new Agent({...}) unaffected).

Comment on lines +15 to +33
execute: async () => {
const startDate = new Date().getFullYear() + "-01-01";
const endDate = new Date().toISOString().split("T")[0];

const response = await fetch(
`https://archive-api.open-meteo.com/v1/archive?latitude=51.5072&longitude=-0.1276&start_date=${startDate}&end_date=${endDate}&daily=temperature_2m_max,temperature_2m_min,precipitation_sum,wind_speed_10m_max,snowfall_sum`,
);

const { daily } = await response.json();

return {
date: daily.time,
temp_max: daily.temperature_2m_max,
temp_min: daily.temperature_2m_min,
rainfall: daily.precipitation_sum,
windspeed: daily.wind_speed_10m_max,
snowfall: daily.snowfall_sum,
};
},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add error handling, timeout, and response shape validation for the external API call.

Current code assumes success and valid shape; a network error or schema drift will crash the tool.

   execute: async () => {
-    const startDate = new Date().getFullYear() + "-01-01";
-    const endDate = new Date().toISOString().split("T")[0];
-
-    const response = await fetch(
-      `https://archive-api.open-meteo.com/v1/archive?latitude=51.5072&longitude=-0.1276&start_date=${startDate}&end_date=${endDate}&daily=temperature_2m_max,temperature_2m_min,precipitation_sum,wind_speed_10m_max,snowfall_sum`,
-    );
-
-    const { daily } = await response.json();
-
-    return {
-      date: daily.time,
-      temp_max: daily.temperature_2m_max,
-      temp_min: daily.temperature_2m_min,
-      rainfall: daily.precipitation_sum,
-      windspeed: daily.wind_speed_10m_max,
-      snowfall: daily.snowfall_sum,
-    };
+    const now = new Date();
+    const startDate = `${now.getFullYear()}-01-01`;
+    const endDate = now.toISOString().split("T")[0];
+
+    const controller = new AbortController();
+    const timeout = setTimeout(() => controller.abort(), 10_000);
+    try {
+      const url =
+        `https://archive-api.open-meteo.com/v1/archive` +
+        `?latitude=51.5072&longitude=-0.1276` +
+        `&start_date=${startDate}&end_date=${endDate}` +
+        `&daily=temperature_2m_max,temperature_2m_min,precipitation_sum,wind_speed_10m_max,snowfall_sum`;
+
+      const response = await fetch(url, {
+        signal: controller.signal,
+        headers: { accept: "application/json" },
+      });
+      if (!response.ok) {
+        throw new Error(`Open-Meteo request failed: ${response.status} ${response.statusText}`);
+      }
+      const json = await response.json();
+      const daily = json?.daily;
+      if (!daily || !Array.isArray(daily.time)) {
+        throw new Error("Unexpected response shape: missing daily time series");
+      }
+      const normalize = (arr: unknown[]) => (Array.isArray(arr) ? arr.map((v: any) => (v ?? 0)) : []);
+      return {
+        date: daily.time,
+        temp_max: normalize(daily.temperature_2m_max),
+        temp_min: normalize(daily.temperature_2m_min),
+        rainfall: normalize(daily.precipitation_sum),
+        windspeed: normalize(daily.wind_speed_10m_max),
+        snowfall: normalize(daily.snowfall_sum),
+      };
+    } finally {
+      clearTimeout(timeout);
+    }
   },
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
execute: async () => {
const startDate = new Date().getFullYear() + "-01-01";
const endDate = new Date().toISOString().split("T")[0];
const response = await fetch(
`https://archive-api.open-meteo.com/v1/archive?latitude=51.5072&longitude=-0.1276&start_date=${startDate}&end_date=${endDate}&daily=temperature_2m_max,temperature_2m_min,precipitation_sum,wind_speed_10m_max,snowfall_sum`,
);
const { daily } = await response.json();
return {
date: daily.time,
temp_max: daily.temperature_2m_max,
temp_min: daily.temperature_2m_min,
rainfall: daily.precipitation_sum,
windspeed: daily.wind_speed_10m_max,
snowfall: daily.snowfall_sum,
};
},
execute: async () => {
// Use a single Date instance and template literals for clarity
const now = new Date();
const startDate = `${now.getFullYear()}-01-01`;
const endDate = now.toISOString().split("T")[0];
// Abort after 10 seconds to avoid hanging requests
const controller = new AbortController();
const timeout = setTimeout(() => controller.abort(), 10_000);
try {
const url =
`https://archive-api.open-meteo.com/v1/archive` +
`?latitude=51.5072&longitude=-0.1276` +
`&start_date=${startDate}&end_date=${endDate}` +
`&daily=temperature_2m_max,temperature_2m_min,precipitation_sum,wind_speed_10m_max,snowfall_sum`;
const response = await fetch(url, {
signal: controller.signal,
headers: { accept: "application/json" },
});
if (!response.ok) {
throw new Error(`Open-Meteo request failed: ${response.status} ${response.statusText}`);
}
// Parse and validate response shape
const json = await response.json();
const daily = json?.daily;
if (!daily || !Array.isArray(daily.time)) {
throw new Error("Unexpected response shape: missing daily time series");
}
// Normalize arrays, replacing null/undefined with 0
const normalize = (arr: unknown[]) =>
Array.isArray(arr) ? arr.map((v: any) => (v ?? 0)) : [];
return {
date: daily.time,
temp_max: normalize(daily.temperature_2m_max),
temp_min: normalize(daily.temperature_2m_min),
rainfall: normalize(daily.precipitation_sum),
windspeed: normalize(daily.wind_speed_10m_max),
snowfall: normalize(daily.snowfall_sum),
};
} finally {
clearTimeout(timeout);
}
},
🤖 Prompt for AI Agents
In frameworks/mastra/using-a-tool/src/tools/london-weather-tool.ts around lines
15 to 33, the external fetch assumes success and a fixed response shape; add
robust error handling, a fetch timeout, and validate the response schema before
returning. Wrap the fetch and JSON parse in a try/catch, use an AbortController
with a reasonable timeout (e.g., 8–10s) to abort slow requests, check
response.ok and throw a descriptive error if not, and validate that the parsed
JSON contains a daily object with the expected arrays (time, temperature_2m_max,
temperature_2m_min, precipitation_sum, wind_speed_10m_max, snowfall_sum) of
matching lengths; if validation fails, throw or return a clear error so callers
can handle it. Ensure all thrown errors include context (URL, dates) and clean
up the abort timer in finally.

@devin-ai-integration
Copy link
Contributor Author

Closing due to inactivity for more than 30 days. Configure here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant