Skip to content

fix(ai): resolve ability IDs when tool name differs from ability ID - #1175

Merged
imjlk merged 1 commit into
mainfrom
fix/operation-id-ability-mapping
Jul 31, 2026
Merged

imjlk merged 1 commit into
mainfrom
fix/operation-id-ability-mapping

Conversation

@imjlk

@imjlk imjlk commented Jul 31, 2026 •

Copy link
Copy Markdown
Owner

Summary

Addresses #13: typia.llm tool names are plain operationIds, but WordPress abilities use category/operationId format. The dispatch handler now tries wp_get_ability($tool_name) directly first, then falls back to searching all abilities via wp_get_abilities() for one whose ID ends with /$tool_name.

Test plan

  • bun run typecheck — clean
  • 5 typia.llm tool endpoint tests pass (1 new)
  • ocr review — minor PHP pattern suggestion

🤖 Created by ZCode

Summary by CodeRabbit

  • Bug Fixes

    • Improved tool dispatch to resolve operations when tool names differ from their registered IDs.
    • Preserved existing handling for unavailable tools and execution errors.
  • Tests

    • Added coverage for fallback resolution using registered ability IDs.
  • Documentation

    • Added a patch changeset for the project tools package.

Address #13: typia.llm tool names are plain operationIds, but WordPress
abilities use category/operationId format. The dispatch handler now
tries wp_get_ability($tool_name) directly first, then falls back to
searching all abilities for one whose ID ends with /$tool_name.

- New fallback search via wp_get_abilities() + str_ends_with.
- Test for the fallback search in the generated PHP.
@coderabbitai

coderabbitai Bot commented Jul 31, 2026 •

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The generated typia.llm dispatch endpoint now tries direct tool lookup first, then matches registered ability IDs by their trailing operation ID. Tests cover the fallback, and a changeset records the patch.

Changes

Operation ID mapping

Layer / File(s) Summary
Dispatch fallback resolution
packages/wp-typia-project-tools/src/runtime/add/cli-add-workspace-ai-templates.ts, packages/wp-typia-project-tools/tests/typia-llm-tool-endpoint.test.ts, .sampo/changesets/operation-id-mapping.md
The endpoint searches registered abilities with wp_get_abilities and str_ends_with when direct lookup fails. Tests verify the fallback. The changeset records the patch.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

  • imjlk/wp-typia#1166: Both modify the generated typia.llm endpoint template and its tests.
  • imjlk/wp-typia#1169: Both modify the generated dispatch endpoint and its tests, but address different behavior.

Suggested reviewers: sampo-s-bot

Poem

A rabbit found a tool ID in the hay,
Direct lookup failed, so it searched the array.
With a matching suffix, the ability came through,
Tests watched closely to confirm what it would do.
Thump, thump—dispatch now knows the way!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: resolving ability IDs when tool names differ from ability IDs.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/operation-id-ability-mapping

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint install failed. For unrecoverable errors, disable the tool in CodeRabbit configuration.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9c22defdf4

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +770 to +772
\t\t\t\t\t$candidate_id = method_exists( $candidate, 'get_id' )
\t\t\t\t\t\t? $candidate->get_id()
\t\t\t\t\t\t: ( property_exists( $candidate, 'id' ) ? $candidate->id : '' );

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Read the identifier exposed by WP_Ability

When direct lookup fails—the exact scenario this fallback handles—wp_get_abilities() returns WP_Ability instances whose identifier is exposed as the ability name (via get_name() or the registry key), not through get_id() or an id property. As a result, $candidate_id is empty for real registered abilities and the endpoint still returns ability_not_found; use the registered ability name when performing the fallback comparison.

Useful? React with 👍 / 👎.

\t\t\t\t\t$candidate_id = method_exists( $candidate, 'get_id' )
\t\t\t\t\t\t? $candidate->get_id()
\t\t\t\t\t\t: ( property_exists( $candidate, 'id' ) ? $candidate->id : '' );
\t\t\t\t\tif ( is_string( $candidate_id ) && str_ends_with( $candidate_id, '/' . $tool_name ) ) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Normalize the operation ID before suffix matching

For the standard camelCase operation IDs generated by this repository, this comparison cannot match the corresponding generated ability ID. For example, the tool artifact contains getPersistenceCounterState, while wordpress-ai.ts converts that to persistence-examples/get-persistence-counter-state; checking for the literal suffix /getPersistenceCounterState therefore still produces a 404. Apply the same operation-ID-to-ability-slug normalization here or preserve an explicit mapping in the artifact.

Useful? React with 👍 / 👎.

Comment on lines +773 to +775
\t\t\t\t\tif ( is_string( $candidate_id ) && str_ends_with( $candidate_id, '/' . $tool_name ) ) {
\t\t\t\t\t\t$ability = $candidate;
\t\t\t\t\t\tbreak;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Reject ambiguous operation-ID matches

When multiple plugins or categories register abilities with the same operation suffix, this loop silently selects whichever ability appears first in the global registry and executes it. Common operation names such as get-status or run can therefore dispatch a tool call to an unrelated plugin's callback, potentially returning or mutating the wrong data. Bind each artifact tool name to its fully qualified ability name, or detect multiple matches and reject the call instead of breaking on the first one.

Useful? React with 👍 / 👎.

@codecov

codecov Bot commented Jul 31, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 0% with 17 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
.../src/runtime/add/cli-add-workspace-ai-templates.ts 0.00% 17 Missing ⚠️

📢 Thoughts on this report? Let us know!

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (1)
packages/wp-typia-project-tools/tests/typia-llm-tool-endpoint.test.ts (1)

62-73: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Test fallback behavior, not only token presence.

These assertions pass when the generated PHP contains the fallback tokens but cannot resolve a real namespaced ability. Assert that the generated code uses get_name(), and add an executable fixture for category/operationId. The WordPress API exposes the registered name through get_name(). (developer.wordpress.org)

Proposed minimum assertion
     expect(source).toContain('wp_get_abilities');
+    expect(source).toContain('get_name');
     expect(source).toContain('str_ends_with');
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/wp-typia-project-tools/tests/typia-llm-tool-endpoint.test.ts` around
lines 62 - 73, Strengthen the test around buildTypiaLlmToolEndpointPhpSource so
it verifies executable fallback behavior rather than only token presence: assert
the generated PHP calls get_name(), and add a fixture for a category/operationId
ability whose namespaced registered name is resolved through the fallback
search. Keep the existing wp_get_abilities and str_ends_with checks while
validating the real lookup path.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@packages/wp-typia-project-tools/src/runtime/add/cli-add-workspace-ai-templates.ts`:
- Around line 770-773: Update the candidate identifier logic in the generated
fallback to call get_name() for WP_Ability instances before checking the suffix
with str_ends_with. Preserve the existing property-based fallback for other
candidate types, ensuring category/operationId ability names resolve correctly.
- Around line 766-777: Update the ability resolution logic around $ability and
wp_get_abilities() to first construct and resolve the known complete ability
name with wp_get_ability( $full_name ). Do not select the first registry entry
matching the /$tool_name suffix; if multiple distinct registered names match
that suffix, return a conflict instead, while preserving the existing successful
resolution behavior for an exact full name.

---

Nitpick comments:
In `@packages/wp-typia-project-tools/tests/typia-llm-tool-endpoint.test.ts`:
- Around line 62-73: Strengthen the test around
buildTypiaLlmToolEndpointPhpSource so it verifies executable fallback behavior
rather than only token presence: assert the generated PHP calls get_name(), and
add a fixture for a category/operationId ability whose namespaced registered
name is resolved through the fallback search. Keep the existing wp_get_abilities
and str_ends_with checks while validating the real lookup path.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 708ff1b9-f239-4fa3-97ad-41693851789f

📥 Commits

Reviewing files that changed from the base of the PR and between f3b6fd7 and 9c22def.

📒 Files selected for processing (3)
  • .sampo/changesets/operation-id-mapping.md
  • packages/wp-typia-project-tools/src/runtime/add/cli-add-workspace-ai-templates.ts
  • packages/wp-typia-project-tools/tests/typia-llm-tool-endpoint.test.ts

Comment on lines +766 to +777
\t\tif ( $ability === null && function_exists( 'wp_get_abilities' ) ) {
\t\t\t$all_abilities = wp_get_abilities();
\t\t\tif ( is_array( $all_abilities ) ) {
\t\t\t\tforeach ( $all_abilities as $candidate ) {
\t\t\t\t\t$candidate_id = method_exists( $candidate, 'get_id' )
\t\t\t\t\t\t? $candidate->get_id()
\t\t\t\t\t\t: ( property_exists( $candidate, 'id' ) ? $candidate->id : '' );
\t\t\t\t\tif ( is_string( $candidate_id ) && str_ends_with( $candidate_id, '/' . $tool_name ) ) {
\t\t\t\t\t\t$ability = $candidate;
\t\t\t\t\t\tbreak;
\t\t\t\t\t}
\t\t\t\t}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

rg -n -C 8 \
  'wp_register_ability|wp_get_abilities|operationId|str_ends_with' \
  packages \
  --glob '*.php' \
  --glob '*.ts' || true

Repository: imjlk/wp-typia

Length of output: 1943


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

printf 'repo root files (top-level):\n'
git ls-files | sed -n '1,50p'

printf '\ncandidate file exists?\n'
if [ -f packages/wp-typia-project-tools/src/runtime/add/cli-add-workspace-ai-templates.ts ]; then
  wc -l packages/wp-typia-project-tools/src/runtime/add/cli-add-workspace-ai-templates.ts
  sed -n '730,800p' packages/wp-typia-project-tools/src/runtime/add/cli-add-workspace-ai-templates.ts | cat -n
else
  fd -i 'cli-add-workspace-ai-templates.ts' .
fi

printf '\nability-related searches in packages:\n'
rg -n -C 8 \
  'wp_register_ability|wp_get_abilities|operationId|str_ends_with|get_id\(\)|property_exists\(.*id' \
  packages \
  --glob '*.php' \
  --glob '*.ts' \
  --glob '*.tsx' || true

Repository: imjlk/wp-typia

Length of output: 1914


🌐 Web query:

WordPress wp_find_abilities function complete abilities registry unique name suffix

💡 Result:

The WordPress Abilities API, introduced in version 6.9.0, does not contain a function named wp_find_abilities. Instead, the registry system utilizes specific functions and class methods for retrieving and querying registered abilities. The Abilities Registry is managed by the WP_Abilities_Registry class, which stores abilities in a collection [1][2]. Abilities are identified by a unique name that must follow a namespaced format, typically namespace/ability-name [3][2][4]. Key mechanisms for interacting with the registry include: 1. Retrieval Functions: - wp_get_ability( string $name): Retrieves a specific registered ability instance by its unique name [5][1]. - wp_get_abilities: Returns an array of all currently registered abilities [6][1]. - wp_has_ability( string $name): A boolean check to determine if an ability is registered [1]. 2. Registry Implementation: The WP_Abilities_Registry class provides the internal logic for registration and retrieval [1][2]. Registration is performed via wp_register_ability( string $name, array $args), which enforces naming conventions [1][3][4]. Specifically, names must consist of lowercase alphanumeric characters, dashes, and a single forward slash to separate the namespace prefix from the ability identifier [3][4]. There is no specific "unique name suffix" requirement in the Abilities API; instead, uniqueness is guaranteed by the full namespaced string (e.g., my-plugin/my-ability) [3][2]. If you were searching for a way to list or filter abilities, wp_get_abilities is the standard approach to retrieve the complete registry [6].

Citations:


🌐 Web query:

WordPress wp_find_abilities API operationId unique full name suffix

💡 Result:

The WordPress Abilities API does not define a specific operationId called wp_find_abilities. The primary functions for managing and interacting with abilities are wp_register_ability, wp_get_ability, wp_get_abilities, and wp_has_ability [1][2][3]. In the context of the WordPress REST API, operationId values typically follow a camelCase convention [4][5]. While the Abilities API exposes endpoints under the /wp-abilities/v1 namespace [6][7], these endpoints are defined by their HTTP methods and resource paths (e.g., /wp-abilities/v1/abilities or /wp-abilities/v1/(namespace)/(ability)/run) rather than a unified "find" operationId [6][7][8]. There is no formal API requirement for a unique full name suffix in this context. Abilities are registered with a namespaced string identifier (e.g., my-plugin/analyze-text) [2], and their execution via the REST API is handled by the WP_REST_Abilities_V1_Run_Controller class, which dynamically processes requests based on these identifiers [8].

Citations:


🌐 Web query:

WordPress wp_find_abilities 6.9.4 all_abilities prefix wp-abilities/v1

💡 Result:

The WordPress Abilities API, introduced in WordPress 6.9, provides a standardized way to register, discover, and execute plugin, theme, and core functionality [1][2][3]. The API uses the wp-abilities/v1 namespace for its REST API endpoints [4][3]. Key details regarding your query include: 1. Abilities API Namespace: All Abilities REST API endpoints are served under the wp-json/wp-abilities/v1 namespace [4][2][3]. 2. PHP Functionality vs. REST API: - There is no core function named wp_find_abilities [5][6]. The standard PHP function to retrieve all registered abilities is wp_get_abilities() [5][7]. - Abilities are not exposed via the REST API by default [4][3]. You must set the show_in_rest meta key to true when registering an ability using wp_register_ability() to make it available via the wp-abilities/v1 REST endpoints [4][3][8]. 3. REST API Endpoints: Once exposed, abilities can be accessed via [4][3]: - List all abilities: GET /wp-abilities/v1/abilities [4][3] - Get a single ability: GET /wp-abilities/v1/abilities/{name} [4][3] - Execute an ability: GET|POST|DELETE /wp-abilities/v1/abilities/{name}/run [4][7][3] The term all_abilities in your query typically refers to the variable used to store the array returned by the wp_get_abilities() function in PHP implementations [5][7][9]. Top results: [5][4][7][3]

Citations:


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

python3 - <<'PY'
import os, subprocess, re
from pathlib import Path

# Determine repo root from git metadata if possible.
try:
    repo = subprocess.check_output(["git", "rev-parse", "--show-toplevel"], text=True, stderr=subprocess.DEVNULL).strip()
except Exception as e:
    print(f"git rev-parse failed: {e}")
    exit(0)

print(f"repo: {repo}")
file_root = Path(repo, "packages/wp-typia-project-tools/src/runtime/add/cli-add-workspace-ai-templates.ts")
print(f"target exists: {file_root.exists()}")
if file_root.exists():
    lines = file_root.read_text().splitlines()
    print(f"lines: {len(lines)}")
    for i in range(730, min(800, len(lines))):
        print(f"{i+1:4d}: {lines[i]}")

print("\nability-related lines:")
search = re.compile(r'wp_register_ability|wp_get_ability|wp_get_abilities|wp_find_abilities|wp-abilities/v1|operationId|get_id\(\)|property_exists\(.*id|str_ends_with')
count = 0
for path in Path(repo).rglob("*"):
    if not path.is_file():
        continue
    if path.name.endswith((".php", ".ts", ".tsx")):
        try:
            text = path.read_text(errors="ignore")
        except Exception:
            continue
        for j, line in enumerate(text.splitlines(), 1):
            if search.search(line):
                count += 1
                if count <= 120:
                    print(f"{path}:{j}: {line.strip()}")
print(f"total matches: {count}")
PY

Repository: imjlk/wp-typia

Length of output: 1914


🌐 Web query:

site:github.com/WordPress/ wordpress-develop trunk wp-includes/abilities-api.php wp_find_abilities

💡 Result:

The wp_find_abilities function is a specific core ability introduced in WordPress 6.9, primarily designed to allow users to discover available abilities within the WordPress system [1]. It is managed via the Abilities API, which provides a unified, extensible framework for registering and executing discrete capabilities [2][3]. Key details regarding wp_find_abilities and the Abilities API include: Purpose and Availability: The core/find-abilities ability, which maps to the functional logic of wp_find_abilities, allows for the discovery of registered abilities [1]. It supports optional filtering by namespace and the show_in_rest property [1]. Access to this ability typically requires the read capability to prevent unauthorized enumeration while remaining accessible to authenticated users [1]. Implementation Context: The Abilities API, including the wp-includes/abilities-api.php file, serves as the registry and management layer for these capabilities [2][3]. Abilities must generally be registered using wp_register_ability during the wp_abilities_api_init action, although recent updates have allowed for registration after the init action in specific contexts [2][4]. Evolution and Filtering: Following the initial release of the Abilities API in WordPress 6.9, improvements have been made to increase flexibility. For example, recent developments (such as those tracked in Trac ticket #64990) have focused on adding comprehensive filtering support to functions like wp_get_abilities to allow for more granular retrieval of abilities by category, namespace, or meta properties [5]. For developers, the primary point of interaction is the Abilities API documentation and the source code located in wp-includes/abilities-api.php, which defines the registration and retrieval primitives [2][3].

Citations:


🌐 Web query:

site:developer.wordpress.org/reference/functions/wp_get_abilities/

💡 Result:

wp_get_abilities() retrieves all currently registered WordPress abilities.

$abilities = wp_get_abilities();

foreach ( $abilities as $ability ) {
    echo $ability->get_label();
}
  • Returns: WP_Ability[]
  • Returns an empty array if no abilities are registered or the registry is unavailable.
  • Introduced: WordPress 6.9.0. (developer.wordpress.org)

Citations:


Resolve abilities by complete name, then validate the operation suffix.

wp_get_abilities() returns the complete registry, but the registry ID is what WordPress guarantees unique. Use wp_get_ability( $full_name ) for a known full ability name, or return a conflict when different registered names match the same /$tool_name suffix.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@packages/wp-typia-project-tools/src/runtime/add/cli-add-workspace-ai-templates.ts`
around lines 766 - 777, Update the ability resolution logic around $ability and
wp_get_abilities() to first construct and resolve the known complete ability
name with wp_get_ability( $full_name ). Do not select the first registry entry
matching the /$tool_name suffix; if multiple distinct registered names match
that suffix, return a conflict instead, while preserving the existing successful
resolution behavior for an exact full name.

Comment on lines +770 to +773
\t\t\t\t\t$candidate_id = method_exists( $candidate, 'get_id' )
\t\t\t\t\t\t? $candidate->get_id()
\t\t\t\t\t\t: ( property_exists( $candidate, 'id' ) ? $candidate->id : '' );
\t\t\t\t\tif ( is_string( $candidate_id ) && str_ends_with( $candidate_id, '/' . $tool_name ) ) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🔴 Critical | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

source_file='packages/wp-typia-project-tools/src/runtime/add/cli-add-workspace-ai-templates.ts'
test_file='packages/wp-typia-project-tools/tests/typia-llm-tool-endpoint.test.ts'

if rg -n '\bget_id\s*\(' "$source_file"; then
  echo 'The generated fallback still uses get_id().' >&2
  exit 1
fi

rg -n -C 3 '\bget_name\s*\(' "$source_file" "$test_file"

Repository: imjlk/wp-typia

Length of output: 1901


🌐 Web query:

WordPress WP_Ability class get_name property names wp_get_abilities

💡 Result:

The WP_Ability class is part of the WordPress Abilities API, introduced in WordPress 6.9.0 [1][2]. The WP_Ability::get_name method is a public method used to retrieve the name of an ability, including its namespace (e.g., my-plugin/my-ability) [3][1]. It returns the value of the protected $name property defined within the class [3][4]. Regarding wp_get_abilities, this is a global function that returns an array of all ability instances currently registered in the system [5][6]. Each element in the returned array is an instance of the WP_Ability class [5]. In summary: - WP_Ability::get_name: Retrieves the name of a specific ability instance [3][2]. - wp_get_abilities: Returns a collection of all registered WP_Ability objects [5][6]. Developers typically use wp_get_abilities to retrieve the full list of abilities, and then call get_name on individual instances as needed for discovery or display purposes [5][6].

Citations:


🌐 Web query:

developer.wordpress.org reference classes WP_Ability methods properties get_id id

💡 Result:

The WP_Ability class is a component of the WordPress Abilities API introduced in WordPress 6.9.0 [1][2]. It is used to encapsulate an "Ability"—a distinct unit of functionality that can be discovered and executed, often used in AI or automation contexts [3]. Regarding your query about get_id and id: 1. Properties: The WP_Ability class does not explicitly list a public property named $id in its core definition [1][2][4]. Instead, it uses a $name property (provided during registration) to identify the ability [2][5]. 2. Methods: The WP_Ability class does not provide a standard get_id method in the core WordPress implementation [1][2][6]. It is important not to confuse the core WP_Ability class with third-party implementations or similarly named classes. For example, some custom abstractions or plugin-specific classes (like Astra_Abstract_Ability) may define their own get_id methods and $id properties to handle internal tracking [7]. Additionally, in the context of your own plugin code, you might manually include an ID in your metadata or schema definitions [8], but this is not a native feature of the WP_Ability class itself. To interact with registered abilities, you should generally use the WP_Abilities_Registry, which manages these instances [3]. The ability name (passed to wp_register_ability) serves as the unique identifier [9][5].

Citations:


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

source_file='packages/wp-typia-project-tools/src/runtime/add/cli-add-workspace-ai-templates.ts'

printf 'Repository checkout status:\n'
git status --short | sed -n '1,20p' || true

printf '\nLines 750-790 in source file:\n'
sed -n '750,790p' "$source_file" | cat -n

printf '\nGenerated PHP snippets containing candidate_id/get_name/get_id/id checks:\n'
rg -n -C 4 '\$candidate_id|get_id|get_name|property_exists|str_ends_with|ability_not_found' "$source_file"

printf '\nRelevant tests mentioning namespaced ability IDs:\n'
fd -i '.*workspace.*ai.*templates.*|.*llm.*endpoint.*|.*ability.*' packages/wp-typia-project-tools/tests packages/wp-typia-project-tools/src 2>/dev/null \
  | sed -n '1,50p' || true

Repository: imjlk/wp-typia

Length of output: 1914


Use get_name() for WP_Ability identifiers.

wp_get_abilities() returns WP_Ability instances, and WP_Ability exposes the registered ability name through get_name(), not get_id(). This generated PHP fallback should read $candidate->get_name() before comparing the suffix, so category/operationId abilities resolve correctly.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@packages/wp-typia-project-tools/src/runtime/add/cli-add-workspace-ai-templates.ts`
around lines 770 - 773, Update the candidate identifier logic in the generated
fallback to call get_name() for WP_Ability instances before checking the suffix
with str_ends_with. Preserve the existing property-based fallback for other
candidate types, ensuring category/operationId ability names resolve correctly.

@imjlk
imjlk merged commit a97d67b into main Jul 31, 2026
35 checks passed
@imjlk
imjlk deleted the fix/operation-id-ability-mapping branch July 31, 2026 10:42
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