Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
OpenDAS
ollama
Commits
b2554455
Unverified
Commit
b2554455
authored
Jul 17, 2024
by
Michael Yang
Committed by
GitHub
Jul 17, 2024
Browse files
marshal json automatically for some template values (#5758)
parent
b23424bb
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
72 additions
and
52 deletions
+72
-52
api/types.go
api/types.go
+48
-25
server/model.go
server/model.go
+10
-8
server/model_test.go
server/model_test.go
+4
-9
server/testdata/tools/command-r-plus.gotmpl
server/testdata/tools/command-r-plus.gotmpl
+1
-1
server/testdata/tools/firefunction.gotmpl
server/testdata/tools/firefunction.gotmpl
+2
-2
server/testdata/tools/llama3-groq-tool-use.gotmpl
server/testdata/tools/llama3-groq-tool-use.gotmpl
+2
-2
server/testdata/tools/mistral.gotmpl
server/testdata/tools/mistral.gotmpl
+2
-2
template/template.go
template/template.go
+3
-3
No files found.
api/types.go
View file @
b2554455
...
...
@@ -101,12 +101,19 @@ type ChatRequest struct {
KeepAlive
*
Duration
`json:"keep_alive,omitempty"`
// Tools is an optional list of tools the model has access to.
Tools
[]
Tool
`json:"tools,omitempty"`
Tools
`json:"tools,omitempty"`
// Options lists model-specific options.
Options
map
[
string
]
interface
{}
`json:"options"`
}
type
Tools
[]
Tool
func
(
t
Tools
)
String
()
string
{
bts
,
_
:=
json
.
Marshal
(
t
)
return
string
(
bts
)
}
// Message is a single message in a chat sequence. The message contains the
// role ("system", "user", or "assistant"), the content and an optional list
// of images.
...
...
@@ -117,30 +124,6 @@ type Message struct {
ToolCalls
[]
ToolCall
`json:"tool_calls,omitempty"`
}
type
ToolCall
struct
{
Function
struct
{
Name
string
`json:"name"`
Arguments
map
[
string
]
any
`json:"arguments"`
}
`json:"function"`
}
type
Tool
struct
{
Type
string
`json:"type"`
Function
struct
{
Name
string
`json:"name"`
Description
string
`json:"description"`
Parameters
struct
{
Type
string
`json:"type"`
Required
[]
string
`json:"required"`
Properties
map
[
string
]
struct
{
Type
string
`json:"type"`
Description
string
`json:"description"`
Enum
[]
string
`json:"enum,omitempty"`
}
`json:"properties"`
}
`json:"parameters"`
}
`json:"function"`
}
func
(
m
*
Message
)
UnmarshalJSON
(
b
[]
byte
)
error
{
type
Alias
Message
var
a
Alias
...
...
@@ -153,6 +136,46 @@ func (m *Message) UnmarshalJSON(b []byte) error {
return
nil
}
type
ToolCall
struct
{
Function
ToolCallFunction
`json:"function"`
}
type
ToolCallFunction
struct
{
Name
string
`json:"name"`
Arguments
ToolCallFunctionArguments
`json:"arguments"`
}
type
ToolCallFunctionArguments
map
[
string
]
any
func
(
t
*
ToolCallFunctionArguments
)
String
()
string
{
bts
,
_
:=
json
.
Marshal
(
t
)
return
string
(
bts
)
}
type
Tool
struct
{
Type
string
`json:"type"`
Function
ToolFunction
`json:"function"`
}
type
ToolFunction
struct
{
Name
string
`json:"name"`
Description
string
`json:"description"`
Parameters
struct
{
Type
string
`json:"type"`
Required
[]
string
`json:"required"`
Properties
map
[
string
]
struct
{
Type
string
`json:"type"`
Description
string
`json:"description"`
Enum
[]
string
`json:"enum,omitempty"`
}
`json:"properties"`
}
`json:"parameters"`
}
func
(
t
*
ToolFunction
)
String
()
string
{
bts
,
_
:=
json
.
Marshal
(
t
)
return
string
(
bts
)
}
// ChatResponse is the response returned by [Client.Chat]. Its fields are
// similar to [GenerateResponse].
type
ChatResponse
struct
{
...
...
server/model.go
View file @
b2554455
...
...
@@ -311,12 +311,14 @@ func (m *Model) parseToolCalls(s string) ([]api.ToolCall, bool) {
}
var
b
bytes
.
Buffer
if
err
:=
tmpl
.
Execute
(
&
b
,
map
[
string
][]
m
ap
[
string
]
any
{
if
err
:=
tmpl
.
Execute
(
&
b
,
map
[
string
][]
ap
i
.
ToolCall
{
"ToolCalls"
:
{
{
"Function"
:
map
[
string
]
any
{
"Name"
:
"@@name@@"
,
"Arguments"
:
"@@arguments@@"
,
Function
:
api
.
ToolCallFunction
{
Name
:
"@@name@@"
,
Arguments
:
api
.
ToolCallFunctionArguments
{
"@@argument@@"
:
1
,
},
},
},
},
...
...
@@ -324,7 +326,7 @@ func (m *Model) parseToolCalls(s string) ([]api.ToolCall, bool) {
return
nil
,
false
}
var
kv
map
[
string
]
string
var
kv
map
[
string
]
any
// execute the subtree with placeholders to identify the keys
// trim any commands that might exist in the template
if
err
:=
json
.
Unmarshal
(
bytes
.
TrimSuffix
(
b
.
Bytes
(),
[]
byte
(
","
)),
&
kv
);
err
!=
nil
{
...
...
@@ -334,10 +336,10 @@ func (m *Model) parseToolCalls(s string) ([]api.ToolCall, bool) {
// find the keys that correspond to the name and arguments fields
var
name
,
arguments
string
for
k
,
v
:=
range
kv
{
switch
v
{
case
"@@name@@"
:
switch
v
.
(
type
)
{
case
string
:
name
=
k
case
"@@arguments@@"
:
case
map
[
string
]
any
:
arguments
=
k
}
}
...
...
server/model_test.go
View file @
b2554455
...
...
@@ -115,11 +115,6 @@ func TestExtractFromZipFile(t *testing.T) {
}
}
type
function
struct
{
Name
string
`json:"name"`
Arguments
map
[
string
]
any
`json:"arguments"`
}
func
readFile
(
t
*
testing
.
T
,
base
,
name
string
)
*
bytes
.
Buffer
{
t
.
Helper
()
...
...
@@ -185,18 +180,18 @@ The temperature in San Francisco, CA is 70°F and in Toronto, Canada is 20°C.`,
calls
:=
[]
api
.
ToolCall
{
{
Function
:
f
unction
{
Function
:
api
.
ToolCallF
unction
{
Name
:
"get_current_weather"
,
Arguments
:
m
ap
[
string
]
any
{
Arguments
:
ap
i
.
ToolCallFunctionArguments
{
"format"
:
"fahrenheit"
,
"location"
:
"San Francisco, CA"
,
},
},
},
{
Function
:
f
unction
{
Function
:
api
.
ToolCallF
unction
{
Name
:
"get_current_weather"
,
Arguments
:
m
ap
[
string
]
any
{
Arguments
:
ap
i
.
ToolCallFunctionArguments
{
"format"
:
"celsius"
,
"location"
:
"Toronto, Canada"
,
},
...
...
server/testdata/tools/command-r-plus.gotmpl
View file @
b2554455
...
...
@@ -46,7 +46,7 @@ Action: ```json
{{- range .ToolCalls }}
{
"tool_name": "{{ .Function.Name }}",
"parameters": {{
json
.Function.Arguments }}
"parameters": {{ .Function.Arguments }}
}
{{- end }}
]```
...
...
server/testdata/tools/firefunction.gotmpl
View file @
b2554455
...
...
@@ -17,7 +17,7 @@ If you decide to call functions:
Available functions as JSON spec:
{{- if .Tools }}
{{
json
.Tools }}
{{ .Tools }}
{{- end }}<|eot_id|>
{{- end }}
{{- range .Messages }}<|start_header_id|>
...
...
@@ -25,7 +25,7 @@ Available functions as JSON spec:
{{- end }}<|end_header_id|>
{{- if .Content }}{{ .Content }}
{{- else if .ToolCalls }} functools[
{{- range .ToolCalls }}{{ "{" }}"name": "{{ .Function.Name }}", "arguments": {{
json
.Function.Arguments }}{{ "}" }}
{{- range .ToolCalls }}{{ "{" }}"name": "{{ .Function.Name }}", "arguments": {{ .Function.Arguments }}{{ "}" }}
{{- end }}]
{{- end }}<|eot_id|>
{{- end }}<|start_header_id|>assistant<|end_header_id|>
\ No newline at end of file
server/testdata/tools/llama3-groq-tool-use.gotmpl
View file @
b2554455
...
...
@@ -9,7 +9,7 @@
Here are the available tools:
<tools>
{{- range .Tools }} {{
json
.Function }}
{{- range .Tools }} {{ .Function }}
{{- end }} </tools>
{{- end }}
{{- end }}<|eot_id|>
...
...
@@ -20,7 +20,7 @@ Here are the available tools:
{{- else if eq .Role "assistant" }}
{{- if .Content }}{{ .Content }}
{{- else if .ToolCalls }}<tool_call>
{{ range .ToolCalls }}{"name": "{{ .Function.Name }}", "arguments": {{
json
.Function.Arguments }}}
{{ range .ToolCalls }}{"name": "{{ .Function.Name }}", "arguments": {{ .Function.Arguments }}}
{{- end }}
</tool_call>
{{- end }}
...
...
server/testdata/tools/mistral.gotmpl
View file @
b2554455
{{- range $index, $_ := .Messages }}
{{- if eq .Role "user" }}
{{- if and (eq (len (slice $.Messages $index)) 1) $.Tools }}[AVAILABLE_TOOLS] {{
json
$.Tools }}[/AVAILABLE_TOOLS]
{{- if and (eq (len (slice $.Messages $index)) 1) $.Tools }}[AVAILABLE_TOOLS] {{ $.Tools }}[/AVAILABLE_TOOLS]
{{- end }}[INST] {{ if and (eq (len (slice $.Messages $index)) 1) $.System }}{{ $.System }}
{{ end }}{{ .Content }}[/INST]
{{- else if eq .Role "assistant" }}
{{- if .Content }} {{ .Content }}</s>
{{- else if .ToolCalls }}[TOOL_CALLS] [
{{- range .ToolCalls }}{"name": "{{ .Function.Name }}", "arguments": {{
json
.Function.Arguments }}}
{{- range .ToolCalls }}{"name": "{{ .Function.Name }}", "arguments": {{ .Function.Arguments }}}
{{- end }}]</s>
{{- end }}
{{- else if eq .Role "tool" }}[TOOL_RESULTS] {"content": {{ .Content }}}[/TOOL_RESULTS]
...
...
template/template.go
View file @
b2554455
...
...
@@ -150,9 +150,9 @@ func (t *Template) Vars() []string {
type
Values
struct
{
Messages
[]
api
.
Message
Tools
[]
api
.
Tool
Prompt
string
Suffix
string
api
.
Tool
s
Prompt
string
Suffix
string
// forceLegacy is a flag used to test compatibility with legacy templates
forceLegacy
bool
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment