Ollama
Integrate with open source LLMs using Ollama. With an instance of Ollama running locally you can use this integration to have a conversation in an Incident, download models, and create new models.
Utilities · Ollama
Details
| ID | Ollama |
|---|---|
| Provider | Open Source |
| Category | Utilities |
| From Version | 6.0.0 |
| Docker Image | demisto/python3:3.12.8.3296088 |
| Supported Modules | Agentix XSIAM |
README
Integrate with open source LLMs using Ollama. With an instance of Ollama running locally you can use this integration to have a conversation in an Incident, download models, and create new models.
Configure Ollama in Cortex
| Parameter | Description | Required |
|---|---|---|
| Protocol | HTTP or HTTPS | False |
| Server hostname or IP | Enter the Ollama IP or hostname | True |
| Port | The port Ollama is running on | True |
| Path | By default Ollama’s API path is /api, but you may be running it behind a proxy with a different path. | True |
| Trust any certificate (not secure) | Trust any certificate (not secure) | False |
| Use system proxy settings | Use system proxy settings | False |
| Cloudflare Access Client Id | If Ollama is running behind CLoudflare ZeroTrust, provide the Service Access ID here. | False |
| Cloudflare Access Client Secret | If Ollama is running behind CLoudflare ZeroTrust, provide the Service Access Secret here. | False |
| Default Model | Some commands allow you to specify a model. If no model is provided, this value will be used. | False |
Commands
You can execute these commands from the CLI, as part of an automation, or in a playbook.
After you successfully execute a command, a DBot message appears in the War Room with the command details.
ollama-list-models
Get a list of all available models
Base Command
ollama-list-models
Input
| Argument Name | Description | Required |
| — | — | — |
Context Output
| Path | Type | Description |
|---|---|---|
| ollama.models | unknown | Output of the command |
ollama-model-pull
Pull a model
Base Command
ollama-model-pull
Input
| Argument Name | Description | Required |
|---|---|---|
| model | Name of model to pull. See https://ollama.com/library for a list of options. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| ollama.pull | unknown | Output of the command |
ollama-model-delete
Delete a model
Base Command
ollama-model-delete
Input
| Argument Name | Description | Required |
|---|---|---|
| model | The name of the model to delete. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| ollama.delete | unknown | Output of the command |
ollama-conversation
General chat command that tracks the conversation history in the Incident.
Base Command
ollama-conversation
Input
| Argument Name | Description | Required |
|---|---|---|
| model | The model name. | Optional |
| message | The message to be sent. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| ollama.history | unknown | Output of the command |
ollama-model-info
Show information for a specific model.
Base Command
ollama-model-info
Input
| Argument Name | Description | Required |
|---|---|---|
| model | name of the model to show. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| ollama.show | unknown | Output of the command |
ollama-model-create
Create a new model from a Modelfile.
Base Command
ollama-model-create
Input
| Argument Name | Description | Required |
|---|---|---|
| model | name of the model to create. | Required |
| model_file | contents of the Modelfile. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| ollama.create | unknown | Output of the command |
ollama-generate
Generate a response for a given prompt with a provided model. Conversation history IS NOT tracked.
Base Command
ollama-generate
Input
| Argument Name | Description | Required |
|---|---|---|
| model | The model name. | Optional |
| message | The message to be sent. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| ollama.generate | unknown | Output of the command |
Configuration parameters
protocol— Protocolhost— Server hostname or IP (required)port— Port (required)path— Path (required)insecure— Trust any certificate (not secure)proxy— Use system proxy settingscf_id— Cloudflare Access Client Idcf_secret— Cloudflare Access Client Secretdefault_model— Default Model
Commands (7)
-
ollama-conversationGeneral chat command that tracks the conversation history in the Incident.
-
ollama-generateGenerate a response for a given prompt with a provided model. Conversation history IS NOT tracked.
-
ollama-list-modelsGet a list of all available models.
-
ollama-model-createCreate a new model from a Modelfile.
-
ollama-model-deleteDelete a model.
-
ollama-model-infoShow information for a specific model.
-
ollama-model-pullPull a model.
import math import demistomock as demisto # noqa: F401 from CommonServerPython import * # noqa: F401 """ CLIENT CLASS """ class Client(BaseClient): """Client class to interact with the service API This Client implements API calls, and does not contain any Demisto logic. Should only do requests and return data. It inherits from BaseClient defined in CommonServer Python. Most calls use _http_request() that handles proxy, SSL verification, etc. For this HelloWorld implementation, no special attributes defined """ def list_local_models(self): response = self._http_request("GET", "tags") return response def pull_model(self, model_name): response = self._http_request("POST", "pull", json_data={"name": model_name, "stream": False}) return response def delete_model(self, model_name): response = self._http_request("DELETE", "delete", json_data={"name": model_name}) return response def create_model(self, model_name, model_file): response = self._http_request("POST", "create", json_data={"name": model_name, "modelfile": model_file, "stream": False}) return response def show_model_info(self, model_name): response = self._http_request("POST", "show", json_data={"name": model_name}) return response def generate(self, model_name, message): response = self._http_request("POST", "generate", json_data={"model": model_name, "prompt": message, "stream": False}) return response def chat(self, model_name, history): response = self._http_request("POST", "chat", json_data={"model": model_name, "messages": history, "stream": False}) return response """ HELPER FUNCTIONS """ def convert_size(size_bytes): if size_bytes == 0: return "0B" size_name = ("B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB") i = int(math.floor(math.log(size_bytes, 1024))) p = math.pow(1024, i) s = round(size_bytes / p, 2) return f"{s} {size_name}" """ COMMAND FUNCTIONS """ def test_module(client: Client, params) -> str: try: client.list_local_models() return "ok" except DemistoException as e: if "Forbidden" in str(e): return "Authorization Error: make sure API Key is correctly set" raise DemistoException(str(e)) def list_local_models_command(client): """ List models that are available locally. """ response = client.list_local_models() results = [] for item in response["models"]: new_item = {"Name": item["name"], "Size": convert_size(item["size"])} results.append(new_item) readable = tableToMarkdown( name="List Local Models", t=results, metadata="Click here to access the models available for download: [here](https://ollama.com/library).", removeNull=True, ) return CommandResults( readable_output=readable, outputs_prefix="ollama.models", outputs_key_field="ollama.models", outputs=response ) def pull_model_command(client, model_name): """ Download a model from the ollama library. Cancelled pulls are resumed from where they left off, and multiple calls will share the same download progress. """ response = client.pull_model(model_name) if response["status"] == "success": readable = f"Successfully pulled the **{model_name}** model." return CommandResults( readable_output=readable, outputs_prefix="ollama.pull", outputs_key_field="ollama.pull", outputs=response ) else: readable = f"Failed to pull **{model_name}**." return CommandResults( readable_output=readable, outputs_prefix="ollama.pull", outputs_key_field="ollama.pull", outputs=response ) def show_model_info_command(client, model_name): """ Show information about a model including details, modelfile, template, parameters, license, and system prompt. """ response = client.show_model_info(model_name) # return json.dumps(response, indent=4) readable = tableToMarkdown("results", response) return CommandResults( readable_output=readable, outputs_prefix="ollama.show", outputs_key_field="ollama.show", outputs=response ) def delete_model_command(client, model_name): """ Delete a model and its data. """ response = client.delete_model(model_name) if response is None: readable = f"Successfully deleted the **{model_name}** model." return CommandResults( readable_output=readable, outputs_prefix="ollama.delete", outputs_key_field="ollama.delete", outputs=response ) else: readable = f"Failed to delete **{model_name}**." return CommandResults( readable_output=readable, outputs_prefix="ollama.delete", outputs_key_field="ollama.delete", outputs=response ) def create_model_command(client, model_name, model_file): """ Create a model from a Modelfile. """ response = client.create(model_name, model_file) readable = f"Successfully created **{model_name}**" return CommandResults( readable_output=readable, outputs_prefix="ollama.create", outputs_key_field="ollama.create", outputs=response ) def generate_command(client, model_name, message): """ Generate a response for a given prompt with a provided model. """ response = client.generate(model_name, message) readable = f"`{model_name}`: {response['response']}" return CommandResults( readable_output=readable, outputs_prefix="ollama.generate", outputs_key_field="ollama.generate", outputs=response["response"], ) def conversation_command(client, model_name, message, history): """ Generate the next message in a chat with a provided model. """ if history == {}: response = client.generate(model_name, message) readable = f"`{model_name}`: {response['response']}" return CommandResults( readable_output=readable, outputs_prefix="ollama.history", outputs_key_field="ollama.history", outputs=[{"role": "user", "content": message}, {"role": "assistant", "content": response["response"]}], ) else: history.append({"role": "user", "content": message}) response = client.chat(model_name, history) readable = f"`{model_name}`: {response['message']['content']}" readable = f"{response['message']['content']}" return CommandResults( readable_output=readable, outputs_prefix="ollama.history", outputs_key_field="ollama.history", outputs=[{"role": "user", "content": message}, response["message"]], ) """ MAIN FUNCTION """ def main() -> None: # pragma: no cover """ main function, parses params and runs command functions """ params = demisto.params() args = demisto.args() command = demisto.command() context = demisto.context() protocol = params.get("protocol", "https") host = params.get("host", "localhost") port = params.get("port", 11434) path = params.get("path", "/api") base_url = f"{protocol}://{host}:{port}{path}" verify_certificate = not params.get("insecure", False) proxy = params.get("proxy", False) demisto.debug(f"Command being called is {command}") try: cf_client_id = params.get("cf_id", None) cf_client_key = params.get("cf_secret", None) default_model = params.get("default_model", None) model_name = args.get("model", default_model) headers = {} if cf_client_id is not None and cf_client_key is not None: headers = {"CF-Access-Client-Id": cf_client_id, "CF-Access-Client-Secret": cf_client_key} client = Client(base_url=base_url, verify=verify_certificate, headers=headers, proxy=proxy, timeout=300) if command == "test-module": # This is the call made when pressing the integration Test button. result = test_module(client, params) return_results(result) elif command == "ollama-list-models": result = list_local_models_command(client) return_results(result) elif command == "ollama-model-pull": result = pull_model_command(client, model_name) return_results(result) elif command == "ollama-model-delete": result = delete_model_command(client, model_name) return_results(result) elif command == "ollama-model-create": model_file = args.get("model_file", None) result = create_model_command(client, model_name, model_file) return_results(result) elif command == "ollama-model-info": result = show_model_info_command(client, model_name) return_results(result) elif command == "ollama-generate": message = args.get("message", None) result = generate_command(client, model_name, message) return_results(result) elif command == "ollama-conversation": message = args.get("message", None) history = context.get("ollama", {}).get("history", {}) result = conversation_command(client, model_name, message, history) return_results(result) else: raise NotImplementedError(f"Command {command} is not implemented") # Log exceptions and return errors except Exception as e: return_error(f"Failed to execute `{command}` command.\nError:\n{e!s}") """ ENTRY POINT """ if __name__ in ("__main__", "__builtin__", "builtins"): main()