cloudflare / cloudflare/partykit
camelCaseToKebabCase breaks acronyms in agent names (e.g., AISessionAgent → a-i-session-agent)
- Dominant language
- TypeScript
- Stars
- 1.3k
- Forks
- 79
- PR merge metrics
- No merged PRs in 30d
Description
## Problem
The `camelCaseToKebabCase` function in `agents/dist/utils.js` treats every capital letter as a word boundary, which breaks common naming conventions that use acronyms (e.g., `AI`, `API`, `UI`, `DB`).
## Expected Behavior
`AISessionAgent` should convert to `ai-session-agent`
## Actual Behavior
`AISessionAgent` converts to `a-i-session-agent` (each letter `A`, `I` treated separately)
## The Error Message
```
The url http://localhost/agents/a-i-session-agent/default does not match any server namespace.
Did you forget to add a durable object binding to the class A-i-session-agent in your wrangler.jsonc?
```
This error is confusing because:
1. It doesn't explain that the agent name was transformed
2. It suggests adding a binding for `A-i-session-agent` (which isn't a valid class name)
3. Users have no indication that their `AISessionAgent` class name is causing the mismatch
## Workaround
Pass the kebab-case name directly to `useAgent()`:
```ts
// Instead of this (broken):
useAgent({ agent: 'AISessionAgent', name: sessionId })
// Do this (works):
useAgent({ agent: 'ai-session-agent', name: sessionId })
```
This works because `camelCaseToKebabCase('ai-session-agent')` returns `'ai-session-agent'` unchanged.
## Suggested Fixes
### Option 1: Improve the transformation function
Update `camelCaseToKebabCase` to handle consecutive capitals as acronyms:
```js
function camelCaseToKebabCase(str) {
// Handle consecutive capitals as acronyms (e.g., "AI" stays together)
return str
.replace(/([A-Z]+)([A-Z][a-z])/g, '$1-$2') // Split before last capital of acronym
.replace(/([a-z])([A-Z])/g, '$1-$2') // Split lowercase to uppercase
.toLowerCase();
}
// AISessionAgent -> ai-session-agent
// APIEndpoint -> api-endpoint
// MyUIComponent -> my-ui-component
```
### Option 2: Better error message
If the namespace isn't found, show what the input was transformed to:
```
Agent namespace 'a-i-session-agent' not found.
Note: 'AISessionAgent' was converted to 'a-i-session-agent'.
Tip: Pass the kebab-case name directly: useAgent({ agent: 'ai-session-agent' })
```
### Option 3: Document the behavior
Add JSDoc to the `agent` option explaining:
- The transformation that occurs
- That kebab-case names pass through unchanged
- Examples with acronyms
## Environment
- `agents` package version: 0.0.74
- `hono-agents` package version: 0.0.9
Contributor guide
Assessment
This issue has not been assessed yet.