@sisu-ai/adapter-ollama 7.0.0 → 8.0.1
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/package.json +2 -2
- package/dist/src/index.d.ts +0 -7
- package/dist/src/index.js +0 -112
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sisu-ai/adapter-ollama",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "8.0.1",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"build": "tsc -b"
|
|
25
25
|
},
|
|
26
26
|
"peerDependencies": {
|
|
27
|
-
"@sisu-ai/core": "2.1
|
|
27
|
+
"@sisu-ai/core": "2.2.1"
|
|
28
28
|
},
|
|
29
29
|
"keywords": [
|
|
30
30
|
"sisu",
|
package/dist/src/index.d.ts
DELETED
package/dist/src/index.js
DELETED
|
@@ -1,112 +0,0 @@
|
|
|
1
|
-
export function ollamaAdapter(opts) {
|
|
2
|
-
const envBase = process.env.OLLAMA_BASE_URL || process.env.BASE_URL;
|
|
3
|
-
const baseUrl = (opts.baseUrl ?? envBase ?? 'http://localhost:11434').replace(/\/$/, '');
|
|
4
|
-
const modelName = `ollama:${opts.model}`;
|
|
5
|
-
return {
|
|
6
|
-
name: modelName,
|
|
7
|
-
capabilities: { functionCall: true, streaming: false },
|
|
8
|
-
async generate(messages, genOpts) {
|
|
9
|
-
// Map messages to Ollama format; include assistant tool_calls and tool messages
|
|
10
|
-
const mapped = messages.map((m) => {
|
|
11
|
-
const base = { role: m.role };
|
|
12
|
-
if (m.role === 'assistant' && Array.isArray(m.tool_calls)) {
|
|
13
|
-
base.tool_calls = m.tool_calls.map((tc) => ({ id: tc.id, type: 'function', function: { name: tc.name, arguments: (tc.arguments ?? {}) } }));
|
|
14
|
-
base.content = m.content ? String(m.content) : null;
|
|
15
|
-
}
|
|
16
|
-
else if (m.role === 'tool') {
|
|
17
|
-
base.content = String(m.content ?? '');
|
|
18
|
-
if (m.tool_call_id)
|
|
19
|
-
base.tool_call_id = m.tool_call_id;
|
|
20
|
-
if (m.name && !m.tool_call_id)
|
|
21
|
-
base.name = m.name;
|
|
22
|
-
}
|
|
23
|
-
else {
|
|
24
|
-
base.content = String(m.content ?? '');
|
|
25
|
-
}
|
|
26
|
-
return base;
|
|
27
|
-
});
|
|
28
|
-
const toolsParam = (genOpts?.tools ?? []).map(toOllamaTool);
|
|
29
|
-
const body = { model: opts.model, messages: mapped, stream: false };
|
|
30
|
-
if (toolsParam.length)
|
|
31
|
-
body.tools = toolsParam;
|
|
32
|
-
const res = await fetch(`${baseUrl}/api/chat`, {
|
|
33
|
-
method: 'POST',
|
|
34
|
-
headers: {
|
|
35
|
-
'Content-Type': 'application/json',
|
|
36
|
-
Accept: 'application/json',
|
|
37
|
-
...(opts.headers ?? {}),
|
|
38
|
-
},
|
|
39
|
-
body: JSON.stringify(body),
|
|
40
|
-
});
|
|
41
|
-
const raw = await res.text();
|
|
42
|
-
if (!res.ok) {
|
|
43
|
-
let details = raw;
|
|
44
|
-
try {
|
|
45
|
-
const j = JSON.parse(raw);
|
|
46
|
-
details = j.error ?? j.message ?? raw;
|
|
47
|
-
}
|
|
48
|
-
catch { }
|
|
49
|
-
throw new Error(`Ollama API error: ${res.status} ${res.statusText} — ${String(details).slice(0, 500)}`);
|
|
50
|
-
}
|
|
51
|
-
const data = raw ? JSON.parse(raw) : {};
|
|
52
|
-
// /api/chat response example (non-stream): { message: { role:'assistant', content:'...', tool_calls?: [...] }, done: true }
|
|
53
|
-
const choice = data?.message ?? {};
|
|
54
|
-
const content = choice?.content ?? '';
|
|
55
|
-
const tcs = Array.isArray(choice?.tool_calls)
|
|
56
|
-
? choice.tool_calls.map((tc) => ({ id: tc.id, name: tc.function?.name, arguments: safeJson(tc.function?.arguments) }))
|
|
57
|
-
: undefined;
|
|
58
|
-
const out = { role: 'assistant', content: String(content ?? '') };
|
|
59
|
-
if (tcs)
|
|
60
|
-
out.tool_calls = tcs;
|
|
61
|
-
return { message: out };
|
|
62
|
-
},
|
|
63
|
-
};
|
|
64
|
-
}
|
|
65
|
-
function toOllamaTool(tool) {
|
|
66
|
-
return {
|
|
67
|
-
type: 'function',
|
|
68
|
-
function: {
|
|
69
|
-
name: tool.name,
|
|
70
|
-
description: tool.description,
|
|
71
|
-
parameters: toJsonSchema(tool.schema),
|
|
72
|
-
},
|
|
73
|
-
};
|
|
74
|
-
}
|
|
75
|
-
function toJsonSchema(schema) {
|
|
76
|
-
if (!schema)
|
|
77
|
-
return { type: 'object' };
|
|
78
|
-
const t = schema?._def?.typeName;
|
|
79
|
-
if (t === 'ZodString')
|
|
80
|
-
return { type: 'string' };
|
|
81
|
-
if (t === 'ZodNumber')
|
|
82
|
-
return { type: 'number' };
|
|
83
|
-
if (t === 'ZodBoolean')
|
|
84
|
-
return { type: 'boolean' };
|
|
85
|
-
if (t === 'ZodArray')
|
|
86
|
-
return { type: 'array', items: toJsonSchema(schema._def?.type) };
|
|
87
|
-
if (t === 'ZodOptional')
|
|
88
|
-
return toJsonSchema(schema._def?.innerType);
|
|
89
|
-
if (t === 'ZodObject') {
|
|
90
|
-
const shape = typeof schema._def?.shape === 'function' ? schema._def.shape() : schema._def?.shape;
|
|
91
|
-
const props = {};
|
|
92
|
-
const required = [];
|
|
93
|
-
for (const [key, val] of Object.entries(shape ?? {})) {
|
|
94
|
-
props[key] = toJsonSchema(val);
|
|
95
|
-
const innerTypeName = val?._def?.typeName;
|
|
96
|
-
if (innerTypeName !== 'ZodOptional' && innerTypeName !== 'ZodDefault')
|
|
97
|
-
required.push(key);
|
|
98
|
-
}
|
|
99
|
-
return { type: 'object', properties: props, ...(required.length ? { required } : {}) };
|
|
100
|
-
}
|
|
101
|
-
return { type: 'object' };
|
|
102
|
-
}
|
|
103
|
-
function safeJson(s) {
|
|
104
|
-
if (typeof s !== 'string')
|
|
105
|
-
return s;
|
|
106
|
-
try {
|
|
107
|
-
return JSON.parse(s);
|
|
108
|
-
}
|
|
109
|
-
catch {
|
|
110
|
-
return s;
|
|
111
|
-
}
|
|
112
|
-
}
|