Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: matlab-deep-learning/llms-with-matlab
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v4.0.0
Choose a base ref
...
head repository: matlab-deep-learning/llms-with-matlab
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: main
Choose a head ref

Commits on Oct 30, 2024

  1. Drop OPENAI_KEY

    For some reason, we used both `OPENAI_KEY` and `OPENAI_API_KEY` env variables, expecting them to have the same values. Drop the `OPENAI_KEY` one, since we document our use of `OPENAI_API_KEY`.
    ccreutzi committed Oct 30, 2024

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    e16afaf View commit details

Commits on Oct 31, 2024

  1. Disable test point

    This test point runs fine on multiple dev machines (with updated Ollama), but fails in CI with an internal error to Ollama/llama.cpp:
    
    ```
      ================================================================================
      Error occurred in tollamaChat/generateWithImages and it did not run to completion.
          ---------
          Error ID:
          ---------
          'llms:apiReturnedError'
          --------------
          Error Details:
          --------------
          Error using ollamaChat/generate (line 238)
          Server returned error indicating: "an unknown error was encountered while
          running the model GGML_ASSERT(i01 >= 0 && i01 < ne01) failed"
    
          Error in tollamaChat>@(~)generate(chat,messages) (line 136)
                      text = arrayfun(@(~) generate(chat,messages), 1:5,
                      UniformOutput=false);
    
          Error in tollamaChat/generateWithImages (line 136)
                      text = arrayfun(@(~) generate(chat,messages), 1:5,
                      UniformOutput=false);
      ================================================================================
    ```
    
    See also ollama/ollama#7288
    ccreutzi committed Oct 31, 2024
    Copy the full SHA
    353d807 View commit details

Commits on Nov 1, 2024

  1. Remove configuration for codecov

    vpapanasta committed Nov 1, 2024
    Copy the full SHA
    739b5a2 View commit details

Commits on Nov 4, 2024

  1. Delete remaining coverage related lines in ci.yml

    vpapanasta committed Nov 4, 2024
    Copy the full SHA
    5b3ac4e View commit details
  2. Retain source-folder to base

    vpapanasta committed Nov 4, 2024
    Copy the full SHA
    6eb862e View commit details
  3. Add Enrico as code owner

    ccreutzi committed Nov 4, 2024
    Copy the full SHA
    b420b8b View commit details
  4. Merge pull request #82 from matlab-deep-learning/removeCodeCov

    Remove configuration for codecov
    vpapanasta authored Nov 4, 2024
    Copy the full SHA
    3dfac40 View commit details

Commits on Nov 5, 2024

  1. Disallow dlarray in prototype

    Using `dlarray` in a prototype results in `dlarray` in the output, but without the dimension labels. Reason: `cast(X,'like',Y)` behaves that way for `dlarray` `Y`.
    
    Given that we do not return higher-dimensional data anyway, it is questionable whether there is any reason one would want to allow `dlarray` in prototypes. Not handling them properly means we are better off disabling them altogether.
    
    Without a dependency on Deep Learning Toolbox, we cannot have an automated test point for this change, unfortunately.
    ccreutzi committed Nov 5, 2024
    Copy the full SHA
    e6199f3 View commit details
  2. Merge pull request #83 from matlab-deep-learning/add-enrico

    Add Enrico as code owner
    ccreutzi authored Nov 5, 2024
    Copy the full SHA
    8d4ca80 View commit details
  3. ToolChoice="none" for azureChat

    `azureChat` should support `ToolChoice="none"`
    ccreutzi committed Nov 5, 2024
    Copy the full SHA
    c5e2ef1 View commit details
  4. Return tool calls properly in azureChat

    Make `azureChat` handle tool calls returned the same way we do in `openAIChat`.
    ccreutzi committed Nov 5, 2024
    Copy the full SHA
    245e4b0 View commit details

Commits on Nov 13, 2024

  1. Stop warning in constructor for ResponseFormat="json"

    Since we now throw an error when `ResponseFormat="json"` is used without
    the required `"json"` in the inputs, we can stop warning in the constructor.
    With the previous state, users got a warning they could not avoid, even
    in code doing everything correctly.
    ccreutzi committed Nov 13, 2024
    Copy the full SHA
    2d0ec2d View commit details
  2. Sentiment to structured

    change example to using structured output
    ccreutzi committed Nov 13, 2024
    Copy the full SHA
    3b1db9d View commit details

Commits on Dec 13, 2024

  1. Structured ollama

    * Activate structured output for ollamaChat
    * Update documentation
    ccreutzi committed Dec 13, 2024
    Copy the full SHA
    44a3679 View commit details
  2. Copy the full SHA
    b8bfd78 View commit details
  3. remove local copies of mustBeNonzeroLengthTextScalar

    ccreutzi committed Dec 13, 2024
    Copy the full SHA
    25b8ffc View commit details

Commits on Dec 18, 2024

  1. More specific error messages: “numeric,” not “numeric or logical”

    ccreutzi committed Dec 18, 2024
    Copy the full SHA
    70baea5 View commit details
  2. Reduce output during tests

    runtests should not print unnecessary text to command window and test log
    ccreutzi committed Dec 18, 2024
    Copy the full SHA
    3f312b5 View commit details

Commits on Jan 23, 2025

  1. Properly accept char and cellstr in extractOpenAIEmbeddings

    Fixes #85
    ccreutzi committed Jan 23, 2025
    Copy the full SHA
    11a54ea View commit details

Commits on Jan 30, 2025

  1. Update list of supported models on OpenAI

    Add o1, remove the deprecated 3.5-0613 models.
    Change examples from outdated 3.5-turbo models to newer ones (picked at random).
    
    `topenAIChat/canUseModel` needed a change because the o1 models error with `MaxNumTokens=1`, as they need a few tokens to get the multiple stages started.
    ccreutzi committed Jan 30, 2025
    Copy the full SHA
    098c830 View commit details
  2. Support tool calling for ollamaChat

    * Switch from Mistral to Mistral NeMo
    
    Switch from Mistral to Mistral NeMo as the default model for tests and
    (tested) examples, to prepare for supporting function calls in `ollamaChat`.
    
    * Extract structured output tests
    
    * Activate structured output for ollamaChat
    
    * Improve error message when trying to use structured output with Ollama < 0.5.0
    
    * extract tool call tests
    
    * tool support for Ollama
    
    * Adapt messageHistory to support Ollama specifics
    
    * response streamer should capture tool calls outside OpenAI's format
    
    * add Ollama function calling example to texampleTests
    
    * Minimal documentation updates
    
    * Split llms:assistantMustHaveTextNameAndArguments in two
    
    To make the error messages simpler
    ccreutzi committed Jan 30, 2025
    Copy the full SHA
    b5121ec View commit details

Commits on Feb 3, 2025

  1. Add o3-mini to supported models

    ccreutzi committed Feb 3, 2025
    Copy the full SHA
    1c9e534 View commit details

Commits on Feb 7, 2025

  1. Update README.md

    MiriamScharnke authored and ccreutzi committed Feb 7, 2025
    Copy the full SHA
    ef2f01a View commit details
  2. Change models used in Ollama.md

    Changed phi-3 to mistral, and llava to moondream.
    MiriamScharnke authored and ccreutzi committed Feb 7, 2025
    Copy the full SHA
    b9e542a View commit details

Commits on Feb 10, 2025

  1. Fix broken link in README.md

    Add an additionally needed “requires Text Analytics Toolbox” for one of the examples which uses `tokenizedDocument`.
    MiriamScharnke authored and ccreutzi committed Feb 10, 2025
    Copy the full SHA
    fb8b1d9 View commit details

Commits on Feb 20, 2025

  1. Remove tests for gpt-3.5

    emanuzzi authored and ccreutzi committed Feb 20, 2025
    Copy the full SHA
    f42a4f0 View commit details

Commits on Feb 26, 2025

  1. OpenAI.md doc redraft

    Refactor for readability
    MiriamScharnke authored and ccreutzi committed Feb 26, 2025
    Copy the full SHA
    cbe5061 View commit details

Commits on Mar 3, 2025

  1. Ollama doc redraft

    Refactoring of Ollama.md
    MiriamScharnke authored and ccreutzi committed Mar 3, 2025
    Copy the full SHA
    b258ead View commit details
  2. Refactored Azure.md

    MiriamScharnke authored and ccreutzi committed Mar 3, 2025
    Copy the full SHA
    a6a1e8f View commit details
Showing with 2,078 additions and 1,234 deletions.
  1. +14 −2 +llms/+internal/callAzureChatAPI.m
  2. +28 −5 +llms/+internal/callOllamaChatAPI.m
  3. +27 −0 +llms/+internal/hasTools.m
  4. +1 −1 +llms/+internal/jsonSchemaFromPrototype.m
  5. +11 −1 +llms/+internal/sendRequest.m
  6. +1 −1 +llms/+internal/useSameFieldTypes.m
  7. +10 −6 +llms/+openai/models.m
  8. +1 −4 +llms/+openai/validateResponseFormat.m
  9. +7 −1 +llms/+stream/responseStreamer.m
  10. +13 −2 +llms/+utils/errorMessageCatalog.m
  11. +9 −0 +llms/+utils/requestsStructuredOutput.m
  12. +1 −1 .github/CODEOWNERS
  13. +2 −10 .github/workflows/ci.yml
  14. +76 −41 README.md
  15. +11 −40 azureChat.m
  16. +0 −3 codecov.yml
  17. +273 −160 doc/Azure.md
  18. +168 −69 doc/Ollama.md
  19. +167 −192 doc/OpenAI.md
  20. +2 −1 doc/functions/addToolMessage.md
  21. +1 −1 doc/functions/generate.md
  22. BIN doc/functions/images/azureEnvExample.png
  23. BIN doc/functions/images/boardwalk.png
  24. BIN doc/functions/images/envExample.png
  25. BIN doc/functions/images/octopus.png
  26. +43 −6 doc/functions/ollamaChat.md
  27. +5 −2 doc/functions/openAIFunction.md
  28. +0 −88 examples/AnalyzeSentimentinTextUsingChatGPTinJSONMode.md
  29. +94 −0 examples/AnalyzeSentimentinTextUsingChatGPTwithStructuredOutput.md
  30. +19 −14 examples/AnalyzeTextDataUsingParallelFunctionCallwithChatGPT.md
  31. +215 −0 examples/AnalyzeTextDataUsingParallelFunctionCallwithOllama.md
  32. +8 −12 examples/CreateSimpleChatBot.md
  33. +191 −70 examples/CreateSimpleOllamaChatBot.md
  34. +11 −15 examples/ProcessGeneratedTextInRealTimeByUsingOllamaInStreamingMode.md
  35. +22 −27 examples/RetrievalAugmentedGenerationUsingOllamaAndMATLAB.md
  36. BIN examples/mlx-scripts/AnalyzeSentimentinTextUsingChatGPTinJSONMode.mlx
  37. BIN examples/mlx-scripts/AnalyzeSentimentinTextUsingChatGPTwithStructuredOutput.mlx
  38. BIN examples/mlx-scripts/AnalyzeTextDataUsingParallelFunctionCallwithChatGPT.mlx
  39. BIN examples/mlx-scripts/AnalyzeTextDataUsingParallelFunctionCallwithOllama.mlx
  40. BIN examples/mlx-scripts/CreateSimpleChatBot.mlx
  41. BIN examples/mlx-scripts/CreateSimpleOllamaChatBot.mlx
  42. BIN examples/mlx-scripts/ProcessGeneratedTextInRealTimeByUsingOllamaInStreamingMode.mlx
  43. BIN examples/mlx-scripts/RetrievalAugmentedGenerationUsingOllamaAndMATLAB.mlx
  44. +8 −6 extractOpenAIEmbeddings.m
  45. +31 −22 messageHistory.m
  46. +71 −17 ollamaChat.m
  47. +7 −36 openAIChat.m
  48. +7 −12 openAIImages.m
  49. +3 −245 tests/hopenAIChat.m
  50. +149 −0 tests/hstructuredOutput.m
  51. +98 −0 tests/htoolCalls.m
  52. BIN tests/recordings/AnalyzeScientificPapersUsingFunctionCalls.mat
  53. BIN tests/recordings/AnalyzeSentimentinTextUsingChatGPTinJSONMode.mat
  54. BIN tests/recordings/AnalyzeSentimentinTextUsingChatGPTwithStructuredOutput.mat
  55. BIN tests/recordings/AnalyzeTextDataUsingParallelFunctionCallwithChatGPT.mat
  56. BIN tests/recordings/AnalyzeTextDataUsingParallelFunctionCallwithOllama.mat
  57. BIN tests/recordings/CreateSimpleChatBot.mat
  58. BIN tests/recordings/CreateSimpleOllamaChatBot.mat
  59. BIN tests/recordings/DescribeImagesUsingChatGPT.mat
  60. BIN tests/recordings/InformationRetrievalUsingOpenAIDocumentEmbedding.mat
  61. BIN tests/recordings/ProcessGeneratedTextInRealTimeByUsingOllamaInStreamingMode.mat
  62. BIN tests/recordings/ProcessGeneratedTextinRealTimebyUsingChatGPTinStreamingMode.mat
  63. BIN tests/recordings/RetrievalAugmentedGenerationUsingChatGPTandMATLAB.mat
  64. BIN tests/recordings/RetrievalAugmentedGenerationUsingOllamaAndMATLAB.mat
  65. BIN tests/recordings/SummarizeLargeDocumentsUsingChatGPTandMATLAB.mat
  66. BIN tests/recordings/UsingDALLEToEditImages.mat
  67. BIN tests/recordings/UsingDALLEToGenerateImages.mat
  68. +21 −36 tests/tazureChat.m
  69. +27 −0 tests/terrorMessageCatalog.m
  70. +22 −18 tests/texampleTests.m
  71. +39 −18 tests/textractOpenAIEmbeddings.m
  72. +32 −5 tests/tmessageHistory.m
  73. +114 −21 tests/tollamaChat.m
  74. +6 −6 tests/topenAIChat.m
  75. +12 −17 tests/topenAIImages.m
16 changes: 14 additions & 2 deletions +llms/+internal/callAzureChatAPI.m
Original file line number Diff line number Diff line change
@@ -73,8 +73,20 @@
if isempty(nvp.StreamFun)
message = response.Body.Data.choices(1).message;
else
message = struct("role", "assistant", ...
"content", streamedText);
pat = '{"' + wildcardPattern + '":';
if contains(streamedText,pat)
s = jsondecode(streamedText);
if contains(s.function.arguments,pat)
prompt = jsondecode(s.function.arguments);
s.function.arguments = prompt;
end
message = struct("role", "assistant", ...
"content",[], ...
"tool_calls",jsondecode(streamedText));
else
message = struct("role", "assistant", ...
"content", streamedText);
end
end
if isfield(message, "tool_choice")
text = "";
33 changes: 28 additions & 5 deletions +llms/+internal/callOllamaChatAPI.m
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
function [text, message, response] = callOllamaChatAPI(model, messages, nvp)
function [text, message, response] = callOllamaChatAPI(model, messages, functions, nvp)
% This function is undocumented and will change in a future release

%callOllamaChatAPI Calls the Ollama™ chat completions API.
@@ -22,11 +22,13 @@
% % Send a request
% [text, message] = llms.internal.callOllamaChatAPI(model, messages)

% Copyright 2023-2024 The MathWorks, Inc.
% Copyright 2023-2025 The MathWorks, Inc.

arguments
model
messages
functions
nvp.ToolChoice
nvp.Temperature
nvp.TopP
nvp.MinP
@@ -52,7 +54,7 @@
nvp.StopSequences = [nvp.StopSequences, nvp.StopSequences];
end

parameters = buildParametersCall(model, messages, nvp);
parameters = buildParametersCall(model, messages, functions, nvp);

[response, streamedText] = llms.internal.sendRequestWrapper(parameters,[],URL,nvp.TimeOut,nvp.StreamFun);

@@ -61,7 +63,11 @@
if response.StatusCode=="OK"
% Outputs the first generation
if isempty(nvp.StreamFun)
message = response.Body.Data.message;
if iscell(response.Body.Data)
message = response.Body.Data{1}.message;
else
message = response.Body.Data.message;
end
else
message = struct("role", "assistant", ...
"content", streamedText);
@@ -73,7 +79,7 @@
end
end

function parameters = buildParametersCall(model, messages, nvp)
function parameters = buildParametersCall(model, messages, functions, nvp)
% Builds a struct in the format that is expected by the API, combining
% MESSAGES, FUNCTIONS and parameters in NVP.

@@ -83,7 +89,24 @@

parameters.stream = ~isempty(nvp.StreamFun);

if ~isempty(functions)
parameters.tools = functions;
end

if ~isempty(nvp.ToolChoice)
parameters.tool_choice = nvp.ToolChoice;
end

options = struct;

if strcmp(nvp.ResponseFormat,"json")
parameters.format = struct('type','json_object');
elseif isstruct(nvp.ResponseFormat)
parameters.format = llms.internal.jsonSchemaFromPrototype(nvp.ResponseFormat);
elseif startsWith(string(nvp.ResponseFormat), asManyOfPattern(whitespacePattern)+"{")
parameters.format = llms.internal.verbatimJSON(nvp.ResponseFormat);
end

if ~isempty(nvp.Seed)
options.seed = nvp.Seed;
end
27 changes: 27 additions & 0 deletions +llms/+internal/hasTools.m
Original file line number Diff line number Diff line change
@@ -12,4 +12,31 @@
Tools
FunctionsStruct
end

methods(Hidden)
function mustBeValidFunctionCall(this, functionCall)
if ~isempty(functionCall)
mustBeTextScalar(functionCall);
if isempty(this.FunctionNames)
error("llms:mustSetFunctionsForCall", llms.utils.errorMessageCatalog.getMessage("llms:mustSetFunctionsForCall"));
end
mustBeMember(functionCall, ["none","auto", this.FunctionNames]);
end
end

function toolChoice = convertToolChoice(this, toolChoice)
% if toolChoice is empty
if isempty(toolChoice)
% if Tools is not empty, the default is 'auto'.
if ~isempty(this.Tools)
toolChoice = "auto";
end
elseif ~ismember(toolChoice,["auto","none"])
% if toolChoice is not empty, then it must be "auto", "none" or in the format
% {"type": "function", "function": {"name": "my_function"}}
toolChoice = struct("type","function","function",struct("name",toolChoice));
end

end
end
end
2 changes: 1 addition & 1 deletion +llms/+internal/jsonSchemaFromPrototype.m
Original file line number Diff line number Diff line change
@@ -27,7 +27,7 @@
schema = struct("type","string");
elseif isinteger(prototype)
schema = struct("type","integer");
elseif isnumeric(prototype)
elseif isnumeric(prototype) && ~isa(prototype,'dlarray')
schema = struct("type","number");
elseif islogical(prototype)
schema = struct("type","boolean");
12 changes: 11 additions & 1 deletion +llms/+internal/sendRequest.m
Original file line number Diff line number Diff line change
@@ -5,7 +5,7 @@
% api key TOKEN. TIMEOUT is the number of seconds to wait for initial
% server connection. STREAMFUN is an optional callback function.

% Copyright 2023-2024 The MathWorks, Inc.
% Copyright 2023-2025 The MathWorks, Inc.

arguments
parameters
@@ -42,4 +42,14 @@
response = send(request, matlab.net.URI(endpoint),httpOpts,consumer);
streamedText = consumer.ResponseText;
end

% When the server sends jsonl or ndjson back, we do not get the automatic conversion.
if isnumeric(response.Body.Data)
txt = native2unicode(response.Body.Data.',"UTF-8");
% convert to JSON array
json = "[" + replace(strtrim(txt),newline,',') + "]";
try
response.Body.Data = jsondecode(json);
end
end
end
2 changes: 1 addition & 1 deletion +llms/+internal/useSameFieldTypes.m
Original file line number Diff line number Diff line change
@@ -21,7 +21,7 @@
case "struct"
prototype = prototype(1);
if isscalar(data)
if isequal(fieldnames(data),fieldnames(prototype))
if isequal(sort(fieldnames(data)),sort(fieldnames(prototype)))
for field_c = fieldnames(data).'
field = field_c{1};
data.(field) = alignTypes(data.(field),prototype.(field));
16 changes: 10 additions & 6 deletions +llms/+openai/models.m
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
function models = models
%MODELS - supported OpenAI models

% Copyright 2024 The MathWorks, Inc.
% Copyright 2024-2025 The MathWorks, Inc.
models = [...
"gpt-4o","gpt-4o-2024-05-13",...
"gpt-4o","gpt-4o-2024-05-13","gpt-4o-2024-08-06","gpt-4o-2024-11-20",...
"chatgpt-4o-latest",...
"gpt-4o-mini","gpt-4o-mini-2024-07-18",...
"gpt-4-turbo","gpt-4-turbo-2024-04-09",...
"gpt-4","gpt-4-0613", ...
"gpt-4-turbo","gpt-4-turbo-2024-04-09","gpt-4-turbo-preview",...
"gpt-4","gpt-4-0125-preview","gpt-4-0613","gpt-4-1106-preview",...
"gpt-3.5-turbo","gpt-3.5-turbo-0125", ...
"gpt-3.5-turbo-1106",...
"o1-preview",...
"o1-mini",...
"gpt-3.5-turbo-16k",...
"o1-preview","o1-preview-2024-09-12",...
"o1-mini","o1-mini-2024-09-12",...
"o1","o1-2024-12-17",...
"o3-mini", "o3-mini-2025-01-31",...
];
end
5 changes: 1 addition & 4 deletions +llms/+openai/validateResponseFormat.m
Original file line number Diff line number Diff line change
@@ -9,7 +9,7 @@ function validateResponseFormat(format,model,messages)
end

if isequal(format, "json")
if ismember(model,["gpt-4","gpt-4-0613","o1-preview","o1-mini"])
if ismember(model,["gpt-4","gpt-4-0613","o1-preview","o1-mini","o1"])
error("llms:invalidOptionAndValueForModel", ...
llms.utils.errorMessageCatalog.getMessage("llms:invalidOptionAndValueForModel", "ResponseFormat", "json", model));
elseif nargin > 2
@@ -18,9 +18,6 @@ function validateResponseFormat(format,model,messages)
error("llms:warningJsonInstruction", ...
llms.utils.errorMessageCatalog.getMessage("llms:warningJsonInstruction"))
end
else
warning("llms:warningJsonInstruction", ...
llms.utils.errorMessageCatalog.getMessage("llms:warningJsonInstruction"))
end
elseif requestsStructuredOutput(format)
if ~startsWith(model,"gpt-4o")
8 changes: 7 additions & 1 deletion +llms/+stream/responseStreamer.m
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@
%responseStreamer Responsible for obtaining the streaming results from the
%API

% Copyright 2023 The MathWorks, Inc.
% Copyright 2023-2025 The MathWorks, Inc.

properties
ResponseText
@@ -97,6 +97,12 @@
this.StreamFun(txt);
this.ResponseText = [this.ResponseText txt];
end
if isfield(json.message,"tool_calls")
s = json.message.tool_calls;
txt = jsonencode(s);
this.StreamFun('');
this.ResponseText = [this.ResponseText txt];
end
if isfield(json,"done")
stop = json.done;
end
15 changes: 13 additions & 2 deletions +llms/+utils/errorMessageCatalog.m
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
classdef errorMessageCatalog
%errorMessageCatalog Stores the error messages from this repository

% Copyright 2023-2024 The MathWorks, Inc.
% Copyright 2023-2025 The MathWorks, Inc.

properties(Constant)
%CATALOG dictionary mapping error ids to error msgs
@@ -28,6 +28,15 @@
end
end
end

function s = createCatalog()
%createCatalog will run the initialization code and return the catalog
% This is only meant to get more correct test coverage reports:
% The test coverage reports do not include the properties initialization
% for Catalog from above, so we have a test seam here to re-run it
% within the framework, where it is reported.
s = buildErrorMessageCatalog;
end
end
end

@@ -40,7 +49,8 @@
catalog("llms:mustBeAssistantWithContent") = "Input struct must contain field 'content' containing text with one or more characters.";
catalog("llms:mustBeAssistantWithIdAndFunction") = "Field 'tool_call' must be a struct with fields 'id' and 'function'.";
catalog("llms:mustBeAssistantWithNameAndArguments") = "Field 'function' must be a struct with fields 'name' and 'arguments'.";
catalog("llms:assistantMustHaveTextNameAndArguments") = "Fields 'name' and 'arguments' must be text with one or more characters.";
catalog("llms:assistantMustHaveTextName") = "Field 'name' must be text with one or more characters.";
catalog("llms:assistantMustHaveTextOrStructArguments") = "Field 'arguments' must be text with one or more characters, or a scalar struct.";
catalog("llms:mustBeValidIndex") = "Index exceeds the number of array elements. Index must be less than or equal to {1}.";
catalog("llms:removeFromEmptyHistory") = "Unable to remove message from empty message history.";
catalog("llms:stopSequencesMustHaveMax4Elements") = "Number of stop sequences must be less than or equal to 4.";
@@ -66,4 +76,5 @@
catalog("llms:stream:responseStreamer:InvalidInput") = "Input does not have the expected json format, got ""{1}"".";
catalog("llms:unsupportedDatatypeInPrototype") = "Invalid data type ''{1}'' in prototype. Prototype must be a struct, composed of numerical, string, logical, categorical, or struct.";
catalog("llms:incorrectResponseFormat") = "Invalid response format. Response format must be ""text"", ""json"", a struct, or a string with a JSON Schema definition.";
catalog("llms:OllamaStructuredOutputNeeds05") = "Structured output is not supported for Ollama version {1}. Use version 0.5.0 or newer.";
end
9 changes: 9 additions & 0 deletions +llms/+utils/requestsStructuredOutput.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
function tf = requestsStructuredOutput(format)
% This function is undocumented and will change in a future release

% Simple function to check if requested format triggers structured output

% Copyright 2024 The MathWorks, Inc.
tf = isstruct(format) || startsWith(format,asManyOfPattern(whitespacePattern)+"{");
end

2 changes: 1 addition & 1 deletion .github/CODEOWNERS
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Code owners, to get auto-filled reviewer lists

# To start with, we just assume everyone in the core team is included on all reviews
* @adulai @ccreutzi @debymf @MiriamScharnke @vpapanasta
* @adulai @ccreutzi @debymf @MiriamScharnke @vpapanasta @emanuzzi
12 changes: 2 additions & 10 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -29,7 +29,7 @@ jobs:
- name: Pull models
run: |
ollama pull mistral
ollama pull mistral-nemo
ollama pull moondream
OLLAMA_HOST=127.0.0.1:11435 ollama pull qwen2:0.5b
- name: Set up MATLAB
@@ -39,19 +39,11 @@ jobs:
cache: true
- name: Run tests and generate artifacts
env:
OPENAI_KEY: ${{ secrets.OPENAI_KEY }}
OPENAI_API_KEY: ${{ secrets.OPENAI_KEY }}
AZURE_OPENAI_DEPLOYMENT: ${{ secrets.AZURE_DEPLOYMENT }}
AZURE_OPENAI_ENDPOINT: ${{ secrets.AZURE_ENDPOINT }}
AZURE_OPENAI_API_KEY: ${{ secrets.AZURE_KEY }}
SECOND_OLLAMA_ENDPOINT: 127.0.0.1:11435
uses: matlab-actions/run-tests@v2
with:
test-results-junit: test-results/results.xml
code-coverage-cobertura: code-coverage/coverage.xml
source-folder: .
- name: Upload coverage reports to Codecov
uses: codecov/codecov-action@v4
with:
token: ${{ secrets.CODECOV_TOKEN }}
slug: matlab-deep-learning/llms-with-matlab
source-folder: .
Loading