mirror of
https://github.com/ollama/ollama-python.git
synced 2026-11-02 13:52:51 +00:00
docs/types: update docs to reference new cloud decision models and support images (#764)
This commit is contained in:
@@ -274,16 +274,25 @@ response = ollama.systemone(
|
||||
print(response.answers['team'])
|
||||
```
|
||||
|
||||
System One uses `POST /v1/systemone` and requires Ollama v0.35.0 or later with a
|
||||
compatible local model such as `nimble`. It returns one JSON response; streaming
|
||||
and cloud models are not supported.
|
||||
System One uses `POST /v1/systemone` and returns one JSON response; streaming is
|
||||
not supported. It runs locally with decision models such as `nimble` (Ollama
|
||||
v0.35.0 or later) or `clef` (v0.35.1 or later), and in the cloud with `clef:cloud`
|
||||
on a paid plan (through Ollama v0.40.5 or later, or [directly against
|
||||
ollama.com](#cloud-api-ollamacom)).
|
||||
|
||||
Clef also reads images (v0.40.0 or later locally): pass `images` as file paths,
|
||||
bytes, or base64 strings, shared by all questions. Cloud requests accept up to 4
|
||||
PNG, JPEG, or WebP images (each at most 4 MiB and 16 megapixels, 8 MiB total).
|
||||
|
||||
`state` and question `instructions` accept text, JSON objects, or arrays. Questions
|
||||
are evaluated in their supplied order:
|
||||
|
||||
- `choice`: 2–26 option keys mapped to descriptions; `None` uses the key as its description.
|
||||
- `choice`: 2–26 option keys mapped to descriptions (up to 255 in the cloud); `None` uses the key as its description.
|
||||
- `noul`: probability of true, with optional `{"false": "No", "true": "Yes"}` descriptions.
|
||||
- `score`: 2–26 descriptions ordered lowest to highest; returns a potentially fractional, zero-based score.
|
||||
- `score`: 2–10 descriptions ordered lowest to highest; returns a potentially fractional, zero-based score.
|
||||
|
||||
In the cloud, question ids may only contain ASCII letters, digits, `_`, `.`, and
|
||||
`-`, up to 100 characters, and a request may ask up to 64 questions.
|
||||
|
||||
Responses contain `model`, `answers`, and `usage.input_tokens` / `usage.output_tokens`.
|
||||
Confidence measures probability concentration, not calibrated correctness.
|
||||
|
||||
+10
-2
@@ -413,8 +413,11 @@ class Client(BaseClient):
|
||||
state: SystemOneContent,
|
||||
questions: Mapping[str, Union[SystemOneQuestion, Mapping[str, Any]]],
|
||||
keep_alive: Optional[Union[float, str]] = None,
|
||||
images: Optional[Sequence[Union[str, bytes, Image]]] = None,
|
||||
) -> SystemOneResponse:
|
||||
"""Score choice, noul, and score questions with a local System One model.
|
||||
"""Score choice, noul, and score questions with a System One decision model.
|
||||
|
||||
`images` are shared by all questions, in order; only models that accept images (such as Clef) support them.
|
||||
|
||||
Returns one JSON response. Streaming is not supported.
|
||||
"""
|
||||
@@ -425,6 +428,7 @@ class Client(BaseClient):
|
||||
json=SystemOneRequest(
|
||||
model=model,
|
||||
state=state,
|
||||
images=list(_copy_images(images)) if images else None,
|
||||
questions=questions,
|
||||
keep_alive=keep_alive,
|
||||
).model_dump(exclude_none=True),
|
||||
@@ -1069,8 +1073,11 @@ class AsyncClient(BaseClient):
|
||||
state: SystemOneContent,
|
||||
questions: Mapping[str, Union[SystemOneQuestion, Mapping[str, Any]]],
|
||||
keep_alive: Optional[Union[float, str]] = None,
|
||||
images: Optional[Sequence[Union[str, bytes, Image]]] = None,
|
||||
) -> SystemOneResponse:
|
||||
"""Score choice, noul, and score questions with a local System One model.
|
||||
"""Score choice, noul, and score questions with a System One decision model.
|
||||
|
||||
`images` are shared by all questions, in order; only models that accept images (such as Clef) support them.
|
||||
|
||||
Returns one JSON response. Streaming is not supported.
|
||||
"""
|
||||
@@ -1081,6 +1088,7 @@ class AsyncClient(BaseClient):
|
||||
json=SystemOneRequest(
|
||||
model=model,
|
||||
state=state,
|
||||
images=list(_copy_images(images)) if images else None,
|
||||
questions=questions,
|
||||
keep_alive=keep_alive,
|
||||
).model_dump(exclude_none=True),
|
||||
|
||||
@@ -648,6 +648,8 @@ SystemOneQuestion = Annotated[Union[SystemOneChoiceQuestion, SystemOneNoulQuesti
|
||||
class SystemOneRequest(SubscriptableBaseModel):
|
||||
model: str
|
||||
state: SystemOneContent
|
||||
images: Optional[Sequence[Image]] = None
|
||||
'Images shared by all questions; base64 PNG, JPEG, or WebP.'
|
||||
questions: Dict[str, SystemOneQuestion]
|
||||
keep_alive: Optional[Union[float, str]] = None
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import base64
|
||||
import inspect
|
||||
import json
|
||||
|
||||
@@ -86,3 +87,24 @@ async def test_systemone_http_errors(client_type, status, message):
|
||||
await response
|
||||
assert error.value.status_code == status
|
||||
assert error.value.error == message
|
||||
|
||||
|
||||
@pytest.mark.anyio
|
||||
@pytest.mark.parametrize('client_type', [ollama.Client, ollama.AsyncClient])
|
||||
async def test_systemone_images(client_type, tmp_path):
|
||||
png = b'\x89PNG\r\n\x1a\nsynthetic'
|
||||
path = tmp_path / 'ticket.png'
|
||||
path.write_bytes(png)
|
||||
encoded = base64.b64encode(png).decode()
|
||||
|
||||
def handle(request):
|
||||
body = json.loads(request.content)
|
||||
assert body['images'] == [encoded] * 4
|
||||
assert list(body) == ['model', 'state', 'images', 'questions']
|
||||
return httpx.Response(200, json={'model': 'clef', 'answers': {'refund': {'type': 'noul', 'noul': 0.5}}, 'usage': {'input_tokens': 1, 'output_tokens': 0}})
|
||||
|
||||
client = client_type(transport=httpx.MockTransport(handle))
|
||||
response = client.systemone('clef', 'See screenshot', {'refund': {'type': 'noul', 'instructions': 'Refund?'}}, images=[png, encoded, str(path), ollama.Image(value=path)])
|
||||
if inspect.isawaitable(response):
|
||||
response = await response
|
||||
assert response.answers['refund'].noul == 0.5
|
||||
|
||||
Reference in New Issue
Block a user