### Local Setup Commands Source: https://github.com/agentjido/ash_jido/blob/main/guides/walkthrough-ash-postgres-consumer.md Commands to set up the local consumer application. Ensure you are in the `ash_jido_consumer` directory before running these. ```bash cd ash_jido_consumer mix deps.get mix ecto.setup mix test ``` -------------------------------- ### Install AshJido via Igniter Source: https://github.com/agentjido/ash_jido/blob/main/README.md Use the Igniter tool to automatically install the dependency. ```bash mix igniter.install ash_jido ``` -------------------------------- ### Setup and Run Ash Jido Consumer Source: https://github.com/agentjido/ash_jido/blob/main/ash_jido_consumer/README.md Commands to set up and run the Ash Jido Consumer project. Ensures database is created and migrated before running tests. ```bash cd ash_jido_consumer mix setup mix test ``` -------------------------------- ### Use Agent for Synchronous Ask Source: https://github.com/agentjido/ash_jido/blob/main/guides/walkthrough-resource-to-action.md Demonstrates starting an agent server and using `ask_sync` to interact with the agent, passing specific tool context including actor and tenant for policy and tenancy-aware calls. ```elixir {:ok, pid} = Jido.AgentServer.start(agent: MyApp.Blog.PostAgent) {:ok, answer} = MyApp.Blog.PostAgent.ask_sync( pid, "Create a post titled 'Hello' for author #{author_id} and then list posts.", tool_context: %{ domain: MyApp.Blog, actor: current_user, tenant: "org_123" } ) ``` -------------------------------- ### Define a Complete Domain and Resource Source: https://github.com/agentjido/ash_jido/blob/main/guides/getting-started.md Example of defining an Ash domain and a resource within it, including necessary modules and configurations for integration. ```elixir # lib/my_app/blog/domain.ex defmodule MyApp.Blog do use Ash.Domain resources do resource MyApp.Blog.Post end end ``` -------------------------------- ### Full CRUD via Generated Actions Source: https://github.com/agentjido/ash_jido/blob/main/guides/walkthrough-ash-postgres-consumer.md Demonstrates a complete Create, Read, Update, and Destroy cycle for an `Author` and `Post` resource using Ash Jido actions. Includes setup for author and post creation, followed by updates and destruction. ```elixir {:ok, author} = \ AshJidoConsumer.Content.Author |> Ash.Changeset.for_create(:create, %{name: "Ada"}, domain: AshJidoConsumer.Content) |> Ash.create(domain: AshJidoConsumer.Content) {:ok, created} = \ AshJidoConsumer.Content.Post.Jido.Create.run( %{title: "Guide Post", author_id: author.id}, %{domain: AshJidoConsumer.Content, signal_dispatch: {:noop, []}} ) {:ok, updated} = \ AshJidoConsumer.Content.Post.Jido.Update.run( %{id: created[:id], title: "Guide Post Updated"}, %{domain: AshJidoConsumer.Content, signal_dispatch: {:noop, []}} ) {:ok, %{deleted: true}} = \ AshJidoConsumer.Content.Post.Jido.Destroy.run( %{id: updated[:id]}, %{domain: AshJidoConsumer.Content, signal_dispatch: {:noop, []}} ) ``` -------------------------------- ### Relationship-Aware Read Load Source: https://github.com/agentjido/ash_jido/blob/main/guides/walkthrough-ash-postgres-consumer.md Demonstrates fetching posts and accessing their associated author data through a relationship load. This example assumes `posts` is a list and accesses the first element. ```elixir {:ok, posts} = \ AshJidoConsumer.Content.Post.Jido.Read.run( %{}, %{domain: AshJidoConsumer.Content} ) Enum.at(posts, 0)[:author] ``` -------------------------------- ### Configuring Jido Actions with Custom Options Source: https://github.com/agentjido/ash_jido/blob/main/guides/getting-started.md Configure Jido actions with custom names, descriptions, categories, tags, and module names for better discoverability and organization. This example shows simple exposure with defaults, custom naming, adding tags, custom module names, and disabling output map conversion. ```elixir jido do # Simple exposure with defaults action :create # Custom name for better AI discoverability action :read, name: "search_users", description: "Search for users by criteria", load: [:profile] # Add tags for categorization action :update, category: "ash.update", tags: ["user-management", "data-modification"], vsn: "1.0.0" # Custom module name action :promote, module_name: MyApp.Actions.PromoteUser # Disable output map conversion (keep Ash structs) action :special, output_map?: false end ``` -------------------------------- ### Conventional Commit Message Examples Source: https://github.com/agentjido/ash_jido/blob/main/CONTRIBUTING.md Examples of commit messages following the Conventional Commits specification. Use these to clearly indicate the type and scope of your changes. ```bash git commit -m "feat(actions): add new Jido action resource" ``` ```bash git commit -m "fix(extension): resolve action registration" ``` ```bash git commit -m "feat(api)!: change action schema" ``` -------------------------------- ### Subscribe to Jido Telemetry Events Source: https://github.com/agentjido/ash_jido/blob/main/guides/walkthrough-signals-telemetry-sensors.md Subscribe to Jido-namespaced telemetry events using `:telemetry.attach_many/4`. This allows you to observe signal and telemetry emission lifecycle events such as start, stop, and exceptions. ```elixir :telemetry.attach_many( "ash-jido-observer", [ [:jido, :action, :ash_jido, :start], [:jido, :action, :ash_jido, :stop], [:jido, :action, :ash_jido, :exception] ], fn event, measurements, metadata, _config -> IO.inspect({event, measurements, metadata}, label: "ash_jido_telemetry") end, nil ) ``` -------------------------------- ### Interact with Generated Jido Actions Source: https://github.com/agentjido/ash_jido/blob/main/guides/getting-started.md Use the generated Jido modules to interact with your Ash resource. This example shows creating, listing, and publishing a blog post. ```elixir alias MyApp.Blog.Post # Create a post {:ok, post} = Post.Jido.Create.run( %{title: "Hello World", body: "My first post"}, %{domain: MyApp.Blog} ) # List all posts {:ok, posts} = Post.Jido.Read.run(%{}, %{domain: MyApp.Blog}) # Publish the post {:ok, published} = Post.Jido.Publish.run( %{id: post.id}, %{domain: MyApp.Blog} ) ``` -------------------------------- ### Export Tool Payloads with AshJido Source: https://github.com/agentjido/ash_jido/blob/main/guides/walkthrough-agent-tool-wiring.md Use `AshJido.Tools.tools/1` to get tool maps containing name, description, parameters schema, and function. Find specific tools by name. ```elixir tools = AshJido.Tools.tools(MyApp.Accounts) create_user_tool = Enum.find(tools, &(&1.name == "create_user")) ``` -------------------------------- ### Paginate Query Results Source: https://github.com/agentjido/ash_jido/blob/main/guides/getting-started.md Control the number of records returned and their starting position using `limit` and `offset` parameters for pagination. ```elixir # First page (20 items) {:ok, page1} = MyApp.Accounts.User.Jido.Read.run( %{limit: 20, offset: 0}, %{domain: MyApp.Accounts} ) # Second page {:ok, page2} = MyApp.Accounts.User.Jido.Read.run( %{limit: 20, offset: 20}, %{domain: MyApp.Accounts} ) # Combine with filtering and sorting {:ok, active_users_page} = MyApp.Accounts.User.Jido.Read.run( %{filter: %{status: "active"}}, %{domain: MyApp.Accounts} ) ``` -------------------------------- ### Execute Generated Jido Actions Source: https://github.com/agentjido/ash_jido/blob/main/guides/walkthrough-resource-to-action.md Demonstrates creating related data with Ash directly and then executing generated Jido actions for creating, reading, and publishing posts. It also shows how static `load` configurations are applied. ```elixir alias MyApp.Blog.{Author, Post} # Create related data with Ash directly author = Author |> Ash.Changeset.for_create(:create, %{name: "Ada"}, domain: MyApp.Blog) |> Ash.create!(domain: MyApp.Blog) # Execute generated Jido actions {:ok, post} = Post.Jido.Create.run( %{title: "Ash + Jido", author_id: author.id}, %{domain: MyApp.Blog} ) {:ok, posts} = Post.Jido.Read.run(%{}, %{domain: MyApp.Blog}) loaded = Enum.find(posts, &(&1[:id] == post[:id])) # Static load from DSL is applied to read actions loaded[:author][:name] # => "Ada" {:ok, published} = Post.Jido.Publish.run( %{id: post[:id]}, %{domain: MyApp.Blog} ) published[:status] # => :published ``` -------------------------------- ### Define Keyword List Options Source: https://github.com/agentjido/ash_jido/blob/main/AGENTS.md Use keyword lists for configuration options. ```elixir [timeout: 5000, retries: 3] ``` -------------------------------- ### Basic Post Operations Source: https://github.com/agentjido/ash_jido/blob/main/guides/getting-started.md Demonstrates the basic usage of Jido actions for creating, listing, and publishing blog posts. ```APIDOC ## Basic Post Operations This section shows how to perform fundamental operations on blog posts using the generated Jido actions. ### Create a Post ```elixir alias MyApp.Blog.Post {:ok, post} = Post.Jido.Create.run( %{title: "Hello World", body: "My first post"}, %{domain: MyApp.Blog} ) ``` ### List All Posts ```elixir {:ok, posts} = Post.Jido.Read.run(%{}, %{domain: MyApp.Blog}) ``` ### Publish a Post ```elixir {:ok, published} = Post.Jido.Publish.run( %{id: post.id}, %{domain: MyApp.Blog} ) ``` ``` -------------------------------- ### Run a Read Action with Query Parameters Source: https://github.com/agentjido/ash_jido/blob/main/guides/getting-started.md Use this to execute a read action with specified filters, sorting, limits, and loaded relationships. Ensure the domain is correctly set. ```elixir {:ok, posts} = MyApp.Blog.Post.Jido.Read.run( %{filter: %{status: "published"}, sort: [published_at: :desc], limit: 10, load: [author: :profile, comments: :author]}, %{domain: MyApp.Blog} ) ``` -------------------------------- ### Define Agent with Generated Resource Actions Source: https://github.com/agentjido/ash_jido/blob/main/guides/walkthrough-resource-to-action.md Shows how to define a `Jido.AI.Agent` and include generated AshJido action modules as tools. It configures the agent's model, tools, tool context, and system prompt. ```elixir defmodule MyApp.Blog.PostAgent do use Jido.AI.Agent, name: "post_agent", model: :fast, tools: [ MyApp.Blog.Post.Jido.Create, MyApp.Blog.Post.Jido.Read, MyApp.Blog.Post.Jido.Publish ], tool_context: %{domain: MyApp.Blog}, system_prompt: "You manage blog posts. Use tools for data operations." end ``` -------------------------------- ### Querying Module and Function Documentation Source: https://github.com/agentjido/ash_jido/blob/main/AGENTS.md Use these commands to retrieve documentation for specific modules, functions, or arities within the current project and its dependencies. ```elixir # Search a whole module mix usage_rules.docs Enum # Search a specific function mix usage_rules.docs Enum.zip # Search a specific function & arity mix usage_rules.docs Enum.zip/1 ``` -------------------------------- ### Override Signal Dispatch at Runtime Source: https://github.com/agentjido/ash_jido/blob/main/guides/walkthrough-signals-telemetry-sensors.md Override the DSL's signal dispatch configuration by providing a `signal_dispatch` option in the context when running an action. This allows for dynamic routing of signals, for example, to a specific process PID. ```elixir context = %{ domain: MyApp.Blog, signal_dispatch: {:pid, target: self()} } {:ok, _post} = MyApp.Blog.Post.Jido.Create.run(%{title: "Hello", author_id: id}, context) assert_receive {:signal, %Jido.Signal{} = signal} signal.type signal.source signal.data ``` -------------------------------- ### Searching Documentation Across Packages Source: https://github.com/agentjido/ash_jido/blob/main/AGENTS.md Execute these commands to perform broader searches across application dependencies, supporting specific package filtering and title-based queries. ```elixir # Search docs for all packages in the current application, including Elixir mix usage_rules.search_docs Enum.zip # Search docs for specific packages mix usage_rules.search_docs Req.get -p req # Search docs for multi-word queries mix usage_rules.search_docs "making requests" -p req # Search only in titles (useful for finding specific functions/modules) mix usage_rules.search_docs "Enum.zip" --query-by title ``` -------------------------------- ### Discover Generated Actions with AshJido.Tools Source: https://github.com/agentjido/ash_jido/blob/main/guides/walkthrough-tools-and-ai.md Use `AshJido.Tools.actions/1` to discover generated action modules for a specific resource or an entire domain. This helps in identifying available actions for tool integration. ```elixir # For one resource AshJido.Tools.actions(MyApp.Blog.Post) # For all resources in a domain AshJido.Tools.actions(MyApp.Blog) ``` -------------------------------- ### Configure Ash Resource with AshJido Extension Source: https://github.com/agentjido/ash_jido/blob/main/guides/getting-started.md Add the `AshJido` extension to your Ash resource and define which actions to expose in the `jido` section with custom names and descriptions. ```elixir defmodule MyApp.Accounts.User do use Ash.Resource, domain: MyApp.Accounts, extensions: [AshJido] attributes do uuid_primary_key :id attribute :name, :string, allow_nil?: false attribute :email, :string, allow_nil?: false attribute :role, :atom, default: :user end actions do defaults [:read, :destroy] create :register do accept [:name, :email] end update :update_profile do accept [:name] end update :promote do accept [] change set_attribute(:role, :admin) end end jido do action :register, name: "create_user", description: "Creates a new user account" action :read, name: "list_users" action :update_profile action :destroy end end ``` -------------------------------- ### Execute Read Actions with Query Parameters Source: https://github.com/agentjido/ash_jido/blob/main/usage-rules.md Run generated read actions by passing a map of query parameters for filtering, sorting, pagination, and loading related data. Query parameters are parsed safely and respect policies. ```elixir MyApp.Blog.Post.Jido.Read.run( %{filter: %{status: %{in: ["draft", "published"]}}, sort: [%{"field" => "inserted_at", "direction" => "desc"}], limit: 20, offset: 40 }, %{domain: MyApp.Blog} ) ``` -------------------------------- ### Discover Generated Actions with AshJido Source: https://github.com/agentjido/ash_jido/blob/main/guides/walkthrough-agent-tool-wiring.md Use `AshJido.Tools.actions/1` to discover actions for a single resource or an entire domain. Domain-level discovery is useful for a unified tool catalog. ```elixir # Resource-level resource_actions = AshJido.Tools.actions(MyApp.Accounts.User) # Domain-level all_actions = AshJido.Tools.actions(MyApp.Accounts) ``` -------------------------------- ### Configuring Context Options for AshJido Actions Source: https://github.com/agentjido/ash_jido/blob/main/guides/getting-started.md Set context options like domain, actor, tenant, and authorization for AshJido actions. This is useful for defining authorization policies, multi-tenancy, and overriding default configurations. ```elixir context = %{ domain: MyApp.Accounts, # Required only when no static resource domain is configured or you need an override actor: current_user, # Optional: for authorization policies tenant: "org_123", # Optional: for multi-tenant apps authorize?: true, # Optional: explicit authorization mode tracer: [MyApp.Tracer], # Optional: Ash tracer modules scope: MyApp.Scope.for(user), # Optional: Ash scope context: %{request_id: "1"}, # Optional: Ash action context timeout: 15_000, # Optional: Ash operation timeout signal_dispatch: {:pid, target: self()} # Optional: override signal dispatch } MyApp.Accounts.User.Jido.Register.run(params, context) ``` -------------------------------- ### Configure bulk AshJido action exposure Source: https://github.com/agentjido/ash_jido/blob/main/README.md Expose multiple Ash actions at once using the all_actions DSL, with options for filtering and metadata. ```elixir jido do all_actions all_actions except: [:destroy, :internal] all_actions only: [:create, :read] all_actions include_private?: true all_actions category: "ash.resource" all_actions tags: ["public-api"] all_actions vsn: "1.0.0" all_actions only: [:read], read_load: [:profile] end ``` -------------------------------- ### Configure Individual Actions with Jido Source: https://github.com/agentjido/ash_jido/blob/main/usage-rules.md Configure individual Ash actions for Jido exposure, specifying names, descriptions, and tags. Use this for fine-grained control over the tool surface. ```elixir jido do action :create action :read, name: "list_users", description: "List users" action :update, tags: ["user-management", "data-modification"] end ``` -------------------------------- ### Configure Resource Publications with AshJido.Notifier Source: https://github.com/agentjido/ash_jido/blob/main/usage-rules.md Set up AshJido.Notifier to publish Ash-native lifecycle events to a Jido signal bus. Configure which events to publish, what data to include, and optional metadata or conditions. ```elixir defmodule MyApp.Blog.Post do use Ash.Resource, domain: MyApp.Blog, extensions: [AshJido], notifiers: [AshJido.Notifier] jido do signal_bus MyApp.SignalBus signal_prefix "blog" publish :create, "blog.post.created", include: [:id, :title] publish_all :update, include: :changes_only end end ``` -------------------------------- ### Execute Read Action with Query Parameters Source: https://github.com/agentjido/ash_jido/blob/main/README.md Perform a read operation with filtering, sorting, and pagination parameters. ```elixir {:ok, users} = MyApp.User.Jido.Read.run( %{ filter: %{status: %{in: ["active", "pending"]}}, sort: [name: :asc, created_at: :desc], limit: 20, offset: 40 }, %{domain: MyApp.Accounts} ) ``` -------------------------------- ### Define Action Metadata with Jido DSL Source: https://github.com/agentjido/ash_jido/blob/main/guides/walkthrough-tools-and-ai.md Use the `jido do ... end` block to define actions with metadata like name, description, category, tags, and version. This metadata is used for tool discovery. ```elixir jido do action :create, name: "create_post", description: "Create a new blog post", category: "ash.create", tags: ["blog", "content"], vsn: "1.0.0" action :read, name: "search_posts", description: "List posts with optional filters" end ``` -------------------------------- ### Expose All Public Ash Actions with Defaults Source: https://github.com/agentjido/ash_jido/blob/main/guides/getting-started.md Use `all_actions` to expose all public Ash actions on a resource with smart defaults. This skips actions with `public?: false` by default. ```elixir jido do all_actions end ``` -------------------------------- ### Querying and Filtering Blog Posts Source: https://github.com/agentjido/ash_jido/blob/main/guides/getting-started.md Explains how to use filter, sort, limit, offset, and load parameters for advanced querying of blog posts. ```APIDOC ## Querying and Filtering Blog Posts Generated Jido read actions support query parameters for filtering, sorting, pagination, and allowlisted relationship loading. These parameters are optional and provide powerful querying capabilities while respecting Ash's authorization policies. ### Filter Syntax Use the `filter` parameter to query records using Ash's filter input syntax. #### Simple Equality Filter ```elixir # Simple equality filter {:ok, users} = MyApp.Accounts.User.Jido.Read.run( %{filter: %{name: "John Doe"}}, %{domain: MyApp.Accounts} ) ``` #### Filter with Operators ```elixir # Filter with operators {:ok, adults} = MyApp.Accounts.User.Jido.Read.run( %{filter: %{age: %{greater_than: 18}}}, %{domain: MyApp.Accounts} ) ``` #### Multiple Conditions (All Must Match) ```elixir # Multiple conditions (all must match) {:ok, active_admins} = MyApp.Accounts.User.Jido.Read.run( %{filter: %{status: "active", role: "admin"}}, %{domain: MyApp.Accounts} ) ``` #### IN Operator for Multiple Values ```elixir # IN operator for multiple values {:ok, users} = MyApp.Accounts.User.Jido.Read.run( %{filter: %{status: %{in: ["active", "pending"]}}}, %{domain: MyApp.Accounts} ) ``` **Common Filter Operators:** - `%{field: value}` — Equality - `%{field: %{greater_than: value}}` — Greater than - `%{field: %{less_than: value}}` — Less than - `%{field: %{greater_than_or_equal: value}}` — Greater than or equal - `%{field: %{less_than_or_equal: value}}` — Less than or equal - `%{field: %{in: [value1, value2]}}` — Match any value in list - `%{field: %{contains: "substring"}}` — String contains (case-sensitive) ### Sorting Use the `sort` parameter to order results. You can specify sorting as JSON-style entries, a keyword list, or a string. #### JSON-Style Entries ```elixir # JSON-style entries (tool-call friendly) {:ok, users} = MyApp.Blog.Post.Jido.Read.run( %{sort: [%{"field" => "created_at", "direction" => "desc"}]}, %{domain: MyApp.Blog} ) ``` #### Keyword List Syntax ```elixir # Keyword list syntax {:ok, users} = MyApp.Blog.Post.Jido.Read.run( %{sort: [created_at: :desc, title: :asc]}, %{domain: MyApp.Blog} ) ``` #### String Syntax ```elixir # String syntax (- prefix for descending) {:ok, users} = MyApp.Blog.Post.Jido.Read.run( %{sort: "-created_at,title"}, %{domain: MyApp.Blog} ) ``` ### Pagination Use `limit` and `offset` for pagination. #### First Page ```elixir # First page (20 items) {:ok, page1} = MyApp.Accounts.User.Jido.Read.run( %{limit: 20, offset: 0}, %{domain: MyApp.Accounts} ) ``` #### Second Page ```elixir # Second page {:ok, page2} = MyApp.Accounts.User.Jido.Read.run( %{limit: 20, offset: 20}, %{domain: MyApp.Accounts} ) ``` #### Combine with Filtering and Sorting ```elixir # Combine with filtering and sorting {:ok, active_users_page} = MyApp.Accounts.User.Jido.Read.run( %{filter: %{status: "active"}, sort: [name: :asc], limit: 50, offset: 100}, %{domain: MyApp.Accounts} ) ``` ### Dynamic Relationship Loading Use the `load` parameter to dynamically load relationships at query time. #### Load a Single Relationship ```elixir # Load a single relationship {:ok, posts} = MyApp.Blog.Post.Jido.Read.run( %{load: :author}, %{domain: MyApp.Blog} ) ``` #### Load Multiple Relationships ```elixir # Load multiple relationships {:ok, posts} = MyApp.Blog.Post.Jido.Read.run( %{load: [:author, :comments, :tags]}, %{domain: MyApp.Blog} ) ``` #### Load Nested Relationships ```elixir # Load nested relationships {:ok, posts} = MyApp.Blog.Post.Jido.Read.run( %{load: [author: [:profile, :roles]]}, %{domain: MyApp.Blog} ) ``` ``` -------------------------------- ### Configure Read Actions in Jido Source: https://github.com/agentjido/ash_jido/blob/main/guides/getting-started.md Configure query parameter behavior for read actions. This includes enabling/disabling them, setting maximum page sizes, and combining with static loads. Defaults can be set for all read actions. ```elixir jido do # Query params enabled by default action :read # Disable query params for a specific action action :read, query_params?: false # Set maximum page size (clamps limit parameter) action :read, max_page_size: 100 # Combine with static load action :read, load: :profile, max_page_size: 50 # Configure defaults for all read actions all_actions only: [:read], read_query_params?: true all_actions only: [:read], read_max_page_size: 100 end ``` -------------------------------- ### Configure individual AshJido actions Source: https://github.com/agentjido/ash_jido/blob/main/README.md Define specific Ash actions to be exposed via the Jido DSL. ```elixir jido do action :create action :read, name: "list_users", description: "List all users", load: [:profile] action :update, category: "ash.update", tags: ["user-management"], vsn: "1.0.0" action :special, output_map?: false # preserve Ash structs end ``` -------------------------------- ### Configure AshJido reactive signals Source: https://github.com/agentjido/ash_jido/blob/main/README.md Integrate AshJido.Notifier into a resource to publish lifecycle events to a Jido signal bus. ```elixir defmodule MyApp.Post do use Ash.Resource, domain: MyApp.Blog, extensions: [AshJido], notifiers: [AshJido.Notifier] jido do signal_bus MyApp.SignalBus signal_prefix "blog" publish :create, "blog.post.created", include: [:id, :title], metadata: [:actor, :tenant] publish_all :update, include: :changes_only end end ``` -------------------------------- ### Configure Jido.AI.Agent with Generated Actions Source: https://github.com/agentjido/ash_jido/blob/main/guides/walkthrough-tools-and-ai.md When using `Jido.AI.Agent`, configure generated action modules directly in the `tools:` option. This allows the agent to discover and utilize these actions. ```elixir defmodule MyApp.Blog.Agent do use Jido.AI.Agent, name: "blog_agent", model: :fast, tools: [ MyApp.Blog.Post.Jido.Create, MyApp.Blog.Post.Jido.Read, MyApp.Blog.Post.Jido.Publish ], tool_context: %{domain: MyApp.Blog} end ``` -------------------------------- ### Add AshJido to mix.exs Source: https://github.com/agentjido/ash_jido/blob/main/README.md Manually add the dependency to your project's mix.exs file. ```elixir def deps do [ {:ash_jido, "~> 0.2.0"} ] end ``` -------------------------------- ### Execute Generated Jido Actions Source: https://github.com/agentjido/ash_jido/blob/main/guides/getting-started.md Call the generated Jido.Action modules using `run/2` with parameters and a context map. The `context[:domain]` can override the Ash resource's static `domain:` configuration. ```elixir # Create a user {:ok, user} = MyApp.Accounts.User.Jido.Register.run( %{name: "John Doe", email: "john@example.com"}, %{domain: MyApp.Accounts} ) # List users (returns list of maps when output_map?: true) {:ok, users} = MyApp.Accounts.User.Jido.Read.run( %{}, %{domain: MyApp.Accounts} ) # Update a user (requires the resource primary key; id for the default primary key) {:ok, updated_user} = MyApp.Accounts.User.Jido.UpdateProfile.run( %{id: user[:id], name: "Jane Doe"}, %{domain: MyApp.Accounts} ) # Delete a user (requires the resource primary key; id for the default primary key) {:ok, _} = MyApp.Accounts.User.Jido.Destroy.run( %{id: user[:id]}, %{domain: MyApp.Accounts} ) ``` -------------------------------- ### Enable Signals and Telemetry in DSL Source: https://github.com/agentjido/ash_jido/blob/main/guides/walkthrough-signals-telemetry-sensors.md Configure actions to emit signals and telemetry by setting `emit_signals?` and `telemetry?` to true in the Jido DSL. Use `signal_dispatch` to control signal routing and `signal_include` to specify payload fields. ```elixir jido do action :create, emit_signals?: true, signal_dispatch: {:noop, []}, signal_include: [:id], telemetry?: true action :update, emit_signals?: true, signal_dispatch: {:noop, []}, signal_type: "my_app.post.updated", signal_source: "/my_app/posts", telemetry?: true end ``` -------------------------------- ### Export Actions for Tool Systems Source: https://github.com/agentjido/ash_jido/blob/main/guides/getting-started.md Use these helpers to expose Ash resource actions for tool-oriented agent systems. They generate functions that agents can call. ```elixir AshJido.Tools.actions(MyApp.Accounts.User) AshJido.Tools.actions(MyApp.Accounts) AshJido.Tools.tools(MyApp.Accounts.User) ``` -------------------------------- ### Export Tool Payloads for Agent Use Source: https://github.com/agentjido/ash_jido/blob/main/guides/walkthrough-tools-and-ai.md Use `AshJido.Tools.tools/1` to generate tool payload maps suitable for agent systems. This includes name, description, schema, and the function to execute the action. ```elixir tools = AshJido.Tools.tools(MyApp.Accounts.User) # Tool payload shape includes name/description/schema/function tool = Enum.find(tools, &(&1.name == "create_user")) {:ok, _result} = tool.function.( %{"name" => "Agent User", "email" => "agent@example.com"}, %{domain: MyApp.Accounts} ) ``` -------------------------------- ### Configure Jido Action Options Source: https://github.com/agentjido/ash_jido/blob/main/README.md Set options for Jido actions within the jido block, including query parameter toggles and load allowances. ```elixir jido do action :read # query params enabled by default action :read, query_params?: false # opt out action :read, allowed_loads: [:profile] # opt into runtime load action :read, max_page_size: 100 # clamp limit to max all_actions read_query_params?: true # default for all read actions all_actions read_allowed_loads: [:profile] all_actions read_max_page_size: 100 # max page size for all reads end ``` -------------------------------- ### Add AshJido to Dependencies Source: https://github.com/agentjido/ash_jido/blob/main/guides/getting-started.md Add `ash_jido` to your project's dependencies in `mix.exs` and then fetch them. ```elixir def deps do [ {:ash_jido, "~> 0.2"} ] end ``` ```bash mix deps.get ``` -------------------------------- ### Apply Static Relationship Loads to Read Actions Source: https://github.com/agentjido/ash_jido/blob/main/guides/getting-started.md Apply static relationship loads to all generated read actions when using `all_actions` with `only: [:read]`. ```elixir jido do all_actions only: [:read], read_load: [:profile, :roles] end ``` -------------------------------- ### Set Tool Metadata in DSL Source: https://github.com/agentjido/ash_jido/blob/main/guides/walkthrough-agent-tool-wiring.md Define metadata like `name`, `category`, `tags`, and `vsn` within the `jido` block in your DSL for easier tool routing and versioning. ```elixir jido do action :create, name: "create_user", category: "ash.accounts.write", tags: ["accounts", "write", "user"], vsn: "1.2.0" end ``` -------------------------------- ### Define Ash Resource with Jido Source: https://github.com/agentjido/ash_jido/blob/main/README.md Configure an Ash resource to use the AshJido extension and define Jido actions. ```elixir defmodule MyApp.User do use Ash.Resource, domain: MyApp.Accounts, extensions: [AshJido] actions do create :register read :by_id update :profile end jido do action :register, name: "create_user" action :by_id, name: "get_user" action :profile end end ``` -------------------------------- ### Export Ash Resources as Tools Source: https://github.com/agentjido/ash_jido/blob/main/README.md List generated action modules or export tool payloads for LLM integration using AshJido.Tools. ```elixir # Generated action modules for a resource AshJido.Tools.actions(MyApp.Accounts.User) # Generated action modules for all resources in a domain AshJido.Tools.actions(MyApp.Accounts) # Tool payloads (name/description/schema/function) for agent/LLM integrations AshJido.Tools.tools(MyApp.Accounts.User) ``` -------------------------------- ### Define Ash Domain and Resources Source: https://github.com/agentjido/ash_jido/blob/main/guides/walkthrough-resource-to-action.md Defines the domain and resources for a blog application, including Author and Post resources with their attributes and actions. ```elixir defmodule MyApp.Blog do use Ash.Domain resources do resource MyApp.Blog.Author resource MyApp.Blog.Post end end defmodule MyApp.Blog.Author do use Ash.Resource, domain: MyApp.Blog, data_layer: AshPostgres.DataLayer postgres do table "authors" repo MyApp.Repo end attributes do uuid_primary_key :id attribute :name, :string, allow_nil?: false end actions do defaults [:read, :destroy] create :create do accept [:name] end end end ``` ```elixir defmodule MyApp.Blog.Post do use Ash.Resource, domain: MyApp.Blog, extensions: [AshJido], data_layer: AshPostgres.DataLayer postgres do table "posts" repo MyApp.Repo end attributes do uuid_primary_key :id attribute :title, :string, allow_nil?: false attribute :status, :atom, default: :draft timestamps() end relationships do belongs_to :author, MyApp.Blog.Author, allow_nil?: false, public?: true end actions do defaults [:read, :destroy] create :create do accept [:title, :author_id] end update :publish do accept [] change set_attribute(:status, :published) end end jido do action :create, name: "create_post" action :read, name: "list_posts", load: [:author] action :publish, name: "publish_post" end end ``` -------------------------------- ### Set Default Metadata for Bulk Action Generation Source: https://github.com/agentjido/ash_jido/blob/main/guides/walkthrough-tools-and-ai.md Use `all_actions` within the `jido do` block to set default metadata for multiple actions, such as common tags. Categories default to `ash.` if not explicitly set. ```elixir jido do all_actions tags: ["blog"] # category defaults to "ash." unless explicitly set end ``` -------------------------------- ### Run Local Test Coverage Report Source: https://github.com/agentjido/ash_jido/blob/main/CONTRIBUTING.md Generates an HTML report for local test coverage. Ensure all tests pass before submitting changes. ```bash mix coveralls.html ``` -------------------------------- ### Define Context for Generated Actions Source: https://github.com/agentjido/ash_jido/blob/main/guides/walkthrough-policy-scope-auth.md Use this context map to provide optional overrides and passthroughs to generated AshJido actions. The `domain` key overrides the resource's static domain, and other keys like `actor`, `tenant`, `scope`, `authorize?`, `tracer`, and `timeout` are optional passthroughs. ```elixir context = %{ domain: MyApp.Accounts, # optional override when the resource has a static domain actor: current_user, # optional tenant: "org_123", # optional scope: %{actor: current_user}, # optional authorize?: true, # optional tracer: [MyApp.Tracer], # optional context: %{request_id: "r1"}, # optional timeout: 15_000 # optional } ``` -------------------------------- ### Execute Generated Jido Actions Source: https://github.com/agentjido/ash_jido/blob/main/README.md Run a generated Jido action using the module's run function. ```elixir {:ok, user} = MyApp.User.Jido.Register.run( %{name: "John", email: "john@example.com"}, %{domain: MyApp.Accounts} ) ``` -------------------------------- ### Expose All Actions in Bulk with Jido Source: https://github.com/agentjido/ash_jido/blob/main/usage-rules.md Expose all public Ash actions or a filtered subset using `all_actions`. This is useful when the resource's public action surface is the intended tool surface. ```elixir jido do all_actions all_actions except: [:internal_action, :admin_only] all_actions only: [:create, :read, :update] end ``` -------------------------------- ### Tenant and Scope Context for Data Access Source: https://github.com/agentjido/ash_jido/blob/main/guides/walkthrough-policy-scope-auth.md Forward tenant context to Ash for runtime availability in actions. Ensure the correct `tenant` is passed in the context for all relevant calls to prevent missing or cross-tenant data issues. ```elixir {:ok, note} = MyApp.Tenanting.Note.Jido.Create.run( %{body: "Tenant note"}, %{domain: MyApp.Tenanting, tenant: "tenant_a", scope: %{actor: %{id: "u1"}}} ) note[:tenant_id] # => "tenant_a" ``` -------------------------------- ### Run Specific Tests Source: https://github.com/agentjido/ash_jido/blob/main/AGENTS.md Commands for executing specific test files or individual tests by line number. ```bash mix test test/my_test.exs ``` ```bash mix test path/to/test.exs:123 ``` -------------------------------- ### Policy Actor via Scope Source: https://github.com/agentjido/ash_jido/blob/main/guides/walkthrough-ash-postgres-consumer.md Illustrates creating a user with a specific actor defined in the scope. This is useful for testing policy enforcement based on the actor's identity. ```elixir {:ok, user} = \ AshJidoConsumer.Accounts.User.Jido.Create.run( %{name: "Scope User", email: "scope-user@example.com"}, %{domain: AshJidoConsumer.Accounts, scope: %{actor: %{id: "scope_actor"}}} ) user[:email] # => "scope-user@example.com" ``` -------------------------------- ### Debug with dbg Source: https://github.com/agentjido/ash_jido/blob/main/AGENTS.md Use the dbg macro to inspect values during execution. ```elixir dbg/1 ``` -------------------------------- ### Enable Generated-Action Signals Source: https://github.com/agentjido/ash_jido/blob/main/usage-rules.md Use `emit_signals?: true` to tie signal dispatch to generated action execution. Requires `signal_dispatch` configuration. ```elixir jido do action :create, emit_signals?: true, signal_dispatch: {:pid, target: self()}, telemetry?: true end ``` -------------------------------- ### Safe Execution Wrapper for Tools Source: https://github.com/agentjido/ash_jido/blob/main/guides/walkthrough-agent-tool-wiring.md Wrap tool execution to normalize context handling and JSON decoding. This pattern injects the domain into the context and handles structured payloads. ```elixir def run_tool(tool, params, domain, base_context \\ %{}) do context = Map.put(base_context, :domain, domain) case tool.function.(params, context) do {:ok, json} -> {:ok, Jason.decode!(json)} {:error, json} -> {:error, Jason.decode!(json)} end end ``` -------------------------------- ### Access Action Metadata from Generated Modules Source: https://github.com/agentjido/ash_jido/blob/main/guides/walkthrough-tools-and-ai.md Metadata defined using `use Jido.Action` can be accessed directly from the generated modules, such as retrieving tags, category, or version. ```elixir MyApp.Blog.Post.Jido.Create.tags() MyApp.Blog.Post.Jido.Create.category() MyApp.Blog.Post.Jido.Create.vsn() ``` -------------------------------- ### Forward Signals via Sensor Bridge Source: https://github.com/agentjido/ash_jido/blob/main/README.md Dispatch signals to sensor runtimes using the AshJido.SensorDispatchBridge. ```elixir # Accepts %Jido.Signal{}, {:signal, %Jido.Signal{}}, and {:signal, {:ok, %Jido.Signal{}}} :ok = AshJido.SensorDispatchBridge.forward(signal_message, sensor_runtime) # Batch forwarding with per-message errors %{forwarded: count, errors: errors} = AshJido.SensorDispatchBridge.forward_many(messages, sensor_runtime) # Ignore non-signal mailbox noise safely :ok | :ignored | {:error, :runtime_unavailable} = AshJido.SensorDispatchBridge.forward_or_ignore(message, sensor_runtime) ``` -------------------------------- ### Expose All Actions Including Private Ones Source: https://github.com/agentjido/ash_jido/blob/main/guides/getting-started.md Use `all_actions include_private?: true` to expose all actions, including those marked as private. This also applies to generated schemas. ```elixir jido do all_actions include_private?: true end ``` -------------------------------- ### Execute Actions with Actor Context Source: https://github.com/agentjido/ash_jido/blob/main/guides/getting-started.md When calling actions on resources with policies, ensure the `actor` is provided in the context. Actions will fail with `:forbidden` if no actor is present. ```elixir # This will fail with :forbidden - no actor provided {:error, error} = SecureDocument.Jido.Create.run( %{title: "Secret"}, %{domain: MyApp.Accounts, actor: nil} ) error.details.reason # => :forbidden # This succeeds - actor is present {:ok, doc} = SecureDocument.Jido.Create.run( %{title: "Secret"}, %{domain: MyApp.Accounts, actor: current_user} ) ``` -------------------------------- ### Handle Missing Domain Error Source: https://github.com/agentjido/ash_jido/blob/main/guides/walkthrough-failure-semantics.md Actions raise an ArgumentError when the domain is not provided in the context or resource configuration. ```elixir assert_raise ArgumentError, ~r/:domain must be provided/, fn -> MyApp.Accounts.User.Jido.Read.run(%{}, %{}) end ``` -------------------------------- ### Dynamically Load Multiple Relationships Source: https://github.com/agentjido/ash_jido/blob/main/guides/getting-started.md Specify multiple relationships in the `load` parameter to fetch them simultaneously. ```elixir # Load multiple relationships {:ok, posts} = MyApp.Blog.Post.Jido.Read.run( %{load: [:author, :comments, :tags]}, %{domain: MyApp.Blog} ) ``` -------------------------------- ### Pass Ash Context Through Runtime Context Source: https://github.com/agentjido/ash_jido/blob/main/guides/walkthrough-resource-to-action.md Illustrates how to pass Ash runtime context options like `actor`, `tenant`, `authorize?`, and `timeout` when executing generated Jido actions. The `domain` in context overrides the resource's static domain. ```elixir context = %{ domain: MyApp.Blog, actor: current_user, tenant: "org_123", scope: %{actor: current_user}, authorize?: true, tracer: [MyApp.Tracer], context: %{request_id: "req_123"}, timeout: 15_000 } Post.Jido.Create.run(params, context) ``` -------------------------------- ### Include Only Specific Actions with `all_actions` Source: https://github.com/agentjido/ash_jido/blob/main/guides/getting-started.md Filter which actions to expose when using `all_actions` by specifying a list of actions to include. ```elixir jido do # Only expose specific actions all_actions only: [:register, :read, :update_profile] end ``` -------------------------------- ### Forward Signals to Jido Sensor Runtime Source: https://github.com/agentjido/ash_jido/blob/main/guides/walkthrough-signals-telemetry-sensors.md Use `AshJido.SensorDispatchBridge` to forward common signal envelopes to `Jido.Sensor.Runtime.event/2`. This includes variants for forwarding single messages, multiple messages, or safely ignoring unsupported message types. ```elixir # forward one :ok = AshJido.SensorDispatchBridge.forward({:signal, signal}, sensor_runtime) # forward many %{forwarded: count, errors: errors} = AshJido.SensorDispatchBridge.forward_many([ signal, {:signal, signal}, :not_a_signal ], sensor_runtime) # mailbox-safe variant :ok | :ignored | {:error, :runtime_unavailable} = AshJido.SensorDispatchBridge.forward_or_ignore(message, sensor_runtime) ``` -------------------------------- ### Handle Missing Primary Key(s) for Update (Composite) Source: https://github.com/agentjido/ash_jido/blob/main/guides/walkthrough-failure-semantics.md For resources with composite primary keys, the error message will list the required key fields. ```elixir error.message # => "Update actions require primary key parameter(s): account_id, external_id" ``` -------------------------------- ### Enable Telemetry for Actions Source: https://github.com/agentjido/ash_jido/blob/main/README.md Configure telemetry for specific actions within a Jido block. ```elixir jido do action :create, telemetry?: true end ``` -------------------------------- ### Define AshJido execution context Source: https://github.com/agentjido/ash_jido/blob/main/README.md Configure the execution context for AshJido operations, including domain, actor, and tenant information. ```elixir context = %{ domain: MyApp.Accounts, # required only when the resource has no static domain or you need an override actor: current_user, # optional: for authorization tenant: "org_123", # optional: for multi-tenancy authorize?: true, # optional: explicit authorization mode tracer: [MyApp.Tracer], # optional: Ash tracer modules scope: MyApp.Scope.for(user), # optional: Ash scope context: %{request_id: "1"}, # optional: Ash action context timeout: 15_000, # optional: Ash operation timeout signal_dispatch: {:pid, target: self()} # optional: override signal dispatch } MyApp.User.Jido.Create.run(params, context) ``` -------------------------------- ### Read Tool Metadata from Generated Modules Source: https://github.com/agentjido/ash_jido/blob/main/guides/walkthrough-agent-tool-wiring.md Access metadata such as category, tags, and version from generated modules. This provides a stable contract for tool catalogs and compatibility tracking. ```elixir MyApp.Accounts.User.Jido.Create.category() MyApp.Accounts.User.Jido.Create.tags() MyApp.Accounts.User.Jido.Create.vsn() ``` -------------------------------- ### Prepend to a List Source: https://github.com/agentjido/ash_jido/blob/main/AGENTS.md Prepend elements to lists for efficiency instead of appending. ```elixir [new | list] ``` -------------------------------- ### Define Jido Context for Ash Actions Source: https://github.com/agentjido/ash_jido/blob/main/usage-rules.md Construct a context map to pass to Jido actions, including domain, actor, tenant, authorization flags, scopes, and other metadata. This context is used for policy-aware operations and multi-tenancy. ```elixir context = %{ domain: MyApp.Accounts, actor: current_user, tenant: "org_123", authorize?: true, scope: MyApp.Scope.for(current_user), context: %{request_id: "req_123"}, timeout: 15_000 } ```