@jsonstudio/llms 0.6.123 → 0.6.141

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:glm",
3
- "protocol": "openai-chat",
4
- "direction": "request",
5
- "mappings": [
6
- {
7
- "action": "rename",
8
- "from": "response_format",
9
- "to": "metadata.generation.response_format"
10
- },
11
- {
12
- "action": "remove",
13
- "path": "metadata.clientModelId"
14
- }
15
- ],
16
- "filters": []
2
+ "id": "chat:glm",
3
+ "protocol": "openai-chat",
4
+ "direction": "request",
5
+ "mappings": [
6
+ {
7
+ "action": "rename",
8
+ "from": "response_format",
9
+ "to": "metadata.generation.response_format"
10
+ },
11
+ {
12
+ "action": "remove",
13
+ "path": "metadata.clientModelId"
14
+ }
15
+ ],
16
+ "filters": []
17
17
  }
@@ -1,36 +1,36 @@
1
1
  {
2
- "id": "chat:iflow",
3
- "protocol": "openai-chat",
4
- "request": {
5
- "mappings": [
6
- {
7
- "action": "remove",
8
- "path": "metadata.toolCallIdStyle"
9
- },
10
- {
11
- "action": "remove",
12
- "path": "metadata.clientModelId"
13
- },
14
- {
15
- "action": "remove",
16
- "path": "metadata.providerHint"
17
- }
18
- ]
19
- },
20
- "response": {
21
- "mappings": [
22
- {
23
- "action": "rename",
24
- "from": "created_at",
25
- "to": "created"
26
- },
27
- {
28
- "action": "convert_responses_output_to_choices"
29
- },
30
- {
31
- "action": "stringify",
32
- "path": "choices[*].message.tool_calls[*].function.arguments"
33
- }
34
- ]
35
- }
2
+ "id": "chat:iflow",
3
+ "protocol": "openai-chat",
4
+ "request": {
5
+ "mappings": [
6
+ {
7
+ "action": "remove",
8
+ "path": "metadata.toolCallIdStyle"
9
+ },
10
+ {
11
+ "action": "remove",
12
+ "path": "metadata.clientModelId"
13
+ },
14
+ {
15
+ "action": "remove",
16
+ "path": "metadata.providerHint"
17
+ }
18
+ ]
19
+ },
20
+ "response": {
21
+ "mappings": [
22
+ {
23
+ "action": "rename",
24
+ "from": "created_at",
25
+ "to": "created"
26
+ },
27
+ {
28
+ "action": "convert_responses_output_to_choices"
29
+ },
30
+ {
31
+ "action": "stringify",
32
+ "path": "choices[*].message.tool_calls[*].function.arguments"
33
+ }
34
+ ]
35
+ }
36
36
  }
@@ -1,37 +1,37 @@
1
1
  {
2
- "id": "chat:lmstudio",
3
- "protocol": "openai-chat",
4
- "request": {
5
- "mappings": [
6
- {
7
- "action": "normalize_tool_choice",
8
- "path": "tool_choice",
9
- "objectReplacement": "required"
10
- }
11
- ]
12
- },
13
- "response": {
14
- "mappings": [
15
- {
16
- "action": "set_default",
17
- "path": "object",
18
- "value": "chat.completion"
19
- },
20
- {
21
- "action": "set_default",
22
- "path": "id",
23
- "valueSource": "chat_completion_id"
24
- },
25
- {
26
- "action": "set_default",
27
- "path": "created",
28
- "valueSource": "timestamp_seconds"
29
- },
30
- {
31
- "action": "set_default",
32
- "path": "model",
33
- "value": "unknown"
34
- }
35
- ]
36
- }
2
+ "id": "chat:lmstudio",
3
+ "protocol": "openai-chat",
4
+ "request": {
5
+ "mappings": [
6
+ {
7
+ "action": "normalize_tool_choice",
8
+ "path": "tool_choice",
9
+ "objectReplacement": "required"
10
+ }
11
+ ]
12
+ },
13
+ "response": {
14
+ "mappings": [
15
+ {
16
+ "action": "set_default",
17
+ "path": "object",
18
+ "value": "chat.completion"
19
+ },
20
+ {
21
+ "action": "set_default",
22
+ "path": "id",
23
+ "valueSource": "chat_completion_id"
24
+ },
25
+ {
26
+ "action": "set_default",
27
+ "path": "created",
28
+ "valueSource": "timestamp_seconds"
29
+ },
30
+ {
31
+ "action": "set_default",
32
+ "path": "model",
33
+ "value": "unknown"
34
+ }
35
+ ]
36
+ }
37
37
  }
@@ -1,18 +1,18 @@
1
1
  {
2
- "id": "chat:qwen",
3
- "protocol": "openai-chat",
4
- "request": {
5
- "mappings": [
6
- {
7
- "action": "parse_json",
8
- "path": "messages[*].tool_calls[*].function.arguments",
9
- "fallback": {}
10
- },
11
- {
12
- "action": "stringify",
13
- "path": "messages[*].tool_calls[*].function.arguments",
14
- "fallback": {}
15
- }
16
- ]
17
- }
2
+ "id": "chat:qwen",
3
+ "protocol": "openai-chat",
4
+ "request": {
5
+ "mappings": [
6
+ {
7
+ "action": "parse_json",
8
+ "path": "messages[*].tool_calls[*].function.arguments",
9
+ "fallback": {}
10
+ },
11
+ {
12
+ "action": "stringify",
13
+ "path": "messages[*].tool_calls[*].function.arguments",
14
+ "fallback": {}
15
+ }
16
+ ]
17
+ }
18
18
  }
@@ -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
  }
@@ -227,9 +227,48 @@ function normalizeResponsesConfig(provider) {
227
227
  if (!node) {
228
228
  return undefined;
229
229
  }
230
+ const config = {};
230
231
  const rawStyle = typeof node.toolCallIdStyle === 'string' ? node.toolCallIdStyle.trim().toLowerCase() : undefined;
231
232
  if (rawStyle === 'fc' || rawStyle === 'preserve') {
232
- return { toolCallIdStyle: rawStyle };
233
+ config.toolCallIdStyle = rawStyle;
234
+ }
235
+ const streaming = normalizeResponsesStreaming(node.streaming);
236
+ if (streaming) {
237
+ config.streaming = streaming;
238
+ }
239
+ const instructionsMode = normalizeResponsesInstructionsMode(node.instructionsMode);
240
+ if (instructionsMode) {
241
+ config.instructionsMode = instructionsMode;
242
+ }
243
+ return Object.keys(config).length ? config : undefined;
244
+ }
245
+ function normalizeResponsesStreaming(value) {
246
+ if (value === true) {
247
+ return 'always';
248
+ }
249
+ if (value === false) {
250
+ return 'never';
251
+ }
252
+ if (typeof value === 'string') {
253
+ const normalized = value.trim().toLowerCase();
254
+ if (normalized === 'always' || normalized === 'true' || normalized === '1' || normalized === 'yes') {
255
+ return 'always';
256
+ }
257
+ if (normalized === 'never' || normalized === 'false' || normalized === '0' || normalized === 'no') {
258
+ return 'never';
259
+ }
260
+ if (normalized === 'auto') {
261
+ return 'auto';
262
+ }
263
+ }
264
+ return undefined;
265
+ }
266
+ function normalizeResponsesInstructionsMode(value) {
267
+ if (value === 'inline') {
268
+ return 'inline';
269
+ }
270
+ if (typeof value === 'string' && value.trim().toLowerCase() === 'inline') {
271
+ return 'inline';
233
272
  }
234
273
  return undefined;
235
274
  }
@@ -31,14 +31,15 @@ export class RoutingClassifier {
31
31
  const hasOtherToolCall = toolCategories.includes('other');
32
32
  const hasToolCall = toolCategories.length > 0;
33
33
  const reachedLongContext = features.estimatedTokens >= (this.config.longContextThresholdTokens ?? DEFAULT_LONG_CONTEXT_THRESHOLD);
34
- const thinkingKeywordHit = features.hasThinkingKeyword ||
35
- containsKeywords(features.userTextSample, this.config.thinkingKeywords ?? []);
36
34
  const routeHint = typeof features.metadata?.routeHint === 'string'
37
35
  ? features.metadata.routeHint.trim().toLowerCase()
38
36
  : undefined;
39
37
  const websearchKeywordHit = containsKeywords(features.userTextSample, WEBSEARCH_HINT_KEYWORDS);
40
38
  const codingContinuation = hasWriteToolCall || lastToolCategory === 'write';
41
39
  const thinkingContinuation = hasReadToolCall || lastToolCategory === 'read';
40
+ const userInputDetected = typeof features.userTextSample === 'string'
41
+ ? features.userTextSample.trim().length > 0
42
+ : false;
42
43
  const searchContinuation = features.assistantCalledWebSearchTool === true;
43
44
  const toolsContinuation = hasOtherToolCall ||
44
45
  searchContinuation ||
@@ -46,6 +47,11 @@ export class RoutingClassifier {
46
47
  const toolContinuationReason = hasOtherToolCall
47
48
  ? formatToolContinuationReason(features.lastAssistantToolName, features.lastAssistantToolDetail)
48
49
  : 'tools:tool-call-detected';
50
+ const thinkingReason = thinkingContinuation
51
+ ? 'thinking:last-tool-read'
52
+ : userInputDetected
53
+ ? 'thinking:user-input'
54
+ : 'thinking';
49
55
  const evaluationMap = {
50
56
  vision: {
51
57
  triggered: features.hasVisionTool && features.hasImageAttachment,
@@ -64,8 +70,8 @@ export class RoutingClassifier {
64
70
  reason: 'coding:last-tool-write'
65
71
  },
66
72
  thinking: {
67
- triggered: thinkingContinuation || thinkingKeywordHit,
68
- reason: thinkingContinuation ? 'thinking:last-tool-read' : 'thinking:keywords'
73
+ triggered: thinkingContinuation || userInputDetected,
74
+ reason: thinkingReason
69
75
  },
70
76
  tools: {
71
77
  triggered: toolsContinuation,
@@ -148,8 +148,11 @@ export interface TargetMetadata {
148
148
  processMode?: 'chat' | 'passthrough';
149
149
  responsesConfig?: ResponsesProviderConfig;
150
150
  }
151
+ export type ResponsesStreamingMode = 'auto' | 'always' | 'never';
151
152
  export interface ResponsesProviderConfig {
152
153
  toolCallIdStyle?: 'fc' | 'preserve';
154
+ streaming?: ResponsesStreamingMode;
155
+ instructionsMode?: 'default' | 'inline';
153
156
  }
154
157
  export declare enum VirtualRouterErrorCode {
155
158
  NO_STANDARDIZED_REQUEST = "NO_STANDARDIZED_REQUEST",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jsonstudio/llms",
3
- "version": "0.6.123",
3
+ "version": "0.6.141",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.js",