@marizmelo/llm-cli 0.0.3 → 0.0.5

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.
package/README.md CHANGED
@@ -51,10 +51,18 @@ llm-cli
51
51
 
52
52
  #### Ollama (Local)
53
53
  ```bash
54
- # Install Ollama first, then:
54
+ # 1. Install Ollama (https://ollama.com)
55
+ # 2. Pull a model
56
+ ollama pull llama3.2:latest
57
+
58
+ # 3. Start llm-cli and switch to Ollama
55
59
  llm-cli
56
60
  /provider switch ollama
61
+
62
+ # 4. (Optional) Switch to a different model
63
+ /provider model <model-name>
57
64
  ```
65
+ The default model is `llama3.2:latest`. Use `/provider model` to list available models and switch between them.
58
66
 
59
67
  #### Traditional Setup (Environment Variables)
60
68
  ```bash
package/bundle/gemini.js CHANGED
@@ -139658,8 +139658,8 @@ var GIT_COMMIT_INFO, CLI_VERSION;
139658
139658
  var init_git_commit = __esm({
139659
139659
  "packages/core/dist/src/generated/git-commit.js"() {
139660
139660
  "use strict";
139661
- GIT_COMMIT_INFO = "30280aba";
139662
- CLI_VERSION = "0.0.2";
139661
+ GIT_COMMIT_INFO = "65cf1981";
139662
+ CLI_VERSION = "0.0.5";
139663
139663
  }
139664
139664
  });
139665
139665
 
@@ -141931,18 +141931,16 @@ var init_ollama_provider = __esm({
141931
141931
  this.model = config.model;
141932
141932
  }
141933
141933
  async generateContent(request3, userPromptId) {
141934
- const prompt = this.convertToOllamaPrompt(request3);
141934
+ const messages = this.convertToOllamaMessages(request3);
141935
+ const tools = this.convertToOllamaTools(request3);
141935
141936
  const ollamaRequest = {
141936
141937
  model: this.model,
141937
- prompt,
141938
+ messages,
141938
141939
  stream: false,
141939
- options: {
141940
- temperature: request3.generationConfig?.temperature || 0,
141941
- top_p: request3.generationConfig?.topP || 1,
141942
- num_predict: request3.generationConfig?.maxOutputTokens
141943
- }
141940
+ ...tools.length > 0 ? { tools } : {},
141941
+ options: this.buildOptions(request3)
141944
141942
  };
141945
- const response = await fetch(`${this.baseUrl}/api/generate`, {
141943
+ const response = await fetch(`${this.baseUrl}/api/chat`, {
141946
141944
  method: "POST",
141947
141945
  headers: {
141948
141946
  "Content-Type": "application/json"
@@ -141950,24 +141948,23 @@ var init_ollama_provider = __esm({
141950
141948
  body: JSON.stringify(ollamaRequest)
141951
141949
  });
141952
141950
  if (!response.ok) {
141953
- throw new Error(`Ollama API error: ${response.status} ${response.statusText}`);
141951
+ const body = await response.text().catch(() => "");
141952
+ throw new Error(`Ollama API error: ${response.status} ${response.statusText} - ${body}`);
141954
141953
  }
141955
141954
  const ollamaResponse = await response.json();
141956
- return this.convertFromOllamaResponse(ollamaResponse);
141955
+ return this.convertFromOllamaChatResponse(ollamaResponse);
141957
141956
  }
141958
141957
  async generateContentStream(request3, userPromptId) {
141959
- const prompt = this.convertToOllamaPrompt(request3);
141958
+ const messages = this.convertToOllamaMessages(request3);
141959
+ const tools = this.convertToOllamaTools(request3);
141960
141960
  const ollamaRequest = {
141961
141961
  model: this.model,
141962
- prompt,
141962
+ messages,
141963
141963
  stream: true,
141964
- options: {
141965
- temperature: request3.generationConfig?.temperature || 0,
141966
- top_p: request3.generationConfig?.topP || 1,
141967
- num_predict: request3.generationConfig?.maxOutputTokens
141968
- }
141964
+ ...tools.length > 0 ? { tools } : {},
141965
+ options: this.buildOptions(request3)
141969
141966
  };
141970
- const response = await fetch(`${this.baseUrl}/api/generate`, {
141967
+ const response = await fetch(`${this.baseUrl}/api/chat`, {
141971
141968
  method: "POST",
141972
141969
  headers: {
141973
141970
  "Content-Type": "application/json"
@@ -141975,7 +141972,8 @@ var init_ollama_provider = __esm({
141975
141972
  body: JSON.stringify(ollamaRequest)
141976
141973
  });
141977
141974
  if (!response.ok) {
141978
- throw new Error(`Ollama API error: ${response.status} ${response.statusText}`);
141975
+ const body = await response.text().catch(() => "");
141976
+ throw new Error(`Ollama API error: ${response.status} ${response.statusText} - ${body}`);
141979
141977
  }
141980
141978
  const reader = response.body?.getReader();
141981
141979
  if (!reader) {
@@ -141984,17 +141982,19 @@ var init_ollama_provider = __esm({
141984
141982
  return this.createStreamGenerator(reader);
141985
141983
  }
141986
141984
  async countTokens(request3) {
141987
- const text = this.convertToOllamaPrompt(request3);
141985
+ const messages = this.convertToOllamaMessages(request3);
141986
+ const text = messages.map((msg) => msg.content).join("");
141988
141987
  const estimatedTokens = Math.ceil(text.length / 4);
141989
141988
  return {
141990
141989
  totalTokens: estimatedTokens
141991
141990
  };
141992
141991
  }
141993
141992
  async embedContent(request3) {
141994
- const prompt = this.convertToOllamaPrompt(request3);
141993
+ const messages = this.convertToOllamaMessages(request3);
141994
+ const text = messages.map((msg) => msg.content).join("");
141995
141995
  const ollamaRequest = {
141996
141996
  model: this.model,
141997
- prompt
141997
+ prompt: text
141998
141998
  };
141999
141999
  const response = await fetch(`${this.baseUrl}/api/embeddings`, {
142000
142000
  method: "POST",
@@ -142021,58 +142021,231 @@ var init_ollama_provider = __esm({
142021
142021
  validateConfig(config) {
142022
142022
  return config.provider === "ollama" && !!config.model;
142023
142023
  }
142024
- convertToOllamaPrompt(request3) {
142024
+ buildOptions(request3) {
142025
+ const options2 = {};
142026
+ const temp = request3.generationConfig?.temperature ?? request3.config?.temperature;
142027
+ if (temp !== void 0)
142028
+ options2.temperature = temp;
142029
+ const topP = request3.generationConfig?.topP ?? request3.config?.topP;
142030
+ if (topP !== void 0)
142031
+ options2.top_p = topP;
142032
+ const maxTokens = request3.generationConfig?.maxOutputTokens ?? request3.config?.maxOutputTokens;
142033
+ if (maxTokens !== void 0)
142034
+ options2.num_predict = maxTokens;
142035
+ return options2;
142036
+ }
142037
+ convertToOllamaMessages(request3) {
142038
+ const messages = [];
142039
+ if (request3.systemInstruction) {
142040
+ const systemText = request3.systemInstruction.parts?.map((part) => part.text || "").join("") || "";
142041
+ if (systemText.trim()) {
142042
+ messages.push({ role: "system", content: systemText });
142043
+ }
142044
+ }
142025
142045
  if (request3.contents && Array.isArray(request3.contents)) {
142026
- return request3.contents.map((content) => {
142027
- if (content.parts && Array.isArray(content.parts)) {
142028
- return content.parts.map((part) => {
142029
- if (part.text)
142030
- return part.text;
142031
- if (part.inlineData?.data) {
142032
- return "";
142046
+ for (const content of request3.contents) {
142047
+ if (!content.parts || !Array.isArray(content.parts))
142048
+ continue;
142049
+ const role = content.role || "user";
142050
+ const functionCallParts = content.parts.filter((p) => p.functionCall);
142051
+ const functionResponseParts = content.parts.filter((p) => p.functionResponse);
142052
+ const textParts = content.parts.filter((p) => p.text !== void 0);
142053
+ if (functionCallParts.length > 0) {
142054
+ const textContent2 = textParts.map((p) => p.text).join("");
142055
+ const toolCalls = functionCallParts.map((p) => ({
142056
+ function: {
142057
+ name: p.functionCall.name,
142058
+ arguments: p.functionCall.args || {}
142033
142059
  }
142034
- return "";
142035
- }).join("");
142060
+ }));
142061
+ messages.push({
142062
+ role: "assistant",
142063
+ content: textContent2,
142064
+ tool_calls: toolCalls
142065
+ });
142066
+ } else if (functionResponseParts.length > 0) {
142067
+ for (const part of functionResponseParts) {
142068
+ const output = part.functionResponse.response?.output ?? JSON.stringify(part.functionResponse.response ?? {});
142069
+ messages.push({
142070
+ role: "tool",
142071
+ content: typeof output === "string" ? output : JSON.stringify(output),
142072
+ name: part.functionResponse.name
142073
+ });
142074
+ }
142075
+ } else {
142076
+ const textContent2 = textParts.map((p) => p.text).join("");
142077
+ if (textContent2.trim()) {
142078
+ messages.push({
142079
+ role: role === "model" ? "assistant" : "user",
142080
+ content: textContent2
142081
+ });
142082
+ }
142036
142083
  }
142037
- return "";
142038
- }).join("\n");
142084
+ }
142039
142085
  }
142040
- return "";
142086
+ return messages;
142087
+ }
142088
+ convertToOllamaTools(request3) {
142089
+ const tools = [];
142090
+ if (request3.config?.tools) {
142091
+ for (const tool of request3.config.tools) {
142092
+ if (tool.functionDeclarations) {
142093
+ for (const func of tool.functionDeclarations) {
142094
+ tools.push({
142095
+ type: "function",
142096
+ function: {
142097
+ name: func.name,
142098
+ description: func.description,
142099
+ parameters: func.parameters || {}
142100
+ }
142101
+ });
142102
+ }
142103
+ }
142104
+ }
142105
+ }
142106
+ return tools;
142041
142107
  }
142042
- convertFromOllamaResponse(ollamaResponse) {
142108
+ convertFromOllamaChatResponse(ollamaResponse) {
142109
+ const message = ollamaResponse.message;
142110
+ const text = message?.content || "";
142111
+ const parts = [];
142112
+ if (text) {
142113
+ parts.push({ text });
142114
+ }
142115
+ if (message?.tool_calls) {
142116
+ for (const toolCall of message.tool_calls) {
142117
+ if (toolCall.function) {
142118
+ const args = typeof toolCall.function.arguments === "string" ? JSON.parse(toolCall.function.arguments) : toolCall.function.arguments || {};
142119
+ parts.push({
142120
+ functionCall: {
142121
+ name: toolCall.function.name,
142122
+ args
142123
+ }
142124
+ });
142125
+ }
142126
+ }
142127
+ }
142043
142128
  return {
142044
142129
  candidates: [
142045
142130
  {
142046
142131
  content: {
142047
- parts: [
142048
- {
142049
- text: ollamaResponse.response
142050
- }
142051
- ]
142132
+ parts
142052
142133
  },
142053
- // Ollama doesn't have token limits like Gemini - it just stops when complete
142054
142134
  finishReason: ollamaResponse.done ? "STOP" : "STOP"
142055
142135
  }
142056
- ]
142136
+ ],
142137
+ text,
142138
+ functionCalls: parts.filter((p) => p.functionCall).map((p) => p.functionCall)
142057
142139
  };
142058
142140
  }
142059
142141
  async *createStreamGenerator(reader) {
142060
142142
  const decoder = new TextDecoder();
142143
+ let buffer = "";
142144
+ let accumulatedToolCalls = [];
142145
+ let accumulatedText = "";
142061
142146
  try {
142062
142147
  while (true) {
142063
142148
  const { done, value } = await reader.read();
142064
142149
  if (done)
142065
142150
  break;
142066
- const chunk = decoder.decode(value);
142067
- const lines = chunk.split("\n").filter((line) => line.trim());
142151
+ buffer += decoder.decode(value, { stream: true });
142152
+ const lines = buffer.split("\n");
142153
+ buffer = lines.pop() || "";
142068
142154
  for (const line of lines) {
142155
+ const trimmedLine = line.trim();
142156
+ if (!trimmedLine)
142157
+ continue;
142069
142158
  try {
142070
- const ollamaResponse = JSON.parse(line);
142071
- yield this.convertFromOllamaResponse(ollamaResponse);
142159
+ const chunk = JSON.parse(trimmedLine);
142160
+ if (chunk.message?.content) {
142161
+ accumulatedText += chunk.message.content;
142162
+ yield {
142163
+ candidates: [
142164
+ {
142165
+ content: {
142166
+ parts: [{ text: chunk.message.content }]
142167
+ },
142168
+ finishReason: void 0
142169
+ }
142170
+ ],
142171
+ text: chunk.message.content
142172
+ };
142173
+ }
142174
+ if (chunk.message?.tool_calls) {
142175
+ for (const toolCall of chunk.message.tool_calls) {
142176
+ if (toolCall.function) {
142177
+ const args = typeof toolCall.function.arguments === "string" ? JSON.parse(toolCall.function.arguments) : toolCall.function.arguments || {};
142178
+ accumulatedToolCalls.push({
142179
+ function: { name: toolCall.function.name, arguments: args }
142180
+ });
142181
+ }
142182
+ }
142183
+ }
142184
+ if (chunk.done && accumulatedToolCalls.length > 0) {
142185
+ const parts = [];
142186
+ for (const tc of accumulatedToolCalls) {
142187
+ parts.push({
142188
+ functionCall: {
142189
+ name: tc.function.name,
142190
+ args: tc.function.arguments
142191
+ }
142192
+ });
142193
+ }
142194
+ yield {
142195
+ candidates: [
142196
+ {
142197
+ content: { parts },
142198
+ finishReason: "STOP"
142199
+ }
142200
+ ],
142201
+ text: "",
142202
+ functionCalls: parts.map((p) => p.functionCall)
142203
+ };
142204
+ }
142072
142205
  } catch (e2) {
142073
142206
  }
142074
142207
  }
142075
142208
  }
142209
+ if (buffer.trim()) {
142210
+ try {
142211
+ const chunk = JSON.parse(buffer.trim());
142212
+ if (chunk.message?.content) {
142213
+ yield {
142214
+ candidates: [
142215
+ {
142216
+ content: {
142217
+ parts: [{ text: chunk.message.content }]
142218
+ },
142219
+ finishReason: chunk.done ? "STOP" : void 0
142220
+ }
142221
+ ],
142222
+ text: chunk.message.content
142223
+ };
142224
+ }
142225
+ if (chunk.done && accumulatedToolCalls.length > 0) {
142226
+ const parts = [];
142227
+ for (const tc of accumulatedToolCalls) {
142228
+ parts.push({
142229
+ functionCall: {
142230
+ name: tc.function.name,
142231
+ args: tc.function.arguments
142232
+ }
142233
+ });
142234
+ }
142235
+ yield {
142236
+ candidates: [
142237
+ {
142238
+ content: { parts },
142239
+ finishReason: "STOP"
142240
+ }
142241
+ ],
142242
+ text: "",
142243
+ functionCalls: parts.map((p) => p.functionCall)
142244
+ };
142245
+ }
142246
+ } catch (e2) {
142247
+ }
142248
+ }
142076
142249
  } finally {
142077
142250
  reader.releaseLock();
142078
142251
  }
@@ -142199,7 +142372,7 @@ function createContentGeneratorConfig(config, authType) {
142199
142372
  return contentGeneratorConfig;
142200
142373
  }
142201
142374
  async function createContentGenerator(config, gcConfig, sessionId2) {
142202
- const version2 = "0.0.3";
142375
+ const version2 = "0.0.5";
142203
142376
  const userAgent2 = `GeminiCLI/${version2} (${process.platform}; ${process.arch})`;
142204
142377
  const baseHeaders = {
142205
142378
  "User-Agent": userAgent2
@@ -274561,7 +274734,7 @@ async function getPackageJson() {
274561
274734
  // packages/cli/src/utils/version.ts
274562
274735
  async function getCliVersion() {
274563
274736
  const pkgJson = await getPackageJson();
274564
- return "0.0.3";
274737
+ return "0.0.5";
274565
274738
  }
274566
274739
 
274567
274740
  // packages/cli/src/ui/commands/aboutCommand.ts
@@ -274613,7 +274786,7 @@ init_open();
274613
274786
  import process30 from "node:process";
274614
274787
 
274615
274788
  // packages/cli/src/generated/git-commit.ts
274616
- var GIT_COMMIT_INFO2 = "03ffabb5";
274789
+ var GIT_COMMIT_INFO2 = "37f235d7";
274617
274790
 
274618
274791
  // packages/cli/src/ui/commands/bugCommand.ts
274619
274792
  init_dist3();
@@ -316757,6 +316930,11 @@ main().catch((error) => {
316757
316930
  * Copyright 2025 Google LLC
316758
316931
  * SPDX-License-Identifier: Apache-2.0
316759
316932
  */
316933
+ /**
316934
+ * @license
316935
+ * Copyright 2026 Google LLC
316936
+ * SPDX-License-Identifier: Apache-2.0
316937
+ */
316760
316938
  /*! Bundled license information:
316761
316939
 
316762
316940
  react/cjs/react.production.js:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@marizmelo/llm-cli",
3
- "version": "0.0.3",
3
+ "version": "0.0.5",
4
4
  "engines": {
5
5
  "node": ">=20.0.0"
6
6
  },