Skip to content

Commit 0047ffa

Browse files
committed
refactor(report): move snake_case conversion to session-report layer
Keep chat-item toJSON() emitting the framework's native camelCase shape and do the snake_case wire conversion in report.ts. toSnakeCaseDeep now recurses into toJSON() output (also fixing camelCase metrics keys), special-cases args->arguments, and passes extra dicts through verbatim.
1 parent 8dd92ba commit 0047ffa

4 files changed

Lines changed: 99 additions & 76 deletions

File tree

agents/src/llm/__snapshots__/chat_context.test.ts.snap

Lines changed: 47 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -29,16 +29,16 @@ exports[`ChatContext.toJSON > should match snapshot for edge cases > edge-cases-
2929
"type": "message",
3030
},
3131
{
32-
"arguments": "{}",
33-
"call_id": "minimal",
32+
"args": "{}",
33+
"callId": "minimal",
3434
"id": "func_minimal",
3535
"name": "test",
3636
"type": "function_call",
3737
},
3838
{
39-
"call_id": "minimal",
39+
"callId": "minimal",
4040
"id": "func_output_nameless",
41-
"is_error": false,
41+
"isError": false,
4242
"name": "",
4343
"output": "OK",
4444
"type": "function_call_output",
@@ -63,7 +63,7 @@ exports[`ChatContext.toJSON > should match snapshot for edge cases > edge-cases-
6363
"items": [
6464
{
6565
"content": [],
66-
"created_at": 5000000000,
66+
"createdAt": 5000000000,
6767
"id": "msg_empty_1",
6868
"interrupted": false,
6969
"role": "user",
@@ -76,7 +76,7 @@ exports[`ChatContext.toJSON > should match snapshot for edge cases > edge-cases-
7676
"type": "audio_content",
7777
},
7878
],
79-
"created_at": 5000000001,
79+
"createdAt": 5000000001,
8080
"id": "msg_silent_audio",
8181
"interrupted": false,
8282
"role": "user",
@@ -88,25 +88,25 @@ exports[`ChatContext.toJSON > should match snapshot for edge cases > edge-cases-
8888
"Part 2. ",
8989
"Part 3.",
9090
],
91-
"created_at": 5000000002,
91+
"createdAt": 5000000002,
9292
"id": "msg_multi_text",
9393
"interrupted": false,
9494
"role": "assistant",
9595
"type": "message",
9696
},
9797
{
98-
"arguments": "{}",
99-
"call_id": "minimal",
100-
"created_at": 5000000003,
98+
"args": "{}",
99+
"callId": "minimal",
100+
"createdAt": 5000000003,
101101
"id": "func_minimal",
102102
"name": "test",
103103
"type": "function_call",
104104
},
105105
{
106-
"call_id": "minimal",
107-
"created_at": 5000000004,
106+
"callId": "minimal",
107+
"createdAt": 5000000004,
108108
"id": "func_output_nameless",
109-
"is_error": false,
109+
"isError": false,
110110
"name": "",
111111
"output": "OK",
112112
"type": "function_call_output",
@@ -117,7 +117,7 @@ exports[`ChatContext.toJSON > should match snapshot for edge cases > edge-cases-
117117
118118
"quotes" 'apostrophes' \\backslashes\\ {braces} [brackets]",
119119
],
120-
"created_at": 5000000005,
120+
"createdAt": 5000000005,
121121
"id": "msg_special_chars",
122122
"interrupted": false,
123123
"role": "user",
@@ -146,16 +146,16 @@ exports[`ChatContext.toJSON > should match snapshot for function calls > convers
146146
"type": "message",
147147
},
148148
{
149-
"arguments": "{"location": "Paris, France", "unit": "celsius"}",
150-
"call_id": "call_weather_123",
149+
"args": "{"location": "Paris, France", "unit": "celsius"}",
150+
"callId": "call_weather_123",
151151
"id": "func_call_1",
152152
"name": "get_weather",
153153
"type": "function_call",
154154
},
155155
{
156-
"call_id": "call_weather_123",
156+
"callId": "call_weather_123",
157157
"id": "func_output_1",
158-
"is_error": false,
158+
"isError": false,
159159
"name": "get_weather",
160160
"output": "{"temperature": 22, "condition": "partly cloudy", "humidity": 65}",
161161
"type": "function_call_output",
@@ -180,25 +180,25 @@ exports[`ChatContext.toJSON > should match snapshot for function calls > convers
180180
"content": [
181181
"What's the weather in Paris?",
182182
],
183-
"created_at": 3000000000,
183+
"createdAt": 3000000000,
184184
"id": "msg_user_3",
185185
"interrupted": false,
186186
"role": "user",
187187
"type": "message",
188188
},
189189
{
190-
"arguments": "{"location": "Paris, France", "unit": "celsius"}",
191-
"call_id": "call_weather_123",
192-
"created_at": 3000000001,
190+
"args": "{"location": "Paris, France", "unit": "celsius"}",
191+
"callId": "call_weather_123",
192+
"createdAt": 3000000001,
193193
"id": "func_call_1",
194194
"name": "get_weather",
195195
"type": "function_call",
196196
},
197197
{
198-
"call_id": "call_weather_123",
199-
"created_at": 3000000002,
198+
"callId": "call_weather_123",
199+
"createdAt": 3000000002,
200200
"id": "func_output_1",
201-
"is_error": false,
201+
"isError": false,
202202
"name": "get_weather",
203203
"output": "{"temperature": 22, "condition": "partly cloudy", "humidity": 65}",
204204
"type": "function_call_output",
@@ -207,7 +207,7 @@ exports[`ChatContext.toJSON > should match snapshot for function calls > convers
207207
"content": [
208208
"The weather in Paris is currently 22°C and partly cloudy with 65% humidity.",
209209
],
210-
"created_at": 3000000003,
210+
"createdAt": 3000000003,
211211
"id": "msg_assistant_2",
212212
"interrupted": false,
213213
"role": "assistant",
@@ -301,7 +301,7 @@ exports[`ChatContext.toJSON > should match snapshot for message property variati
301301
"content": [
302302
"Message with custom ID",
303303
],
304-
"created_at": 6000000000,
304+
"createdAt": 6000000000,
305305
"id": "custom-message-id-123",
306306
"interrupted": false,
307307
"role": "user",
@@ -311,7 +311,7 @@ exports[`ChatContext.toJSON > should match snapshot for message property variati
311311
"content": [
312312
"This response was interrupted...",
313313
],
314-
"created_at": 6000000001,
314+
"createdAt": 6000000001,
315315
"id": "msg_interrupted",
316316
"interrupted": true,
317317
"role": "assistant",
@@ -321,7 +321,7 @@ exports[`ChatContext.toJSON > should match snapshot for message property variati
321321
"content": [
322322
"Developer message",
323323
],
324-
"created_at": 6000000002,
324+
"createdAt": 6000000002,
325325
"id": "msg_dev_2",
326326
"interrupted": false,
327327
"role": "developer",
@@ -331,7 +331,7 @@ exports[`ChatContext.toJSON > should match snapshot for message property variati
331331
"content": [
332332
"System message",
333333
],
334-
"created_at": 6000000003,
334+
"createdAt": 6000000003,
335335
"id": "msg_system_3",
336336
"interrupted": false,
337337
"role": "system",
@@ -343,14 +343,14 @@ exports[`ChatContext.toJSON > should match snapshot for message property variati
343343
{
344344
"id": "img_detailed",
345345
"image": "https://example.com/image.jpg",
346-
"inference_detail": "low",
347-
"inference_height": 512,
348-
"inference_width": 512,
349-
"mime_type": "image/png",
346+
"inferenceDetail": "low",
347+
"inferenceHeight": 512,
348+
"inferenceWidth": 512,
349+
"mimeType": "image/png",
350350
"type": "image_content",
351351
},
352352
],
353-
"created_at": 6000000004,
353+
"createdAt": 6000000004,
354354
"id": "msg_with_image",
355355
"interrupted": false,
356356
"role": "user",
@@ -386,10 +386,10 @@ exports[`ChatContext.toJSON > should match snapshot for multimodal content > mul
386386
{
387387
"id": "img_test_1",
388388
"image": "https://example.com/test-image.jpg",
389-
"inference_detail": "high",
390-
"inference_height": 768,
391-
"inference_width": 1024,
392-
"mime_type": "image/jpeg",
389+
"inferenceDetail": "high",
390+
"inferenceHeight": 768,
391+
"inferenceWidth": 1024,
392+
"mimeType": "image/jpeg",
393393
"type": "image_content",
394394
},
395395
{
@@ -398,7 +398,7 @@ exports[`ChatContext.toJSON > should match snapshot for multimodal content > mul
398398
},
399399
"What do you think?",
400400
],
401-
"created_at": 2000000000,
401+
"createdAt": 2000000000,
402402
"id": "msg_user_2",
403403
"interrupted": false,
404404
"role": "user",
@@ -438,10 +438,10 @@ exports[`ChatContext.toJSON > should match snapshot for multimodal content > mul
438438
{
439439
"id": "img_test_1",
440440
"image": "https://example.com/test-image.jpg",
441-
"inference_detail": "high",
442-
"inference_height": 768,
443-
"inference_width": 1024,
444-
"mime_type": "image/jpeg",
441+
"inferenceDetail": "high",
442+
"inferenceHeight": 768,
443+
"inferenceWidth": 1024,
444+
"mimeType": "image/jpeg",
445445
"type": "image_content",
446446
},
447447
"What do you think?",
@@ -496,7 +496,7 @@ exports[`ChatContext.toJSON > should match snapshot for simple conversation > si
496496
"content": [
497497
"You are a helpful assistant.",
498498
],
499-
"created_at": 1000000000,
499+
"createdAt": 1000000000,
500500
"id": "msg_system_1",
501501
"interrupted": false,
502502
"role": "system",
@@ -506,7 +506,7 @@ exports[`ChatContext.toJSON > should match snapshot for simple conversation > si
506506
"content": [
507507
"Hello, how are you?",
508508
],
509-
"created_at": 1000000001,
509+
"createdAt": 1000000001,
510510
"id": "msg_user_1",
511511
"interrupted": false,
512512
"role": "user",
@@ -516,7 +516,7 @@ exports[`ChatContext.toJSON > should match snapshot for simple conversation > si
516516
"content": [
517517
"I'm doing well, thank you! How can I help you today?",
518518
],
519-
"created_at": 1000000002,
519+
"createdAt": 1000000002,
520520
"id": "msg_assistant_1",
521521
"interrupted": false,
522522
"role": "assistant",

agents/src/llm/chat_context.ts

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -378,10 +378,10 @@ export class ChatMessage {
378378
id: c.id,
379379
type: c.type,
380380
image: c.image,
381-
inference_detail: c.inferenceDetail,
382-
inference_width: c.inferenceWidth,
383-
inference_height: c.inferenceHeight,
384-
mime_type: c.mimeType,
381+
inferenceDetail: c.inferenceDetail,
382+
inferenceWidth: c.inferenceWidth,
383+
inferenceHeight: c.inferenceHeight,
384+
mimeType: c.mimeType,
385385
} as JSONObject;
386386
} else {
387387
return {
@@ -403,11 +403,11 @@ export class ChatMessage {
403403
};
404404

405405
if (!excludeTimestamp) {
406-
result.created_at = this.createdAt;
406+
result.createdAt = this.createdAt;
407407
}
408408

409409
if (this.transcriptConfidence !== undefined) {
410-
result.transcript_confidence = this.transcriptConfidence;
410+
result.transcriptConfidence = this.transcriptConfidence;
411411
}
412412
if (Object.keys(this.metrics).length > 0) {
413413
result.metrics = { ...this.metrics };
@@ -500,25 +500,25 @@ export class FunctionCall {
500500
const result: JSONValue = {
501501
id: this.id,
502502
type: this.type,
503-
call_id: this.callId,
503+
callId: this.callId,
504504
name: this.name,
505-
arguments: this.args,
505+
args: this.args,
506506
};
507507

508508
if (Object.keys(this.extra).length > 0) {
509509
result.extra = this.extra as JSONValue;
510510
}
511511

512512
if (this.groupId) {
513-
result.group_id = this.groupId;
513+
result.groupId = this.groupId;
514514
}
515515

516516
if (this.thoughtSignature) {
517-
result.thought_signature = this.thoughtSignature;
517+
result.thoughtSignature = this.thoughtSignature;
518518
}
519519

520520
if (!excludeTimestamp) {
521-
result.created_at = this.createdAt;
521+
result.createdAt = this.createdAt;
522522
}
523523

524524
return result;
@@ -580,13 +580,13 @@ export class FunctionCallOutput {
580580
id: this.id,
581581
type: this.type,
582582
name: this.name,
583-
call_id: this.callId,
583+
callId: this.callId,
584584
output: this.output,
585-
is_error: this.isError,
585+
isError: this.isError,
586586
};
587587

588588
if (!excludeTimestamp) {
589-
result.created_at = this.createdAt;
589+
result.createdAt = this.createdAt;
590590
}
591591

592592
return result;
@@ -630,15 +630,15 @@ export class AgentHandoffItem {
630630
const result: JSONValue = {
631631
id: this.id,
632632
type: this.type,
633-
new_agent_id: this.newAgentId,
633+
newAgentId: this.newAgentId,
634634
};
635635

636636
if (this.oldAgentId !== undefined) {
637-
result.old_agent_id = this.oldAgentId;
637+
result.oldAgentId = this.oldAgentId;
638638
}
639639

640640
if (!excludeTimestamp) {
641-
result.created_at = this.createdAt;
641+
result.createdAt = this.createdAt;
642642
}
643643

644644
return result;
@@ -703,13 +703,13 @@ export class AgentConfigUpdate {
703703
: this.instructions;
704704
}
705705
if (this.toolsAdded !== undefined) {
706-
result.tools_added = this.toolsAdded;
706+
result.toolsAdded = this.toolsAdded;
707707
}
708708
if (this.toolsRemoved !== undefined) {
709-
result.tools_removed = this.toolsRemoved;
709+
result.toolsRemoved = this.toolsRemoved;
710710
}
711711
if (!excludeTimestamp) {
712-
result.created_at = this.createdAt;
712+
result.createdAt = this.createdAt;
713713
}
714714

715715
return result;

agents/src/voice/report.test.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,16 @@ describe('sessionReportToJSON', () => {
250250
},
251251
{
252252
type: 'conversation_item_added',
253-
item: msg.toJSON(),
253+
// chat items expose camelCase via toJSON(); the report layer converts to the
254+
// snake_case wire shape (e.g. created_at).
255+
item: {
256+
id: msg.id,
257+
type: 'message',
258+
role: 'user',
259+
content: ['hi'],
260+
interrupted: false,
261+
created_at: 5,
262+
},
254263
created_at: 11,
255264
},
256265
]);

0 commit comments

Comments
 (0)