diff --git a/package.json b/package.json index eac9973..6c9b9ce 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@elevenlabs/cli", - "version": "0.5.0", + "version": "0.5.1", "description": "CLI tool to manage ElevenLabs agents", "type": "module", "keywords": [ diff --git a/src/__tests__/utils.test.ts b/src/__tests__/utils.test.ts index b85f514..2162660 100644 --- a/src/__tests__/utils.test.ts +++ b/src/__tests__/utils.test.ts @@ -824,6 +824,90 @@ describe("Utils", () => { expect(afterPull).toEqual(originalWorkflow); }); + it("should preserve model_usage keys in toCamelCaseKeys", () => { + const input = { + from_conversation_metadata: { + original_agent_reply: { + llm_usage: { + model_usage: { + "gpt_5.2": { input_tokens: 100, output_tokens: 50 }, + "gpt-4o-mini": { input_tokens: 200, output_tokens: 100 }, + "gemini-2.5-flash": { input_tokens: 300, output_tokens: 150 }, + "claude-3-opus": { input_tokens: 400, output_tokens: 200 } + } + } + } + } + }; + + const result = toCamelCaseKeys(input); + + expect(result).toEqual({ + fromConversationMetadata: { + originalAgentReply: { + llmUsage: { + modelUsage: { + "gpt_5.2": { inputTokens: 100, outputTokens: 50 }, // preserved - model name + "gpt-4o-mini": { inputTokens: 200, outputTokens: 100 }, // preserved - model name + "gemini-2.5-flash": { inputTokens: 300, outputTokens: 150 }, // preserved - model name + "claude-3-opus": { inputTokens: 400, outputTokens: 200 } // preserved - model name + } + } + } + } + }); + }); + + it("should preserve modelUsage keys in toSnakeCaseKeys", () => { + const input = { + fromConversationMetadata: { + originalAgentReply: { + llmUsage: { + modelUsage: { + "gpt-5.2": { inputTokens: 100, outputTokens: 50 }, + "gpt-4o-mini": { inputTokens: 200, outputTokens: 100 } + } + } + } + } + }; + + const result = toSnakeCaseKeys(input); + + expect(result).toEqual({ + from_conversation_metadata: { + original_agent_reply: { + llm_usage: { + model_usage: { + "gpt-5.2": { input_tokens: 100, output_tokens: 50 }, // preserved - model name + "gpt-4o-mini": { input_tokens: 200, output_tokens: 100 } // preserved - model name + } + } + } + } + }); + }); + + it("should maintain round-trip conversion symmetry for model_usage", () => { + const original = { + from_conversation_metadata: { + original_agent_reply: { + llm_usage: { + model_usage: { + "gpt_5.2": { input_tokens: 100, output_tokens: 50 }, + "gpt-4o-mini": { input_tokens: 200, output_tokens: 100 } + } + } + } + } + }; + + const afterPush = toCamelCaseKeys(original); + const afterPull = toSnakeCaseKeys(afterPush); + + expect(afterPull).toEqual(original); + }); + it("should maintain round-trip conversion symmetry for dynamic_variables", () => { // Simulate pull → push cycle for tests const originalTestConfig = { diff --git a/src/shared/utils.ts b/src/shared/utils.ts index cac2116..7ac85a6 100644 --- a/src/shared/utils.ts +++ b/src/shared/utils.ts @@ -124,6 +124,7 @@ const PRESERVE_CHILD_KEYS = new Set([ 'request_headers', 'requestHeaders', 'dynamic_variables', 'dynamicVariables', 'language_presets', 'languagePresets', + 'model_usage', 'modelUsage', 'nodes', 'edges', ]);