@jsonstudio/llms 0.6.749 → 0.6.753

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.
@@ -1,17 +1,17 @@
1
1
  {
2
- "id": "chat:gemini",
3
- "protocol": "gemini-chat",
4
- "request": {
5
- "mappings": [
6
- { "action": "snapshot", "phase": "compat-pre" },
7
- { "action": "claude_thinking_tool_schema" },
8
- {
9
- "action": "gemini_web_search_request"
10
- },
11
- { "action": "snapshot", "phase": "compat-post" }
12
- ]
13
- },
14
- "response": {
15
- "mappings": []
16
- }
2
+ "id": "chat:gemini",
3
+ "protocol": "gemini-chat",
4
+ "request": {
5
+ "mappings": [
6
+ { "action": "snapshot", "phase": "compat-pre" },
7
+ { "action": "claude_thinking_tool_schema" },
8
+ {
9
+ "action": "gemini_web_search_request"
10
+ },
11
+ { "action": "snapshot", "phase": "compat-post" }
12
+ ]
13
+ },
14
+ "response": {
15
+ "mappings": []
16
+ }
17
17
  }
@@ -1,204 +1,204 @@
1
1
  {
2
- "id": "chat:glm",
3
- "protocol": "openai-chat",
4
- "request": {
5
- "mappings": [
6
- { "action": "snapshot", "phase": "compat-pre" },
7
- { "action": "dto_unwrap" },
8
- {
9
- "action": "remove",
10
- "path": "parallel_tool_calls"
11
- },
12
- {
13
- "action": "glm_image_content"
14
- },
15
- {
16
- "action": "glm_vision_prompt"
17
- },
18
- {
19
- "action": "rename",
20
- "from": "response_format",
21
- "to": "metadata.generation.response_format"
22
- },
23
- {
24
- "action": "remove",
25
- "path": "metadata.clientModelId"
26
- },
27
- {
28
- "action": "shape_filter",
29
- "target": "request",
30
- "config": {
31
- "request": {
32
- "allowTopLevel": [
33
- "model", "messages", "stream", "thinking", "do_sample", "temperature", "top_p",
34
- "max_tokens", "tools", "tool_choice", "stop", "response_format", "web_search"
35
- ],
36
- "messages": {
37
- "allowedRoles": ["system", "user", "assistant", "tool"],
38
- "assistantWithToolCallsContentNull": true,
39
- "toolContentStringify": false
2
+ "id": "chat:glm",
3
+ "protocol": "openai-chat",
4
+ "request": {
5
+ "mappings": [
6
+ { "action": "snapshot", "phase": "compat-pre" },
7
+ { "action": "dto_unwrap" },
8
+ {
9
+ "action": "remove",
10
+ "path": "parallel_tool_calls"
40
11
  },
41
- "messagesRules": [],
42
- "tools": {
43
- "normalize": false,
44
- "forceToolChoiceAuto": true
12
+ {
13
+ "action": "glm_image_content"
45
14
  },
46
- "assistantToolCalls": { "functionArgumentsType": "string" }
47
- },
48
- "response": {
49
- "allowTopLevel": [
50
- "id", "request_id", "created", "model",
51
- "choices", "usage", "video_result", "web_search", "content_filter",
52
- "required_action", "output", "output_text", "status"
53
- ],
54
- "choices": {
55
- "required": true,
56
- "message": {
57
- "allow": ["role", "content", "reasoning_content", "audio", "tool_calls"],
58
- "roleDefault": "assistant",
59
- "contentNullWhenToolCalls": true,
60
- "tool_calls": { "function": { "nameRequired": true, "argumentsType": "string" } }
61
- },
62
- "finish_reason": ["stop", "tool_calls", "length", "sensitive", "network_error"]
15
+ {
16
+ "action": "glm_vision_prompt"
63
17
  },
64
- "usage": { "allow": ["prompt_tokens", "completion_tokens", "prompt_tokens_details", "total_tokens"] }
65
- }
66
- }
67
- },
68
- {
69
- "action": "apply_rules",
70
- "config": {
71
- "tools": {
72
- "function": {
73
- "removeKeys": ["strict", "json_schema"]
74
- }
75
- },
76
- "messages": {
77
- "assistantToolCalls": {
78
- "function": {
79
- "removeKeys": ["strict"]
80
- }
81
- }
82
- },
83
- "topLevel": {
84
- "conditional": [
85
- { "when": { "tools": "empty" }, "remove": ["tool_choice"] }
86
- ]
87
- }
88
- }
89
- },
90
- {
91
- "action": "field_map",
92
- "direction": "incoming",
93
- "config": [
94
- { "sourcePath": "usage.prompt_tokens", "targetPath": "usage.input_tokens", "type": "number" },
95
- { "sourcePath": "usage.completion_tokens", "targetPath": "usage.output_tokens", "type": "number" },
96
- { "sourcePath": "created", "targetPath": "created_at", "type": "number" },
97
- { "sourcePath": "request_id", "targetPath": "request_id", "type": "string" },
98
- { "sourcePath": "model", "targetPath": "model", "type": "string", "transform": "normalizeModelName" },
99
- {
100
- "sourcePath": "choices[*].message.tool_calls[*].function.arguments",
101
- "targetPath": "choices[*].message.tool_calls[*].function.arguments",
102
- "type": "string"
103
- }
18
+ {
19
+ "action": "rename",
20
+ "from": "response_format",
21
+ "to": "metadata.generation.response_format"
22
+ },
23
+ {
24
+ "action": "remove",
25
+ "path": "metadata.clientModelId"
26
+ },
27
+ {
28
+ "action": "shape_filter",
29
+ "target": "request",
30
+ "config": {
31
+ "request": {
32
+ "allowTopLevel": [
33
+ "model", "messages", "stream", "thinking", "do_sample", "temperature", "top_p",
34
+ "max_tokens", "tools", "tool_choice", "stop", "response_format", "web_search"
35
+ ],
36
+ "messages": {
37
+ "allowedRoles": ["system", "user", "assistant", "tool"],
38
+ "assistantWithToolCallsContentNull": true,
39
+ "toolContentStringify": false
40
+ },
41
+ "messagesRules": [],
42
+ "tools": {
43
+ "normalize": false,
44
+ "forceToolChoiceAuto": true
45
+ },
46
+ "assistantToolCalls": { "functionArgumentsType": "string" }
47
+ },
48
+ "response": {
49
+ "allowTopLevel": [
50
+ "id", "request_id", "created", "model",
51
+ "choices", "usage", "video_result", "web_search", "content_filter",
52
+ "required_action", "output", "output_text", "status"
53
+ ],
54
+ "choices": {
55
+ "required": true,
56
+ "message": {
57
+ "allow": ["role", "content", "reasoning_content", "audio", "tool_calls"],
58
+ "roleDefault": "assistant",
59
+ "contentNullWhenToolCalls": true,
60
+ "tool_calls": { "function": { "nameRequired": true, "argumentsType": "string" } }
61
+ },
62
+ "finish_reason": ["stop", "tool_calls", "length", "sensitive", "network_error"]
63
+ },
64
+ "usage": { "allow": ["prompt_tokens", "completion_tokens", "prompt_tokens_details", "total_tokens"] }
65
+ }
66
+ }
67
+ },
68
+ {
69
+ "action": "apply_rules",
70
+ "config": {
71
+ "tools": {
72
+ "function": {
73
+ "removeKeys": ["strict", "json_schema"]
74
+ }
75
+ },
76
+ "messages": {
77
+ "assistantToolCalls": {
78
+ "function": {
79
+ "removeKeys": ["strict"]
80
+ }
81
+ }
82
+ },
83
+ "topLevel": {
84
+ "conditional": [
85
+ { "when": { "tools": "empty" }, "remove": ["tool_choice"] }
86
+ ]
87
+ }
88
+ }
89
+ },
90
+ {
91
+ "action": "field_map",
92
+ "direction": "incoming",
93
+ "config": [
94
+ { "sourcePath": "usage.prompt_tokens", "targetPath": "usage.input_tokens", "type": "number" },
95
+ { "sourcePath": "usage.completion_tokens", "targetPath": "usage.output_tokens", "type": "number" },
96
+ { "sourcePath": "created", "targetPath": "created_at", "type": "number" },
97
+ { "sourcePath": "request_id", "targetPath": "request_id", "type": "string" },
98
+ { "sourcePath": "model", "targetPath": "model", "type": "string", "transform": "normalizeModelName" },
99
+ {
100
+ "sourcePath": "choices[*].message.tool_calls[*].function.arguments",
101
+ "targetPath": "choices[*].message.tool_calls[*].function.arguments",
102
+ "type": "string"
103
+ }
104
+ ]
105
+ },
106
+ { "action": "tool_schema_sanitize", "mode": "glm_shell" },
107
+ {
108
+ "action": "glm_web_search_request"
109
+ },
110
+ {
111
+ "action": "auto_thinking",
112
+ "config": {
113
+ "modelPrefixes": ["glm-4.7", "glm-4.6", "glm-4.5", "glm-z1"],
114
+ "excludePrefixes": ["glm-4.6v"]
115
+ }
116
+ },
117
+ { "action": "snapshot", "phase": "compat-post" },
118
+ { "action": "dto_rewrap" }
104
119
  ]
105
- },
106
- { "action": "tool_schema_sanitize", "mode": "glm_shell" },
107
- {
108
- "action": "glm_web_search_request"
109
- },
110
- {
111
- "action": "auto_thinking",
112
- "config": {
113
- "modelPrefixes": ["glm-4.7", "glm-4.6", "glm-4.5", "glm-z1"],
114
- "excludePrefixes": ["glm-4.6v"]
115
- }
116
- },
117
- { "action": "snapshot", "phase": "compat-post" },
118
- { "action": "dto_rewrap" }
119
- ]
120
- },
121
- "response": {
122
- "mappings": [
123
- { "action": "snapshot", "phase": "compat-pre" },
124
- { "action": "dto_unwrap" },
125
- {
126
- "action": "resp_blacklist",
127
- "config": {
128
- "paths": ["usage.prompt_tokens_details.cached_tokens"],
129
- "keepCritical": true
130
- }
131
- },
132
- {
133
- "action": "shape_filter",
134
- "target": "response",
135
- "config": {
136
- "request": {
137
- "allowTopLevel": [
138
- "model", "messages", "stream", "thinking", "do_sample", "temperature", "top_p",
139
- "max_tokens", "tools", "tool_choice", "stop", "response_format"
140
- ],
141
- "messages": {
142
- "allowedRoles": ["system", "user", "assistant", "tool"],
143
- "assistantWithToolCallsContentNull": true,
144
- "toolContentStringify": false
120
+ },
121
+ "response": {
122
+ "mappings": [
123
+ { "action": "snapshot", "phase": "compat-pre" },
124
+ { "action": "dto_unwrap" },
125
+ {
126
+ "action": "resp_blacklist",
127
+ "config": {
128
+ "paths": ["usage.prompt_tokens_details.cached_tokens"],
129
+ "keepCritical": true
130
+ }
145
131
  },
146
- "messagesRules": [],
147
- "tools": {
148
- "normalize": false,
149
- "forceToolChoiceAuto": true
132
+ {
133
+ "action": "shape_filter",
134
+ "target": "response",
135
+ "config": {
136
+ "request": {
137
+ "allowTopLevel": [
138
+ "model", "messages", "stream", "thinking", "do_sample", "temperature", "top_p",
139
+ "max_tokens", "tools", "tool_choice", "stop", "response_format"
140
+ ],
141
+ "messages": {
142
+ "allowedRoles": ["system", "user", "assistant", "tool"],
143
+ "assistantWithToolCallsContentNull": true,
144
+ "toolContentStringify": false
145
+ },
146
+ "messagesRules": [],
147
+ "tools": {
148
+ "normalize": false,
149
+ "forceToolChoiceAuto": true
150
+ },
151
+ "assistantToolCalls": { "functionArgumentsType": "string" }
152
+ },
153
+ "response": {
154
+ "allowTopLevel": [
155
+ "id", "request_id", "created", "model",
156
+ "choices", "usage", "video_result", "web_search", "content_filter",
157
+ "required_action", "output", "output_text", "status"
158
+ ],
159
+ "choices": {
160
+ "required": true,
161
+ "message": {
162
+ "allow": ["role", "content", "reasoning_content", "audio", "tool_calls"],
163
+ "roleDefault": "assistant",
164
+ "contentNullWhenToolCalls": true,
165
+ "tool_calls": { "function": { "nameRequired": true, "argumentsType": "string" } }
166
+ },
167
+ "finish_reason": ["stop", "tool_calls", "length", "sensitive", "network_error"]
168
+ },
169
+ "usage": { "allow": ["prompt_tokens", "completion_tokens", "prompt_tokens_details", "total_tokens"] }
170
+ }
171
+ }
150
172
  },
151
- "assistantToolCalls": { "functionArgumentsType": "string" }
152
- },
153
- "response": {
154
- "allowTopLevel": [
155
- "id", "request_id", "created", "model",
156
- "choices", "usage", "video_result", "web_search", "content_filter",
157
- "required_action", "output", "output_text", "status"
158
- ],
159
- "choices": {
160
- "required": true,
161
- "message": {
162
- "allow": ["role", "content", "reasoning_content", "audio", "tool_calls"],
163
- "roleDefault": "assistant",
164
- "contentNullWhenToolCalls": true,
165
- "tool_calls": { "function": { "nameRequired": true, "argumentsType": "string" } }
166
- },
167
- "finish_reason": ["stop", "tool_calls", "length", "sensitive", "network_error"]
173
+ {
174
+ "action": "field_map",
175
+ "direction": "outgoing",
176
+ "config": [
177
+ { "sourcePath": "usage.input_tokens", "targetPath": "usage.prompt_tokens", "type": "number" },
178
+ { "sourcePath": "usage.output_tokens", "targetPath": "usage.completion_tokens", "type": "number" },
179
+ { "sourcePath": "usage.total_input_tokens", "targetPath": "usage.prompt_tokens", "type": "number" },
180
+ { "sourcePath": "usage.total_output_tokens", "targetPath": "usage.completion_tokens", "type": "number" },
181
+ { "sourcePath": "created_at", "targetPath": "created", "type": "number" },
182
+ { "sourcePath": "request_id", "targetPath": "request_id", "type": "string" },
183
+ {
184
+ "sourcePath": "choices[*].finish_reason",
185
+ "targetPath": "choices[*].finish_reason",
186
+ "type": "string",
187
+ "transform": "normalizeFinishReason"
188
+ },
189
+ {
190
+ "sourcePath": "choices[*].message.tool_calls[*].function.arguments",
191
+ "targetPath": "choices[*].message.tool_calls[*].function.arguments",
192
+ "type": "string"
193
+ }
194
+ ]
168
195
  },
169
- "usage": { "allow": ["prompt_tokens", "completion_tokens", "prompt_tokens_details", "total_tokens"] }
170
- }
171
- }
172
- },
173
- {
174
- "action": "field_map",
175
- "direction": "outgoing",
176
- "config": [
177
- { "sourcePath": "usage.input_tokens", "targetPath": "usage.prompt_tokens", "type": "number" },
178
- { "sourcePath": "usage.output_tokens", "targetPath": "usage.completion_tokens", "type": "number" },
179
- { "sourcePath": "usage.total_input_tokens", "targetPath": "usage.prompt_tokens", "type": "number" },
180
- { "sourcePath": "usage.total_output_tokens", "targetPath": "usage.completion_tokens", "type": "number" },
181
- { "sourcePath": "created_at", "targetPath": "created", "type": "number" },
182
- { "sourcePath": "request_id", "targetPath": "request_id", "type": "string" },
183
- {
184
- "sourcePath": "choices[*].finish_reason",
185
- "targetPath": "choices[*].finish_reason",
186
- "type": "string",
187
- "transform": "normalizeFinishReason"
188
- },
189
- {
190
- "sourcePath": "choices[*].message.tool_calls[*].function.arguments",
191
- "targetPath": "choices[*].message.tool_calls[*].function.arguments",
192
- "type": "string"
193
- }
196
+ { "action": "tool_schema_sanitize", "mode": "glm_shell" },
197
+ { "action": "response_normalize" },
198
+ { "action": "extract_glm_tool_markup" },
199
+ { "action": "response_validate" },
200
+ { "action": "snapshot", "phase": "compat-post" },
201
+ { "action": "dto_rewrap" }
194
202
  ]
195
- },
196
- { "action": "tool_schema_sanitize", "mode": "glm_shell" },
197
- { "action": "response_normalize" },
198
- { "action": "extract_glm_tool_markup" },
199
- { "action": "response_validate" },
200
- { "action": "snapshot", "phase": "compat-post" },
201
- { "action": "dto_rewrap" }
202
- ]
203
- }
203
+ }
204
204
  }
@@ -1,208 +1,208 @@
1
1
  {
2
- "id": "chat:iflow",
3
- "protocol": "openai-chat",
4
- "request": {
5
- "mappings": [
6
- { "action": "snapshot", "phase": "compat-pre" },
7
- { "action": "dto_unwrap" },
8
- {
9
- "action": "remove",
10
- "path": "metadata.toolCallIdStyle"
11
- },
12
- {
13
- "action": "remove",
14
- "path": "metadata.clientModelId"
15
- },
16
- {
17
- "action": "remove",
18
- "path": "metadata.providerHint"
19
- },
20
- {
21
- "action": "shape_filter",
22
- "target": "request",
23
- "config": {
24
- "request": {
25
- "allowTopLevel": [
26
- "model",
27
- "messages",
28
- "stream",
29
- "thinking",
30
- "do_sample",
31
- "temperature",
32
- "top_p",
33
- "max_tokens",
34
- "tools",
35
- "tool_choice",
36
- "stop",
37
- "response_format",
38
- "web_search"
39
- ],
40
- "messages": {
41
- "allowedRoles": ["system", "user", "assistant", "tool"],
42
- "assistantWithToolCallsContentNull": true,
43
- "toolContentStringify": false
2
+ "id": "chat:iflow",
3
+ "protocol": "openai-chat",
4
+ "request": {
5
+ "mappings": [
6
+ { "action": "snapshot", "phase": "compat-pre" },
7
+ { "action": "dto_unwrap" },
8
+ {
9
+ "action": "remove",
10
+ "path": "metadata.toolCallIdStyle"
44
11
  },
45
- "messagesRules": [],
46
- "tools": {
47
- "normalize": false,
48
- "forceToolChoiceAuto": true
12
+ {
13
+ "action": "remove",
14
+ "path": "metadata.clientModelId"
49
15
  },
50
- "assistantToolCalls": { "functionArgumentsType": "string" }
51
- },
52
- "response": {
53
- "allowTopLevel": [
54
- "id",
55
- "request_id",
56
- "created",
57
- "model",
58
- "choices",
59
- "usage",
60
- "video_result",
61
- "web_search",
62
- "content_filter",
63
- "required_action",
64
- "output",
65
- "output_text",
66
- "status"
67
- ],
68
- "choices": {
69
- "required": true,
70
- "message": {
71
- "allow": ["role", "content", "reasoning_content", "audio", "tool_calls"],
72
- "roleDefault": "assistant",
73
- "contentNullWhenToolCalls": true,
74
- "tool_calls": { "function": { "nameRequired": true, "argumentsType": "string" } }
75
- },
76
- "finish_reason": ["stop", "tool_calls", "length", "sensitive", "network_error"]
16
+ {
17
+ "action": "remove",
18
+ "path": "metadata.providerHint"
77
19
  },
78
- "usage": {
79
- "allow": ["prompt_tokens", "completion_tokens", "prompt_tokens_details", "total_tokens"]
80
- }
81
- }
82
- }
83
- },
84
- {
85
- "action": "field_map",
86
- "direction": "incoming",
87
- "config": [
88
- { "sourcePath": "usage.prompt_tokens", "targetPath": "usage.input_tokens", "type": "number" },
89
- { "sourcePath": "usage.completion_tokens", "targetPath": "usage.output_tokens", "type": "number" },
90
- { "sourcePath": "created", "targetPath": "created_at", "type": "number" },
91
- { "sourcePath": "request_id", "targetPath": "request_id", "type": "string" },
92
- {
93
- "sourcePath": "model",
94
- "targetPath": "model",
95
- "type": "string",
96
- "transform": "normalizeModelName"
97
- },
98
- {
99
- "sourcePath": "choices[*].message.tool_calls[*].function.arguments",
100
- "targetPath": "choices[*].message.tool_calls[*].function.arguments",
101
- "type": "string"
102
- }
103
- ]
104
- },
105
- { "action": "tool_schema_sanitize", "mode": "glm_shell" },
106
- {
107
- "action": "iflow_web_search_request"
108
- },
109
- { "action": "snapshot", "phase": "compat-post" },
110
- { "action": "dto_rewrap" }
111
- ]
112
- },
113
- "response": {
114
- "mappings": [
115
- { "action": "snapshot", "phase": "compat-pre" },
116
- { "action": "dto_unwrap" },
117
- {
118
- "action": "shape_filter",
119
- "target": "response",
120
- "config": {
121
- "request": {
122
- "allowTopLevel": [
123
- "model",
124
- "messages",
125
- "stream",
126
- "thinking",
127
- "do_sample",
128
- "temperature",
129
- "top_p",
130
- "max_tokens",
131
- "tools",
132
- "tool_choice",
133
- "stop",
134
- "response_format"
135
- ],
136
- "messages": {
137
- "allowedRoles": ["system", "user", "assistant", "tool"],
138
- "assistantWithToolCallsContentNull": true,
139
- "toolContentStringify": false
20
+ {
21
+ "action": "shape_filter",
22
+ "target": "request",
23
+ "config": {
24
+ "request": {
25
+ "allowTopLevel": [
26
+ "model",
27
+ "messages",
28
+ "stream",
29
+ "thinking",
30
+ "do_sample",
31
+ "temperature",
32
+ "top_p",
33
+ "max_tokens",
34
+ "tools",
35
+ "tool_choice",
36
+ "stop",
37
+ "response_format",
38
+ "web_search"
39
+ ],
40
+ "messages": {
41
+ "allowedRoles": ["system", "user", "assistant", "tool"],
42
+ "assistantWithToolCallsContentNull": true,
43
+ "toolContentStringify": false
44
+ },
45
+ "messagesRules": [],
46
+ "tools": {
47
+ "normalize": false,
48
+ "forceToolChoiceAuto": true
49
+ },
50
+ "assistantToolCalls": { "functionArgumentsType": "string" }
51
+ },
52
+ "response": {
53
+ "allowTopLevel": [
54
+ "id",
55
+ "request_id",
56
+ "created",
57
+ "model",
58
+ "choices",
59
+ "usage",
60
+ "video_result",
61
+ "web_search",
62
+ "content_filter",
63
+ "required_action",
64
+ "output",
65
+ "output_text",
66
+ "status"
67
+ ],
68
+ "choices": {
69
+ "required": true,
70
+ "message": {
71
+ "allow": ["role", "content", "reasoning_content", "audio", "tool_calls"],
72
+ "roleDefault": "assistant",
73
+ "contentNullWhenToolCalls": true,
74
+ "tool_calls": { "function": { "nameRequired": true, "argumentsType": "string" } }
75
+ },
76
+ "finish_reason": ["stop", "tool_calls", "length", "sensitive", "network_error"]
77
+ },
78
+ "usage": {
79
+ "allow": ["prompt_tokens", "completion_tokens", "prompt_tokens_details", "total_tokens"]
80
+ }
81
+ }
82
+ }
83
+ },
84
+ {
85
+ "action": "field_map",
86
+ "direction": "incoming",
87
+ "config": [
88
+ { "sourcePath": "usage.prompt_tokens", "targetPath": "usage.input_tokens", "type": "number" },
89
+ { "sourcePath": "usage.completion_tokens", "targetPath": "usage.output_tokens", "type": "number" },
90
+ { "sourcePath": "created", "targetPath": "created_at", "type": "number" },
91
+ { "sourcePath": "request_id", "targetPath": "request_id", "type": "string" },
92
+ {
93
+ "sourcePath": "model",
94
+ "targetPath": "model",
95
+ "type": "string",
96
+ "transform": "normalizeModelName"
97
+ },
98
+ {
99
+ "sourcePath": "choices[*].message.tool_calls[*].function.arguments",
100
+ "targetPath": "choices[*].message.tool_calls[*].function.arguments",
101
+ "type": "string"
102
+ }
103
+ ]
140
104
  },
141
- "messagesRules": [],
142
- "tools": {
143
- "normalize": false,
144
- "forceToolChoiceAuto": true
105
+ { "action": "tool_schema_sanitize", "mode": "glm_shell" },
106
+ {
107
+ "action": "iflow_web_search_request"
108
+ },
109
+ { "action": "snapshot", "phase": "compat-post" },
110
+ { "action": "dto_rewrap" }
111
+ ]
112
+ },
113
+ "response": {
114
+ "mappings": [
115
+ { "action": "snapshot", "phase": "compat-pre" },
116
+ { "action": "dto_unwrap" },
117
+ {
118
+ "action": "shape_filter",
119
+ "target": "response",
120
+ "config": {
121
+ "request": {
122
+ "allowTopLevel": [
123
+ "model",
124
+ "messages",
125
+ "stream",
126
+ "thinking",
127
+ "do_sample",
128
+ "temperature",
129
+ "top_p",
130
+ "max_tokens",
131
+ "tools",
132
+ "tool_choice",
133
+ "stop",
134
+ "response_format"
135
+ ],
136
+ "messages": {
137
+ "allowedRoles": ["system", "user", "assistant", "tool"],
138
+ "assistantWithToolCallsContentNull": true,
139
+ "toolContentStringify": false
140
+ },
141
+ "messagesRules": [],
142
+ "tools": {
143
+ "normalize": false,
144
+ "forceToolChoiceAuto": true
145
+ },
146
+ "assistantToolCalls": { "functionArgumentsType": "string" }
147
+ },
148
+ "response": {
149
+ "allowTopLevel": [
150
+ "id",
151
+ "request_id",
152
+ "created",
153
+ "model",
154
+ "choices",
155
+ "usage",
156
+ "video_result",
157
+ "web_search",
158
+ "content_filter",
159
+ "required_action",
160
+ "output",
161
+ "output_text",
162
+ "status"
163
+ ],
164
+ "choices": {
165
+ "required": true,
166
+ "message": {
167
+ "allow": ["role", "content", "reasoning_content", "audio", "tool_calls"],
168
+ "roleDefault": "assistant",
169
+ "contentNullWhenToolCalls": true,
170
+ "tool_calls": { "function": { "nameRequired": true, "argumentsType": "string" } }
171
+ },
172
+ "finish_reason": ["stop", "tool_calls", "length", "sensitive", "network_error"]
173
+ },
174
+ "usage": {
175
+ "allow": ["prompt_tokens", "completion_tokens", "prompt_tokens_details", "total_tokens"]
176
+ }
177
+ }
178
+ }
145
179
  },
146
- "assistantToolCalls": { "functionArgumentsType": "string" }
147
- },
148
- "response": {
149
- "allowTopLevel": [
150
- "id",
151
- "request_id",
152
- "created",
153
- "model",
154
- "choices",
155
- "usage",
156
- "video_result",
157
- "web_search",
158
- "content_filter",
159
- "required_action",
160
- "output",
161
- "output_text",
162
- "status"
163
- ],
164
- "choices": {
165
- "required": true,
166
- "message": {
167
- "allow": ["role", "content", "reasoning_content", "audio", "tool_calls"],
168
- "roleDefault": "assistant",
169
- "contentNullWhenToolCalls": true,
170
- "tool_calls": { "function": { "nameRequired": true, "argumentsType": "string" } }
171
- },
172
- "finish_reason": ["stop", "tool_calls", "length", "sensitive", "network_error"]
180
+ {
181
+ "action": "field_map",
182
+ "direction": "outgoing",
183
+ "config": [
184
+ { "sourcePath": "usage.input_tokens", "targetPath": "usage.prompt_tokens", "type": "number" },
185
+ { "sourcePath": "usage.output_tokens", "targetPath": "usage.completion_tokens", "type": "number" },
186
+ { "sourcePath": "usage.total_input_tokens", "targetPath": "usage.prompt_tokens", "type": "number" },
187
+ { "sourcePath": "usage.total_output_tokens", "targetPath": "usage.completion_tokens", "type": "number" },
188
+ { "sourcePath": "created_at", "targetPath": "created", "type": "number" },
189
+ { "sourcePath": "request_id", "targetPath": "request_id", "type": "string" },
190
+ {
191
+ "sourcePath": "choices[*].finish_reason",
192
+ "targetPath": "choices[*].finish_reason",
193
+ "type": "string",
194
+ "transform": "normalizeFinishReason"
195
+ },
196
+ {
197
+ "sourcePath": "choices[*].message.tool_calls[*].function.arguments",
198
+ "targetPath": "choices[*].message.tool_calls[*].function.arguments",
199
+ "type": "string"
200
+ }
201
+ ]
173
202
  },
174
- "usage": {
175
- "allow": ["prompt_tokens", "completion_tokens", "prompt_tokens_details", "total_tokens"]
176
- }
177
- }
178
- }
179
- },
180
- {
181
- "action": "field_map",
182
- "direction": "outgoing",
183
- "config": [
184
- { "sourcePath": "usage.input_tokens", "targetPath": "usage.prompt_tokens", "type": "number" },
185
- { "sourcePath": "usage.output_tokens", "targetPath": "usage.completion_tokens", "type": "number" },
186
- { "sourcePath": "usage.total_input_tokens", "targetPath": "usage.prompt_tokens", "type": "number" },
187
- { "sourcePath": "usage.total_output_tokens", "targetPath": "usage.completion_tokens", "type": "number" },
188
- { "sourcePath": "created_at", "targetPath": "created", "type": "number" },
189
- { "sourcePath": "request_id", "targetPath": "request_id", "type": "string" },
190
- {
191
- "sourcePath": "choices[*].finish_reason",
192
- "targetPath": "choices[*].finish_reason",
193
- "type": "string",
194
- "transform": "normalizeFinishReason"
195
- },
196
- {
197
- "sourcePath": "choices[*].message.tool_calls[*].function.arguments",
198
- "targetPath": "choices[*].message.tool_calls[*].function.arguments",
199
- "type": "string"
200
- }
203
+ { "action": "tool_schema_sanitize", "mode": "glm_shell" },
204
+ { "action": "snapshot", "phase": "compat-post" },
205
+ { "action": "dto_rewrap" }
201
206
  ]
202
- },
203
- { "action": "tool_schema_sanitize", "mode": "glm_shell" },
204
- { "action": "snapshot", "phase": "compat-post" },
205
- { "action": "dto_rewrap" }
206
- ]
207
- }
207
+ }
208
208
  }
@@ -1,45 +1,45 @@
1
1
  {
2
- "id": "chat:lmstudio",
3
- "protocol": "openai-chat",
4
- "request": {
5
- "mappings": [
6
- { "action": "snapshot", "phase": "compat-pre" },
7
- { "action": "dto_unwrap" },
8
- {
9
- "action": "normalize_tool_choice",
10
- "path": "tool_choice",
11
- "objectReplacement": "required"
12
- },
13
- { "action": "snapshot", "phase": "compat-post" },
14
- { "action": "dto_rewrap" }
15
- ]
16
- },
17
- "response": {
18
- "mappings": [
19
- { "action": "snapshot", "phase": "compat-pre" },
20
- { "action": "dto_unwrap" },
21
- {
22
- "action": "set_default",
23
- "path": "object",
24
- "value": "chat.completion"
25
- },
26
- {
27
- "action": "set_default",
28
- "path": "id",
29
- "valueSource": "chat_completion_id"
30
- },
31
- {
32
- "action": "set_default",
33
- "path": "created",
34
- "valueSource": "timestamp_seconds"
35
- },
36
- {
37
- "action": "set_default",
38
- "path": "model",
39
- "value": "unknown"
40
- },
41
- { "action": "snapshot", "phase": "compat-post" },
42
- { "action": "dto_rewrap" }
43
- ]
44
- }
2
+ "id": "chat:lmstudio",
3
+ "protocol": "openai-chat",
4
+ "request": {
5
+ "mappings": [
6
+ { "action": "snapshot", "phase": "compat-pre" },
7
+ { "action": "dto_unwrap" },
8
+ {
9
+ "action": "normalize_tool_choice",
10
+ "path": "tool_choice",
11
+ "objectReplacement": "required"
12
+ },
13
+ { "action": "snapshot", "phase": "compat-post" },
14
+ { "action": "dto_rewrap" }
15
+ ]
16
+ },
17
+ "response": {
18
+ "mappings": [
19
+ { "action": "snapshot", "phase": "compat-pre" },
20
+ { "action": "dto_unwrap" },
21
+ {
22
+ "action": "set_default",
23
+ "path": "object",
24
+ "value": "chat.completion"
25
+ },
26
+ {
27
+ "action": "set_default",
28
+ "path": "id",
29
+ "valueSource": "chat_completion_id"
30
+ },
31
+ {
32
+ "action": "set_default",
33
+ "path": "created",
34
+ "valueSource": "timestamp_seconds"
35
+ },
36
+ {
37
+ "action": "set_default",
38
+ "path": "model",
39
+ "value": "unknown"
40
+ },
41
+ { "action": "snapshot", "phase": "compat-post" },
42
+ { "action": "dto_rewrap" }
43
+ ]
44
+ }
45
45
  }
@@ -1,22 +1,22 @@
1
1
  {
2
- "id": "chat:qwen",
3
- "protocol": "openai-chat",
4
- "request": {
5
- "mappings": [
6
- { "action": "snapshot", "phase": "compat-pre" },
7
- { "action": "dto_unwrap" },
8
- { "action": "qwen_request_transform" },
9
- { "action": "snapshot", "phase": "compat-post" },
10
- { "action": "dto_rewrap" }
11
- ]
12
- },
13
- "response": {
14
- "mappings": [
15
- { "action": "snapshot", "phase": "compat-pre" },
16
- { "action": "dto_unwrap" },
17
- { "action": "qwen_response_transform" },
18
- { "action": "snapshot", "phase": "compat-post" },
19
- { "action": "dto_rewrap" }
20
- ]
21
- }
2
+ "id": "chat:qwen",
3
+ "protocol": "openai-chat",
4
+ "request": {
5
+ "mappings": [
6
+ { "action": "snapshot", "phase": "compat-pre" },
7
+ { "action": "dto_unwrap" },
8
+ { "action": "qwen_request_transform" },
9
+ { "action": "snapshot", "phase": "compat-post" },
10
+ { "action": "dto_rewrap" }
11
+ ]
12
+ },
13
+ "response": {
14
+ "mappings": [
15
+ { "action": "snapshot", "phase": "compat-pre" },
16
+ { "action": "dto_unwrap" },
17
+ { "action": "qwen_response_transform" },
18
+ { "action": "snapshot", "phase": "compat-post" },
19
+ { "action": "dto_rewrap" }
20
+ ]
21
+ }
22
22
  }
@@ -1,45 +1,45 @@
1
1
  {
2
- "id": "responses:c4m",
3
- "protocol": "openai-responses",
4
- "request": {
5
- "mappings": [
6
- {
7
- "action": "remove",
8
- "path": "max_tokens"
9
- },
10
- {
11
- "action": "remove",
12
- "path": "maxTokens"
13
- },
14
- {
15
- "action": "remove",
16
- "path": "max_output_tokens"
17
- },
18
- {
19
- "action": "remove",
20
- "path": "maxOutputTokens"
21
- },
22
- {
23
- "action": "inject_instruction",
24
- "sourcePath": "instructions",
25
- "targetPath": "input",
26
- "role": "system",
27
- "contentType": "input_text",
28
- "stripHtml": true,
29
- "maxLengthEnv": [
30
- "ROUTECODEX_C4M_INSTRUCTIONS_MAX",
31
- "RCC_C4M_INSTRUCTIONS_MAX",
32
- "ROUTECODEX_COMPAT_INSTRUCTIONS_MAX"
2
+ "id": "responses:c4m",
3
+ "protocol": "openai-responses",
4
+ "request": {
5
+ "mappings": [
6
+ {
7
+ "action": "remove",
8
+ "path": "max_tokens"
9
+ },
10
+ {
11
+ "action": "remove",
12
+ "path": "maxTokens"
13
+ },
14
+ {
15
+ "action": "remove",
16
+ "path": "max_output_tokens"
17
+ },
18
+ {
19
+ "action": "remove",
20
+ "path": "maxOutputTokens"
21
+ },
22
+ {
23
+ "action": "inject_instruction",
24
+ "sourcePath": "instructions",
25
+ "targetPath": "input",
26
+ "role": "system",
27
+ "contentType": "input_text",
28
+ "stripHtml": true,
29
+ "maxLengthEnv": [
30
+ "ROUTECODEX_C4M_INSTRUCTIONS_MAX",
31
+ "RCC_C4M_INSTRUCTIONS_MAX",
32
+ "ROUTECODEX_COMPAT_INSTRUCTIONS_MAX"
33
+ ]
34
+ }
33
35
  ]
34
- }
35
- ]
36
- },
37
- "response": {
38
- "filters": [
39
- {
40
- "action": "rate_limit_text",
41
- "needle": "The Codex-For.ME service is available, but you have reached the request limit"
42
- }
43
- ]
44
- }
36
+ },
37
+ "response": {
38
+ "filters": [
39
+ {
40
+ "action": "rate_limit_text",
41
+ "needle": "The Codex-For.ME service is available, but you have reached the request limit"
42
+ }
43
+ ]
44
+ }
45
45
  }
@@ -1,12 +1,11 @@
1
1
  {
2
- "id": "responses:output2choices-test",
3
- "protocol": "openai-responses",
4
- "response": {
5
- "mappings": [
6
- {
7
- "action": "convert_responses_output_to_choices"
8
- }
9
- ]
10
- }
2
+ "id": "responses:output2choices-test",
3
+ "protocol": "openai-responses",
4
+ "response": {
5
+ "mappings": [
6
+ {
7
+ "action": "convert_responses_output_to_choices"
8
+ }
9
+ ]
10
+ }
11
11
  }
12
-
@@ -1,4 +1,4 @@
1
- export type ProviderProtocolErrorCode = 'TOOL_PROTOCOL_ERROR' | 'SSE_DECODE_ERROR' | 'MALFORMED_RESPONSE' | 'MALFORMED_REQUEST' | 'SERVERTOOL_FOLLOWUP_FAILED';
1
+ export type ProviderProtocolErrorCode = 'TOOL_PROTOCOL_ERROR' | 'SSE_DECODE_ERROR' | 'MALFORMED_RESPONSE' | 'MALFORMED_REQUEST' | 'SERVERTOOL_FOLLOWUP_FAILED' | 'SERVERTOOL_TIMEOUT' | 'SERVERTOOL_HANDLER_FAILED';
2
2
  export type ProviderErrorCategory = 'EXTERNAL_ERROR' | 'TOOL_ERROR' | 'INTERNAL_ERROR';
3
3
  export interface ProviderProtocolErrorOptions {
4
4
  code: ProviderProtocolErrorCode;
@@ -2,6 +2,9 @@ function inferCategoryFromCode(code) {
2
2
  switch (code) {
3
3
  case 'TOOL_PROTOCOL_ERROR':
4
4
  return 'TOOL_ERROR';
5
+ case 'SERVERTOOL_TIMEOUT':
6
+ case 'SERVERTOOL_HANDLER_FAILED':
7
+ return 'INTERNAL_ERROR';
5
8
  case 'SSE_DECODE_ERROR':
6
9
  case 'MALFORMED_RESPONSE':
7
10
  case 'MALFORMED_REQUEST':
@@ -3,7 +3,64 @@ import { ProviderProtocolError } from '../conversion/shared/errors.js';
3
3
  import { createHash } from 'node:crypto';
4
4
  import { loadRoutingInstructionStateSync, saveRoutingInstructionStateSync } from '../router/virtual-router/sticky-session-store.js';
5
5
  import { deserializeRoutingInstructionState, serializeRoutingInstructionState } from '../router/virtual-router/routing-instructions.js';
6
+ function parseTimeoutMs(raw, fallback) {
7
+ const n = typeof raw === 'string' ? Number(raw.trim()) : typeof raw === 'number' ? raw : NaN;
8
+ if (!Number.isFinite(n) || n <= 0) {
9
+ return fallback;
10
+ }
11
+ return Math.floor(n);
12
+ }
13
+ function resolveServerToolTimeoutMs() {
14
+ return parseTimeoutMs(process.env.ROUTECODEX_SERVERTOOL_TIMEOUT_MS ||
15
+ process.env.RCC_SERVERTOOL_TIMEOUT_MS ||
16
+ process.env.LLMSWITCH_SERVERTOOL_TIMEOUT_MS, 500_000);
17
+ }
18
+ function resolveServerToolFollowupTimeoutMs(fallback) {
19
+ return parseTimeoutMs(process.env.ROUTECODEX_SERVERTOOL_FOLLOWUP_TIMEOUT_MS ||
20
+ process.env.RCC_SERVERTOOL_FOLLOWUP_TIMEOUT_MS ||
21
+ process.env.LLMSWITCH_SERVERTOOL_FOLLOWUP_TIMEOUT_MS, fallback);
22
+ }
23
+ function withTimeout(promise, timeoutMs, buildError) {
24
+ if (!Number.isFinite(timeoutMs) || timeoutMs <= 0) {
25
+ return promise;
26
+ }
27
+ let timer;
28
+ return new Promise((resolve, reject) => {
29
+ timer = setTimeout(() => reject(buildError()), timeoutMs);
30
+ promise.then(resolve, reject).finally(() => {
31
+ if (timer) {
32
+ clearTimeout(timer);
33
+ timer = undefined;
34
+ }
35
+ });
36
+ });
37
+ }
38
+ function isServerToolTimeoutError(error) {
39
+ return Boolean(error &&
40
+ typeof error === 'object' &&
41
+ typeof error.code === 'string' &&
42
+ error.code === 'SERVERTOOL_TIMEOUT');
43
+ }
44
+ function createServerToolTimeoutError(options) {
45
+ const err = new ProviderProtocolError(`[servertool] ${options.phase} timeout after ${options.timeoutMs}ms` +
46
+ (options.flowId ? ` flow=${options.flowId}` : ''), {
47
+ code: 'SERVERTOOL_TIMEOUT',
48
+ category: 'INTERNAL_ERROR',
49
+ details: {
50
+ requestId: options.requestId,
51
+ phase: options.phase,
52
+ flowId: options.flowId,
53
+ timeoutMs: options.timeoutMs,
54
+ attempt: options.attempt,
55
+ maxAttempts: options.maxAttempts
56
+ }
57
+ });
58
+ err.status = 504;
59
+ return err;
60
+ }
6
61
  export async function runServerToolOrchestration(options) {
62
+ const serverToolTimeoutMs = resolveServerToolTimeoutMs();
63
+ const followupTimeoutMs = resolveServerToolFollowupTimeoutMs(serverToolTimeoutMs);
7
64
  const engineOptions = {
8
65
  chatResponse: options.chat,
9
66
  adapterContext: options.adapterContext,
@@ -13,7 +70,11 @@ export async function runServerToolOrchestration(options) {
13
70
  providerInvoker: options.providerInvoker,
14
71
  reenterPipeline: options.reenterPipeline
15
72
  };
16
- const engineResult = await runServerSideToolEngine(engineOptions);
73
+ const engineResult = await withTimeout(runServerSideToolEngine(engineOptions), serverToolTimeoutMs, () => createServerToolTimeoutError({
74
+ requestId: options.requestId,
75
+ phase: 'engine',
76
+ timeoutMs: serverToolTimeoutMs
77
+ }));
17
78
  if (engineResult.mode === 'passthrough' || !engineResult.execution) {
18
79
  return {
19
80
  chat: engineResult.finalChatResponse,
@@ -70,12 +131,19 @@ export async function runServerToolOrchestration(options) {
70
131
  if (isStopMessageFlow) {
71
132
  reservation = reserveStopMessageUsage(options.adapterContext);
72
133
  }
73
- followup = await options.reenterPipeline({
134
+ followup = await withTimeout(options.reenterPipeline({
74
135
  entryEndpoint: followupEntryEndpoint,
75
136
  requestId: followupRequestId,
76
137
  body: engineResult.execution.followup.payload,
77
138
  metadata
78
- });
139
+ }), followupTimeoutMs, () => createServerToolTimeoutError({
140
+ requestId: options.requestId,
141
+ phase: 'followup',
142
+ timeoutMs: followupTimeoutMs,
143
+ flowId: engineResult.execution.flowId,
144
+ attempt,
145
+ maxAttempts
146
+ }));
79
147
  lastError = undefined;
80
148
  break;
81
149
  }
@@ -84,6 +152,9 @@ export async function runServerToolOrchestration(options) {
84
152
  rollbackStopMessageUsage(reservation);
85
153
  reservation = null;
86
154
  }
155
+ if (isServerToolTimeoutError(error)) {
156
+ throw error;
157
+ }
87
158
  lastError = error;
88
159
  if (attempt >= maxAttempts) {
89
160
  const wrapped = new ProviderProtocolError(`[servertool] Followup failed for flow ${engineResult.execution.flowId ?? 'unknown'} ` +
@@ -1,4 +1,5 @@
1
1
  import { getServerToolHandler, listAutoServerToolHandlers } from './registry.js';
2
+ import { ProviderProtocolError } from '../conversion/shared/errors.js';
2
3
  import './handlers/web-search.js';
3
4
  import './handlers/vision.js';
4
5
  import './handlers/iflow-model-error-retry.js';
@@ -49,14 +50,24 @@ async function runHandler(handler, ctx) {
49
50
  return await handler(ctx);
50
51
  }
51
52
  catch (error) {
52
- try {
53
- // eslint-disable-next-line no-console
54
- console.error('[servertool] handler failed', error);
55
- }
56
- catch {
57
- /* logging best-effort */
58
- }
59
- return null;
53
+ const toolName = ctx && ctx.toolCall && typeof ctx.toolCall.name === 'string' && ctx.toolCall.name.trim()
54
+ ? ctx.toolCall.name.trim()
55
+ : 'auto';
56
+ const message = error instanceof Error ? error.message : String(error ?? 'unknown');
57
+ const wrapped = new ProviderProtocolError(`[servertool] handler failed: ${toolName}: ${message}`, {
58
+ code: 'SERVERTOOL_HANDLER_FAILED',
59
+ category: 'INTERNAL_ERROR',
60
+ details: {
61
+ toolName,
62
+ requestId: ctx.options?.requestId,
63
+ entryEndpoint: ctx.options?.entryEndpoint,
64
+ providerProtocol: ctx.options?.providerProtocol,
65
+ error: message
66
+ }
67
+ });
68
+ wrapped.status = 500;
69
+ wrapped.cause = error;
70
+ throw wrapped;
60
71
  }
61
72
  }
62
73
  export function extractToolCalls(chatResponse) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jsonstudio/llms",
3
- "version": "0.6.749",
3
+ "version": "0.6.753",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.js",