@marizmelo/llm-cli 0.0.3 → 0.0.4

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 = "55b76129";
139662
+ CLI_VERSION = "0.0.4";
139663
139663
  }
139664
139664
  });
139665
139665
 
@@ -141931,18 +141931,20 @@ 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,
141940
+ ...tools.length > 0 ? { tools } : {},
141939
141941
  options: {
141940
- temperature: request3.generationConfig?.temperature || 0,
141941
- top_p: request3.generationConfig?.topP || 1,
141942
- num_predict: request3.generationConfig?.maxOutputTokens
141942
+ temperature: request3.generationConfig?.temperature ?? request3.config?.temperature ?? 0,
141943
+ top_p: request3.generationConfig?.topP ?? request3.config?.topP ?? 1,
141944
+ num_predict: request3.generationConfig?.maxOutputTokens ?? request3.config?.maxOutputTokens
141943
141945
  }
141944
141946
  };
141945
- const response = await fetch(`${this.baseUrl}/api/generate`, {
141947
+ const response = await fetch(`${this.baseUrl}/api/chat`, {
141946
141948
  method: "POST",
141947
141949
  headers: {
141948
141950
  "Content-Type": "application/json"
@@ -141953,21 +141955,23 @@ var init_ollama_provider = __esm({
141953
141955
  throw new Error(`Ollama API error: ${response.status} ${response.statusText}`);
141954
141956
  }
141955
141957
  const ollamaResponse = await response.json();
141956
- return this.convertFromOllamaResponse(ollamaResponse);
141958
+ return this.convertFromOllamaChatResponse(ollamaResponse);
141957
141959
  }
141958
141960
  async generateContentStream(request3, userPromptId) {
141959
- const prompt = this.convertToOllamaPrompt(request3);
141961
+ const messages = this.convertToOllamaMessages(request3);
141962
+ const tools = this.convertToOllamaTools(request3);
141960
141963
  const ollamaRequest = {
141961
141964
  model: this.model,
141962
- prompt,
141965
+ messages,
141963
141966
  stream: true,
141967
+ ...tools.length > 0 ? { tools } : {},
141964
141968
  options: {
141965
- temperature: request3.generationConfig?.temperature || 0,
141966
- top_p: request3.generationConfig?.topP || 1,
141967
- num_predict: request3.generationConfig?.maxOutputTokens
141969
+ temperature: request3.generationConfig?.temperature ?? request3.config?.temperature ?? 0,
141970
+ top_p: request3.generationConfig?.topP ?? request3.config?.topP ?? 1,
141971
+ num_predict: request3.generationConfig?.maxOutputTokens ?? request3.config?.maxOutputTokens
141968
141972
  }
141969
141973
  };
141970
- const response = await fetch(`${this.baseUrl}/api/generate`, {
141974
+ const response = await fetch(`${this.baseUrl}/api/chat`, {
141971
141975
  method: "POST",
141972
141976
  headers: {
141973
141977
  "Content-Type": "application/json"
@@ -141984,17 +141988,19 @@ var init_ollama_provider = __esm({
141984
141988
  return this.createStreamGenerator(reader);
141985
141989
  }
141986
141990
  async countTokens(request3) {
141987
- const text = this.convertToOllamaPrompt(request3);
141991
+ const messages = this.convertToOllamaMessages(request3);
141992
+ const text = messages.map((msg) => msg.content).join("");
141988
141993
  const estimatedTokens = Math.ceil(text.length / 4);
141989
141994
  return {
141990
141995
  totalTokens: estimatedTokens
141991
141996
  };
141992
141997
  }
141993
141998
  async embedContent(request3) {
141994
- const prompt = this.convertToOllamaPrompt(request3);
141999
+ const messages = this.convertToOllamaMessages(request3);
142000
+ const text = messages.map((msg) => msg.content).join("");
141995
142001
  const ollamaRequest = {
141996
142002
  model: this.model,
141997
- prompt
142003
+ prompt: text
141998
142004
  };
141999
142005
  const response = await fetch(`${this.baseUrl}/api/embeddings`, {
142000
142006
  method: "POST",
@@ -142021,58 +142027,218 @@ var init_ollama_provider = __esm({
142021
142027
  validateConfig(config) {
142022
142028
  return config.provider === "ollama" && !!config.model;
142023
142029
  }
142024
- convertToOllamaPrompt(request3) {
142030
+ convertToOllamaMessages(request3) {
142031
+ const messages = [];
142032
+ if (request3.systemInstruction) {
142033
+ const systemText = request3.systemInstruction.parts?.map((part) => part.text || "").join("") || "";
142034
+ if (systemText.trim()) {
142035
+ messages.push({ role: "system", content: systemText });
142036
+ }
142037
+ }
142025
142038
  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 "";
142039
+ for (const content of request3.contents) {
142040
+ if (!content.parts || !Array.isArray(content.parts))
142041
+ continue;
142042
+ const role = content.role || "user";
142043
+ const functionCallParts = content.parts.filter((p) => p.functionCall);
142044
+ const functionResponseParts = content.parts.filter((p) => p.functionResponse);
142045
+ const textParts = content.parts.filter((p) => p.text !== void 0);
142046
+ if (functionCallParts.length > 0) {
142047
+ const textContent2 = textParts.map((p) => p.text).join("");
142048
+ const toolCalls = functionCallParts.map((p) => ({
142049
+ function: {
142050
+ name: p.functionCall.name,
142051
+ arguments: p.functionCall.args || {}
142033
142052
  }
142034
- return "";
142035
- }).join("");
142053
+ }));
142054
+ messages.push({
142055
+ role: "assistant",
142056
+ content: textContent2,
142057
+ tool_calls: toolCalls
142058
+ });
142059
+ } else if (functionResponseParts.length > 0) {
142060
+ for (const part of functionResponseParts) {
142061
+ const output = part.functionResponse.response?.output ?? JSON.stringify(part.functionResponse.response ?? {});
142062
+ messages.push({
142063
+ role: "tool",
142064
+ content: typeof output === "string" ? output : JSON.stringify(output),
142065
+ name: part.functionResponse.name
142066
+ });
142067
+ }
142068
+ } else {
142069
+ const textContent2 = textParts.map((p) => p.text).join("");
142070
+ if (textContent2.trim()) {
142071
+ messages.push({
142072
+ role: role === "model" ? "assistant" : "user",
142073
+ content: textContent2
142074
+ });
142075
+ }
142036
142076
  }
142037
- return "";
142038
- }).join("\n");
142077
+ }
142039
142078
  }
142040
- return "";
142079
+ return messages;
142041
142080
  }
142042
- convertFromOllamaResponse(ollamaResponse) {
142081
+ convertToOllamaTools(request3) {
142082
+ const tools = [];
142083
+ if (request3.config?.tools) {
142084
+ for (const tool of request3.config.tools) {
142085
+ if (tool.functionDeclarations) {
142086
+ for (const func of tool.functionDeclarations) {
142087
+ tools.push({
142088
+ type: "function",
142089
+ function: {
142090
+ name: func.name,
142091
+ description: func.description,
142092
+ parameters: func.parameters || {}
142093
+ }
142094
+ });
142095
+ }
142096
+ }
142097
+ }
142098
+ }
142099
+ return tools;
142100
+ }
142101
+ convertFromOllamaChatResponse(ollamaResponse) {
142102
+ const message = ollamaResponse.message;
142103
+ const text = message?.content || "";
142104
+ const parts = [];
142105
+ if (text) {
142106
+ parts.push({ text });
142107
+ }
142108
+ if (message?.tool_calls) {
142109
+ for (const toolCall of message.tool_calls) {
142110
+ if (toolCall.function) {
142111
+ const args = typeof toolCall.function.arguments === "string" ? JSON.parse(toolCall.function.arguments) : toolCall.function.arguments || {};
142112
+ parts.push({
142113
+ functionCall: {
142114
+ name: toolCall.function.name,
142115
+ args
142116
+ }
142117
+ });
142118
+ }
142119
+ }
142120
+ }
142043
142121
  return {
142044
142122
  candidates: [
142045
142123
  {
142046
142124
  content: {
142047
- parts: [
142048
- {
142049
- text: ollamaResponse.response
142050
- }
142051
- ]
142125
+ parts
142052
142126
  },
142053
- // Ollama doesn't have token limits like Gemini - it just stops when complete
142054
142127
  finishReason: ollamaResponse.done ? "STOP" : "STOP"
142055
142128
  }
142056
- ]
142129
+ ],
142130
+ text,
142131
+ functionCalls: parts.filter((p) => p.functionCall).map((p) => p.functionCall)
142057
142132
  };
142058
142133
  }
142059
142134
  async *createStreamGenerator(reader) {
142060
142135
  const decoder = new TextDecoder();
142136
+ let buffer = "";
142137
+ let accumulatedToolCalls = [];
142138
+ let accumulatedText = "";
142061
142139
  try {
142062
142140
  while (true) {
142063
142141
  const { done, value } = await reader.read();
142064
142142
  if (done)
142065
142143
  break;
142066
- const chunk = decoder.decode(value);
142067
- const lines = chunk.split("\n").filter((line) => line.trim());
142144
+ buffer += decoder.decode(value, { stream: true });
142145
+ const lines = buffer.split("\n");
142146
+ buffer = lines.pop() || "";
142068
142147
  for (const line of lines) {
142148
+ const trimmedLine = line.trim();
142149
+ if (!trimmedLine)
142150
+ continue;
142069
142151
  try {
142070
- const ollamaResponse = JSON.parse(line);
142071
- yield this.convertFromOllamaResponse(ollamaResponse);
142152
+ const chunk = JSON.parse(trimmedLine);
142153
+ if (chunk.message?.content) {
142154
+ accumulatedText += chunk.message.content;
142155
+ yield {
142156
+ candidates: [
142157
+ {
142158
+ content: {
142159
+ parts: [{ text: chunk.message.content }]
142160
+ },
142161
+ finishReason: void 0
142162
+ }
142163
+ ],
142164
+ text: chunk.message.content
142165
+ };
142166
+ }
142167
+ if (chunk.message?.tool_calls) {
142168
+ for (const toolCall of chunk.message.tool_calls) {
142169
+ if (toolCall.function) {
142170
+ const args = typeof toolCall.function.arguments === "string" ? JSON.parse(toolCall.function.arguments) : toolCall.function.arguments || {};
142171
+ accumulatedToolCalls.push({
142172
+ function: { name: toolCall.function.name, arguments: args }
142173
+ });
142174
+ }
142175
+ }
142176
+ }
142177
+ if (chunk.done && accumulatedToolCalls.length > 0) {
142178
+ const parts = [];
142179
+ for (const tc of accumulatedToolCalls) {
142180
+ parts.push({
142181
+ functionCall: {
142182
+ name: tc.function.name,
142183
+ args: tc.function.arguments
142184
+ }
142185
+ });
142186
+ }
142187
+ yield {
142188
+ candidates: [
142189
+ {
142190
+ content: { parts },
142191
+ finishReason: "STOP"
142192
+ }
142193
+ ],
142194
+ text: "",
142195
+ functionCalls: parts.map((p) => p.functionCall)
142196
+ };
142197
+ }
142072
142198
  } catch (e2) {
142073
142199
  }
142074
142200
  }
142075
142201
  }
142202
+ if (buffer.trim()) {
142203
+ try {
142204
+ const chunk = JSON.parse(buffer.trim());
142205
+ if (chunk.message?.content) {
142206
+ yield {
142207
+ candidates: [
142208
+ {
142209
+ content: {
142210
+ parts: [{ text: chunk.message.content }]
142211
+ },
142212
+ finishReason: chunk.done ? "STOP" : void 0
142213
+ }
142214
+ ],
142215
+ text: chunk.message.content
142216
+ };
142217
+ }
142218
+ if (chunk.done && accumulatedToolCalls.length > 0) {
142219
+ const parts = [];
142220
+ for (const tc of accumulatedToolCalls) {
142221
+ parts.push({
142222
+ functionCall: {
142223
+ name: tc.function.name,
142224
+ args: tc.function.arguments
142225
+ }
142226
+ });
142227
+ }
142228
+ yield {
142229
+ candidates: [
142230
+ {
142231
+ content: { parts },
142232
+ finishReason: "STOP"
142233
+ }
142234
+ ],
142235
+ text: "",
142236
+ functionCalls: parts.map((p) => p.functionCall)
142237
+ };
142238
+ }
142239
+ } catch (e2) {
142240
+ }
142241
+ }
142076
142242
  } finally {
142077
142243
  reader.releaseLock();
142078
142244
  }
@@ -142199,7 +142365,7 @@ function createContentGeneratorConfig(config, authType) {
142199
142365
  return contentGeneratorConfig;
142200
142366
  }
142201
142367
  async function createContentGenerator(config, gcConfig, sessionId2) {
142202
- const version2 = "0.0.3";
142368
+ const version2 = "0.0.4";
142203
142369
  const userAgent2 = `GeminiCLI/${version2} (${process.platform}; ${process.arch})`;
142204
142370
  const baseHeaders = {
142205
142371
  "User-Agent": userAgent2
@@ -274561,7 +274727,7 @@ async function getPackageJson() {
274561
274727
  // packages/cli/src/utils/version.ts
274562
274728
  async function getCliVersion() {
274563
274729
  const pkgJson = await getPackageJson();
274564
- return "0.0.3";
274730
+ return "0.0.4";
274565
274731
  }
274566
274732
 
274567
274733
  // packages/cli/src/ui/commands/aboutCommand.ts
@@ -274613,7 +274779,7 @@ init_open();
274613
274779
  import process30 from "node:process";
274614
274780
 
274615
274781
  // packages/cli/src/generated/git-commit.ts
274616
- var GIT_COMMIT_INFO2 = "03ffabb5";
274782
+ var GIT_COMMIT_INFO2 = "55b76129";
274617
274783
 
274618
274784
  // packages/cli/src/ui/commands/bugCommand.ts
274619
274785
  init_dist3();
@@ -316757,6 +316923,11 @@ main().catch((error) => {
316757
316923
  * Copyright 2025 Google LLC
316758
316924
  * SPDX-License-Identifier: Apache-2.0
316759
316925
  */
316926
+ /**
316927
+ * @license
316928
+ * Copyright 2026 Google LLC
316929
+ * SPDX-License-Identifier: Apache-2.0
316930
+ */
316760
316931
  /*! Bundled license information:
316761
316932
 
316762
316933
  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.4",
4
4
  "engines": {
5
5
  "node": ">=20.0.0"
6
6
  },