@ailib-official/ai-protocol 0.8.4

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.
Files changed (194) hide show
  1. package/LICENSE +6 -0
  2. package/README.md +415 -0
  3. package/dist/index.json +8 -0
  4. package/dist/v1/models/ai21.json +140 -0
  5. package/dist/v1/models/baichuan.json +138 -0
  6. package/dist/v1/models/cerebras.json +147 -0
  7. package/dist/v1/models/claude.json +114 -0
  8. package/dist/v1/models/cohere.json +235 -0
  9. package/dist/v1/models/deepinfra.json +43 -0
  10. package/dist/v1/models/deepseek-chat.json +55 -0
  11. package/dist/v1/models/doubao.json +197 -0
  12. package/dist/v1/models/ernie.json +223 -0
  13. package/dist/v1/models/fireworks.json +222 -0
  14. package/dist/v1/models/gemini.json +58 -0
  15. package/dist/v1/models/gpt.json +166 -0
  16. package/dist/v1/models/grok.json +138 -0
  17. package/dist/v1/models/huggingface.json +183 -0
  18. package/dist/v1/models/hunyuan.json +255 -0
  19. package/dist/v1/models/jina.json +139 -0
  20. package/dist/v1/models/lepton.json +188 -0
  21. package/dist/v1/models/llama.json +143 -0
  22. package/dist/v1/models/minimax.json +194 -0
  23. package/dist/v1/models/mistral.json +177 -0
  24. package/dist/v1/models/moonshot.json +144 -0
  25. package/dist/v1/models/nvidia.json +212 -0
  26. package/dist/v1/models/palmyra.json +103 -0
  27. package/dist/v1/models/perplexity.json +143 -0
  28. package/dist/v1/models/qwen.json +49 -0
  29. package/dist/v1/models/replicate.json +206 -0
  30. package/dist/v1/models/sensenova.json +144 -0
  31. package/dist/v1/models/siliconflow.json +44 -0
  32. package/dist/v1/models/spark.json +173 -0
  33. package/dist/v1/models/stable-diffusion.json +161 -0
  34. package/dist/v1/models/tiangong.json +169 -0
  35. package/dist/v1/models/together.json +43 -0
  36. package/dist/v1/models/yi.json +199 -0
  37. package/dist/v1/models/zhipu.json +250 -0
  38. package/dist/v1/providers/ai21.json +215 -0
  39. package/dist/v1/providers/anthropic.json +253 -0
  40. package/dist/v1/providers/anyscale.json +115 -0
  41. package/dist/v1/providers/azure.json +188 -0
  42. package/dist/v1/providers/baichuan.json +205 -0
  43. package/dist/v1/providers/baidu.json +205 -0
  44. package/dist/v1/providers/cerebras.json +216 -0
  45. package/dist/v1/providers/cohere.json +209 -0
  46. package/dist/v1/providers/deepinfra.json +196 -0
  47. package/dist/v1/providers/deepseek.json +221 -0
  48. package/dist/v1/providers/doubao.json +209 -0
  49. package/dist/v1/providers/fireworks.json +227 -0
  50. package/dist/v1/providers/gemini.json +279 -0
  51. package/dist/v1/providers/groq.json +218 -0
  52. package/dist/v1/providers/huggingface.json +181 -0
  53. package/dist/v1/providers/hunyuan.json +198 -0
  54. package/dist/v1/providers/jina.json +202 -0
  55. package/dist/v1/providers/lepton.json +221 -0
  56. package/dist/v1/providers/minimax.json +209 -0
  57. package/dist/v1/providers/mistral.json +214 -0
  58. package/dist/v1/providers/moonshot.json +214 -0
  59. package/dist/v1/providers/nvidia.json +213 -0
  60. package/dist/v1/providers/openai.json +267 -0
  61. package/dist/v1/providers/openrouter.json +220 -0
  62. package/dist/v1/providers/perplexity.json +172 -0
  63. package/dist/v1/providers/qwen.json +231 -0
  64. package/dist/v1/providers/replicate.json +192 -0
  65. package/dist/v1/providers/sensenova.json +185 -0
  66. package/dist/v1/providers/siliconflow.json +197 -0
  67. package/dist/v1/providers/spark.json +204 -0
  68. package/dist/v1/providers/stability.json +221 -0
  69. package/dist/v1/providers/tiangong.json +207 -0
  70. package/dist/v1/providers/together.json +196 -0
  71. package/dist/v1/providers/writer.json +253 -0
  72. package/dist/v1/providers/xai.json +238 -0
  73. package/dist/v1/providers/yi.json +205 -0
  74. package/dist/v1/providers/zhipu.json +208 -0
  75. package/dist/v1/spec.json +783 -0
  76. package/dist/v2/providers/anthropic.json +372 -0
  77. package/dist/v2/providers/cohere.json +109 -0
  78. package/dist/v2/providers/deepseek.json +272 -0
  79. package/dist/v2/providers/doubao.json +260 -0
  80. package/dist/v2/providers/google.json +388 -0
  81. package/dist/v2/providers/jina.json +71 -0
  82. package/dist/v2/providers/moonshot.json +284 -0
  83. package/dist/v2/providers/openai.json +419 -0
  84. package/dist/v2/providers/qwen.json +274 -0
  85. package/dist/v2/providers/zhipu.json +257 -0
  86. package/dist/v2-alpha/providers/anthropic.json +182 -0
  87. package/dist/v2-alpha/providers/gemini.json +187 -0
  88. package/dist/v2-alpha/providers/openai.json +215 -0
  89. package/dist/v2-alpha/spec.json +644 -0
  90. package/package.json +61 -0
  91. package/schemas/spec.json +186 -0
  92. package/schemas/v1.json +1116 -0
  93. package/schemas/v2/availability.json +66 -0
  94. package/schemas/v2/capabilities.json +182 -0
  95. package/schemas/v2/capability-profile.json +174 -0
  96. package/schemas/v2/computer-use.json +222 -0
  97. package/schemas/v2/context-policy.json +148 -0
  98. package/schemas/v2/endpoint.json +2 -0
  99. package/schemas/v2/error-codes.yaml +225 -0
  100. package/schemas/v2/errors.json +250 -0
  101. package/schemas/v2/execution-metadata.json +59 -0
  102. package/schemas/v2/mcp.json +225 -0
  103. package/schemas/v2/message-roles.json +10 -0
  104. package/schemas/v2/multimodal.json +297 -0
  105. package/schemas/v2/pricing.json +14 -0
  106. package/schemas/v2/provider-contract.json +317 -0
  107. package/schemas/v2/provider.json +203 -0
  108. package/schemas/v2/regions.json +14 -0
  109. package/v1/models/ai21.yaml +97 -0
  110. package/v1/models/baichuan.yaml +95 -0
  111. package/v1/models/cerebras.yaml +99 -0
  112. package/v1/models/claude.yaml +59 -0
  113. package/v1/models/cohere.yaml +165 -0
  114. package/v1/models/deepinfra.yaml +29 -0
  115. package/v1/models/deepseek-chat.yaml +32 -0
  116. package/v1/models/doubao.yaml +129 -0
  117. package/v1/models/ernie.yaml +146 -0
  118. package/v1/models/fireworks.yaml +145 -0
  119. package/v1/models/gemini.yaml +32 -0
  120. package/v1/models/gpt.yaml +90 -0
  121. package/v1/models/grok.yaml +74 -0
  122. package/v1/models/huggingface.yaml +110 -0
  123. package/v1/models/hunyuan.yaml +164 -0
  124. package/v1/models/jina.yaml +98 -0
  125. package/v1/models/lepton.yaml +130 -0
  126. package/v1/models/llama.yaml +91 -0
  127. package/v1/models/minimax.yaml +132 -0
  128. package/v1/models/mistral.yaml +100 -0
  129. package/v1/models/moonshot.yaml +97 -0
  130. package/v1/models/nvidia.yaml +118 -0
  131. package/v1/models/palmyra.yaml +59 -0
  132. package/v1/models/perplexity.yaml +97 -0
  133. package/v1/models/qwen.yaml +27 -0
  134. package/v1/models/replicate.yaml +136 -0
  135. package/v1/models/sensenova.yaml +97 -0
  136. package/v1/models/siliconflow.yaml +29 -0
  137. package/v1/models/spark.yaml +114 -0
  138. package/v1/models/stable-diffusion.yaml +113 -0
  139. package/v1/models/tiangong.yaml +114 -0
  140. package/v1/models/together.yaml +29 -0
  141. package/v1/models/yi.yaml +132 -0
  142. package/v1/models/zhipu.yaml +163 -0
  143. package/v1/providers/ai21.yaml +176 -0
  144. package/v1/providers/anthropic.yaml +209 -0
  145. package/v1/providers/anyscale.yaml +106 -0
  146. package/v1/providers/azure.yaml +155 -0
  147. package/v1/providers/baichuan.yaml +168 -0
  148. package/v1/providers/baidu.yaml +173 -0
  149. package/v1/providers/cerebras.yaml +178 -0
  150. package/v1/providers/cohere.yaml +175 -0
  151. package/v1/providers/deepinfra.yaml +156 -0
  152. package/v1/providers/deepseek.yaml +189 -0
  153. package/v1/providers/doubao.yaml +172 -0
  154. package/v1/providers/fireworks.yaml +187 -0
  155. package/v1/providers/gemini.yaml +229 -0
  156. package/v1/providers/groq.yaml +181 -0
  157. package/v1/providers/huggingface.yaml +157 -0
  158. package/v1/providers/hunyuan.yaml +162 -0
  159. package/v1/providers/jina.yaml +171 -0
  160. package/v1/providers/lepton.yaml +183 -0
  161. package/v1/providers/minimax.yaml +172 -0
  162. package/v1/providers/mistral.yaml +186 -0
  163. package/v1/providers/moonshot.yaml +176 -0
  164. package/v1/providers/nvidia.yaml +172 -0
  165. package/v1/providers/openai.yaml +224 -0
  166. package/v1/providers/openrouter.yaml +181 -0
  167. package/v1/providers/perplexity.yaml +144 -0
  168. package/v1/providers/qwen.yaml +192 -0
  169. package/v1/providers/replicate.yaml +159 -0
  170. package/v1/providers/sensenova.yaml +153 -0
  171. package/v1/providers/siliconflow.yaml +156 -0
  172. package/v1/providers/spark.yaml +167 -0
  173. package/v1/providers/stability.yaml +185 -0
  174. package/v1/providers/tiangong.yaml +170 -0
  175. package/v1/providers/together.yaml +156 -0
  176. package/v1/providers/writer.yaml +212 -0
  177. package/v1/providers/xai.yaml +206 -0
  178. package/v1/providers/yi.yaml +168 -0
  179. package/v1/providers/zhipu.yaml +171 -0
  180. package/v1/spec.yaml +637 -0
  181. package/v2/providers/anthropic.yaml +244 -0
  182. package/v2/providers/cohere.yaml +75 -0
  183. package/v2/providers/deepseek.yaml +176 -0
  184. package/v2/providers/doubao.yaml +169 -0
  185. package/v2/providers/google.yaml +245 -0
  186. package/v2/providers/jina.yaml +55 -0
  187. package/v2/providers/moonshot.yaml +186 -0
  188. package/v2/providers/openai.yaml +266 -0
  189. package/v2/providers/qwen.yaml +174 -0
  190. package/v2/providers/zhipu.yaml +176 -0
  191. package/v2-alpha/providers/anthropic.yaml +134 -0
  192. package/v2-alpha/providers/gemini.yaml +144 -0
  193. package/v2-alpha/providers/openai.yaml +154 -0
  194. package/v2-alpha/spec.yaml +512 -0
@@ -0,0 +1,187 @@
1
+ $schema: "https://raw.githubusercontent.com/ailib-official/ai-protocol/main/schemas/v1.json"
2
+
3
+ id: fireworks
4
+ protocol_version: "1.5"
5
+
6
+ name: Fireworks AI
7
+ version: "v1"
8
+ status: stable
9
+ category: ai_provider
10
+ official_url: "https://docs.fireworks.ai"
11
+ support_contact: "https://fireworks.ai/contact"
12
+
13
+ endpoint:
14
+ base_url: "https://api.fireworks.ai/inference/v1"
15
+ protocol: https
16
+ timeout_ms: 30000
17
+
18
+ auth:
19
+ type: bearer
20
+ token_env: "FIREWORKS_API_KEY"
21
+
22
+ payload_format: "openai_style"
23
+
24
+ # OpenAI-compatible API families
25
+ api_families: ["chat_completions", "completions"]
26
+ default_api_family: "chat_completions"
27
+
28
+ endpoints:
29
+ chat:
30
+ path: "/chat/completions"
31
+ method: "POST"
32
+ adapter: "openai"
33
+ completions:
34
+ path: "/completions"
35
+ method: "POST"
36
+ adapter: "openai"
37
+
38
+ services:
39
+ list_models:
40
+ path: "/models"
41
+ method: "GET"
42
+ response_binding: "data"
43
+
44
+ termination:
45
+ source_field: "finish_reason"
46
+ mapping:
47
+ stop: "end_turn"
48
+ length: "max_tokens"
49
+ tool_calls: "tool_use"
50
+ content_filter: "refusal"
51
+ notes:
52
+ - "OpenAI-compatible: finish_reason is reported per candidate."
53
+
54
+ tooling:
55
+ source_model: "openai_tool_calls"
56
+ tool_use:
57
+ id_path: "id"
58
+ name_path: "function.name"
59
+ input_path: "function.arguments"
60
+ input_format: "json_string"
61
+ notes:
62
+ - "OpenAI-compatible tool calling format."
63
+
64
+ rate_limit_headers:
65
+ requests_limit: "x-ratelimit-limit-requests"
66
+ requests_remaining: "x-ratelimit-remaining-requests"
67
+ tokens_limit: "x-ratelimit-limit-tokens"
68
+ tokens_remaining: "x-ratelimit-remaining-tokens"
69
+
70
+ retry_policy:
71
+ strategy: "exponential_backoff"
72
+ max_retries: 3
73
+ min_delay_ms: 1000
74
+ max_delay_ms: 30000
75
+ jitter: "full"
76
+ retry_on_http_status: [429, 500, 502, 503]
77
+ notes:
78
+ - "Fireworks AI uses standard rate limiting with exponential backoff."
79
+
80
+ error_classification:
81
+ by_http_status:
82
+ "400": "invalid_request"
83
+ "401": "authentication"
84
+ "403": "permission_denied"
85
+ "404": "not_found"
86
+ "429": "rate_limited"
87
+ "500": "server_error"
88
+ "502": "server_error"
89
+ "503": "overloaded"
90
+
91
+ parameter_mappings:
92
+ temperature: "temperature"
93
+ max_tokens: "max_tokens"
94
+ stream: "stream"
95
+ top_p: "top_p"
96
+ stop_sequences: "stop"
97
+ frequency_penalty: "frequency_penalty"
98
+ presence_penalty: "presence_penalty"
99
+ tools: "tools"
100
+ tool_choice: "tool_choice"
101
+ seed: "seed"
102
+ top_k: "top_k"
103
+
104
+ response_format: "openai_style"
105
+
106
+ response_paths:
107
+ content: "choices[0].message.content"
108
+ tool_calls: "choices[0].message.tool_calls"
109
+ usage: "usage"
110
+ finish_reason: "choices[0].finish_reason"
111
+
112
+ streaming:
113
+ event_format: "data_lines"
114
+ decoder:
115
+ format: "sse"
116
+ delimiter: "\n\n"
117
+ prefix: "data: "
118
+ done_signal: "[DONE]"
119
+ content_path: "choices[0].delta.content"
120
+ tool_call_path: "choices[0].delta.tool_calls"
121
+ usage_path: "usage"
122
+ frame_selector: "exists($.choices) || exists($.error)"
123
+ event_map:
124
+ - match: "exists($.choices[*].delta.content)"
125
+ emit: "PartialContentDelta"
126
+ fields:
127
+ content: "$.choices[*].delta.content"
128
+ - match: "exists($.choices[*].delta.tool_calls[*].function.name)"
129
+ emit: "ToolCallStarted"
130
+ fields:
131
+ tool_call_id: "$.choices[*].delta.tool_calls[*].id"
132
+ tool_name: "$.choices[*].delta.tool_calls[*].function.name"
133
+ index: "$.choices[*].delta.tool_calls[*].index"
134
+ - match: "exists($.choices[*].delta.tool_calls[*].function.arguments)"
135
+ emit: "PartialToolCall"
136
+ fields:
137
+ arguments: "$.choices[*].delta.tool_calls[*].function.arguments"
138
+ index: "$.choices[*].delta.tool_calls[*].index"
139
+ - match: "exists($.usage)"
140
+ emit: "Metadata"
141
+ fields:
142
+ usage: "$.usage"
143
+ - match: "exists($.choices[*].finish_reason)"
144
+ emit: "FinalCandidate"
145
+ fields:
146
+ finish_reason: "$.choices[*].finish_reason"
147
+ candidate_index: "$.choices[*].index"
148
+ stop_condition: "$.choices[0].finish_reason != null"
149
+
150
+ features:
151
+ multi_candidate:
152
+ support_type: "native"
153
+ param_name: "n"
154
+ response_mapping:
155
+ tool_calls:
156
+ path: "choices[0].message.tool_calls"
157
+ fields:
158
+ id: "id"
159
+ name: "function.name"
160
+ args: "function.arguments"
161
+ error:
162
+ message_path: "error.message"
163
+ code_path: "error.code"
164
+ type_path: "error.type"
165
+
166
+ capabilities:
167
+ streaming: true
168
+ tools: true
169
+ vision: true
170
+ agentic: true
171
+ parallel_tools: true
172
+ reasoning: false
173
+
174
+ availability:
175
+ required: false
176
+ regions:
177
+ - global
178
+ check:
179
+ method: GET
180
+ path: "/models"
181
+ expected_status: [200, 401]
182
+ timeout_ms: 5000
183
+
184
+ experimental_features:
185
+ - "function_calling"
186
+ - "json_mode"
187
+ - "serverless_inference"
@@ -0,0 +1,229 @@
1
+ $schema: "https://raw.githubusercontent.com/ailib-official/ai-protocol/main/schemas/v1.json"
2
+
3
+ id: gemini
4
+ protocol_version: "1.5"
5
+
6
+ name: Google Gemini
7
+ version: "v1beta"
8
+ status: stable
9
+ category: ai_provider
10
+ official_url: "https://ai.google.dev/docs"
11
+ support_contact: "https://support.google.com/gemini"
12
+
13
+ endpoint:
14
+ base_url: "https://generativelanguage.googleapis.com/v1beta"
15
+ protocol: https
16
+ timeout_ms: 10000
17
+ auth:
18
+ type: query_param
19
+ param_name: "key"
20
+ token_env: "GEMINI_API_KEY"
21
+ payload_format: "gemini_style"
22
+
23
+ # Gemini native API families
24
+ api_families: ["generate_content"]
25
+ default_api_family: "generate_content"
26
+ endpoints:
27
+ chat:
28
+ path: "/models/{model}:generateContent"
29
+ method: "POST"
30
+ adapter: "gemini"
31
+
32
+ # V1.5 Service Endpoints
33
+ services:
34
+ list_models:
35
+ path: "/models"
36
+ method: "GET"
37
+ response_binding: "models"
38
+ list_files:
39
+ path: "/files"
40
+ method: "GET"
41
+ response_binding: "files"
42
+ get_model:
43
+ path: "/models/{model}"
44
+ method: "GET"
45
+ termination:
46
+ # Gemini response field is typically named finishReason (provider-defined enum).
47
+ source_field: "finishReason"
48
+ mapping:
49
+ FINISH_REASON_UNSPECIFIED: "other"
50
+ STOP: "end_turn"
51
+ MAX_TOKENS: "max_tokens"
52
+ SAFETY: "refusal"
53
+ RECITATION: "refusal"
54
+ LANGUAGE: "refusal"
55
+ OTHER: "other"
56
+ BLOCKLIST: "refusal"
57
+ PROHIBITED_CONTENT: "refusal"
58
+ SPII: "refusal"
59
+ MALFORMED_FUNCTION_CALL: "other"
60
+ IMAGE_SAFETY: "refusal"
61
+ IMAGE_PROHIBITED_CONTENT: "refusal"
62
+ IMAGE_OTHER: "other"
63
+ NO_IMAGE: "other"
64
+ IMAGE_RECITATION: "refusal"
65
+ UNEXPECTED_TOOL_CALL: "other"
66
+ TOO_MANY_TOOL_CALLS: "other"
67
+ MISSING_THOUGHT_SIGNATURE: "other"
68
+ notes:
69
+ - "finishReason enum is VERIFIED in research/providers/gemini.md (from official generate-content reference)."
70
+ - "STOP covers both natural stop and provided stop sequence; this mapping chooses end_turn because stop_sequence cannot be distinguished from finishReason alone."
71
+ tooling:
72
+ source_model: "gemini_function_call"
73
+ tool_use:
74
+ name_path: "functionCall.name"
75
+ input_path: "functionCall.args"
76
+ input_format: "json_object"
77
+ tool_result:
78
+ id_path: "functionResponse.id"
79
+ name_path: "functionResponse.name"
80
+ response_path: "functionResponse.response"
81
+ output_path: "functionResponse.response.output"
82
+ error_path: "functionResponse.response.error"
83
+ format: "json_object"
84
+ notes:
85
+ - "Gemini represents tool invocations via functionCall in content parts; normalization to tool_use/tool_result should follow the runtime's part-parsing logic."
86
+
87
+ # Retry policy (VERIFIED evidence in research/providers/gemini.md via Vertex AI errors docs)
88
+ retry_policy:
89
+ strategy: "exponential_backoff"
90
+ max_retries: 2
91
+ min_delay_ms: 1000
92
+ max_delay_ms: 8000
93
+ jitter: "full"
94
+ retry_on_http_status: [429, 503, 504]
95
+ retry_on_error_status: ["RESOURCE_EXHAUSTED", "UNAVAILABLE", "DEADLINE_EXCEEDED"]
96
+ notes:
97
+ - "On 429/RESOURCE_EXHAUSTED: retry after a few seconds; recommend no more than two retries; min 1s with exponential backoff."
98
+
99
+ # Error classification hints (see v1/spec.yaml: standard_schema.error_handling.error_classes)
100
+ error_classification:
101
+ by_http_status:
102
+ "400": "invalid_request"
103
+ "403": "permission_denied"
104
+ "404": "not_found"
105
+ "429": "rate_limited"
106
+ "499": "cancelled"
107
+ "500": "server_error"
108
+ "503": "overloaded"
109
+ "504": "timeout"
110
+ by_error_status:
111
+ "INVALID_ARGUMENT": "invalid_request"
112
+ "FAILED_PRECONDITION": "invalid_request"
113
+ "PERMISSION_DENIED": "permission_denied"
114
+ "NOT_FOUND": "not_found"
115
+ "RESOURCE_EXHAUSTED": "rate_limited"
116
+ "CANCELLED": "cancelled"
117
+ "UNKNOWN": "server_error"
118
+ "INTERNAL": "server_error"
119
+ "UNAVAILABLE": "overloaded"
120
+ "DEADLINE_EXCEEDED": "timeout"
121
+ notes:
122
+ - "Vertex/Gemini follows the Google Cloud API error model; prefer mapping by canonical error.status when present."
123
+ parameter_mappings:
124
+ temperature: "generationConfig.temperature"
125
+ max_tokens: "generationConfig.maxOutputTokens"
126
+ top_p: "generationConfig.topP"
127
+ top_k: "generationConfig.topK"
128
+ stop_sequences: "stopSequences"
129
+ tools: "tools"
130
+ tool_choice: "toolConfig"
131
+ response_format: "gemini_style"
132
+ response_paths:
133
+ content: "candidates[0].content.parts[0].text"
134
+ tool_calls: "candidates[0].content.parts[0].functionCall"
135
+ usage: "usageMetadata"
136
+ finish_reason: "candidates[0].finishReason"
137
+ streaming:
138
+ event_format: "sse_data_lines"
139
+ decoder:
140
+ format: "sse"
141
+ delimiter: "\n\n"
142
+ prefix: "data: "
143
+ # Stream may contain normal candidate frames or error frames.
144
+ frame_selector: "exists($.candidates) || exists($.error)"
145
+ candidate:
146
+ candidate_id_path: "$.candidates[*].index"
147
+ fan_out: true
148
+ event_map:
149
+ # Stream-level error delivered as SSE data JSON
150
+ - match: "exists($.error)"
151
+ emit: "StreamError"
152
+ fields:
153
+ error: "$.error"
154
+ model_version: "$.modelVersion"
155
+ # Text content (supports multi-candidate via array fan-out)
156
+ - match: "exists($.candidates[*].content.parts[*].text)"
157
+ emit: "PartialContentDelta"
158
+ fields:
159
+ content: "$.candidates[*].content.parts[*].text"
160
+ # Function call start (Gemini returns complete function call in one chunk)
161
+ - match: "exists($.candidates[*].content.parts[*].functionCall.name)"
162
+ emit: "ToolCallStarted"
163
+ fields:
164
+ tool_name: "$.candidates[*].content.parts[*].functionCall.name"
165
+ tool_call_id: "_generate_uuid"
166
+ # Function call arguments
167
+ - match: "exists($.candidates[*].content.parts[*].functionCall.args)"
168
+ emit: "PartialToolCall"
169
+ fields:
170
+ arguments: "$.candidates[*].content.parts[*].functionCall.args"
171
+ tool_name: "$.candidates[*].content.parts[*].functionCall.name"
172
+ tool_call_id: "_generate_uuid"
173
+ # Usage metadata
174
+ - match: "exists($.usageMetadata)"
175
+ emit: "Metadata"
176
+ fields:
177
+ usage: "$.usageMetadata"
178
+ prompt_tokens: "$.usageMetadata.promptTokenCount"
179
+ completion_tokens: "$.usageMetadata.candidatesTokenCount"
180
+ # Finish with reason
181
+ - match: "exists($.candidates[*].finishReason)"
182
+ emit: "FinalCandidate"
183
+ fields:
184
+ finish_reason: "$.candidates[*].finishReason"
185
+ candidate_index: "$.candidates[*].index"
186
+ stop_condition: "exists($.candidates[*].finishReason)"
187
+ extra_metadata_path: "$.usageMetadata"
188
+ content_path: "candidates[0].content.parts[0].text"
189
+ tool_call_path: "candidates[0].content.parts[0].functionCall.args"
190
+ features:
191
+ multi_candidate:
192
+ support_type: "native"
193
+ param_name: "candidateCount"
194
+ response_mapping:
195
+ tool_calls:
196
+ path: "candidates[0].content.parts"
197
+ filter: "exists(functionCall)"
198
+ fields:
199
+ id: "_generate_uuid"
200
+ name: "functionCall.name"
201
+ args: "functionCall.args"
202
+ id_strategy: "generate_uuid"
203
+ array_fan_out: true
204
+ error:
205
+ # Vertex / Gemini HTTP error envelope: { "error": { code, message, status, errors[] } }
206
+ message_path: "error.message"
207
+ code_path: "error.code"
208
+ status_path: "error.status"
209
+ errors_path: "error.errors"
210
+ capabilities:
211
+ streaming: true
212
+ tools: true
213
+ vision: true
214
+ agentic: false
215
+ parallel_tools: false
216
+ reasoning: false
217
+
218
+ availability:
219
+ required: false
220
+ regions:
221
+ - global
222
+ check:
223
+ method: GET
224
+ path: "/models"
225
+ expected_status: [200, 401]
226
+ timeout_ms: 3000
227
+ experimental_features:
228
+ - "multimodal_video"
229
+ - "multimodal_audio"
@@ -0,0 +1,181 @@
1
+ $schema: "https://raw.githubusercontent.com/ailib-official/ai-protocol/main/schemas/v1.json"
2
+
3
+ id: groq
4
+ protocol_version: "1.5"
5
+
6
+ name: Groq
7
+ version: "v1"
8
+ status: stable
9
+ category: ai_provider
10
+ official_url: "https://console.groq.com/docs"
11
+ support_contact: "https://support.groq.com"
12
+
13
+ endpoint:
14
+ base_url: "https://api.groq.com/openai/v1"
15
+ protocol: https
16
+ timeout_ms: 10000
17
+ auth:
18
+ type: bearer
19
+ token_env: "GROQ_API_KEY"
20
+ payload_format: "openai_style"
21
+
22
+ # OpenAI-compatible API families
23
+ api_families: ["chat_completions", "completions"]
24
+ default_api_family: "chat_completions"
25
+ endpoints:
26
+ # Runtime uses UnifiedRequest.operation (currently "chat") to resolve endpoints.
27
+ # Keep keys aligned with runtime expectations.
28
+ chat:
29
+ path: "/chat/completions"
30
+ method: "POST"
31
+ adapter: "openai"
32
+ completions:
33
+ path: "/completions"
34
+ method: "POST"
35
+ adapter: "openai"
36
+
37
+ # Optional service endpoints (OpenAI-compatible).
38
+ services:
39
+ list_models:
40
+ path: "/models"
41
+ method: "GET"
42
+ response_binding: "data"
43
+
44
+ # Termination reason normalization (see v1/spec.yaml: standard_schema.streaming_events.termination_reasons)
45
+ termination:
46
+ source_field: "finish_reason"
47
+ mapping:
48
+ stop: "end_turn"
49
+ length: "max_tokens"
50
+ tool_calls: "tool_use"
51
+ content_filter: "refusal"
52
+ notes:
53
+ - "OpenAI-compatible: finish_reason is reported per candidate."
54
+
55
+ # Tool invocation normalization (see v1/spec.yaml: standard_schema.content_blocks)
56
+ tooling:
57
+ source_model: "openai_tool_calls"
58
+ tool_use:
59
+ id_path: "id"
60
+ name_path: "function.name"
61
+ input_path: "function.arguments"
62
+ input_format: "json_string"
63
+ notes:
64
+ - "OpenAI-compatible tool_calls.function.arguments is typically a JSON string; runtimes SHOULD parse it into an object when normalizing."
65
+
66
+ # Rate limits (OpenAI-compatible; see OpenAI rate limits guide)
67
+ rate_limit_headers:
68
+ requests_limit: "x-ratelimit-limit-requests"
69
+ requests_remaining: "x-ratelimit-remaining-requests"
70
+ requests_reset: "x-ratelimit-reset-requests"
71
+ tokens_limit: "x-ratelimit-limit-tokens"
72
+ tokens_remaining: "x-ratelimit-remaining-tokens"
73
+ tokens_reset: "x-ratelimit-reset-tokens"
74
+ retry_after: "retry-after"
75
+
76
+ # Retry policy (OpenAI-compatible guidance: exponential backoff for 429; retry 5xx after brief wait)
77
+ retry_policy:
78
+ max_retries: 3
79
+ max_delay_ms: 30000
80
+ strategy: "exponential_backoff"
81
+ min_delay_ms: 1000
82
+ jitter: "full"
83
+ retry_on_http_status: [429, 500, 502, 503]
84
+ notes:
85
+ - "OpenAI-compatible: exponential backoff is recommended for rate limit errors (429)."
86
+ - "Retry 500 after a brief wait."
87
+ parameter_mappings:
88
+ temperature: "temperature"
89
+ max_tokens: "max_tokens"
90
+ stream: "stream"
91
+ stop_sequences: "stop"
92
+ tools: "tools"
93
+ tool_choice: "tool_choice"
94
+ frequency_penalty: "frequency_penalty"
95
+ presence_penalty: "presence_penalty"
96
+ logprobs: "logprobs"
97
+ top_logprobs: "top_logprobs"
98
+ seed: "seed"
99
+ response_format: "openai_style"
100
+ response_paths:
101
+ content: "choices[0].message.content"
102
+ tool_calls: "choices[0].message.tool_calls"
103
+ usage: "usage"
104
+ streaming:
105
+ event_format: "data_lines"
106
+ decoder:
107
+ format: "sse"
108
+ delimiter: "\n\n"
109
+ prefix: "data: "
110
+ done_signal: "[DONE]"
111
+ content_path: "choices[0].delta.content"
112
+ tool_call_path: "choices[0].delta.tool_calls"
113
+ usage_path: "usage"
114
+ frame_selector: "exists($.choices) || exists($.error)"
115
+ event_map:
116
+ # Text content delta
117
+ - match: "exists($.choices[*].delta.content)"
118
+ emit: "PartialContentDelta"
119
+ fields:
120
+ content: "$.choices[*].delta.content"
121
+ # Tool call start
122
+ - match: "exists($.choices[*].delta.tool_calls[*].function.name)"
123
+ emit: "ToolCallStarted"
124
+ fields:
125
+ tool_call_id: "$.choices[*].delta.tool_calls[*].id"
126
+ tool_name: "$.choices[*].delta.tool_calls[*].function.name"
127
+ index: "$.choices[*].delta.tool_calls[*].index"
128
+ # Tool call arguments streaming
129
+ - match: "exists($.choices[*].delta.tool_calls[*].function.arguments)"
130
+ emit: "PartialToolCall"
131
+ fields:
132
+ arguments: "$.choices[*].delta.tool_calls[*].function.arguments"
133
+ index: "$.choices[*].delta.tool_calls[*].index"
134
+ # Usage metadata
135
+ - match: "exists($.usage)"
136
+ emit: "Metadata"
137
+ fields:
138
+ usage: "$.usage"
139
+ # Stream end with finish reason
140
+ - match: "$.choices[*].finish_reason != null"
141
+ emit: "StreamEnd"
142
+ fields:
143
+ finish_reason: "$.choices[*].finish_reason"
144
+ stop_condition: "$.choices[0].finish_reason != null"
145
+ features:
146
+ multi_candidate:
147
+ support_type: "native"
148
+ param_name: "n"
149
+ response_mapping:
150
+ tool_calls:
151
+ path: "choices[0].message.tool_calls"
152
+ fields:
153
+ id: "id"
154
+ name: "function.name"
155
+ args: "function.arguments"
156
+ error:
157
+ message_path: "error.message"
158
+ code_path: "error.code"
159
+ type_path: "error.type"
160
+ param_path: "error.param"
161
+ capabilities:
162
+ streaming: true
163
+ tools: true
164
+ vision: false
165
+ agentic: true
166
+ parallel_tools: true
167
+ reasoning: false
168
+
169
+ availability:
170
+ required: false
171
+ regions:
172
+ - global
173
+ check:
174
+ method: GET
175
+ path: "/models"
176
+ expected_status: [200, 401]
177
+ timeout_ms: 3000
178
+ experimental_features:
179
+ - "builtin_search"
180
+ - "code_execution"
181
+ - "fast_inference"