Skip to content

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

@markdembo

Description

@markdembo

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():

// 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:

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions