@@ -60,21 +60,21 @@ def get_summary() -> LogfireSummary:
60
60
61
61
@pytest .mark .skipif (not logfire_installed , reason = 'logfire not installed' )
62
62
def test_logfire (get_logfire_summary : Callable [[], LogfireSummary ], set_event_loop : None ) -> None :
63
- agent = Agent (model = TestModel ())
63
+ my_agent = Agent (model = TestModel ())
64
64
65
- @agent .tool_plain
65
+ @my_agent .tool_plain
66
66
async def my_ret (x : int ) -> str :
67
67
return str (x + 1 )
68
68
69
- result = agent .run_sync ('Hello' )
69
+ result = my_agent .run_sync ('Hello' )
70
70
assert result .data == snapshot ('{"my_ret":"1"}' )
71
71
72
72
summary = get_logfire_summary ()
73
73
assert summary .traces == snapshot (
74
74
[
75
75
{
76
76
'id' : 0 ,
77
- 'message' : 'agent run prompt=Hello' ,
77
+ 'message' : 'my_agent run prompt=Hello' ,
78
78
'children' : [
79
79
{'id' : 1 , 'message' : 'model request -> model-structured-response' },
80
80
{
@@ -88,6 +88,162 @@ async def my_ret(x: int) -> str:
88
88
}
89
89
]
90
90
)
91
+ assert summary .attributes [0 ] == snapshot (
92
+ {
93
+ 'code.filepath' : 'agent.py' ,
94
+ 'code.function' : 'run' ,
95
+ 'code.lineno' : 123 ,
96
+ 'prompt' : 'Hello' ,
97
+ 'agent' : IsJson (
98
+ {
99
+ 'model' : {
100
+ 'call_tools' : 'all' ,
101
+ 'custom_result_text' : None ,
102
+ 'custom_result_args' : None ,
103
+ 'seed' : 0 ,
104
+ 'agent_model_tools' : {
105
+ 'my_ret' : {
106
+ 'function' : IsStr (regex = '<function test_logfire.<locals>.my_ret at 0x.+>' ),
107
+ 'takes_ctx' : False ,
108
+ 'max_retries' : 1 ,
109
+ 'name' : 'my_ret' ,
110
+ 'description' : '' ,
111
+ '_is_async' : True ,
112
+ '_single_arg_name' : None ,
113
+ '_positional_fields' : [],
114
+ '_var_positional_field' : None ,
115
+ '_json_schema' : {
116
+ 'properties' : {'x' : {'title' : 'X' , 'type' : 'integer' }},
117
+ 'required' : ['x' ],
118
+ 'type' : 'object' ,
119
+ 'additionalProperties' : False ,
120
+ },
121
+ '_current_retry' : 0 ,
122
+ }
123
+ },
124
+ 'agent_model_allow_text_result' : True ,
125
+ 'agent_model_result_tools' : None ,
126
+ },
127
+ 'name' : 'my_agent' ,
128
+ 'last_run_messages' : None ,
129
+ }
130
+ ),
131
+ 'logfire.null_args' : ('custom_model' ,),
132
+ 'model_name' : 'test-model' ,
133
+ 'agent_name' : 'my_agent' ,
134
+ 'logfire.msg_template' : '{agent_name} run {prompt=}' ,
135
+ 'logfire.msg' : 'my_agent run prompt=Hello' ,
136
+ 'logfire.span_type' : 'span' ,
137
+ 'all_messages' : IsJson (
138
+ [
139
+ {'content' : 'Hello' , 'timestamp' : IsStr (regex = r'\d{4}-\d{2}-.+' ), 'role' : 'user' },
140
+ {
141
+ 'calls' : [{'tool_name' : 'my_ret' , 'args' : {'args_dict' : {'x' : 0 }}, 'tool_id' : None }],
142
+ 'timestamp' : IsStr (regex = r'\d{4}-\d{2}-.+' ),
143
+ 'role' : 'model-structured-response' ,
144
+ },
145
+ {
146
+ 'tool_name' : 'my_ret' ,
147
+ 'content' : '1' ,
148
+ 'tool_id' : None ,
149
+ 'timestamp' : IsStr (regex = r'\d{4}-\d{2}-.+' ),
150
+ 'role' : 'tool-return' ,
151
+ },
152
+ {
153
+ 'content' : '{"my_ret":"1"}' ,
154
+ 'timestamp' : IsStr (regex = r'\d{4}-\d{2}-.+' ),
155
+ 'role' : 'model-text-response' ,
156
+ },
157
+ ]
158
+ ),
159
+ 'cost' : IsJson ({'request_tokens' : None , 'response_tokens' : None , 'total_tokens' : None , 'details' : None }),
160
+ 'logfire.json_schema' : IsJson (
161
+ {
162
+ 'type' : 'object' ,
163
+ 'properties' : {
164
+ 'prompt' : {},
165
+ 'agent' : {
166
+ 'type' : 'object' ,
167
+ 'title' : 'Agent' ,
168
+ 'x-python-datatype' : 'dataclass' ,
169
+ 'properties' : {
170
+ 'model' : {
171
+ 'type' : 'object' ,
172
+ 'title' : 'TestModel' ,
173
+ 'x-python-datatype' : 'dataclass' ,
174
+ 'properties' : {
175
+ 'agent_model_tools' : {
176
+ 'type' : 'object' ,
177
+ 'properties' : {
178
+ 'my_ret' : {
179
+ 'type' : 'object' ,
180
+ 'title' : 'Tool' ,
181
+ 'x-python-datatype' : 'dataclass' ,
182
+ 'properties' : {
183
+ 'function' : {'type' : 'object' , 'x-python-datatype' : 'unknown' }
184
+ },
185
+ }
186
+ },
187
+ }
188
+ },
189
+ }
190
+ },
191
+ },
192
+ 'custom_model' : {},
193
+ 'model_name' : {},
194
+ 'agent_name' : {},
195
+ 'all_messages' : {
196
+ 'type' : 'array' ,
197
+ 'prefixItems' : [
198
+ {
199
+ 'type' : 'object' ,
200
+ 'title' : 'UserPrompt' ,
201
+ 'x-python-datatype' : 'dataclass' ,
202
+ 'properties' : {'timestamp' : {'type' : 'string' , 'format' : 'date-time' }},
203
+ },
204
+ {
205
+ 'type' : 'object' ,
206
+ 'title' : 'ModelStructuredResponse' ,
207
+ 'x-python-datatype' : 'dataclass' ,
208
+ 'properties' : {
209
+ 'calls' : {
210
+ 'type' : 'array' ,
211
+ 'items' : {
212
+ 'type' : 'object' ,
213
+ 'title' : 'ToolCall' ,
214
+ 'x-python-datatype' : 'dataclass' ,
215
+ 'properties' : {
216
+ 'args' : {
217
+ 'type' : 'object' ,
218
+ 'title' : 'ArgsDict' ,
219
+ 'x-python-datatype' : 'dataclass' ,
220
+ }
221
+ },
222
+ },
223
+ },
224
+ 'timestamp' : {'type' : 'string' , 'format' : 'date-time' },
225
+ },
226
+ },
227
+ {
228
+ 'type' : 'object' ,
229
+ 'title' : 'ToolReturn' ,
230
+ 'x-python-datatype' : 'dataclass' ,
231
+ 'properties' : {'timestamp' : {'type' : 'string' , 'format' : 'date-time' }},
232
+ },
233
+ {
234
+ 'type' : 'object' ,
235
+ 'title' : 'ModelTextResponse' ,
236
+ 'x-python-datatype' : 'dataclass' ,
237
+ 'properties' : {'timestamp' : {'type' : 'string' , 'format' : 'date-time' }},
238
+ },
239
+ ],
240
+ },
241
+ 'cost' : {'type' : 'object' , 'title' : 'Cost' , 'x-python-datatype' : 'dataclass' },
242
+ },
243
+ }
244
+ ),
245
+ }
246
+ )
91
247
assert summary .attributes [1 ] == snapshot (
92
248
{
93
249
'code.filepath' : 'agent.py' ,
0 commit comments