react-native-nobodywho 3.0.0 → 5.0.0
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/README.md +113 -7
- package/android/build.gradle +5 -1
- package/generated/cpp/nobodywho.cpp +524 -80
- package/generated/cpp/nobodywho.hpp +67 -8
- package/generated/ts/nobodywho-ffi.ts +21 -5
- package/generated/ts/nobodywho.ts +978 -270
- package/package.json +7 -3
- package/src/chat.ts +50 -3
- package/src/message.ts +91 -24
- package/src/model.ts +5 -0
- package/src/prompt.ts +8 -8
- package/src/sampler_presets.ts +7 -11
- package/src/wrapper.ts +5 -3
package/package.json
CHANGED
|
@@ -1,21 +1,25 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-nobodywho",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "Run LLMs locally
|
|
3
|
+
"version": "5.0.0",
|
|
4
|
+
"description": "Run LLMs locally and offline with React Native & Expo - Tool calling, RAG, Speech-to-Text, Text-to-Speech, and VAD",
|
|
5
5
|
"main": "src/wrapper.ts",
|
|
6
6
|
"types": "src/wrapper.ts",
|
|
7
7
|
"exports": {
|
|
8
8
|
".": "./src/wrapper.ts"
|
|
9
9
|
},
|
|
10
10
|
"license": "EUPL-1.2",
|
|
11
|
-
"homepage": "https://nobodywho.
|
|
11
|
+
"homepage": "https://www.nobodywho.ai",
|
|
12
12
|
"bugs": "https://github.com/nobodywho-ooo/nobodywho/issues",
|
|
13
13
|
"keywords": [
|
|
14
14
|
"react-native",
|
|
15
|
+
"expo",
|
|
15
16
|
"ai",
|
|
16
17
|
"llm",
|
|
17
18
|
"local-ai",
|
|
18
19
|
"inference",
|
|
20
|
+
"stt",
|
|
21
|
+
"tts",
|
|
22
|
+
"vad",
|
|
19
23
|
"gguf",
|
|
20
24
|
"on-device",
|
|
21
25
|
"offline"
|
package/src/chat.ts
CHANGED
|
@@ -2,6 +2,7 @@ import {
|
|
|
2
2
|
RustChat,
|
|
3
3
|
SamplerConfig,
|
|
4
4
|
MtpConfig,
|
|
5
|
+
ContextShiftOptions,
|
|
5
6
|
type ChatStats,
|
|
6
7
|
} from "../generated/ts/nobodywho";
|
|
7
8
|
import { Model } from "./model";
|
|
@@ -10,6 +11,18 @@ import { TokenStream } from "./streaming";
|
|
|
10
11
|
import type { Prompt } from "./prompt";
|
|
11
12
|
import type { Tool } from "./tool";
|
|
12
13
|
|
|
14
|
+
/**
|
|
15
|
+
* Settings to apply before a `complete` turn. An omitted field keeps what the
|
|
16
|
+
* chat has; a set one stays set, like a leading system message.
|
|
17
|
+
*/
|
|
18
|
+
export type Options = {
|
|
19
|
+
sampler?: SamplerConfig;
|
|
20
|
+
/** Replaces the chat's template variables wholesale. */
|
|
21
|
+
templateVariables?: Record<string, boolean>;
|
|
22
|
+
/** Re-selects the chat template, so the turn re-prefills from near token zero. */
|
|
23
|
+
tools?: Tool[];
|
|
24
|
+
};
|
|
25
|
+
|
|
13
26
|
/**
|
|
14
27
|
* A chat session for local LLM inference.
|
|
15
28
|
*
|
|
@@ -37,6 +50,9 @@ export class Chat {
|
|
|
37
50
|
* device's physical core count (performance cores only, on Apple silicon) — hyperthreads
|
|
38
51
|
* and efficiency cores make inference slower, not faster. Lower it to leave CPU headroom
|
|
39
52
|
* for the rest of the app.
|
|
53
|
+
*
|
|
54
|
+
* `contextShift` sets how old turns are forgotten when the context is full; omit it for
|
|
55
|
+
* the defaults, or pass `{ enabled: false }` to disable shifting.
|
|
40
56
|
*/
|
|
41
57
|
constructor(opts: {
|
|
42
58
|
model: Model;
|
|
@@ -47,6 +63,7 @@ export class Chat {
|
|
|
47
63
|
sampler?: SamplerConfig;
|
|
48
64
|
mtp?: Partial<MtpConfig>;
|
|
49
65
|
threadCount?: number;
|
|
66
|
+
contextShift?: Partial<ContextShiftOptions>;
|
|
50
67
|
}) {
|
|
51
68
|
this._inner = new RustChat(
|
|
52
69
|
opts.model._inner,
|
|
@@ -57,6 +74,7 @@ export class Chat {
|
|
|
57
74
|
opts.sampler ?? undefined,
|
|
58
75
|
opts.mtp !== undefined ? MtpConfig.create(opts.mtp) : undefined,
|
|
59
76
|
opts.threadCount ?? undefined,
|
|
77
|
+
opts.contextShift !== undefined ? ContextShiftOptions.create(opts.contextShift) : undefined,
|
|
60
78
|
);
|
|
61
79
|
}
|
|
62
80
|
|
|
@@ -84,6 +102,7 @@ export class Chat {
|
|
|
84
102
|
sampler?: SamplerConfig;
|
|
85
103
|
mtp?: Partial<MtpConfig>;
|
|
86
104
|
threadCount?: number;
|
|
105
|
+
contextShift?: Partial<ContextShiftOptions>;
|
|
87
106
|
onDownloadProgress?: (downloaded: number, total: number) => void;
|
|
88
107
|
}): Promise<Chat> {
|
|
89
108
|
const model = await Model.load({
|
|
@@ -107,6 +126,29 @@ export class Chat {
|
|
|
107
126
|
return new TokenStream(this._inner.askWithPrompt(message._parts!));
|
|
108
127
|
}
|
|
109
128
|
|
|
129
|
+
/**
|
|
130
|
+
* Answer a full list of messages, replacing the chat history.
|
|
131
|
+
*
|
|
132
|
+
* The list is the whole conversation, used as given: it must be non-empty and
|
|
133
|
+
* end in a user or tool message. A leading system message sets the chat's system
|
|
134
|
+
* prompt; leave it out and the prompt already on the chat is kept. A later one
|
|
135
|
+
* stays in the history, for the chat template to render in place. The response
|
|
136
|
+
* is appended, and the next `ask` continues from there.
|
|
137
|
+
*
|
|
138
|
+
* `options` follows the same rule for the chat's other settings.
|
|
139
|
+
*/
|
|
140
|
+
complete(messages: Message[], options: Options = {}): TokenStream {
|
|
141
|
+
return new TokenStream(
|
|
142
|
+
this._inner.complete(messages.map(toInternal), {
|
|
143
|
+
sampler: options.sampler,
|
|
144
|
+
templateVariables: options.templateVariables
|
|
145
|
+
? new Map(Object.entries(options.templateVariables))
|
|
146
|
+
: undefined,
|
|
147
|
+
tools: options.tools?.map((t) => t._inner),
|
|
148
|
+
}),
|
|
149
|
+
);
|
|
150
|
+
}
|
|
151
|
+
|
|
110
152
|
/** Stop the current generation. */
|
|
111
153
|
stopGeneration(): void {
|
|
112
154
|
this._inner.stopGeneration();
|
|
@@ -145,12 +187,12 @@ export class Chat {
|
|
|
145
187
|
}
|
|
146
188
|
|
|
147
189
|
/** Tokenize a text message or multimodal prompt and return the token IDs.
|
|
148
|
-
* Each element is a token ID (number) for text, or
|
|
149
|
-
async tokenize(message: string | Prompt): Promise<(number |
|
|
190
|
+
* Each element is a token ID (number) for text, or undefined for image/audio embedding slots. */
|
|
191
|
+
async tokenize(message: string | Prompt): Promise<(number | undefined)[]> {
|
|
150
192
|
if (typeof message === "string") {
|
|
151
193
|
return this._inner.tokenize(message);
|
|
152
194
|
}
|
|
153
|
-
return this._inner.tokenizeWithPrompt(message._parts);
|
|
195
|
+
return this._inner.tokenizeWithPrompt(message._parts!);
|
|
154
196
|
}
|
|
155
197
|
|
|
156
198
|
/** Set the system prompt. */
|
|
@@ -158,6 +200,11 @@ export class Chat {
|
|
|
158
200
|
return this._inner.setSystemPrompt(systemPrompt);
|
|
159
201
|
}
|
|
160
202
|
|
|
203
|
+
/** Set how old turns are forgotten when the context is full. */
|
|
204
|
+
async setContextShift(options: Partial<ContextShiftOptions>): Promise<void> {
|
|
205
|
+
return this._inner.setContextShift(ContextShiftOptions.create(options));
|
|
206
|
+
}
|
|
207
|
+
|
|
161
208
|
/** Set the tools available to the model. */
|
|
162
209
|
async setTools(tools: Tool[]): Promise<void> {
|
|
163
210
|
return this._inner.setTools(tools.map((t) => t._inner));
|
package/src/message.ts
CHANGED
|
@@ -1,19 +1,45 @@
|
|
|
1
1
|
import {
|
|
2
|
+
ContentPart as InternalContentPart,
|
|
3
|
+
ContentPart_Tags,
|
|
2
4
|
Message as InternalMessage,
|
|
3
5
|
Message_Tags,
|
|
4
|
-
|
|
6
|
+
MessageContent as InternalMessageContent,
|
|
7
|
+
MessageContent_Tags,
|
|
5
8
|
type ToolCall,
|
|
6
9
|
} from "../generated/ts/nobodywho";
|
|
7
10
|
|
|
11
|
+
/** One piece of a message: a run of text, or a media file at this position. */
|
|
12
|
+
export type ContentPart =
|
|
13
|
+
| { type: "text"; text: string }
|
|
14
|
+
| { type: "image"; path: string }
|
|
15
|
+
| { type: "audio"; path: string };
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Message content: plain text, interleaved text and media, or a raw JSON value
|
|
19
|
+
* handed straight to the chat template.
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```typescript
|
|
23
|
+
* const content: Content = [
|
|
24
|
+
* { type: "text", text: "What is in this image?" },
|
|
25
|
+
* { type: "image", path: "./dog.png" },
|
|
26
|
+
* ];
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
export type Content = string | ContentPart[] | { type: "json"; json: string };
|
|
30
|
+
|
|
8
31
|
/**
|
|
9
32
|
* A chat message. The variant determines the message type:
|
|
10
33
|
*
|
|
11
|
-
* - **User message:** `{ role: "user", content
|
|
34
|
+
* - **User message:** `{ role: "user", content }`
|
|
12
35
|
* - **Assistant message:** `{ role: "assistant", content }`
|
|
13
36
|
* - **Assistant tool call:** `{ role: "assistant", content, toolCalls }`
|
|
14
37
|
* - **System message:** `{ role: "system", content }`
|
|
15
38
|
* - **Tool response:** `{ role: "tool", name, content }`
|
|
16
39
|
*
|
|
40
|
+
* `content` is a string, a list of parts for multimodal input, or a
|
|
41
|
+
* `{ type: "json", json }` wrapper for raw template passthrough.
|
|
42
|
+
*
|
|
17
43
|
* @example
|
|
18
44
|
* ```typescript
|
|
19
45
|
* const history = await chat.getChatHistory();
|
|
@@ -29,33 +55,75 @@ import {
|
|
|
29
55
|
* ```
|
|
30
56
|
*/
|
|
31
57
|
export type Message =
|
|
32
|
-
| { role: "user"; content:
|
|
33
|
-
| { role: "assistant"; content:
|
|
34
|
-
| { role: "assistant"; content:
|
|
35
|
-
| { role: "system"; content:
|
|
36
|
-
| { role: "tool"; name: string; content:
|
|
58
|
+
| { role: "user"; content: Content }
|
|
59
|
+
| { role: "assistant"; content: Content }
|
|
60
|
+
| { role: "assistant"; content: Content; toolCalls: ToolCall[] }
|
|
61
|
+
| { role: "system"; content: Content }
|
|
62
|
+
| { role: "tool"; name: string; content: Content };
|
|
63
|
+
|
|
64
|
+
function partFromInternal(part: InternalContentPart): ContentPart {
|
|
65
|
+
if (part.tag === ContentPart_Tags.Text) {
|
|
66
|
+
return { type: "text", text: part.inner.text };
|
|
67
|
+
} else if (part.tag === ContentPart_Tags.Image) {
|
|
68
|
+
return { type: "image", path: part.inner.path };
|
|
69
|
+
} else {
|
|
70
|
+
return { type: "audio", path: part.inner.path };
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function partToInternal(part: ContentPart): InternalContentPart {
|
|
75
|
+
if (part.type === "text") {
|
|
76
|
+
return new InternalContentPart.Text({ text: part.text });
|
|
77
|
+
} else if (part.type === "image") {
|
|
78
|
+
return new InternalContentPart.Image({ path: part.path });
|
|
79
|
+
} else {
|
|
80
|
+
return new InternalContentPart.Audio({ path: part.path });
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/** @internal */
|
|
85
|
+
export function contentFromInternal(content: InternalMessageContent): Content {
|
|
86
|
+
if (content.tag === MessageContent_Tags.Text) {
|
|
87
|
+
return content.inner.text;
|
|
88
|
+
} else if (content.tag === MessageContent_Tags.Parts) {
|
|
89
|
+
return content.inner.parts.map(partFromInternal);
|
|
90
|
+
} else {
|
|
91
|
+
return { type: "json", json: content.inner.json };
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/** @internal */
|
|
96
|
+
export function contentToInternal(content: Content): InternalMessageContent {
|
|
97
|
+
if (typeof content === "string") {
|
|
98
|
+
return new InternalMessageContent.Text({ text: content });
|
|
99
|
+
}
|
|
100
|
+
if (Array.isArray(content)) {
|
|
101
|
+
return new InternalMessageContent.Parts({
|
|
102
|
+
parts: content.map(partToInternal),
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
return new InternalMessageContent.Json({ json: content.json });
|
|
106
|
+
}
|
|
37
107
|
|
|
38
108
|
/** @internal Convert internal Message to Message */
|
|
39
109
|
export function fromInternal(msg: InternalMessage): Message {
|
|
40
110
|
if (msg.tag === Message_Tags.User) {
|
|
41
|
-
|
|
42
|
-
return {
|
|
43
|
-
role: "user",
|
|
44
|
-
content,
|
|
45
|
-
...(assets.length > 0 ? { assets } : {}),
|
|
46
|
-
};
|
|
111
|
+
return { role: "user", content: contentFromInternal(msg.inner.content) };
|
|
47
112
|
} else if (msg.tag === Message_Tags.Assistant) {
|
|
48
113
|
const { content, toolCalls } = msg.inner;
|
|
49
114
|
if (toolCalls != null && toolCalls.length > 0) {
|
|
50
|
-
return {
|
|
115
|
+
return {
|
|
116
|
+
role: "assistant",
|
|
117
|
+
content: contentFromInternal(content),
|
|
118
|
+
toolCalls,
|
|
119
|
+
};
|
|
51
120
|
}
|
|
52
|
-
return { role: "assistant", content };
|
|
121
|
+
return { role: "assistant", content: contentFromInternal(content) };
|
|
53
122
|
} else if (msg.tag === Message_Tags.System) {
|
|
54
|
-
|
|
55
|
-
return { role: "system", content };
|
|
123
|
+
return { role: "system", content: contentFromInternal(msg.inner.content) };
|
|
56
124
|
} else {
|
|
57
125
|
const { name, content } = msg.inner;
|
|
58
|
-
return { role: "tool", name, content };
|
|
126
|
+
return { role: "tool", name, content: contentFromInternal(content) };
|
|
59
127
|
}
|
|
60
128
|
}
|
|
61
129
|
|
|
@@ -63,27 +131,26 @@ export function fromInternal(msg: InternalMessage): Message {
|
|
|
63
131
|
export function toInternal(msg: Message): InternalMessage {
|
|
64
132
|
if (msg.role === "user") {
|
|
65
133
|
return new InternalMessage.User({
|
|
66
|
-
content: msg.content,
|
|
67
|
-
assets: msg.assets ?? [],
|
|
134
|
+
content: contentToInternal(msg.content),
|
|
68
135
|
});
|
|
69
136
|
} else if (msg.role === "assistant" && "toolCalls" in msg) {
|
|
70
137
|
return new InternalMessage.Assistant({
|
|
71
|
-
content: msg.content,
|
|
138
|
+
content: contentToInternal(msg.content),
|
|
72
139
|
toolCalls: msg.toolCalls,
|
|
73
140
|
});
|
|
74
141
|
} else if (msg.role === "assistant") {
|
|
75
142
|
return new InternalMessage.Assistant({
|
|
76
|
-
content: msg.content,
|
|
143
|
+
content: contentToInternal(msg.content),
|
|
77
144
|
toolCalls: undefined,
|
|
78
145
|
});
|
|
79
146
|
} else if (msg.role === "system") {
|
|
80
147
|
return new InternalMessage.System({
|
|
81
|
-
content: msg.content,
|
|
148
|
+
content: contentToInternal(msg.content),
|
|
82
149
|
});
|
|
83
150
|
} else {
|
|
84
151
|
return new InternalMessage.Tool({
|
|
85
152
|
name: msg.name,
|
|
86
|
-
content: msg.content,
|
|
153
|
+
content: contentToInternal(msg.content),
|
|
87
154
|
});
|
|
88
155
|
}
|
|
89
156
|
}
|
package/src/model.ts
CHANGED
|
@@ -65,6 +65,11 @@ export class Model {
|
|
|
65
65
|
return new Model(inner);
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
+
/** The identifier used to load this model. */
|
|
69
|
+
get source(): string {
|
|
70
|
+
return this._inner.source();
|
|
71
|
+
}
|
|
72
|
+
|
|
68
73
|
/**
|
|
69
74
|
* The maximum context size this model was trained with.
|
|
70
75
|
* Use this to avoid setting `contextSize` above what the model supports.
|
package/src/prompt.ts
CHANGED
|
@@ -1,32 +1,32 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ContentPart } from "../generated/ts/nobodywho";
|
|
2
2
|
|
|
3
3
|
/** A text part of a multimodal prompt. */
|
|
4
4
|
class TextPart {
|
|
5
5
|
/** @internal */
|
|
6
|
-
readonly _inner:
|
|
6
|
+
readonly _inner: ContentPart;
|
|
7
7
|
|
|
8
8
|
constructor(content: string) {
|
|
9
|
-
this._inner = new
|
|
9
|
+
this._inner = new ContentPart.Text({ text: content });
|
|
10
10
|
}
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
/** An image part of a multimodal prompt. */
|
|
14
14
|
class ImagePart {
|
|
15
15
|
/** @internal */
|
|
16
|
-
readonly _inner:
|
|
16
|
+
readonly _inner: ContentPart;
|
|
17
17
|
|
|
18
18
|
constructor(path: string) {
|
|
19
|
-
this._inner = new
|
|
19
|
+
this._inner = new ContentPart.Image({ path });
|
|
20
20
|
}
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
/** An audio part of a multimodal prompt. */
|
|
24
24
|
class AudioPart {
|
|
25
25
|
/** @internal */
|
|
26
|
-
readonly _inner:
|
|
26
|
+
readonly _inner: ContentPart;
|
|
27
27
|
|
|
28
28
|
constructor(path: string) {
|
|
29
|
-
this._inner = new
|
|
29
|
+
this._inner = new ContentPart.Audio({ path });
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
32
|
|
|
@@ -53,7 +53,7 @@ type Part = TextPart | ImagePart | AudioPart;
|
|
|
53
53
|
*/
|
|
54
54
|
export class Prompt {
|
|
55
55
|
/** @internal */
|
|
56
|
-
readonly _parts:
|
|
56
|
+
readonly _parts: ContentPart[] | null;
|
|
57
57
|
/** @internal */
|
|
58
58
|
readonly _jsonString: string | null;
|
|
59
59
|
|
package/src/sampler_presets.ts
CHANGED
|
@@ -5,7 +5,6 @@ import {
|
|
|
5
5
|
samplerPresetConstrainWithRegex,
|
|
6
6
|
samplerPresetDefault,
|
|
7
7
|
samplerPresetDry,
|
|
8
|
-
samplerPresetGrammar,
|
|
9
8
|
samplerPresetGreedy,
|
|
10
9
|
samplerPresetJson,
|
|
11
10
|
samplerPresetTemperature,
|
|
@@ -16,6 +15,10 @@ import {
|
|
|
16
15
|
/**
|
|
17
16
|
* Static factory methods for common sampler configurations.
|
|
18
17
|
*
|
|
18
|
+
* Every preset builds on the default configuration and adds its own step on top,
|
|
19
|
+
* replacing the default step of the same kind if there is one. `greedy()` is the
|
|
20
|
+
* exception: it always picks the most probable token, so it needs no steps.
|
|
21
|
+
*
|
|
19
22
|
* @example
|
|
20
23
|
* ```typescript
|
|
21
24
|
* const sampler = SamplerPresets.temperature(0.7);
|
|
@@ -30,12 +33,12 @@ export class SamplerPresets {
|
|
|
30
33
|
return samplerPresetDefault() as SamplerConfig;
|
|
31
34
|
}
|
|
32
35
|
|
|
33
|
-
/** Create a sampler with top-k
|
|
36
|
+
/** Create a sampler with the default steps, but top-k overridden. */
|
|
34
37
|
static topK(topK: number): SamplerConfig {
|
|
35
38
|
return samplerPresetTopK(topK) as SamplerConfig;
|
|
36
39
|
}
|
|
37
40
|
|
|
38
|
-
/** Create a sampler with nucleus (top-p)
|
|
41
|
+
/** Create a sampler with the default steps, but nucleus (top-p) overridden. */
|
|
39
42
|
static topP(topP: number): SamplerConfig {
|
|
40
43
|
return samplerPresetTopP(topP) as SamplerConfig;
|
|
41
44
|
}
|
|
@@ -55,7 +58,7 @@ export class SamplerPresets {
|
|
|
55
58
|
return samplerPresetDry() as SamplerConfig;
|
|
56
59
|
}
|
|
57
60
|
|
|
58
|
-
/**
|
|
61
|
+
/** Constrain output to a JSON object of any shape. */
|
|
59
62
|
static json(): SamplerConfig {
|
|
60
63
|
return samplerPresetJson() as SamplerConfig;
|
|
61
64
|
}
|
|
@@ -80,11 +83,4 @@ export class SamplerPresets {
|
|
|
80
83
|
static constrainWithGrammar(grammar: string): SamplerConfig {
|
|
81
84
|
return samplerPresetConstrainWithGrammar(grammar) as SamplerConfig;
|
|
82
85
|
}
|
|
83
|
-
|
|
84
|
-
/**
|
|
85
|
-
* @deprecated Use {@link constrainWithGrammar} instead. It accepts both Lark and GBNF strings.
|
|
86
|
-
*/
|
|
87
|
-
static grammar(grammar: string): SamplerConfig {
|
|
88
|
-
return samplerPresetGrammar(grammar) as SamplerConfig;
|
|
89
|
-
}
|
|
90
86
|
}
|
package/src/wrapper.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* This is the public entry point. It re-exports the public API:
|
|
5
5
|
* - Wrapper classes: Model, Chat, Encoder, CrossEncoder, TextToSpeech, Tool, TokenStream, Prompt
|
|
6
6
|
* - Direct re-exports: SamplerBuilder, SamplerConfig
|
|
7
|
-
* - Types: Message,
|
|
7
|
+
* - Types: Message, Content, ContentPart, ToolCall
|
|
8
8
|
* - Utilities: SamplerPresets, cosineSimilarity, downloadModel
|
|
9
9
|
*
|
|
10
10
|
* This file is NOT generated — it is safe to edit.
|
|
@@ -57,6 +57,7 @@ export async function downloadModel(opts: {
|
|
|
57
57
|
// Wrapper classes
|
|
58
58
|
export { Model } from "./model";
|
|
59
59
|
export { Chat } from "./chat";
|
|
60
|
+
export type { Options } from "./chat";
|
|
60
61
|
export { SpeechToText } from "./speech_to_text";
|
|
61
62
|
export { VoiceActivityDetection } from "./vad";
|
|
62
63
|
export { Encoder } from "./encoder";
|
|
@@ -67,7 +68,7 @@ export { Tool } from "./tool";
|
|
|
67
68
|
export { TokenStream } from "./streaming";
|
|
68
69
|
|
|
69
70
|
// Message types
|
|
70
|
-
export type { Message } from "./message";
|
|
71
|
+
export type { Message, Content, ContentPart } from "./message";
|
|
71
72
|
|
|
72
73
|
// Re-export types that don't need wrapping.
|
|
73
74
|
//
|
|
@@ -76,15 +77,16 @@ export type { Message } from "./message";
|
|
|
76
77
|
export {
|
|
77
78
|
SamplerBuilder,
|
|
78
79
|
SamplerConfig,
|
|
80
|
+
ShiftTarget,
|
|
79
81
|
cosineSimilarity,
|
|
80
82
|
getCachedModels,
|
|
81
83
|
} from "../generated/ts/nobodywho";
|
|
82
84
|
|
|
83
85
|
export type {
|
|
84
|
-
Asset,
|
|
85
86
|
ToolCall,
|
|
86
87
|
CachedModel,
|
|
87
88
|
ChatStats,
|
|
89
|
+
ContextShiftOptions,
|
|
88
90
|
} from "../generated/ts/nobodywho";
|
|
89
91
|
export type { TextToSpeechArchitecture, TextToSpeechDevice, TextToSpeechOptions } from "./text_to_speech";
|
|
90
92
|
export type { SpeechToTextOptions } from "./speech_to_text";
|