ask-my-llm 1.1.6 → 1.1.8

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 (2) hide show
  1. package/index.js +28 -18
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -39,13 +39,30 @@ function loadConfig(options) {
39
39
  }
40
40
  }
41
41
 
42
+ function parseSSE(output) {
43
+ let content = '';
44
+ for (const line of output.split('\n')) {
45
+ if (!line.startsWith('data: ')) continue;
46
+ const payload = line.slice(6).trim();
47
+ if (payload === '[DONE]') break;
48
+ try {
49
+ const parsed = JSON.parse(payload);
50
+ const delta = parsed.choices && parsed.choices[0] && parsed.choices[0].delta;
51
+ if (delta && delta.content) content += delta.content;
52
+ } catch (e) { /* skip malformed SSE */ }
53
+ }
54
+ if (!content) throw new Error('API returned no content:\n' + output.slice(0, 2000));
55
+ return content;
56
+ }
57
+
42
58
  function ask(prompt, options) {
43
59
  const config = loadConfig(options);
44
60
 
45
61
  const postData = JSON.stringify({
46
62
  model: config.model,
47
63
  messages: [{ role: 'user', content: prompt }],
48
- temperature: 0.7
64
+ temperature: 0.7,
65
+ stream: true
49
66
  });
50
67
 
51
68
  let baseUrl = config.baseApi.replace(/\/$/, '');
@@ -64,18 +81,18 @@ function ask(prompt, options) {
64
81
  }
65
82
 
66
83
  const args = [
67
- '-s', '-S', '-X', 'POST',
84
+ '-s', '-S', '-X', 'POST', '-N',
68
85
  ...headerArgs,
69
- '-d', postData,
86
+ '-d', '@-',
70
87
  url
71
88
  ];
72
89
 
73
- const result = spawnSync('curl', args, { encoding: 'utf8' });
90
+ const result = spawnSync('curl', args, { encoding: 'utf8', input: postData });
74
91
 
75
92
  if (result.error) throw result.error;
76
93
  if (result.status !== 0) throw new Error('curl failed: ' + (result.stderr || result.stdout));
77
94
 
78
- return parseResponse(result.stdout);
95
+ return parseSSE(result.stdout);
79
96
  }
80
97
 
81
98
  function askAsync(prompt, options) {
@@ -85,7 +102,8 @@ function askAsync(prompt, options) {
85
102
  const postData = JSON.stringify({
86
103
  model: config.model,
87
104
  messages: [{ role: 'user', content: prompt }],
88
- temperature: 0.7
105
+ temperature: 0.7,
106
+ stream: true
89
107
  });
90
108
 
91
109
  let baseUrl = config.baseApi.replace(/\/$/, '');
@@ -95,7 +113,7 @@ function askAsync(prompt, options) {
95
113
  const url = baseUrl + '/chat/completions';
96
114
 
97
115
  const headerArgs = [
98
- '-s', '-S', '-X', 'POST',
116
+ '-s', '-S', '-X', 'POST', '-N',
99
117
  '-H', 'Content-Type: application/json',
100
118
  '-H', 'HTTP-Referer: https://cows.info.gf',
101
119
  '-H', 'X-OpenRouter-Title: ask-my-llm'
@@ -103,7 +121,7 @@ function askAsync(prompt, options) {
103
121
  if (config.apiKey) {
104
122
  headerArgs.push('-H', `Authorization: Bearer ${config.apiKey}`);
105
123
  }
106
- headerArgs.push('-d', postData, url);
124
+ headerArgs.push('-d', '@-', url);
107
125
 
108
126
  const child = spawn('curl', headerArgs, { encoding: 'utf8' });
109
127
  let data = '';
@@ -111,12 +129,13 @@ function askAsync(prompt, options) {
111
129
 
112
130
  child.stdout.on('data', chunk => data += chunk);
113
131
  child.stderr.on('data', chunk => error += chunk);
132
+ child.stdin.end(postData);
114
133
  child.on('close', code => {
115
134
  if (code !== 0) {
116
135
  reject(new Error('curl failed: ' + (error || data)));
117
136
  } else {
118
137
  try {
119
- resolve(parseResponse(data));
138
+ resolve(parseSSE(data));
120
139
  } catch (e) {
121
140
  reject(e);
122
141
  }
@@ -126,15 +145,6 @@ function askAsync(prompt, options) {
126
145
  });
127
146
  }
128
147
 
129
- function parseResponse(stdout) {
130
- const parsed = JSON.parse(stdout);
131
- if (parsed.choices && parsed.choices[0]) {
132
- return parsed.choices[0].message.content;
133
- } else {
134
- throw new Error('API Error: ' + stdout);
135
- }
136
- }
137
-
138
148
  /**
139
149
  * Returns the model name from the current configuration.
140
150
  * Synchronous.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ask-my-llm",
3
- "version": "1.1.6",
3
+ "version": "1.1.8",
4
4
  "description": "Oversimplified, zero-dependency AI usage npm module",
5
5
  "main": "index.js",
6
6
  "bin": {