inferlet 0.3.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.
- inferlet/__init__.py +150 -0
- inferlet/_async.py +37 -0
- inferlet/adapter.py +64 -0
- inferlet/bindings/__init__.py +1 -0
- inferlet/bindings/componentize_py_async_support/__init__.py +529 -0
- inferlet/bindings/componentize_py_async_support/futures.py +93 -0
- inferlet/bindings/componentize_py_async_support/streams.py +189 -0
- inferlet/bindings/componentize_py_runtime.pyi +34 -0
- inferlet/bindings/componentize_py_types.py +19 -0
- inferlet/bindings/poll_loop.py +441 -0
- inferlet/bindings/wit_world/__init__.py +15 -0
- inferlet/bindings/wit_world/imports/__init__.py +0 -0
- inferlet/bindings/wit_world/imports/adapter.py +49 -0
- inferlet/bindings/wit_world/imports/chat.py +81 -0
- inferlet/bindings/wit_world/imports/client.py +107 -0
- inferlet/bindings/wit_world/imports/context.py +147 -0
- inferlet/bindings/wit_world/imports/error.py +56 -0
- inferlet/bindings/wit_world/imports/inference.py +287 -0
- inferlet/bindings/wit_world/imports/insecure.py +39 -0
- inferlet/bindings/wit_world/imports/insecure_seed.py +40 -0
- inferlet/bindings/wit_world/imports/messaging.py +65 -0
- inferlet/bindings/wit_world/imports/model.py +80 -0
- inferlet/bindings/wit_world/imports/pie_core_types.py +56 -0
- inferlet/bindings/wit_world/imports/pie_mcp_types.py +34 -0
- inferlet/bindings/wit_world/imports/poll.py +72 -0
- inferlet/bindings/wit_world/imports/preopens.py +18 -0
- inferlet/bindings/wit_world/imports/random.py +43 -0
- inferlet/bindings/wit_world/imports/reasoning.py +57 -0
- inferlet/bindings/wit_world/imports/runtime.py +33 -0
- inferlet/bindings/wit_world/imports/scheduling.py +42 -0
- inferlet/bindings/wit_world/imports/session.py +33 -0
- inferlet/bindings/wit_world/imports/streams.py +330 -0
- inferlet/bindings/wit_world/imports/tool_use.py +70 -0
- inferlet/bindings/wit_world/imports/wall_clock.py +61 -0
- inferlet/bindings/wit_world/imports/wasi_filesystem_types.py +594 -0
- inferlet/bindings/wit_world/imports/zo.py +26 -0
- inferlet/chat.py +175 -0
- inferlet/context.py +379 -0
- inferlet/forward.py +394 -0
- inferlet/generation.py +551 -0
- inferlet/grammar.py +307 -0
- inferlet/mcp.py +83 -0
- inferlet/messaging.py +78 -0
- inferlet/model.py +65 -0
- inferlet/reasoning.py +111 -0
- inferlet/runtime.py +29 -0
- inferlet/sample.py +176 -0
- inferlet/scheduling.py +44 -0
- inferlet/session.py +54 -0
- inferlet/spec.py +59 -0
- inferlet/tools.py +150 -0
- inferlet/zo.py +59 -0
- inferlet-0.3.0.dist-info/METADATA +70 -0
- inferlet-0.3.0.dist-info/RECORD +55 -0
- inferlet-0.3.0.dist-info/WHEEL +4 -0
inferlet/__init__.py
ADDED
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Pie Inferlet SDK — Python bindings for the Pie runtime.
|
|
3
|
+
|
|
4
|
+
Quickstart::
|
|
5
|
+
|
|
6
|
+
from inferlet import Context, Model, Sampler, runtime
|
|
7
|
+
|
|
8
|
+
model = Model.load(runtime.models()[0])
|
|
9
|
+
ctx = Context(model)
|
|
10
|
+
|
|
11
|
+
ctx.system("You are helpful.").user("What is 2 + 2?")
|
|
12
|
+
text = await ctx.generate(Sampler.argmax(), max_tokens=64).collect_text()
|
|
13
|
+
|
|
14
|
+
Three-layer surface:
|
|
15
|
+
|
|
16
|
+
* :class:`Context` — KV cache + chat fillers + ``forward()`` / ``generate()``.
|
|
17
|
+
* :class:`Forward` (``ctx.forward()``) — single forward-pass primitive
|
|
18
|
+
with auto page management. For prefill / scoring / custom loops.
|
|
19
|
+
* :class:`Generator` (``ctx.generate()``) — multi-step state machine
|
|
20
|
+
over Forward. Iterate with ``async for step in gen``, or use
|
|
21
|
+
``await gen.collect_text() / .collect_tokens() / .collect_json()``.
|
|
22
|
+
|
|
23
|
+
Streaming decoders for chat / reasoning / tools live as independent
|
|
24
|
+
modules — compose by hand, no implicit suppression::
|
|
25
|
+
|
|
26
|
+
from inferlet import chat, reasoning, tools
|
|
27
|
+
|
|
28
|
+
chat_dec = chat.Decoder(model)
|
|
29
|
+
async for step in gen:
|
|
30
|
+
out = await step.execute()
|
|
31
|
+
match chat_dec.feed(out.tokens):
|
|
32
|
+
case chat.Event.Delta(text=t): print(t, end="")
|
|
33
|
+
case chat.Event.Done(text=full): break
|
|
34
|
+
case _: pass
|
|
35
|
+
|
|
36
|
+
Constraint specs (:class:`JsonSchema`, :class:`AnyJson`, :class:`Regex`,
|
|
37
|
+
:class:`Ebnf`) implement the :class:`Schema` protocol — duck-typed, so
|
|
38
|
+
your own grammar source class plugs in by adding a ``build_constraint``
|
|
39
|
+
method. No inheritance required.
|
|
40
|
+
"""
|
|
41
|
+
|
|
42
|
+
from __future__ import annotations
|
|
43
|
+
|
|
44
|
+
# --- Core ---
|
|
45
|
+
from .model import Model, Tokenizer
|
|
46
|
+
from .sample import (
|
|
47
|
+
Distribution,
|
|
48
|
+
Entropy,
|
|
49
|
+
Logits,
|
|
50
|
+
Logprob,
|
|
51
|
+
Logprobs,
|
|
52
|
+
Sampler,
|
|
53
|
+
)
|
|
54
|
+
from .forward import Forward, Output, ProbeHandle, SampleHandle
|
|
55
|
+
from .generation import GenStep, Generator
|
|
56
|
+
from .context import Context
|
|
57
|
+
|
|
58
|
+
# --- Decoders + tools (sub-modules; users import as `inferlet.chat`, etc.) ---
|
|
59
|
+
from . import chat
|
|
60
|
+
from . import reasoning
|
|
61
|
+
from . import tools
|
|
62
|
+
|
|
63
|
+
# --- Constraint surface ---
|
|
64
|
+
from .grammar import (
|
|
65
|
+
AnyJson,
|
|
66
|
+
Constraint,
|
|
67
|
+
Ebnf,
|
|
68
|
+
Grammar,
|
|
69
|
+
GrammarConstraint,
|
|
70
|
+
JsonSchema,
|
|
71
|
+
Matcher,
|
|
72
|
+
Regex,
|
|
73
|
+
Schema,
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
# --- Speculation ---
|
|
77
|
+
from .spec import Speculator
|
|
78
|
+
|
|
79
|
+
# --- Runtime / IO ---
|
|
80
|
+
from . import runtime
|
|
81
|
+
from . import scheduling
|
|
82
|
+
from . import messaging
|
|
83
|
+
from . import session
|
|
84
|
+
from . import mcp
|
|
85
|
+
from . import zo
|
|
86
|
+
|
|
87
|
+
# --- Adapter ---
|
|
88
|
+
from .adapter import Adapter
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
__all__ = [
|
|
92
|
+
# Core
|
|
93
|
+
"Context",
|
|
94
|
+
"Model",
|
|
95
|
+
"Tokenizer",
|
|
96
|
+
"Adapter",
|
|
97
|
+
# Forward primitive
|
|
98
|
+
"Forward",
|
|
99
|
+
"Output",
|
|
100
|
+
"SampleHandle",
|
|
101
|
+
"ProbeHandle",
|
|
102
|
+
# Generator
|
|
103
|
+
"Generator",
|
|
104
|
+
"GenStep",
|
|
105
|
+
# Sampler / Probe
|
|
106
|
+
"Sampler",
|
|
107
|
+
"Logits",
|
|
108
|
+
"Distribution",
|
|
109
|
+
"Logprob",
|
|
110
|
+
"Logprobs",
|
|
111
|
+
"Entropy",
|
|
112
|
+
# Decoders + tools
|
|
113
|
+
"chat",
|
|
114
|
+
"reasoning",
|
|
115
|
+
"tools",
|
|
116
|
+
# Constraints
|
|
117
|
+
"Schema",
|
|
118
|
+
"JsonSchema",
|
|
119
|
+
"AnyJson",
|
|
120
|
+
"Regex",
|
|
121
|
+
"Ebnf",
|
|
122
|
+
"Constraint",
|
|
123
|
+
"GrammarConstraint",
|
|
124
|
+
"Grammar",
|
|
125
|
+
"Matcher",
|
|
126
|
+
# Speculation
|
|
127
|
+
"Speculator",
|
|
128
|
+
# Runtime / IO
|
|
129
|
+
"runtime",
|
|
130
|
+
"scheduling",
|
|
131
|
+
"messaging",
|
|
132
|
+
"session",
|
|
133
|
+
"mcp",
|
|
134
|
+
"zo",
|
|
135
|
+
]
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
# --- Internal: return value plumbing for bakery wrapper ---
|
|
139
|
+
_return_value: str | None = None
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
def set_return(value: str) -> None:
|
|
143
|
+
"""Set the return value for the inferlet (internal use by bakery wrapper)."""
|
|
144
|
+
global _return_value
|
|
145
|
+
_return_value = value
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
def get_return_value() -> str | None:
|
|
149
|
+
"""Get the return value for the inferlet (internal use by bakery wrapper)."""
|
|
150
|
+
return _return_value
|
inferlet/_async.py
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Internal async utilities for WASI pollable futures.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import asyncio
|
|
6
|
+
from typing import Protocol, TypeVar, runtime_checkable
|
|
7
|
+
|
|
8
|
+
from wit_world.imports.poll import Pollable
|
|
9
|
+
|
|
10
|
+
T = TypeVar("T")
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@runtime_checkable
|
|
14
|
+
class WasiFuture(Protocol[T]):
|
|
15
|
+
"""Generic interface for WASI async operations."""
|
|
16
|
+
|
|
17
|
+
def pollable(self) -> Pollable: ...
|
|
18
|
+
def get(self) -> T | None: ...
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
async def await_future(future: WasiFuture[T], error_message: str) -> T:
|
|
22
|
+
"""Await a WASI future cooperatively.
|
|
23
|
+
|
|
24
|
+
Registers the future's pollable with the asyncio event loop and
|
|
25
|
+
yields control until it becomes ready, allowing other coroutines
|
|
26
|
+
to make progress concurrently.
|
|
27
|
+
"""
|
|
28
|
+
pollable = future.pollable()
|
|
29
|
+
loop = asyncio.get_event_loop()
|
|
30
|
+
waker: asyncio.Future[None] = loop.create_future()
|
|
31
|
+
loop.wakers.append((pollable, waker)) # type: ignore[attr-defined]
|
|
32
|
+
await waker
|
|
33
|
+
|
|
34
|
+
result = future.get()
|
|
35
|
+
if result is None:
|
|
36
|
+
raise RuntimeError(error_message)
|
|
37
|
+
return result
|
inferlet/adapter.py
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Adapter resource wrapper for ``pie:core/adapter``.
|
|
3
|
+
|
|
4
|
+
Supports loading, saving, cloning, and locking model adapters (e.g. LoRA).
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
from typing import TYPE_CHECKING
|
|
10
|
+
|
|
11
|
+
from wit_world.imports import adapter as _adapter
|
|
12
|
+
|
|
13
|
+
if TYPE_CHECKING:
|
|
14
|
+
from .model import Model
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class Adapter:
|
|
18
|
+
"""Wraps the WIT adapter resource.
|
|
19
|
+
|
|
20
|
+
Usage::
|
|
21
|
+
|
|
22
|
+
adapter = Adapter.create(model, "my-adapter")
|
|
23
|
+
adapter.load("/path/to/weights")
|
|
24
|
+
adapter.save("/path/to/output")
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
__slots__ = ("_handle",)
|
|
28
|
+
|
|
29
|
+
def __init__(self, handle: _adapter.Adapter) -> None:
|
|
30
|
+
self._handle = handle
|
|
31
|
+
|
|
32
|
+
@staticmethod
|
|
33
|
+
def create(model: Model, name: str) -> Adapter:
|
|
34
|
+
"""Create a new adapter for a model."""
|
|
35
|
+
return Adapter(_adapter.Adapter.create(model._handle, name))
|
|
36
|
+
|
|
37
|
+
@staticmethod
|
|
38
|
+
def open(model: Model, name: str) -> Adapter | None:
|
|
39
|
+
"""Open an existing adapter by name."""
|
|
40
|
+
raw = _adapter.Adapter.open(model._handle, name)
|
|
41
|
+
if raw is None:
|
|
42
|
+
return None
|
|
43
|
+
return Adapter(raw)
|
|
44
|
+
|
|
45
|
+
def fork(self, new_name: str) -> Adapter:
|
|
46
|
+
"""Fork this adapter with a new name."""
|
|
47
|
+
return Adapter(self._handle.fork(new_name))
|
|
48
|
+
|
|
49
|
+
def load(self, path: str) -> None:
|
|
50
|
+
"""Load adapter weights from a file path."""
|
|
51
|
+
self._handle.load(path)
|
|
52
|
+
|
|
53
|
+
def save(self, path: str) -> None:
|
|
54
|
+
"""Save adapter weights to a file path."""
|
|
55
|
+
self._handle.save(path)
|
|
56
|
+
|
|
57
|
+
def __enter__(self) -> Adapter:
|
|
58
|
+
return self
|
|
59
|
+
|
|
60
|
+
def __exit__(self, *args) -> None:
|
|
61
|
+
pass
|
|
62
|
+
|
|
63
|
+
def __repr__(self) -> str:
|
|
64
|
+
return f"Adapter({id(self._handle):#x})"
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# WIT-generated bindings and runtime support.
|