lex-llm 0.4.18 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop.yml +13 -2
- data/B1b-conformance-kit.md +79 -0
- data/CHANGELOG.md +19 -0
- data/lex-llm.gemspec +2 -3
- data/lib/legion/extensions/llm/attachment.rb +1 -1
- data/lib/legion/extensions/llm/canonical/chunk.rb +184 -0
- data/lib/legion/extensions/llm/canonical/content_block.rb +126 -0
- data/lib/legion/extensions/llm/canonical/message.rb +125 -0
- data/lib/legion/extensions/llm/canonical/params.rb +61 -0
- data/lib/legion/extensions/llm/canonical/request.rb +117 -0
- data/lib/legion/extensions/llm/canonical/response.rb +124 -0
- data/lib/legion/extensions/llm/canonical/thinking.rb +81 -0
- data/lib/legion/extensions/llm/canonical/tool_call.rb +134 -0
- data/lib/legion/extensions/llm/canonical/tool_definition.rb +73 -0
- data/lib/legion/extensions/llm/canonical/usage.rb +61 -0
- data/lib/legion/extensions/llm/canonical.rb +49 -0
- data/lib/legion/extensions/llm/chat.rb +3 -5
- data/lib/legion/extensions/llm/connection.rb +5 -1
- data/lib/legion/extensions/llm/error.rb +3 -7
- data/lib/legion/extensions/llm/fleet/envelope_validation.rb +1 -3
- data/lib/legion/extensions/llm/fleet/provider_responder.rb +1 -3
- data/lib/legion/extensions/llm/fleet/token_validator.rb +1 -3
- data/lib/legion/extensions/llm/model/info.rb +4 -6
- data/lib/legion/extensions/llm/models.rb +3 -3
- data/lib/legion/extensions/llm/provider/open_ai_compatible.rb +7 -3
- data/lib/legion/extensions/llm/routing/lane_key.rb +1 -3
- data/lib/legion/extensions/llm/stream_accumulator.rb +1 -1
- data/lib/legion/extensions/llm/streaming.rb +1 -3
- data/lib/legion/extensions/llm/tool.rb +1 -3
- data/lib/legion/extensions/llm/version.rb +1 -1
- data/lib/legion/extensions/llm.rb +118 -35
- data/spec/fixtures/ruby.mp3 +0 -0
- data/spec/fixtures/ruby.mp4 +0 -0
- data/spec/fixtures/ruby.png +0 -0
- data/spec/fixtures/ruby.txt +1 -0
- data/spec/fixtures/ruby.wav +0 -0
- data/spec/fixtures/ruby.xml +1 -0
- data/spec/fixtures/sample.pdf +0 -0
- data/spec/legion/extensions/llm/agent_spec.rb +179 -0
- data/spec/legion/extensions/llm/attachment_spec.rb +25 -0
- data/spec/legion/extensions/llm/auto_registration_spec.rb +38 -0
- data/spec/legion/extensions/llm/canonical/chunk_spec.rb +285 -0
- data/spec/legion/extensions/llm/canonical/content_block_spec.rb +179 -0
- data/spec/legion/extensions/llm/canonical/message_spec.rb +203 -0
- data/spec/legion/extensions/llm/canonical/params_spec.rb +159 -0
- data/spec/legion/extensions/llm/canonical/request_spec.rb +174 -0
- data/spec/legion/extensions/llm/canonical/response_spec.rb +234 -0
- data/spec/legion/extensions/llm/canonical/thinking_spec.rb +151 -0
- data/spec/legion/extensions/llm/canonical/tool_call_spec.rb +191 -0
- data/spec/legion/extensions/llm/canonical/tool_definition_spec.rb +174 -0
- data/spec/legion/extensions/llm/canonical/usage_spec.rb +138 -0
- data/spec/legion/extensions/llm/configuration_spec.rb +38 -0
- data/spec/legion/extensions/llm/conformance/client_translator_examples.rb +269 -0
- data/spec/legion/extensions/llm/conformance/conformance.rb +51 -0
- data/spec/legion/extensions/llm/conformance/echo_translator.rb +56 -0
- data/spec/legion/extensions/llm/conformance/echo_translator_spec.rb +13 -0
- data/spec/legion/extensions/llm/conformance/fixtures/canonical_empty_response.json +13 -0
- data/spec/legion/extensions/llm/conformance/fixtures/canonical_error_response.json +19 -0
- data/spec/legion/extensions/llm/conformance/fixtures/canonical_fleet_round_trip.json +81 -0
- data/spec/legion/extensions/llm/conformance/fixtures/canonical_metering_audit_events.json +101 -0
- data/spec/legion/extensions/llm/conformance/fixtures/canonical_params_mapping_request.json +21 -0
- data/spec/legion/extensions/llm/conformance/fixtures/canonical_simple_text_request.json +13 -0
- data/spec/legion/extensions/llm/conformance/fixtures/canonical_simple_text_response.json +13 -0
- data/spec/legion/extensions/llm/conformance/fixtures/canonical_stop_reason_matrix.json +36 -0
- data/spec/legion/extensions/llm/conformance/fixtures/canonical_streaming_accumulated_response.json +20 -0
- data/spec/legion/extensions/llm/conformance/fixtures/canonical_streaming_error_chunks.json +26 -0
- data/spec/legion/extensions/llm/conformance/fixtures/canonical_streaming_text_chunks.json +33 -0
- data/spec/legion/extensions/llm/conformance/fixtures/canonical_streaming_thinking_chunks.json +42 -0
- data/spec/legion/extensions/llm/conformance/fixtures/canonical_streaming_tool_call_chunks.json +41 -0
- data/spec/legion/extensions/llm/conformance/fixtures/canonical_system_prompt_request.json +14 -0
- data/spec/legion/extensions/llm/conformance/fixtures/canonical_thinking_request.json +18 -0
- data/spec/legion/extensions/llm/conformance/fixtures/canonical_thinking_response.json +17 -0
- data/spec/legion/extensions/llm/conformance/fixtures/canonical_tool_results_continuation_request.json +75 -0
- data/spec/legion/extensions/llm/conformance/fixtures/canonical_tool_use_response.json +25 -0
- data/spec/legion/extensions/llm/conformance/fixtures/canonical_tools_request.json +34 -0
- data/spec/legion/extensions/llm/conformance/provider_translator_examples.rb +390 -0
- data/spec/legion/extensions/llm/connection_logging_spec.rb +53 -0
- data/spec/legion/extensions/llm/connection_retry_spec.rb +36 -0
- data/spec/legion/extensions/llm/context_spec.rb +127 -0
- data/spec/legion/extensions/llm/credential_sources_spec.rb +468 -0
- data/spec/legion/extensions/llm/error_middleware_spec.rb +102 -0
- data/spec/legion/extensions/llm/error_spec.rb +87 -0
- data/spec/legion/extensions/llm/fleet/provider_responder_spec.rb +120 -0
- data/spec/legion/extensions/llm/fleet/token_validator_spec.rb +163 -0
- data/spec/legion/extensions/llm/fleet/worker_execution_spec.rb +128 -0
- data/spec/legion/extensions/llm/fleet_messages_spec.rb +402 -0
- data/spec/legion/extensions/llm/gemspec_spec.rb +25 -0
- data/spec/legion/extensions/llm/message_spec.rb +64 -0
- data/spec/legion/extensions/llm/model/info_spec.rb +222 -0
- data/spec/legion/extensions/llm/models_spec.rb +104 -0
- data/spec/legion/extensions/llm/provider/open_ai_compatible_spec.rb +203 -0
- data/spec/legion/extensions/llm/provider_contract_spec.rb +60 -0
- data/spec/legion/extensions/llm/provider_settings_spec.rb +76 -0
- data/spec/legion/extensions/llm/provider_spec.rb +592 -0
- data/spec/legion/extensions/llm/registry_event_builder_spec.rb +68 -0
- data/spec/legion/extensions/llm/registry_publisher_spec.rb +22 -0
- data/spec/legion/extensions/llm/responses/response_objects_spec.rb +75 -0
- data/spec/legion/extensions/llm/responses/thinking_extractor_spec.rb +75 -0
- data/spec/legion/extensions/llm/routing/model_offering_spec.rb +222 -0
- data/spec/legion/extensions/llm/routing/offering_registry_spec.rb +50 -0
- data/spec/legion/extensions/llm/routing/registry_event_spec.rb +120 -0
- data/spec/legion/extensions/llm/stream_accumulator_spec.rb +103 -0
- data/spec/legion/extensions/llm/streaming_spec.rb +108 -0
- data/spec/legion/extensions/llm/tool_spec.rb +94 -0
- data/spec/legion/extensions/llm/transport/fleet_lane_spec.rb +60 -0
- data/spec/legion/extensions/llm/utils_spec.rb +113 -0
- data/spec/legion/extensions/llm_base_contract_spec.rb +110 -0
- data/spec/legion/extensions/llm_extension_spec.rb +78 -0
- data/spec/legion/extensions/llm_root_spec.rb +51 -0
- data/spec/spec_helper.rb +24 -0
- data/spec/support/fake_llm_provider.rb +148 -0
- data/spec/support/llm_configuration.rb +21 -0
- data/spec/support/rspec_configuration.rb +19 -0
- data/spec/support/simplecov_configuration.rb +20 -0
- metadata +96 -15
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"description": "Stop reason mapping matrix — every provider value maps to a canonical enum",
|
|
3
|
+
"canonical_stop_reasons": ["end_turn", "tool_use", "max_tokens", "stop_sequence", "content_filter", "error"],
|
|
4
|
+
"provider_mappings": {
|
|
5
|
+
"anthropic": {
|
|
6
|
+
"end_turn": "end_turn",
|
|
7
|
+
"tool_use": "tool_use",
|
|
8
|
+
"max_tokens": "max_tokens",
|
|
9
|
+
"stop_sequence": "stop_sequence",
|
|
10
|
+
"content_filter": "content_filter"
|
|
11
|
+
},
|
|
12
|
+
"openai": {
|
|
13
|
+
"stop": "end_turn",
|
|
14
|
+
"tool_calls": "tool_use",
|
|
15
|
+
"length": "max_tokens",
|
|
16
|
+
"content_filter": "content_filter"
|
|
17
|
+
},
|
|
18
|
+
"openai_responses": {
|
|
19
|
+
"completed": "end_turn",
|
|
20
|
+
"incomplete": "max_tokens",
|
|
21
|
+
"cancelled": "stop_sequence",
|
|
22
|
+
"failed": "error"
|
|
23
|
+
},
|
|
24
|
+
"vllm": {
|
|
25
|
+
"stop": "end_turn",
|
|
26
|
+
"tool_use": "tool_use",
|
|
27
|
+
"length": "max_tokens"
|
|
28
|
+
},
|
|
29
|
+
"bedrock_converse": {
|
|
30
|
+
"end_turn": "end_turn",
|
|
31
|
+
"tool_use": "tool_use",
|
|
32
|
+
"max_tokens": "max_tokens",
|
|
33
|
+
"guardrail_intervened": "content_filter"
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
data/spec/legion/extensions/llm/conformance/fixtures/canonical_streaming_accumulated_response.json
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"description": "Expected accumulated Canonical::Response after processing canonical_streaming_tool_call_chunks.json — verify accumulate(chunks) == parse(full)",
|
|
3
|
+
"text": "Let me check the weather for you.",
|
|
4
|
+
"thinking": null,
|
|
5
|
+
"tool_calls": [
|
|
6
|
+
{
|
|
7
|
+
"id": "call_def456",
|
|
8
|
+
"name": "get_weather",
|
|
9
|
+
"arguments": {"location": "San Francisco, CA", "unit": "fahrenheit"},
|
|
10
|
+
"source": "client",
|
|
11
|
+
"status": "pending"
|
|
12
|
+
}
|
|
13
|
+
],
|
|
14
|
+
"usage": {
|
|
15
|
+
"input_tokens": 45,
|
|
16
|
+
"output_tokens": 28
|
|
17
|
+
},
|
|
18
|
+
"stop_reason": "tool_use",
|
|
19
|
+
"model": "test-model-1"
|
|
20
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"description": "Streaming error mid-chunk sequence — provider errors during stream per G5/G6",
|
|
3
|
+
"request_id": "req_stream_error_001",
|
|
4
|
+
"chunks": [
|
|
5
|
+
{
|
|
6
|
+
"request_id": "req_stream_error_001",
|
|
7
|
+
"index": 0,
|
|
8
|
+
"type": "text_delta",
|
|
9
|
+
"delta": "The weather"
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
"request_id": "req_stream_error_001",
|
|
13
|
+
"index": 1,
|
|
14
|
+
"type": "error",
|
|
15
|
+
"stop_reason": "error",
|
|
16
|
+
"metadata": {
|
|
17
|
+
"error": {
|
|
18
|
+
"type": "overloaded",
|
|
19
|
+
"message": "Upstream provider timed out",
|
|
20
|
+
"code": 504
|
|
21
|
+
},
|
|
22
|
+
"partial_text": "The weather"
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
]
|
|
26
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{
|
|
2
|
+
"description": "Streaming text-only chunk sequence — sanitized from real E2E traffic",
|
|
3
|
+
"request_id": "req_stream_text_001",
|
|
4
|
+
"chunks": [
|
|
5
|
+
{
|
|
6
|
+
"request_id": "req_stream_text_001",
|
|
7
|
+
"index": 0,
|
|
8
|
+
"type": "text_delta",
|
|
9
|
+
"delta": "Hello"
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
"request_id": "req_stream_text_001",
|
|
13
|
+
"index": 1,
|
|
14
|
+
"type": "text_delta",
|
|
15
|
+
"delta": ", world!"
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"request_id": "req_stream_text_001",
|
|
19
|
+
"index": 2,
|
|
20
|
+
"type": "text_delta",
|
|
21
|
+
"delta": " How can I help you today?"
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"request_id": "req_stream_text_001",
|
|
25
|
+
"type": "done",
|
|
26
|
+
"stop_reason": "end_turn",
|
|
27
|
+
"usage": {
|
|
28
|
+
"input_tokens": 12,
|
|
29
|
+
"output_tokens": 10
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
]
|
|
33
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"description": "Streaming thinking + text chunk sequence — sanitized from real E2E traffic",
|
|
3
|
+
"request_id": "req_stream_thinking_001",
|
|
4
|
+
"chunks": [
|
|
5
|
+
{
|
|
6
|
+
"request_id": "req_stream_thinking_001",
|
|
7
|
+
"index": 0,
|
|
8
|
+
"type": "thinking_delta",
|
|
9
|
+
"delta": "Let me think about this step by step.",
|
|
10
|
+
"signature": null
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
"request_id": "req_stream_thinking_001",
|
|
14
|
+
"index": 1,
|
|
15
|
+
"type": "thinking_delta",
|
|
16
|
+
"delta": "The key concepts are superposition and entanglement.",
|
|
17
|
+
"signature": "eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NiJ9"
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"request_id": "req_stream_thinking_001",
|
|
21
|
+
"index": 2,
|
|
22
|
+
"type": "text_delta",
|
|
23
|
+
"delta": "Quantum computing uses qubits that can be in multiple states at once."
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
"request_id": "req_stream_thinking_001",
|
|
27
|
+
"index": 3,
|
|
28
|
+
"type": "text_delta",
|
|
29
|
+
"delta": " This enables parallel computation on a massive scale."
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
"request_id": "req_stream_thinking_001",
|
|
33
|
+
"type": "done",
|
|
34
|
+
"stop_reason": "end_turn",
|
|
35
|
+
"usage": {
|
|
36
|
+
"input_tokens": 15,
|
|
37
|
+
"output_tokens": 45,
|
|
38
|
+
"thinking_tokens": 80
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
]
|
|
42
|
+
}
|
data/spec/legion/extensions/llm/conformance/fixtures/canonical_streaming_tool_call_chunks.json
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"description": "Streaming tool-call chunk sequence — multi-chunk stateful tool-loop per A7. Each tool_call_delta carries the complete current state (not raw incremental fragments); the assembler merges deltas via buffer_policy.",
|
|
3
|
+
"request_id": "req_stream_tool_001",
|
|
4
|
+
"chunks": [
|
|
5
|
+
{
|
|
6
|
+
"request_id": "req_stream_tool_001",
|
|
7
|
+
"index": 0,
|
|
8
|
+
"type": "text_delta",
|
|
9
|
+
"delta": "Let me check the weather for you."
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
"request_id": "req_stream_tool_001",
|
|
13
|
+
"index": 1,
|
|
14
|
+
"type": "tool_call_delta",
|
|
15
|
+
"tool_call": {
|
|
16
|
+
"id": "call_def456",
|
|
17
|
+
"name": "get_weather",
|
|
18
|
+
"arguments": {"location": "San Francisco, CA"}
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"request_id": "req_stream_tool_001",
|
|
23
|
+
"index": 2,
|
|
24
|
+
"type": "tool_call_delta",
|
|
25
|
+
"tool_call": {
|
|
26
|
+
"id": "call_def456",
|
|
27
|
+
"name": "get_weather",
|
|
28
|
+
"arguments": {"location": "San Francisco, CA", "unit": "fahrenheit"}
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
"request_id": "req_stream_tool_001",
|
|
33
|
+
"type": "done",
|
|
34
|
+
"stop_reason": "tool_use",
|
|
35
|
+
"usage": {
|
|
36
|
+
"input_tokens": 45,
|
|
37
|
+
"output_tokens": 28
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
]
|
|
41
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "req_system_prompt_001",
|
|
3
|
+
"system": "You are a helpful assistant that always responds in haiku form.",
|
|
4
|
+
"messages": [
|
|
5
|
+
{
|
|
6
|
+
"role": "user",
|
|
7
|
+
"content": [{ "type": "text", "text": "Tell me about Ruby." }]
|
|
8
|
+
}
|
|
9
|
+
],
|
|
10
|
+
"params": {
|
|
11
|
+
"max_tokens": 512
|
|
12
|
+
},
|
|
13
|
+
"stream": false
|
|
14
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "req_thinking_001",
|
|
3
|
+
"messages": [
|
|
4
|
+
{
|
|
5
|
+
"role": "user",
|
|
6
|
+
"content": [{ "type": "text", "text": "Explain quantum computing in simple terms." }]
|
|
7
|
+
}
|
|
8
|
+
],
|
|
9
|
+
"thinking": {
|
|
10
|
+
"effort": "high",
|
|
11
|
+
"budget": 4096
|
|
12
|
+
},
|
|
13
|
+
"params": {
|
|
14
|
+
"max_tokens": 2048,
|
|
15
|
+
"max_thinking_tokens": 4096
|
|
16
|
+
},
|
|
17
|
+
"stream": false
|
|
18
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"text": "Quantum computing uses quantum bits (qubits) that can represent both 0 and 1 simultaneously, unlike classical bits.",
|
|
3
|
+
"thinking": {
|
|
4
|
+
"content": "I need to explain quantum computing simply. Start with the basic difference between classical and quantum bits, then mention superposition and entanglement as key concepts.",
|
|
5
|
+
"signature": "eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NiJ9"
|
|
6
|
+
},
|
|
7
|
+
"tool_calls": [],
|
|
8
|
+
"usage": {
|
|
9
|
+
"input_tokens": 15,
|
|
10
|
+
"output_tokens": 45,
|
|
11
|
+
"thinking_tokens": 120
|
|
12
|
+
},
|
|
13
|
+
"stop_reason": "end_turn",
|
|
14
|
+
"model": "test-model-thinking-1",
|
|
15
|
+
"routing": {},
|
|
16
|
+
"metadata": {}
|
|
17
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
{
|
|
2
|
+
"description": "Full multi-turn history: mixed client/server tool calls + thinking block per G4",
|
|
3
|
+
"id": "req_tool_continuation_001",
|
|
4
|
+
"system": "You are a helpful assistant.",
|
|
5
|
+
"messages": [
|
|
6
|
+
{
|
|
7
|
+
"role": "user",
|
|
8
|
+
"content": [{"type": "text", "text": "What's the weather in San Francisco, and summarize today's news about it?"}]
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
"role": "assistant",
|
|
12
|
+
"content": [
|
|
13
|
+
{"type": "text", "text": ""},
|
|
14
|
+
{"type": "tool_use", "id": "call_weather_01", "name": "get_weather", "input": {"location": "San Francisco, CA", "unit": "fahrenheit"}}
|
|
15
|
+
],
|
|
16
|
+
"tool_calls": [
|
|
17
|
+
{
|
|
18
|
+
"id": "call_weather_01",
|
|
19
|
+
"exchange_id": "exch_turn1_001",
|
|
20
|
+
"name": "get_weather",
|
|
21
|
+
"arguments": {"location": "San Francisco, CA", "unit": "fahrenheit"},
|
|
22
|
+
"source": "client",
|
|
23
|
+
"status": "success",
|
|
24
|
+
"result": {"temperature": 68, "unit": "fahrenheit", "conditions": "partly cloudy"}
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"id": "call_summarize_01",
|
|
28
|
+
"exchange_id": "exch_turn1_002",
|
|
29
|
+
"name": "summarize_article",
|
|
30
|
+
"arguments": {"topic": "San Francisco weather today"},
|
|
31
|
+
"source": "registry",
|
|
32
|
+
"status": "success",
|
|
33
|
+
"result": {"headline": "Partly cloudy skies, mild temperatures continue in Bay Area", "summary": "San Francisco enjoys its typical spring weather..."}
|
|
34
|
+
}
|
|
35
|
+
]
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
"role": "tool",
|
|
39
|
+
"tool_call_id": "call_weather_01",
|
|
40
|
+
"content": [{"type": "tool_result", "tool_use_id": "call_weather_01", "text": "{\"temperature\":68,\"unit\":\"fahrenheit\",\"conditions\":\"partly cloudy\"}"}]
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
"role": "tool",
|
|
44
|
+
"tool_call_id": "call_summarize_01",
|
|
45
|
+
"content": [{"type": "tool_result", "tool_use_id": "call_summarize_01", "text": "{\"headline\":\"SF weather report\",\"summary\":\"Partly cloudy, 68F\"}"}]
|
|
46
|
+
}
|
|
47
|
+
],
|
|
48
|
+
"tools": {
|
|
49
|
+
"get_weather": {
|
|
50
|
+
"name": "get_weather",
|
|
51
|
+
"description": "Get current weather for a location",
|
|
52
|
+
"parameters": {
|
|
53
|
+
"type": "object",
|
|
54
|
+
"properties": {
|
|
55
|
+
"location": {"type": "string"},
|
|
56
|
+
"unit": {"type": "string", "enum": ["celsius", "fahrenheit"]}
|
|
57
|
+
},
|
|
58
|
+
"required": ["location"]
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
"summarize_article": {
|
|
62
|
+
"name": "summarize_article",
|
|
63
|
+
"description": "Summarize a news article by topic",
|
|
64
|
+
"parameters": {
|
|
65
|
+
"type": "object",
|
|
66
|
+
"properties": {
|
|
67
|
+
"topic": {"type": "string"}
|
|
68
|
+
},
|
|
69
|
+
"required": ["topic"]
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
"params": {"max_tokens": 1024},
|
|
74
|
+
"stream": false
|
|
75
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"text": "",
|
|
3
|
+
"thinking": null,
|
|
4
|
+
"tool_calls": [
|
|
5
|
+
{
|
|
6
|
+
"id": "call_abc123",
|
|
7
|
+
"exchange_id": "exch_001",
|
|
8
|
+
"name": "get_weather",
|
|
9
|
+
"arguments": {
|
|
10
|
+
"location": "San Francisco, CA",
|
|
11
|
+
"unit": "fahrenheit"
|
|
12
|
+
},
|
|
13
|
+
"source": "client",
|
|
14
|
+
"status": "pending"
|
|
15
|
+
}
|
|
16
|
+
],
|
|
17
|
+
"usage": {
|
|
18
|
+
"input_tokens": 45,
|
|
19
|
+
"output_tokens": 28
|
|
20
|
+
},
|
|
21
|
+
"stop_reason": "tool_use",
|
|
22
|
+
"model": "test-model-1",
|
|
23
|
+
"routing": {},
|
|
24
|
+
"metadata": {}
|
|
25
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "req_tools_001",
|
|
3
|
+
"messages": [
|
|
4
|
+
{
|
|
5
|
+
"role": "user",
|
|
6
|
+
"content": [{ "type": "text", "text": "What's the weather in San Francisco?" }]
|
|
7
|
+
}
|
|
8
|
+
],
|
|
9
|
+
"tools": {
|
|
10
|
+
"get_weather": {
|
|
11
|
+
"name": "get_weather",
|
|
12
|
+
"description": "Get the current weather in a given location",
|
|
13
|
+
"parameters": {
|
|
14
|
+
"type": "object",
|
|
15
|
+
"properties": {
|
|
16
|
+
"location": {
|
|
17
|
+
"type": "string",
|
|
18
|
+
"description": "The city and state, e.g. San Francisco, CA"
|
|
19
|
+
},
|
|
20
|
+
"unit": {
|
|
21
|
+
"type": "string",
|
|
22
|
+
"enum": ["celsius", "fahrenheit"],
|
|
23
|
+
"description": "The unit of temperature"
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
"required": ["location"]
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
"params": {
|
|
31
|
+
"max_tokens": 1024
|
|
32
|
+
},
|
|
33
|
+
"stream": false
|
|
34
|
+
}
|