Skip to content

Conversation

@takahirom
Copy link
Owner

What

  • Rename ArbigentHint: prefix to [[aihint:...]] format
  • Rename variables/constants: appHintsaiHints, APP_HINTSAI_HINTS
  • Change XML tag from <HINT_FROM_APP> to <AI_HINTS>
  • Add edge case tests for parsing logic

Why

  • The [[...]] format allows hints to coexist with accessibility labels
  • Supports structured data like JSON inside hints
  • More extensible for future hint types (e.g., [[aistate:...]], [[aiaction:...]])
  • Fixes parsing bug when multiple ]] exist in the text

@coderabbitai
Copy link

coderabbitai bot commented Dec 26, 2025

📝 Walkthrough

Walkthrough

This PR renames the App-Provided Context feature from "ArbigentHint" to "AI Hints", updates APIs and data fields from appHintsaiHints, and changes hint extraction to recognize the new [[aihint:...]] bracketed syntax across platform examples, parsing, and tests.

Changes

Cohort / File(s) Summary
Docs & Examples
README.md
Rename to "AI Hints", update usage examples for Android/iOS/Web to use [[aihint:...]], document coexistence with accessibility labels and testing guidance.
Core model & prompt template
arbigent-core-model/src/commonMain/kotlin/ArbigentResult.kt, arbigent-core/src/main/java/io/github/takahirom/arbigent/UserPromptTemplate.kt
Public property/constant and formatting parameter renamed: appHintsaiHints, APP_HINTSAI_HINTS; placeholder token changed to {{AI_HINTS}}.
Context & AI wiring
arbigent-core/src/main/java/io/github/takahirom/arbigent/ArbigentContextHolder.kt, arbigent-ai-openai/src/main/java/io/github/takahirom/arbigent/OpenAIAi.kt
Method/constructor parameter renames from appHintsaiHints; prompt building and decision flow updated to forward aiHints.
Hint extraction & public API
arbigent-core/src/main/java/io/github/takahirom/arbigent/ArbigentDevice.kt
Rename TreeNode.findAllArbigentHints()TreeNode.findAllAiHints(); change extraction logic to parse [[aihint:...]] inline syntax (including JSON-like content) and update callers to populate aiHints in returned UI tree strings.
Tests — extraction & edge cases
arbigent-core/src/test/kotlin/io/github/takahirom/arbigent/TreeNodeExtensionsTest.kt
Rename tests to findAllAiHints variants, switch test data to [[aihint:...]], and add multiple edge-case tests (JSON content, unclosed/missing brackets, empty/prefix-only hints, multiple hints behavior).
Tests — prompt template
arbigent-core/src/test/kotlin/io/github/takahirom/arbigent/UserPromptTemplateTest.kt
Rename test functions and parameters from appHintsaiHints; replace <HINT_FROM_APP> markers with <AI_HINTS> and update expectations accordingly.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • robert-northmind

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 4.17% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: refactoring the AI hints format from ArbigentHint: prefix to [[aihint:...]] format, which is the primary objective across all modified files.
Description check ✅ Passed The description is well-related to the changeset, clearly explaining what was changed (format rename, variable renaming), why these changes were made (coexistence with labels, extensibility, bug fixes), and supporting details.
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch tm/refactor-aihint-format

📜 Recent review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c078a58 and 8498524.

📒 Files selected for processing (1)
  • README.md
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: takahirom
Repo: takahirom/arbigent PR: 329
File: arbigent-core/src/main/java/io/github/takahirom/arbigent/ArbigentAgent.kt:0-0
Timestamp: 2025-07-08T15:34:42.649Z
Learning: takahirom prefers simplified implementations over complex caching libraries, favoring manual cache management through methods like clearResolvedGoalCache() rather than using bounded cache implementations with automatic eviction policies.
🪛 markdownlint-cli2 (0.18.1)
README.md

92-92: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


93-93: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


106-106: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


107-107: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (12)
  • GitHub Check: cli-e2e-web
  • GitHub Check: build (ubuntu-latest)
  • GitHub Check: build (macos-latest)
  • GitHub Check: build (windows-latest)
  • GitHub Check: cli-e2e-android (2, 2)
  • GitHub Check: compare-screenshot-test
  • GitHub Check: cli-e2e-ios
  • GitHub Check: build
  • GitHub Check: cli-e2e-android (1, 2)
  • GitHub Check: test
  • GitHub Check: store-screenshot-test
  • GitHub Check: Analyze (java-kotlin)
🔇 Additional comments (1)
README.md (1)

91-107: Documentation for AI Hints is clear and comprehensive.

The new section accurately reflects the refactored [[aihint:...]] format and provides well-structured cross-platform examples (Android, iOS, Web) that make the feature usage patterns immediately clear. The warning about screen reader impact is appropriately placed and helpful for developers.


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 and usage tips.

Copy link

@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: 1

🧹 Nitpick comments (1)
arbigent-core/src/main/java/io/github/takahirom/arbigent/ArbigentDevice.kt (1)

705-738: Parsing logic handles common cases, but nested ]] in JSON arrays may truncate hints.

The indexOf(AI_HINT_SUFFIX, ...) approach correctly finds the first ]] after the prefix, which fixes the original bug. However, if JSON content contains array syntax like [[aihint:["a","b"]]], the parser would extract ["a","b" (truncating at the first ]]).

Consider whether this edge case needs handling, or if the documentation should note that ]] sequences within hint content should be avoided.

🔎 Alternative: Find matching closing brackets

If you need to support ]] within hint content in the future, you could search for ]] that is NOT preceded by another ]:

-      val endIndex = text.indexOf(AI_HINT_SUFFIX, startIndex + AI_HINT_PREFIX.length)
-      if (endIndex > startIndex) {
-        val hint = text.substring(startIndex + AI_HINT_PREFIX.length, endIndex)
+      // Find ]] that closes the hint (last ]] in case of nested sequences)
+      val searchStart = startIndex + AI_HINT_PREFIX.length
+      var endIndex = text.lastIndexOf(AI_HINT_SUFFIX)
+      if (endIndex >= searchStart) {
+        val hint = text.substring(searchStart, endIndex)

Or simply document that ]] should not appear in hint content.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 915c15a and c078a58.

📒 Files selected for processing (8)
  • README.md
  • arbigent-ai-openai/src/main/java/io/github/takahirom/arbigent/OpenAIAi.kt
  • arbigent-core-model/src/commonMain/kotlin/ArbigentResult.kt
  • arbigent-core/src/main/java/io/github/takahirom/arbigent/ArbigentContextHolder.kt
  • arbigent-core/src/main/java/io/github/takahirom/arbigent/ArbigentDevice.kt
  • arbigent-core/src/main/java/io/github/takahirom/arbigent/UserPromptTemplate.kt
  • arbigent-core/src/test/kotlin/io/github/takahirom/arbigent/TreeNodeExtensionsTest.kt
  • arbigent-core/src/test/kotlin/io/github/takahirom/arbigent/UserPromptTemplateTest.kt
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: takahirom
Repo: takahirom/arbigent PR: 329
File: arbigent-core/src/main/java/io/github/takahirom/arbigent/ArbigentAgent.kt:0-0
Timestamp: 2025-07-08T15:34:42.649Z
Learning: takahirom prefers simplified implementations over complex caching libraries, favoring manual cache management through methods like clearResolvedGoalCache() rather than using bounded cache implementations with automatic eviction policies.
📚 Learning: 2025-07-02T09:57:37.159Z
Learnt from: takahirom
Repo: takahirom/arbigent PR: 318
File: arbigent-cli/src/main/kotlin/main.kt:27-28
Timestamp: 2025-07-02T09:57:37.159Z
Learning: In the arbigent project, YamlValueSource in arbigent-cli/src/main/kotlin/main.kt is accessible without requiring an explicit import statement, contrary to initial analysis suggesting a missing import.

Applied to files:

  • arbigent-core-model/src/commonMain/kotlin/ArbigentResult.kt
🪛 markdownlint-cli2 (0.18.1)
README.md

92-92: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


93-93: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


104-104: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (12)
  • GitHub Check: cli-e2e-android (2, 2)
  • GitHub Check: build
  • GitHub Check: cli-e2e-ios
  • GitHub Check: cli-e2e-android (1, 2)
  • GitHub Check: test
  • GitHub Check: build (macos-latest)
  • GitHub Check: build (ubuntu-latest)
  • GitHub Check: cli-e2e-web
  • GitHub Check: build (windows-latest)
  • GitHub Check: store-screenshot-test
  • GitHub Check: compare-screenshot-test
  • GitHub Check: Analyze (java-kotlin)
🔇 Additional comments (10)
arbigent-core-model/src/commonMain/kotlin/ArbigentResult.kt (1)

99-104: LGTM!

The property rename from appHints to aiHints aligns with the broader refactoring effort and maintains the same type and default value.

arbigent-core/src/main/java/io/github/takahirom/arbigent/ArbigentContextHolder.kt (1)

96-111: LGTM!

The parameter rename and updated call site properly propagate the aiHints naming convention through the prompt construction chain.

arbigent-core/src/main/java/io/github/takahirom/arbigent/UserPromptTemplate.kt (2)

14-18: LGTM!

The constant and template placeholder renaming is consistent with the new AI hints convention.


88-101: LGTM!

The format() function properly handles the renamed aiHints parameter and generates the <AI_HINTS> XML block correctly.

arbigent-core/src/main/java/io/github/takahirom/arbigent/ArbigentDevice.kt (1)

275-276: LGTM!

Correctly updated to use the renamed findAllAiHints() function.

arbigent-ai-openai/src/main/java/io/github/takahirom/arbigent/OpenAIAi.kt (2)

214-224: LGTM!

The aiHints parameter is correctly extracted from uiTreeStrings.aiHints and passed to buildPrompt.


339-358: LGTM!

The buildPrompt function correctly propagates aiHints to the context holder's prompt method.

arbigent-core/src/test/kotlin/io/github/takahirom/arbigent/UserPromptTemplateTest.kt (1)

115-167: LGTM!

Test cases properly updated to reflect the renamed aiHints parameter and <AI_HINTS> XML tags. The position test ensures hints maintain correct ordering in the template output.

arbigent-core/src/test/kotlin/io/github/takahirom/arbigent/TreeNodeExtensionsTest.kt (2)

7-112: LGTM!

Existing tests properly updated to use findAllAiHints() and the new [[aihint:...]] syntax.


114-211: Excellent edge case coverage!

The new tests comprehensively verify:

  • Hint coexistence with accessibility labels (line 117)
  • JSON content handling (line 131)
  • Single hint extraction per node behavior (line 145)
  • Malformed hint robustness (unclosed, missing bracket, prefix-only)
  • Empty hint content behavior

This test suite provides strong confidence in the parsing logic.

README.md Outdated
Comment on lines 91 to 105
* **AI Hints - App-Provided Context:**
* Apps can provide domain-specific hints to help the AI understand the current screen better.
* Set `contentDescription` with `ArbigentHint:` prefix:
* Embed hints in `contentDescription` using the `[[aihint:...]]` format:
```kotlin
view.contentDescription = "ArbigentHint:Video player, buffering"
// Hint only
view.contentDescription = "[[aihint:Video player, buffering]]"

// Coexisting with accessibility label
view.contentDescription = "Play button [[aihint:Video player, currently buffering]]"

// Structured data (JSON)
view.contentDescription = """[[aihint:{"screen":"player","state":"buffering"}]]"""
```
* The `[[...]]` format allows hints to coexist with accessibility labels and supports structured data like JSON.
* **Note:** Since this uses `contentDescription`, it affects screen readers. Enable hints only during testing via Intent flag or debug BuildConfig to avoid accessibility issues in production.
Copy link

@coderabbitai coderabbitai bot Dec 26, 2025

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Fix markdown list indentation to align with style guidelines.

Lines 92–93 and 104 use 4-space indentation for nested list items, but the project's markdown style expects 2-space indentation (MD007).

🔎 Proposed fix for markdown indentation
 * **AI Hints - App-Provided Context:**
-    * Apps can provide domain-specific hints to help the AI understand the current screen better.
-    * Embed hints in `contentDescription` using the `[[aihint:...]]` format:
+  * Apps can provide domain-specific hints to help the AI understand the current screen better.
+  * Embed hints in `contentDescription` using the `[[aihint:...]]` format:
       ```kotlin
-      // Hint only
-      view.contentDescription = "[[aihint:Video player, buffering]]"
+      * // Hint only
+      * view.contentDescription = "[[aihint:Video player, buffering]]"

Wait, let me reconsider—the code block itself should stay unchanged. The fix should only apply to the list items:

 * **AI Hints - App-Provided Context:**
-    * Apps can provide domain-specific hints to help the AI understand the current screen better.
-    * Embed hints in `contentDescription` using the `[[aihint:...]]` format:
+  * Apps can provide domain-specific hints to help the AI understand the current screen better.
+  * Embed hints in `contentDescription` using the `[[aihint:...]]` format:
       ```kotlin
       // Hint only
       view.contentDescription = "[[aihint:Video player, buffering]]"
@@ -101,7 +101,7 @@
       // Structured data (JSON)
       view.contentDescription = """[[aihint:{"screen":"player","state":"buffering"}]]"""
       ```
-    * The `[[...]]` format allows hints to coexist with accessibility labels and supports structured data like JSON.
-    * **Note:** Since this uses `contentDescription`, it affects screen readers. Enable hints only during testing via Intent flag or debug BuildConfig to avoid accessibility issues in production.
+  * The `[[...]]` format allows hints to coexist with accessibility labels and supports structured data like JSON.
+  * **Note:** Since this uses `contentDescription`, it affects screen readers. Enable hints only during testing via Intent flag or debug BuildConfig to avoid accessibility issues in production.

Content Review: The documentation accurately reflects the new [[aihint:...]] format and provides clear examples covering hint-only, coexisting-with-label, and structured JSON use cases. The warning about screen reader impact is appropriate and helpful.

📝 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
* **AI Hints - App-Provided Context:**
* Apps can provide domain-specific hints to help the AI understand the current screen better.
* Set `contentDescription` with `ArbigentHint:` prefix:
* Embed hints in `contentDescription` using the `[[aihint:...]]` format:
```kotlin
view.contentDescription = "ArbigentHint:Video player, buffering"
// Hint only
view.contentDescription = "[[aihint:Video player, buffering]]"
// Coexisting with accessibility label
view.contentDescription = "Play button [[aihint:Video player, currently buffering]]"
// Structured data (JSON)
view.contentDescription = """[[aihint:{"screen":"player","state":"buffering"}]]"""
```
* The `[[...]]` format allows hints to coexist with accessibility labels and supports structured data like JSON.
* **Note:** Since this uses `contentDescription`, it affects screen readers. Enable hints only during testing via Intent flag or debug BuildConfig to avoid accessibility issues in production.
* **AI Hints - App-Provided Context:**
* Apps can provide domain-specific hints to help the AI understand the current screen better.
* Embed hints in `contentDescription` using the `[[aihint:...]]` format:
🧰 Tools
🪛 markdownlint-cli2 (0.18.1)

92-92: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


93-93: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


104-104: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


105-105: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)

🤖 Prompt for AI Agents
In README.md around lines 91–105 the nested markdown list items use 4-space
indentation which violates MD007; change the list indentation to 2 spaces for
the nested bullets (e.g., the lines starting with "The `[[...]]` format..." and
"**Note:** ...", and any other nested list markers in this block) so they align
with the project's 2-space list style, and do not modify the contents of the
fenced Kotlin code block — only adjust the surrounding list marker indentation.

Copy link
Owner Author

Choose a reason for hiding this comment

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

It's working fine in previews

Copy link

Choose a reason for hiding this comment

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

@takahirom, understood! If the markdown renders correctly in your preview, you can keep it as-is.

If you'd like to suppress this markdownlint warning in the future, you can configure .markdownlint.json to adjust the MD007 rule settings or disable it for this project. But since it's rendering fine, no changes are needed.


🧠 Learnings used
Learnt from: takahirom
Repo: takahirom/arbigent PR: 329
File: arbigent-core/src/main/java/io/github/takahirom/arbigent/ArbigentAgent.kt:0-0
Timestamp: 2025-07-08T15:34:42.649Z
Learning: takahirom prefers simplified implementations over complex caching libraries, favoring manual cache management through methods like clearResolvedGoalCache() rather than using bounded cache implementations with automatic eviction policies.

@takahirom takahirom merged commit 41e111b into main Dec 28, 2025
15 checks passed
@takahirom takahirom deleted the tm/refactor-aihint-format branch December 28, 2025 03:46
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.

2 participants