cloudflare / cloudflare/partykit

camelCaseToKebabCase breaks acronyms in agent names (e.g., AISessionAgent → a-i-session-agent)

Open
#351 10 comments 0 reactions 0 assignees View on GitHub
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

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.