langchain-llama-cpp 0.1.0__py3-none-any.whl

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.
@@ -0,0 +1,27 @@
1
+ """LangChain chat model for llama.cpp's llama-server."""
2
+
3
+ from langchain_llama_cpp.chat_models import ChatLlama
4
+ from langchain_llama_cpp.exceptions import (
5
+ LlamaAPIError,
6
+ LlamaAuthenticationError,
7
+ LlamaConnectionError,
8
+ LlamaContextOverflowError,
9
+ LlamaInvalidRequestError,
10
+ LlamaModelNotFoundError,
11
+ LlamaPermissionDeniedError,
12
+ LlamaRateLimitError,
13
+ LlamaTimeoutError,
14
+ )
15
+
16
+ __all__ = [
17
+ "ChatLlama",
18
+ "LlamaAPIError",
19
+ "LlamaAuthenticationError",
20
+ "LlamaConnectionError",
21
+ "LlamaContextOverflowError",
22
+ "LlamaInvalidRequestError",
23
+ "LlamaModelNotFoundError",
24
+ "LlamaPermissionDeniedError",
25
+ "LlamaRateLimitError",
26
+ "LlamaTimeoutError",
27
+ ]
@@ -0,0 +1,328 @@
1
+ """The JSON llama-server sends back from `/v1/chat/completions` (b11429).
2
+
3
+ Types for the type checker only: replies are plain dicts from `json.loads`,
4
+ never validated, so a server that sends something else isn't rejected here.
5
+ Every class is `total=False` because the code reads each key with `.get()`
6
+ and copes when it's missing; the docstrings say which keys the server always
7
+ sends.
8
+
9
+ Sources (llama.cpp b11429): `tools/server/server-task.cpp`
10
+ (`to_json_oaicompat_chat`, `to_json_oaicompat_chat_stream`,
11
+ `server_task_result_cmpl_partial::to_json_oaicompat_chat`,
12
+ `probs_vector_to_json`, `result_prompt_progress::to_json`),
13
+ `server-chat.cpp` (`server_chat_msg_diff_to_json_oaicompat`),
14
+ `server-common.cpp` (`server_slot_stats::to_json`, `format_error_response`),
15
+ `common/chat.cpp` (`common_chat_msg::to_json_oaicompat`).
16
+
17
+ A reply (`stream` off):
18
+
19
+ {"id": "chatcmpl-...", "object": "chat.completion", "created": 1760000000,
20
+ "model": "google/gemma-4-26B-A4B-it-qat-q4_0-gguf:Q4_0",
21
+ "system_fingerprint": "b11429-d81235049",
22
+ "choices": [{
23
+ "index": 0, "finish_reason": "tool_calls",
24
+ "message": {
25
+ "role": "assistant", "content": "", "reasoning_content": "...",
26
+ "tool_calls": [{
27
+ "type": "function", "id": "...",
28
+ "function": {"name": "get_weather", "arguments": "<JSON text>"}}]}}],
29
+ "usage": {"prompt_tokens": 32, "completion_tokens": 5, "total_tokens": 37,
30
+ "prompt_tokens_details": {"cached_tokens": 27}},
31
+ "timings": {"cache_n": 27, "prompt_n": 5, ...}}
32
+
33
+ A stream (`stream` on) is SSE `data:` lines, each a `LlamaChunk`, then
34
+ `data: [DONE]`:
35
+
36
+ {"choices": [{"index": 0, "finish_reason": null,
37
+ "delta": {"role": "assistant", "content": null}}], ...} # first
38
+ {"choices": [{"index": 0, "finish_reason": null,
39
+ "delta": {"reasoning_content": "Let"}}], ...}
40
+ {"choices": [{"index": 0, "finish_reason": null,
41
+ "delta": {"tool_calls": [{
42
+ "index": 0, "id": "...", "type": "function",
43
+ "function": {"name": "get_weather"}}]}}], ...}
44
+ {"choices": [{"index": 0, "finish_reason": null,
45
+ "delta": {"tool_calls": [{
46
+ "index": 0, "function": {"arguments": "<JSON piece>"}}]}}],
47
+ ...}
48
+ {"choices": [{"index": 0, "finish_reason": "tool_calls", "delta": {}}], ...}
49
+ {"choices": [], "usage": {...}, "timings": {...}, ...} # with include_usage
50
+
51
+ A failure after the first chunk arrives as `data: {"error": LlamaError}` and
52
+ the stream ends without `[DONE]`.
53
+ """
54
+
55
+ from typing import Literal, TypedDict
56
+
57
+ FinishReason = Literal["stop", "length", "tool_calls"]
58
+ """`length` when `max_tokens` or the context window ran out (b11429 sends
59
+ `length` for every stop that isn't an end-of-sequence token or a stop string)."""
60
+
61
+
62
+ class LlamaFunction(TypedDict, total=False):
63
+ """A tool call's function. In a reply both keys are sent.
64
+
65
+ In a stream, `name` comes in the first fragment and `arguments` in pieces
66
+ after it; a fragment leaves out whichever it doesn't carry.
67
+ """
68
+
69
+ name: str
70
+
71
+ arguments: str
72
+ """JSON text, not an object: `'{"city": "Paris"}'`."""
73
+
74
+
75
+ class LlamaToolCall(TypedDict, total=False):
76
+ """One tool call.
77
+
78
+ In a reply: `type`, `function`, and `id` (left out if the template made
79
+ none). In a stream fragment: always `index`; `id` and `type` only in the
80
+ first fragment of each call; `function` when there's a name or arguments.
81
+ """
82
+
83
+ index: int
84
+ """Which call a stream fragment belongs to (0, 1, ...). Stream only."""
85
+
86
+ id: str
87
+
88
+ type: Literal["function"]
89
+
90
+ function: LlamaFunction
91
+
92
+
93
+ class LlamaContentPart(TypedDict, total=False):
94
+ """A content part.
95
+
96
+ `common_chat_msg::to_json_oaicompat` writes `content` as a list of these
97
+ when the message holds parts instead of text; the reply parsers write
98
+ text, so a list hasn't been seen in a reply.
99
+ """
100
+
101
+ type: str
102
+ text: str
103
+
104
+
105
+ class LlamaMessage(TypedDict, total=False):
106
+ """`choices[].message` in a reply. Always `role` and `content`."""
107
+
108
+ role: Literal["assistant"]
109
+
110
+ content: str | list[LlamaContentPart]
111
+ """`""` when the model only called tools."""
112
+
113
+ reasoning_content: str
114
+ """The thinking, separate from `content`. Left out when there was none."""
115
+
116
+ tool_calls: list[LlamaToolCall]
117
+ """Left out when there were no calls."""
118
+
119
+
120
+ class LlamaDelta(TypedDict, total=False):
121
+ """`choices[].delta` in a stream chunk. Each key only when it changed.
122
+
123
+ The first chunk is `{"role": "assistant", "content": None}`; the finish
124
+ chunk is `{}`. `tool_calls` holds one fragment at a time.
125
+ """
126
+
127
+ role: Literal["assistant"]
128
+ content: str | None
129
+ reasoning_content: str
130
+ tool_calls: list[LlamaToolCall]
131
+
132
+
133
+ class LlamaTopLogprob(TypedDict, total=False):
134
+ """One candidate token. `logprob`, or `prob` with `post_sampling_probs`."""
135
+
136
+ id: int
137
+ token: str
138
+ bytes: list[int]
139
+ logprob: float
140
+ prob: float
141
+
142
+
143
+ class LlamaTokenLogprob(LlamaTopLogprob, total=False):
144
+ """One generated token and its candidates.
145
+
146
+ `top_logprobs`, or `top_probs` with `post_sampling_probs`.
147
+ """
148
+
149
+ top_logprobs: list[LlamaTopLogprob]
150
+ top_probs: list[LlamaTopLogprob]
151
+
152
+
153
+ class LlamaLogprobs(TypedDict, total=False):
154
+ """`choices[].logprobs`, only when `logprobs` or `n_probs` asked for it.
155
+
156
+ In a stream, each chunk carries the tokens it generated.
157
+ """
158
+
159
+ content: list[LlamaTokenLogprob]
160
+
161
+
162
+ class LlamaChoice(TypedDict, total=False):
163
+ """`choices[]` in a reply. Always `index`, `finish_reason` and `message`."""
164
+
165
+ index: int
166
+ finish_reason: FinishReason
167
+ message: LlamaMessage
168
+ logprobs: LlamaLogprobs
169
+
170
+
171
+ class LlamaChunkChoice(TypedDict, total=False):
172
+ """`choices[]` in a stream chunk. Always `index`, `finish_reason`, `delta`.
173
+
174
+ `finish_reason` is None until the finish chunk.
175
+ """
176
+
177
+ index: int
178
+ finish_reason: FinishReason | None
179
+ delta: LlamaDelta
180
+ logprobs: LlamaLogprobs
181
+
182
+
183
+ class LlamaPromptTokensDetails(TypedDict, total=False):
184
+ """`usage.prompt_tokens_details`."""
185
+
186
+ cached_tokens: int
187
+ """Prompt tokens taken from the KV cache. Part of `prompt_tokens`."""
188
+
189
+
190
+ class LlamaCompletionTokensDetails(TypedDict, total=False):
191
+ """`usage.completion_tokens_details`, as OpenAI sends it.
192
+
193
+ b11429 never sends it (reasoning tokens are counted in
194
+ `completion_tokens` but not reported apart); read in case a build does.
195
+ """
196
+
197
+ reasoning_tokens: int
198
+
199
+
200
+ class LlamaUsage(TypedDict, total=False):
201
+ """`usage`. b11429 always sends the four keys below except the last."""
202
+
203
+ prompt_tokens: int
204
+
205
+ completion_tokens: int
206
+ """Includes thinking tokens."""
207
+
208
+ total_tokens: int
209
+
210
+ prompt_tokens_details: LlamaPromptTokensDetails
211
+
212
+ completion_tokens_details: LlamaCompletionTokensDetails
213
+
214
+
215
+ class LlamaTimings(TypedDict, total=False):
216
+ """`timings`, llama-server's own.
217
+
218
+ The `draft_*` keys come only with speculative decoding.
219
+ """
220
+
221
+ cache_n: int
222
+ """Prompt tokens reused from the KV cache."""
223
+
224
+ prompt_n: int
225
+ """Prompt tokens processed for this request."""
226
+
227
+ prompt_ms: float
228
+
229
+ prompt_per_token_ms: float
230
+
231
+ prompt_per_second: float
232
+
233
+ predicted_n: int
234
+ """Tokens generated, thinking included."""
235
+
236
+ predicted_ms: float
237
+
238
+ predicted_per_token_ms: float
239
+
240
+ predicted_per_second: float
241
+
242
+ draft_n: int
243
+
244
+ draft_n_accepted: int
245
+
246
+
247
+ class LlamaPromptProgress(TypedDict, total=False):
248
+ """`prompt_progress`, in stream chunks with `return_progress`."""
249
+
250
+ total: int
251
+ cache: int
252
+ processed: int
253
+ time_ms: int
254
+
255
+
256
+ class LlamaResponse(TypedDict, total=False):
257
+ """A `chat.completion` reply. Always every key but `timings`."""
258
+
259
+ id: str
260
+ """`chatcmpl-...`."""
261
+
262
+ object: Literal["chat.completion"]
263
+
264
+ created: int
265
+ """Unix time, in seconds."""
266
+
267
+ model: str
268
+ """The file llama-swap loaded, not the entry name that was requested."""
269
+
270
+ system_fingerprint: str
271
+ """The server build, e.g. `b11429-d81235049`."""
272
+
273
+ choices: list[LlamaChoice]
274
+ """One per completion: `n` of them."""
275
+
276
+ usage: LlamaUsage
277
+
278
+ timings: LlamaTimings
279
+ """Sent when the slot recorded timings (in every reply seen so far)."""
280
+
281
+
282
+ class LlamaChunk(TypedDict, total=False):
283
+ """A `chat.completion.chunk` stream event.
284
+
285
+ Always `id`, `object`, `created`, `model`, `system_fingerprint` and
286
+ `choices`. `choices` is empty only in the usage chunk at the end (with
287
+ `stream_options.include_usage`), which carries `usage`; `timings` goes on
288
+ the last chunk sent, and on others with `timings_per_token`.
289
+ """
290
+
291
+ id: str
292
+ object: Literal["chat.completion.chunk"]
293
+ created: int
294
+ model: str
295
+ system_fingerprint: str
296
+ choices: list[LlamaChunkChoice]
297
+ usage: LlamaUsage
298
+ timings: LlamaTimings
299
+ prompt_progress: LlamaPromptProgress
300
+
301
+
302
+ class LlamaError(TypedDict, total=False):
303
+ """The `error` object of an HTTP error reply or a stream `error` event.
304
+
305
+ Always `code` (the HTTP status), `message` and `type`. llama-swap's own
306
+ errors (e.g. 404 for an unknown model) are plain text, not this.
307
+ """
308
+
309
+ code: int
310
+
311
+ message: str
312
+
313
+ type: Literal[
314
+ "invalid_request_error",
315
+ "authentication_error",
316
+ "not_found_error",
317
+ "server_error",
318
+ "permission_error",
319
+ "not_supported_error",
320
+ "unavailable_error",
321
+ "exceed_context_size_error",
322
+ ]
323
+
324
+ n_prompt_tokens: int
325
+ """With `exceed_context_size_error`: tokens in the rejected prompt."""
326
+
327
+ n_ctx: int
328
+ """With `exceed_context_size_error`: the context window."""