Skip to content

[Components] ollama: new action components #14278

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Merged
merged 1 commit into from
Oct 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions components/ollama/actions/copy-model/copy-model.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import app from "../../ollama.app.mjs";

export default {
key: "ollama-copy-model",
name: "Copy Model",
description: "Copies a model, creating a model with another name from an existing model. [See the documentation](https://github.com/ollama/ollama/blob/main/docs/api.md#copy-a-model).",
version: "0.0.1",
type: "action",
props: {
app,
source: {
propDefinition: [
app,
"model",
],
},
destination: {
type: "string",
label: "New Model Name",
description: "The new name for the copied model.",
},
},
methods: {
copyModel(args = {}) {
return this.app.post({
path: "/copy",
...args,
});
},
},
async run({ $ }) {
const {
copyModel,
source,
destination,
} = this;

await copyModel({
$,
data: {
source,
destination,
},
});
$.export("$summary", "Successfully copied model.");
return {
success: true,
};
},
};
55 changes: 55 additions & 0 deletions components/ollama/actions/create-model/create-model.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import app from "../../ollama.app.mjs";

export default {
key: "ollama-create-model",
name: "Create Model",
description: "Create a model from a modelfile. [See the documentation](https://github.com/ollama/ollama/blob/main/docs/api.md#create-a-model).",
version: "0.0.1",
type: "action",
props: {
app,
name: {
type: "string",
label: "Name",
description: "The name of the model.",
},
modelfile: {
type: "string",
label: "Model File",
description: "Contents of the Modelfile. Eg. `FROM llama3 SYSTEM You are mario from Super Mario Bros`",
},
stream: {
propDefinition: [
app,
"stream",
],
},
},
methods: {
createModel(args = {}) {
return this.app.post({
path: "/create",
...args,
});
},
},
async run({ $ }) {
const {
createModel,
name,
modelfile,
stream,
} = this;

const response = await createModel({
$,
data: {
name,
modelfile,
stream,
},
});
$.export("$summary", "Successfully created model.");
return response;
},
};
43 changes: 43 additions & 0 deletions components/ollama/actions/delete-model/delete-model.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import app from "../../ollama.app.mjs";

export default {
key: "ollama-delete-model",
name: "Delete Model",
description: "Delete a model and its data. [See the documentation](https://github.com/ollama/ollama/blob/main/docs/api.md#delete-a-model)",
version: "0.0.1",
type: "action",
props: {
app,
name: {
propDefinition: [
app,
"model",
],
},
},
methods: {
deleteModel(args = {}) {
return this.app.delete({
path: "/delete",
...args,
});
},
},
async run({ $ }) {
const {
deleteModel,
name,
} = this;

await deleteModel({
$,
data: {
name,
},
});
$.export("$summary", "Successfully deleted model.");
return {
success: true,
};
},
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import app from "../../ollama.app.mjs";
import utils from "../../common/utils.mjs";

export default {
key: "ollama-generate-chat-completion",
name: "Generate Chat Completion",
description: "Generates the next message in a chat with a provided model. [See the documentation](https://github.com/ollama/ollama/blob/main/docs/api.md#generate-a-chat-completion).",
version: "0.0.1",
type: "action",
props: {
app,
model: {
propDefinition: [
app,
"model",
],
},
messages: {
type: "string[]",
label: "Messages",
description: "The messages of the chat, this can be used to keep a chat memory. Each row should be set as a JSON format string. Eg. `{\"role\": \"user\", \"content\": \"Hello\"}`. The message object has the following fields:\n- `role`: the role of the message, either `system`, `user`, `assistant`, or `tool`.\n- `content`: The content of the message.\n- `images` (optional): a list of images to include in the message (for multimodal models such as `llava`).\n- `tool_calls`(optional): a list of tools the model wants to use.",
},
tools: {
type: "string[]",
label: "Tools",
description: "A list of tools the model can use. Each row should be set as a JSON format string.",
optional: true,
},
options: {
propDefinition: [
app,
"options",
],
},
stream: {
propDefinition: [
app,
"stream",
],
},
keepAlive: {
propDefinition: [
app,
"keepAlive",
],
},
},
methods: {
generateChatCompletion(args = {}) {
return this.app.post({
path: "/chat",
...args,
});
},
},
Comment on lines +48 to +55
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Enhance error handling in the generateChatCompletion method.

While the method is correctly implemented, it lacks error handling. Consider adding a try-catch block to provide more informative feedback in case of API errors:

generateChatCompletion(args = {}) {
  return this.app.post({
    path: "/chat",
    ...args,
  }).catch(error => {
    throw new Error(`Failed to generate chat completion: ${error.message}`);
  });
},

This will help in debugging and provide clearer error messages to the user.

async run({ $ }) {
const {
generateChatCompletion,
model,
messages,
tools,
options,
stream,
keepAlive,
} = this;

const response = await generateChatCompletion({
$,
data: {
model,
messages: utils.parseArray(messages),
tools: utils.parseArray(tools),
options: utils.parseOptions(options),
stream,
keep_alive: keepAlive,
},
});

$.export("$summary", "Successfully generated chat completion.");
return response;
},
Comment on lines +56 to +81
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Improve error handling and clean up undefined properties in the run method.

  1. Add error handling for the API call:
try {
  const response = await generateChatCompletion({
    // ... existing code ...
  });
  $.export("$summary", "Successfully generated chat completion.");
  return response;
} catch (error) {
  $.export("$summary", `Failed to generate chat completion: ${error.message}`);
  throw error;
}
  1. Clean up undefined properties in the request data:
const data = {
  model,
  messages: utils.parseArray(messages),
  tools: utils.parseArray(tools),
  options: utils.parseOptions(options),
  stream,
  keep_alive: keepAlive,
};

const response = await generateChatCompletion({
  $,
  data: Object.fromEntries(Object.entries(data).filter(([_, v]) => v != null)),
});

These changes will improve error reporting and prevent sending undefined properties to the API.

};
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import utils from "../../common/utils.mjs";
import app from "../../ollama.app.mjs";

export default {
key: "ollama-generate-completion",
name: "Generate Completion",
description: "Generates a response for a given prompt with a provided model. [See the documentation](https://github.com/ollama/ollama/blob/main/docs/api.md#generate-a-completion).",
version: "0.0.1",
type: "action",
props: {
app,
model: {
propDefinition: [
app,
"model",
],
},
prompt: {
propDefinition: [
app,
"prompt",
],
},
suffix: {
propDefinition: [
app,
"suffix",
],
},
images: {
propDefinition: [
app,
"images",
],
},
options: {
propDefinition: [
app,
"options",
],
},
stream: {
propDefinition: [
app,
"stream",
],
},
keepAlive: {
propDefinition: [
app,
"keepAlive",
],
},
},
methods: {
generateCompletion(args = {}) {
return this.app.post({
path: "/generate",
...args,
});
},
},
async run({ $ }) {
const {
generateCompletion,
model,
prompt,
suffix,
images,
options,
stream,
keepAlive,
} = this;

const response = await generateCompletion({
$,
data: {
model,
prompt,
suffix,
images,
options: utils.parseOptions(options),
stream,
keep_alive: keepAlive,
},
});
$.export("$summary", "Successfully generated completion.");
return response;
},
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import utils from "../../common/utils.mjs";
import app from "../../ollama.app.mjs";

export default {
key: "ollama-generate-embeddings",
name: "Generate Embeddings",
description: "Generate embeddings from a model. [See the documentation](https://github.com/ollama/ollama/blob/main/docs/api.md#generate-embeddings).",
version: "0.0.1",
type: "action",
props: {
app,
model: {
propDefinition: [
app,
"model",
],
},
input: {
type: "string[]",
label: "Input",
description: "The list of texts to generate embeddings for.",
},
truncate: {
type: "boolean",
label: "Truncate",
description: "Truncates the end of each input to fit within context length. Returns error if `false` and context length is exceeded. Defaults to `true`.",
optional: true,
},
options: {
propDefinition: [
app,
"options",
],
},
keepAlive: {
propDefinition: [
app,
"keepAlive",
],
},
},
methods: {
generateEmbeddings(args = {}) {
return this.app.post({
path: "/embed",
...args,
});
},
},
async run({ $ }) {
const {
generateEmbeddings,
model,
input,
truncate,
options,
keepAlive,
} = this;

const response = await generateEmbeddings({
$,
data: {
model,
input,
truncate,
options: utils.parseOptions(options),
keep_alive: keepAlive,
},
});
$.export("$summary", "Successfully generated embeddings.");
return response;
},
};
Loading
Loading