@jsonstudio/llms 0.6.199 → 0.6.203

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.
@@ -0,0 +1,2 @@
1
+ import type { JsonObject } from '../../hub/types/json.js';
2
+ export declare function extractGlmToolMarkup(root: JsonObject): void;
@@ -0,0 +1,264 @@
1
+ function flattenContent(content, depth = 0) {
2
+ if (depth > 4 || content == null) {
3
+ return '';
4
+ }
5
+ if (typeof content === 'string') {
6
+ return content;
7
+ }
8
+ if (Array.isArray(content)) {
9
+ return content.map((entry) => flattenContent(entry, depth + 1)).join('');
10
+ }
11
+ if (typeof content === 'object') {
12
+ const record = content;
13
+ if (typeof record.text === 'string') {
14
+ return record.text;
15
+ }
16
+ if (record.content !== undefined) {
17
+ return flattenContent(record.content, depth + 1);
18
+ }
19
+ }
20
+ return '';
21
+ }
22
+ const GLM_CUSTOM_TAG = /<tool_call(?:\s+name="([^"]+)")?>([\s\S]*?)<\/tool_call>/gi;
23
+ const GLM_TAGGED_SEQUENCE = /<tool_call(?:\s+name="([^"]+)")?\s*>([\s\S]*?)(?:<\/tool_call>|(?=<tool_call)|$)/gi;
24
+ const GLM_TAGGED_BLOCK = /<arg_key>([\s\S]*?)<\/arg_key>\s*<arg_value>([\s\S]*?)<\/arg_value>/gi;
25
+ const GLM_INLINE_NAME = /^[\s\r\n]*([A-Za-z0-9_.:-]+)/;
26
+ const GENERIC_PATTERNS = [
27
+ [
28
+ /```(?:tool|function|tool_call|function_call)?\s*([\s\S]*?)\s*```/gi,
29
+ (match) => ({ body: match[1] ?? '' })
30
+ ],
31
+ [
32
+ /\[(tool_call|function_call)(?:\s+name="([^"]+)")?\]([\s\S]*?)\[\/\1\]/gi,
33
+ (match) => ({ body: match[3] ?? '', nameHint: match[2] })
34
+ ],
35
+ [
36
+ /(tool_call|function_call)\s*[:=]\s*({[\s\S]+?})/gi,
37
+ (match) => ({ body: match[2] ?? '' })
38
+ ]
39
+ ];
40
+ export function extractGlmToolMarkup(root) {
41
+ const choicesRaw = root?.choices;
42
+ const choices = Array.isArray(choicesRaw) ? choicesRaw : [];
43
+ choices.forEach((choice, index) => {
44
+ if (!choice || typeof choice !== 'object') {
45
+ return;
46
+ }
47
+ const message = choice.message;
48
+ if (!message || typeof message !== 'object') {
49
+ return;
50
+ }
51
+ const msgRecord = message;
52
+ const contentField = msgRecord.content;
53
+ const reasoningField = msgRecord.reasoning_content;
54
+ const text = contentField !== undefined
55
+ ? flattenContent(contentField)
56
+ : typeof reasoningField === 'string'
57
+ ? reasoningField
58
+ : '';
59
+ if (!text) {
60
+ return;
61
+ }
62
+ const extraction = extractToolCallsFromText(text, index + 1);
63
+ if (!extraction) {
64
+ return;
65
+ }
66
+ if (extraction.toolCalls.length) {
67
+ msgRecord.tool_calls = extraction.toolCalls;
68
+ if (contentField !== undefined) {
69
+ msgRecord.content = null;
70
+ }
71
+ }
72
+ if (extraction.reasoningText) {
73
+ msgRecord.reasoning_content = extraction.reasoningText;
74
+ }
75
+ else if ('reasoning_content' in msgRecord) {
76
+ delete msgRecord.reasoning_content;
77
+ }
78
+ });
79
+ }
80
+ function extractToolCallsFromText(text, choiceIndex) {
81
+ const matches = [];
82
+ const applyPattern = (pattern, factory) => {
83
+ pattern.lastIndex = 0;
84
+ let exec;
85
+ while ((exec = pattern.exec(text))) {
86
+ const payload = factory(exec);
87
+ if (!payload)
88
+ continue;
89
+ const parsed = parseToolCall(payload.body, payload.nameHint);
90
+ if (!parsed)
91
+ continue;
92
+ matches.push({
93
+ start: exec.index,
94
+ end: exec.index + exec[0].length,
95
+ call: parsed
96
+ });
97
+ }
98
+ };
99
+ applyPattern(GLM_CUSTOM_TAG, (match) => ({ body: match[2] ?? '', nameHint: match[1] }));
100
+ for (const [pattern, factory] of GENERIC_PATTERNS) {
101
+ applyPattern(pattern, factory);
102
+ }
103
+ applyTaggedArgPatterns(text, matches);
104
+ if (!matches.length && typeof text === 'string' && text.includes('<arg_key>')) {
105
+ GLM_INLINE_NAME.lastIndex = 0;
106
+ const inline = GLM_INLINE_NAME.exec(text);
107
+ GLM_INLINE_NAME.lastIndex = 0;
108
+ if (inline && inline[1]) {
109
+ const name = inline[1].trim();
110
+ const block = text.slice(inline[0].length);
111
+ const argsRecord = parseTaggedArgBlock(block);
112
+ if (name && argsRecord) {
113
+ matches.push({
114
+ start: 0,
115
+ end: text.length,
116
+ call: {
117
+ name,
118
+ args: safeStringify(argsRecord)
119
+ }
120
+ });
121
+ }
122
+ }
123
+ }
124
+ matches.sort((a, b) => a.start - b.start);
125
+ const toolCalls = matches.map((entry, idx) => ({
126
+ id: `glm_tool_${choiceIndex}_${idx + 1}`,
127
+ type: 'function',
128
+ function: {
129
+ name: entry.call.name,
130
+ arguments: entry.call.args
131
+ }
132
+ }));
133
+ matches.sort((a, b) => b.start - a.start);
134
+ let cleaned = text;
135
+ for (const entry of matches) {
136
+ cleaned = cleaned.slice(0, entry.start) + cleaned.slice(entry.end);
137
+ }
138
+ const reasoningText = cleaned.trim();
139
+ return {
140
+ toolCalls,
141
+ reasoningText: reasoningText.length ? reasoningText : undefined
142
+ };
143
+ }
144
+ function parseToolCall(body, nameHint) {
145
+ if (!body || typeof body !== 'string') {
146
+ return null;
147
+ }
148
+ const trimmed = body.trim();
149
+ if (!trimmed.length) {
150
+ return null;
151
+ }
152
+ try {
153
+ const parsed = JSON.parse(trimmed);
154
+ if (!parsed || typeof parsed !== 'object') {
155
+ return null;
156
+ }
157
+ const record = parsed;
158
+ const candidateName = (typeof record.name === 'string' && record.name.trim().length
159
+ ? record.name.trim()
160
+ : undefined) ??
161
+ (typeof record.tool_name === 'string' && record.tool_name.trim().length
162
+ ? record.tool_name.trim()
163
+ : undefined) ??
164
+ (typeof record.tool === 'string' && record.tool.trim().length
165
+ ? record.tool.trim()
166
+ : undefined) ??
167
+ (nameHint && nameHint.trim().length ? nameHint.trim() : undefined);
168
+ if (!candidateName) {
169
+ return null;
170
+ }
171
+ const argsSource = record.arguments ??
172
+ record.input ??
173
+ record.params ??
174
+ record.parameters ??
175
+ record.payload ??
176
+ {};
177
+ let args = '{}';
178
+ if (typeof argsSource === 'string' && argsSource.trim().length) {
179
+ args = argsSource.trim();
180
+ }
181
+ else {
182
+ try {
183
+ args = JSON.stringify(argsSource ?? {});
184
+ }
185
+ catch {
186
+ args = '{}';
187
+ }
188
+ }
189
+ return { name: candidateName, args };
190
+ }
191
+ catch {
192
+ return null;
193
+ }
194
+ }
195
+ function applyTaggedArgPatterns(text, matches) {
196
+ if (!text || typeof text !== 'string') {
197
+ return;
198
+ }
199
+ GLM_TAGGED_SEQUENCE.lastIndex = 0;
200
+ let exec;
201
+ while ((exec = GLM_TAGGED_SEQUENCE.exec(text))) {
202
+ let name = typeof exec[1] === 'string' ? exec[1].trim() : '';
203
+ let block = exec[2] ?? '';
204
+ if (!name) {
205
+ const inline = GLM_INLINE_NAME.exec(block);
206
+ if (inline && inline[1]) {
207
+ name = inline[1].trim();
208
+ block = block.slice(inline[0].length);
209
+ }
210
+ }
211
+ if (!name) {
212
+ continue;
213
+ }
214
+ const argsRecord = parseTaggedArgBlock(block);
215
+ if (!argsRecord) {
216
+ continue;
217
+ }
218
+ matches.push({
219
+ start: exec.index,
220
+ end: exec.index + exec[0].length,
221
+ call: {
222
+ name,
223
+ args: safeStringify(argsRecord)
224
+ }
225
+ });
226
+ }
227
+ }
228
+ function parseTaggedArgBlock(block) {
229
+ if (!block || typeof block !== 'string') {
230
+ return null;
231
+ }
232
+ const record = {};
233
+ GLM_TAGGED_BLOCK.lastIndex = 0;
234
+ let exec;
235
+ while ((exec = GLM_TAGGED_BLOCK.exec(block))) {
236
+ const key = typeof exec[1] === 'string' ? exec[1].trim() : '';
237
+ if (!key) {
238
+ continue;
239
+ }
240
+ const rawValue = typeof exec[2] === 'string' ? exec[2].trim() : '';
241
+ record[key] = coerceTaggedValue(rawValue);
242
+ }
243
+ return Object.keys(record).length ? record : null;
244
+ }
245
+ function coerceTaggedValue(raw) {
246
+ if (!raw) {
247
+ return '';
248
+ }
249
+ const trimmed = raw.trim();
250
+ try {
251
+ return JSON.parse(trimmed);
252
+ }
253
+ catch {
254
+ return trimmed;
255
+ }
256
+ }
257
+ function safeStringify(value) {
258
+ try {
259
+ return JSON.stringify(value ?? {});
260
+ }
261
+ catch {
262
+ return '{}';
263
+ }
264
+ }
@@ -1,191 +1,191 @@
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": "rename",
10
- "from": "response_format",
11
- "to": "metadata.generation.response_format"
12
- },
13
- {
14
- "action": "remove",
15
- "path": "metadata.clientModelId"
16
- },
17
- {
18
- "action": "shape_filter",
19
- "target": "request",
20
- "config": {
21
- "request": {
22
- "allowTopLevel": [
23
- "model", "messages", "stream", "thinking", "do_sample", "temperature", "top_p",
24
- "max_tokens", "tools", "tool_choice", "stop", "response_format"
25
- ],
26
- "messages": {
27
- "allowedRoles": ["system", "user", "assistant", "tool"],
28
- "assistantWithToolCallsContentNull": true,
29
- "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": "rename",
10
+ "from": "response_format",
11
+ "to": "metadata.generation.response_format"
30
12
  },
31
- "messagesRules": [],
32
- "tools": {
33
- "normalize": false,
34
- "forceToolChoiceAuto": true
13
+ {
14
+ "action": "remove",
15
+ "path": "metadata.clientModelId"
35
16
  },
36
- "assistantToolCalls": { "functionArgumentsType": "string" }
37
- },
38
- "response": {
39
- "allowTopLevel": [
40
- "id", "request_id", "created", "model",
41
- "choices", "usage", "video_result", "web_search", "content_filter",
42
- "required_action", "output", "output_text", "status"
43
- ],
44
- "choices": {
45
- "required": true,
46
- "message": {
47
- "allow": ["role", "content", "reasoning_content", "audio", "tool_calls"],
48
- "roleDefault": "assistant",
49
- "contentNullWhenToolCalls": true,
50
- "tool_calls": { "function": { "nameRequired": true, "argumentsType": "string" } }
51
- },
52
- "finish_reason": ["stop", "tool_calls", "length", "sensitive", "network_error"]
17
+ {
18
+ "action": "shape_filter",
19
+ "target": "request",
20
+ "config": {
21
+ "request": {
22
+ "allowTopLevel": [
23
+ "model", "messages", "stream", "thinking", "do_sample", "temperature", "top_p",
24
+ "max_tokens", "tools", "tool_choice", "stop", "response_format"
25
+ ],
26
+ "messages": {
27
+ "allowedRoles": ["system", "user", "assistant", "tool"],
28
+ "assistantWithToolCallsContentNull": true,
29
+ "toolContentStringify": false
30
+ },
31
+ "messagesRules": [],
32
+ "tools": {
33
+ "normalize": false,
34
+ "forceToolChoiceAuto": true
35
+ },
36
+ "assistantToolCalls": { "functionArgumentsType": "string" }
37
+ },
38
+ "response": {
39
+ "allowTopLevel": [
40
+ "id", "request_id", "created", "model",
41
+ "choices", "usage", "video_result", "web_search", "content_filter",
42
+ "required_action", "output", "output_text", "status"
43
+ ],
44
+ "choices": {
45
+ "required": true,
46
+ "message": {
47
+ "allow": ["role", "content", "reasoning_content", "audio", "tool_calls"],
48
+ "roleDefault": "assistant",
49
+ "contentNullWhenToolCalls": true,
50
+ "tool_calls": { "function": { "nameRequired": true, "argumentsType": "string" } }
51
+ },
52
+ "finish_reason": ["stop", "tool_calls", "length", "sensitive", "network_error"]
53
+ },
54
+ "usage": { "allow": ["prompt_tokens", "completion_tokens", "prompt_tokens_details", "total_tokens"] }
55
+ }
56
+ }
53
57
  },
54
- "usage": { "allow": ["prompt_tokens", "completion_tokens", "prompt_tokens_details", "total_tokens"] }
55
- }
56
- }
57
- },
58
- {
59
- "action": "apply_rules",
60
- "config": {
61
- "tools": {
62
- "function": {
63
- "removeKeys": ["strict", "json_schema"]
64
- }
65
- },
66
- "messages": {
67
- "assistantToolCalls": {
68
- "function": {
69
- "removeKeys": ["strict"]
70
- }
71
- }
72
- },
73
- "topLevel": {
74
- "conditional": [
75
- { "when": { "tools": "empty" }, "remove": ["tool_choice"] }
76
- ]
77
- }
78
- }
79
- },
80
- {
81
- "action": "field_map",
82
- "direction": "incoming",
83
- "config": [
84
- { "sourcePath": "usage.prompt_tokens", "targetPath": "usage.input_tokens", "type": "number" },
85
- { "sourcePath": "usage.completion_tokens", "targetPath": "usage.output_tokens", "type": "number" },
86
- { "sourcePath": "created", "targetPath": "created_at", "type": "number" },
87
- { "sourcePath": "request_id", "targetPath": "request_id", "type": "string" },
88
- { "sourcePath": "model", "targetPath": "model", "type": "string", "transform": "normalizeModelName" },
89
- {
90
- "sourcePath": "choices[*].message.tool_calls[*].function.arguments",
91
- "targetPath": "choices[*].message.tool_calls[*].function.arguments",
92
- "type": "string"
93
- }
58
+ {
59
+ "action": "apply_rules",
60
+ "config": {
61
+ "tools": {
62
+ "function": {
63
+ "removeKeys": ["strict", "json_schema"]
64
+ }
65
+ },
66
+ "messages": {
67
+ "assistantToolCalls": {
68
+ "function": {
69
+ "removeKeys": ["strict"]
70
+ }
71
+ }
72
+ },
73
+ "topLevel": {
74
+ "conditional": [
75
+ { "when": { "tools": "empty" }, "remove": ["tool_choice"] }
76
+ ]
77
+ }
78
+ }
79
+ },
80
+ {
81
+ "action": "field_map",
82
+ "direction": "incoming",
83
+ "config": [
84
+ { "sourcePath": "usage.prompt_tokens", "targetPath": "usage.input_tokens", "type": "number" },
85
+ { "sourcePath": "usage.completion_tokens", "targetPath": "usage.output_tokens", "type": "number" },
86
+ { "sourcePath": "created", "targetPath": "created_at", "type": "number" },
87
+ { "sourcePath": "request_id", "targetPath": "request_id", "type": "string" },
88
+ { "sourcePath": "model", "targetPath": "model", "type": "string", "transform": "normalizeModelName" },
89
+ {
90
+ "sourcePath": "choices[*].message.tool_calls[*].function.arguments",
91
+ "targetPath": "choices[*].message.tool_calls[*].function.arguments",
92
+ "type": "string"
93
+ }
94
+ ]
95
+ },
96
+ { "action": "tool_schema_sanitize", "mode": "glm_shell" },
97
+ {
98
+ "action": "auto_thinking",
99
+ "config": {
100
+ "modelPrefixes": ["glm-4.7", "glm-4.6", "glm-4.5", "glm-z1"],
101
+ "excludePrefixes": ["glm-4.6v"]
102
+ }
103
+ },
104
+ { "action": "snapshot", "phase": "compat-post" },
105
+ { "action": "dto_rewrap" }
94
106
  ]
95
- },
96
- { "action": "tool_schema_sanitize", "mode": "glm_shell" },
97
- {
98
- "action": "auto_thinking",
99
- "config": {
100
- "modelPrefixes": ["glm-4.7", "glm-4.6", "glm-4.5", "glm-z1"],
101
- "excludePrefixes": ["glm-4.6v"]
102
- }
103
- },
104
- { "action": "snapshot", "phase": "compat-post" },
105
- { "action": "dto_rewrap" }
106
- ]
107
- },
108
- "response": {
109
- "mappings": [
110
- { "action": "snapshot", "phase": "compat-pre" },
111
- { "action": "dto_unwrap" },
112
- {
113
- "action": "resp_blacklist",
114
- "config": {
115
- "paths": ["usage.prompt_tokens_details.cached_tokens"],
116
- "keepCritical": true
117
- }
118
- },
119
- {
120
- "action": "shape_filter",
121
- "target": "response",
122
- "config": {
123
- "request": {
124
- "allowTopLevel": [
125
- "model", "messages", "stream", "thinking", "do_sample", "temperature", "top_p",
126
- "max_tokens", "tools", "tool_choice", "stop", "response_format"
127
- ],
128
- "messages": {
129
- "allowedRoles": ["system", "user", "assistant", "tool"],
130
- "assistantWithToolCallsContentNull": true,
131
- "toolContentStringify": false
107
+ },
108
+ "response": {
109
+ "mappings": [
110
+ { "action": "snapshot", "phase": "compat-pre" },
111
+ { "action": "dto_unwrap" },
112
+ {
113
+ "action": "resp_blacklist",
114
+ "config": {
115
+ "paths": ["usage.prompt_tokens_details.cached_tokens"],
116
+ "keepCritical": true
117
+ }
132
118
  },
133
- "messagesRules": [],
134
- "tools": {
135
- "normalize": false,
136
- "forceToolChoiceAuto": true
119
+ {
120
+ "action": "shape_filter",
121
+ "target": "response",
122
+ "config": {
123
+ "request": {
124
+ "allowTopLevel": [
125
+ "model", "messages", "stream", "thinking", "do_sample", "temperature", "top_p",
126
+ "max_tokens", "tools", "tool_choice", "stop", "response_format"
127
+ ],
128
+ "messages": {
129
+ "allowedRoles": ["system", "user", "assistant", "tool"],
130
+ "assistantWithToolCallsContentNull": true,
131
+ "toolContentStringify": false
132
+ },
133
+ "messagesRules": [],
134
+ "tools": {
135
+ "normalize": false,
136
+ "forceToolChoiceAuto": true
137
+ },
138
+ "assistantToolCalls": { "functionArgumentsType": "string" }
139
+ },
140
+ "response": {
141
+ "allowTopLevel": [
142
+ "id", "request_id", "created", "model",
143
+ "choices", "usage", "video_result", "web_search", "content_filter",
144
+ "required_action", "output", "output_text", "status"
145
+ ],
146
+ "choices": {
147
+ "required": true,
148
+ "message": {
149
+ "allow": ["role", "content", "reasoning_content", "audio", "tool_calls"],
150
+ "roleDefault": "assistant",
151
+ "contentNullWhenToolCalls": true,
152
+ "tool_calls": { "function": { "nameRequired": true, "argumentsType": "string" } }
153
+ },
154
+ "finish_reason": ["stop", "tool_calls", "length", "sensitive", "network_error"]
155
+ },
156
+ "usage": { "allow": ["prompt_tokens", "completion_tokens", "prompt_tokens_details", "total_tokens"] }
157
+ }
158
+ }
137
159
  },
138
- "assistantToolCalls": { "functionArgumentsType": "string" }
139
- },
140
- "response": {
141
- "allowTopLevel": [
142
- "id", "request_id", "created", "model",
143
- "choices", "usage", "video_result", "web_search", "content_filter",
144
- "required_action", "output", "output_text", "status"
145
- ],
146
- "choices": {
147
- "required": true,
148
- "message": {
149
- "allow": ["role", "content", "reasoning_content", "audio", "tool_calls"],
150
- "roleDefault": "assistant",
151
- "contentNullWhenToolCalls": true,
152
- "tool_calls": { "function": { "nameRequired": true, "argumentsType": "string" } }
153
- },
154
- "finish_reason": ["stop", "tool_calls", "length", "sensitive", "network_error"]
160
+ {
161
+ "action": "field_map",
162
+ "direction": "outgoing",
163
+ "config": [
164
+ { "sourcePath": "usage.input_tokens", "targetPath": "usage.prompt_tokens", "type": "number" },
165
+ { "sourcePath": "usage.output_tokens", "targetPath": "usage.completion_tokens", "type": "number" },
166
+ { "sourcePath": "usage.total_input_tokens", "targetPath": "usage.prompt_tokens", "type": "number" },
167
+ { "sourcePath": "usage.total_output_tokens", "targetPath": "usage.completion_tokens", "type": "number" },
168
+ { "sourcePath": "created_at", "targetPath": "created", "type": "number" },
169
+ { "sourcePath": "request_id", "targetPath": "request_id", "type": "string" },
170
+ {
171
+ "sourcePath": "choices[*].finish_reason",
172
+ "targetPath": "choices[*].finish_reason",
173
+ "type": "string",
174
+ "transform": "normalizeFinishReason"
175
+ },
176
+ {
177
+ "sourcePath": "choices[*].message.tool_calls[*].function.arguments",
178
+ "targetPath": "choices[*].message.tool_calls[*].function.arguments",
179
+ "type": "string"
180
+ }
181
+ ]
155
182
  },
156
- "usage": { "allow": ["prompt_tokens", "completion_tokens", "prompt_tokens_details", "total_tokens"] }
157
- }
158
- }
159
- },
160
- {
161
- "action": "field_map",
162
- "direction": "outgoing",
163
- "config": [
164
- { "sourcePath": "usage.input_tokens", "targetPath": "usage.prompt_tokens", "type": "number" },
165
- { "sourcePath": "usage.output_tokens", "targetPath": "usage.completion_tokens", "type": "number" },
166
- { "sourcePath": "usage.total_input_tokens", "targetPath": "usage.prompt_tokens", "type": "number" },
167
- { "sourcePath": "usage.total_output_tokens", "targetPath": "usage.completion_tokens", "type": "number" },
168
- { "sourcePath": "created_at", "targetPath": "created", "type": "number" },
169
- { "sourcePath": "request_id", "targetPath": "request_id", "type": "string" },
170
- {
171
- "sourcePath": "choices[*].finish_reason",
172
- "targetPath": "choices[*].finish_reason",
173
- "type": "string",
174
- "transform": "normalizeFinishReason"
175
- },
176
- {
177
- "sourcePath": "choices[*].message.tool_calls[*].function.arguments",
178
- "targetPath": "choices[*].message.tool_calls[*].function.arguments",
179
- "type": "string"
180
- }
183
+ { "action": "tool_schema_sanitize", "mode": "glm_shell" },
184
+ { "action": "response_normalize" },
185
+ { "action": "extract_glm_tool_markup" },
186
+ { "action": "response_validate" },
187
+ { "action": "snapshot", "phase": "compat-post" },
188
+ { "action": "dto_rewrap" }
181
189
  ]
182
- },
183
- { "action": "tool_schema_sanitize", "mode": "glm_shell" },
184
- { "action": "response_normalize" },
185
- { "action": "extract_glm_tool_markup" },
186
- { "action": "response_validate" },
187
- { "action": "snapshot", "phase": "compat-post" },
188
- { "action": "dto_rewrap" }
189
- ]
190
- }
190
+ }
191
191
  }