Skip to content

Commit 3af75f7

Browse files
committed
Feat: Add Neo.snakeToCamel utility function #7940
1 parent d90957a commit 3af75f7

File tree

6 files changed

+82
-20
lines changed

6 files changed

+82
-20
lines changed

.github/.sync-metadata.json

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
2-
"lastSync": "2025-11-29T23:03:54.787Z",
3-
"releasesLastFetched": "2025-11-29T23:03:54.794Z",
2+
"lastSync": "2025-11-29T23:19:20.751Z",
3+
"releasesLastFetched": "2025-11-29T23:19:20.757Z",
44
"pushFailures": [],
55
"issues": {
66
"3789": {
@@ -11736,11 +11736,18 @@
1173611736
"contentHash": "10525f2a50464a3019ed39536425b0cde283568dbdc70789bb087e78d0dcbd95"
1173711737
},
1173811738
"7939": {
11739-
"state": "OPEN",
11739+
"state": "CLOSED",
1174011740
"path": "/Users/Shared/github/neomjs/neo/.github/ISSUE/issue-7939.md",
11741+
"closedAt": "2025-11-29T23:11:27Z",
11742+
"updatedAt": "2025-11-29T23:11:27Z",
11743+
"contentHash": "b5fcb602780dd7198866f75a182e7b192e81468abf1c94d66da513befa4207a3"
11744+
},
11745+
"7940": {
11746+
"state": "OPEN",
11747+
"path": "/Users/Shared/github/neomjs/neo/.github/ISSUE/issue-7940.md",
1174111748
"closedAt": null,
11742-
"updatedAt": "2025-11-29T23:03:33Z",
11743-
"contentHash": "875a835dad6ce0e6f9324347430ffa0fafffc7dedaad2583e471df772d452324"
11749+
"updatedAt": "2025-11-29T23:19:01Z",
11750+
"contentHash": "976cc3e8bf884413165b242075850e5e4d6c18c111a9c0902e0f550bbf34ddca"
1174411751
}
1174511752
},
1174611753
"releases": {

.github/ISSUE/issue-7939.md

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,24 @@
11
---
22
id: 7939
33
title: 'Feat: Implement Dynamic Tool Proxies for MCP Client'
4-
state: OPEN
4+
state: CLOSED
55
labels:
66
- enhancement
77
- ai
88
assignees:
99
- tobiu
1010
createdAt: '2025-11-29T23:03:33Z'
11-
updatedAt: '2025-11-29T23:03:33Z'
11+
updatedAt: '2025-11-29T23:11:27Z'
1212
githubUrl: 'https://github.com/neomjs/neo/issues/7939'
1313
author: tobiu
14-
commentsCount: 0
14+
commentsCount: 1
1515
parentIssue: 7931
1616
subIssues: []
1717
subIssuesCompleted: 0
1818
subIssuesTotal: 0
1919
blockedBy: []
2020
blocking: []
21+
closedAt: '2025-11-29T23:11:27Z'
2122
---
2223
# Feat: Implement Dynamic Tool Proxies for MCP Client
2324

@@ -31,9 +32,23 @@ This task aims to enhance the MCP Client by implementing Dynamic Tool Proxies. A
3132
2. **Demo Agent Update:** Modify `ai/agents/mcp-demo-agent.mjs` to demonstrate using the new `client.tools.<toolName>()` syntax.
3233
3. **Argument Validation (Optional/Future):** (Consider for later) Integrate OpenAPI schemas from `listTools()` to perform client-side argument validation before making the `callTool` request.
3334

35+
## Comments
36+
37+
### @tobiu - 2025-11-29 23:11
38+
39+
**Input from Gemini 2.5:**
40+
41+
> ✦ I have implemented Dynamic Tool Proxies for the MCP Client.
42+
>
43+
> ### Deliverables Completed
44+
> 1. **Dynamic Tool Proxy Implementation:** Enhanced `Neo.ai.mcp.client.Client` to dynamically create proxy methods on a `client.tools` object for each discovered tool. Tool names are converted from `snake_case` to `camelCase` for ergonomic access.
45+
> 2. **Demo Agent Update:** Modified `ai/agents/mcp-demo-agent.mjs` to successfully use the new `client.tools.<toolName>()` syntax (e.g., `ghClient.tools.listIssues()`).
46+
3447
## Activity Log
3548

3649
- 2025-11-29 @tobiu assigned to @tobiu
3750
- 2025-11-29 @tobiu added the `enhancement` label
3851
- 2025-11-29 @tobiu added the `ai` label
52+
- 2025-11-29 @tobiu referenced in commit `d90957a` - "Feat: Implement Dynamic Tool Proxies for MCP Client #7939"
53+
- 2025-11-29 @tobiu closed this issue
3954

.github/ISSUE/issue-7940.md

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
---
2+
id: 7940
3+
title: 'Feat: Add Neo.snakeToCamel utility function'
4+
state: OPEN
5+
labels:
6+
- enhancement
7+
- ai
8+
- refactoring
9+
assignees:
10+
- tobiu
11+
createdAt: '2025-11-29T23:19:01Z'
12+
updatedAt: '2025-11-29T23:19:01Z'
13+
githubUrl: 'https://github.com/neomjs/neo/issues/7940'
14+
author: tobiu
15+
commentsCount: 0
16+
parentIssue: 7931
17+
subIssues: []
18+
subIssuesCompleted: 0
19+
subIssuesTotal: 0
20+
blockedBy: []
21+
blocking: []
22+
---
23+
# Feat: Add Neo.snakeToCamel utility function
24+
25+
To provide a dedicated and semantically clear utility for converting snake_case strings to camelCase, and to maintain consistency within the core framework''s naming conversion utilities (`Neo.camel`, `Neo.decamel`), a new `snakeToCamel` function will be introduced. This function will reside in `src/core/Util.mjs` and be borrowed into the global `Neo` object for easy access.
26+
27+
### Deliverables
28+
1. **Implement `snakeToCamel` in `src/core/Util.mjs`:** Create a static utility method `snakeToCamel(value)` that converts a snake_case string to camelCase.
29+
2. **Borrow into `Neo` object:** Add `Neo.core.Util.snakeToCamel` as `Neo.snakeToCamel` in `src/Neo.mjs`.
30+
3. **Update `ai/mcp/client/Client.mjs`:** Refactor `Neo.ai.mcp.client.Client` to remove its internal `snakeToCamel` method and use the new `Neo.snakeToCamel` utility.
31+
4. **Update JSDoc:** Ensure all relevant JSDoc comments are updated to reflect the changes and proper usage.
32+
33+
## Activity Log
34+
35+
- 2025-11-29 @tobiu assigned to @tobiu
36+
- 2025-11-29 @tobiu added the `enhancement` label
37+
- 2025-11-29 @tobiu added the `ai` label
38+
- 2025-11-29 @tobiu added the `refactoring` label
39+

ai/mcp/client/Client.mjs

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ class Client extends Base {
128128
const tools = await this.listTools(); // Using listTools from this class
129129
this.tools = {};
130130
tools.forEach(tool => {
131-
const camelCaseName = this.snakeToCamel(tool.name); // Use the new function
131+
const camelCaseName = Neo.snakeToCamel(tool.name); // Use the global Neo.snakeToCamel
132132
console.log(`[MCP Client] Creating tool proxy: ${tool.name} -> ${camelCaseName}`); // Debug log
133133
this.tools[camelCaseName] = async (args) => {
134134
return this.callTool(tool.name, args);
@@ -170,16 +170,6 @@ class Client extends Base {
170170
}
171171
}
172172

173-
/**
174-
* Converts snake_case strings into camelCase.
175-
* @param {String} s The snake_case string.
176-
* @returns {String} The camelCase string.
177-
* @protected
178-
*/
179-
snakeToCamel(s) {
180-
return s.replace(/(_\w)/g, m => m[1].toUpperCase());
181-
}
182-
183173
/**
184174
* Cleanup when the instance is destroyed
185175
*/

src/Neo.mjs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,9 @@ const
5959
* @borrows Neo.core.Util.isDefined as isDefined
6060
* @borrows Neo.core.Compare.isEqual as isEqual
6161
* @borrows Neo.core.Util.isNumber as isNumber
62-
* @borrows Neo.core.Util.isObject as isObject
62+
* @borrows Neo.core.Util.isRecord as isRecord
6363
* @borrows Neo.core.Util.isString as isString
64+
* @borrows Neo.core.Util.snakeToCamel as snakeToCamel
6465
* @borrows Neo.core.Util.toArray as toArray
6566
* @tutorial 01_Concept
6667
*/

src/core/Util.mjs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,15 @@ class Util {
191191
return typeof value === 'string'
192192
}
193193

194+
/**
195+
* Converts a snake_case string into camelCase.
196+
* @param {String} value The snake_case string.
197+
* @returns {String} The camelCase string.
198+
*/
199+
static snakeToCamel(value) {
200+
return value.replace(/(_\w)/g, m => m[1].toUpperCase());
201+
}
202+
194203
/**
195204
* Converts any iterable (strings, numeric indices and a length property) into a true array
196205
* @param {Object|String} iterable
@@ -232,6 +241,7 @@ Neo.applyFromNs(Neo, Util, {
232241
isPromise : 'isPromise',
233242
isRecord : 'isRecord',
234243
isString : 'isString',
244+
snakeToCamel : 'snakeToCamel',
235245
toArray : 'toArray'
236246
}, true);
237247

0 commit comments

Comments
 (0)