llm.get_async_model(), llm.AsyncModel base class and OpenAI async models (#613)
- https://github.com/simonw/llm/issues/507#issuecomment-2458639308 * register_model is now async aware Refs https://github.com/simonw/llm/issues/507#issuecomment-2458658134 * Refactor Chat and AsyncChat to use _Shared base class Refs https://github.com/simonw/llm/issues/507#issuecomment-2458692338 * fixed function name * Fix for infinite loop * Applied Black * Ran cog * Applied Black * Add Response.from_row() classmethod back again It does not matter that this is a blocking call, since it is a classmethod * Made mypy happy with llm/models.py * mypy fixes for openai_models.py I am unhappy with this, had to duplicate some code. * First test for AsyncModel * Still have not quite got this working * Fix for not loading plugins during tests, refs #626 * audio/wav not audio/wave, refs #603 * Black and mypy and ruff all happy * Refactor to avoid generics * Removed obsolete response() method * Support text = await async_mock_model.prompt("hello") * Initial docs for llm.get_async_model() and await model.prompt() Refs #507 * Initial async model plugin creation docs * duration_ms ANY to pass test * llm models --async option Refs https://github.com/simonw/llm/pull/613#issuecomment-2474724406 * Removed obsolete TypeVars * Expanded register_models() docs for async * await model.prompt() now returns AsyncResponse Refs https://github.com/simonw/llm/pull/613#issuecomment-2475157822 --------- Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
这个提交包含在:
+30
-2
@@ -75,6 +75,29 @@ class MockModel(llm.Model):
|
||||
break
|
||||
|
||||
|
||||
class AsyncMockModel(llm.AsyncModel):
|
||||
model_id = "mock"
|
||||
|
||||
def __init__(self):
|
||||
self.history = []
|
||||
self._queue = []
|
||||
|
||||
def enqueue(self, messages):
|
||||
assert isinstance(messages, list)
|
||||
self._queue.append(messages)
|
||||
|
||||
async def execute(self, prompt, stream, response, conversation):
|
||||
self.history.append((prompt, stream, response, conversation))
|
||||
while True:
|
||||
try:
|
||||
messages = self._queue.pop(0)
|
||||
for message in messages:
|
||||
yield message
|
||||
break
|
||||
except IndexError:
|
||||
break
|
||||
|
||||
|
||||
class EmbedDemo(llm.EmbeddingModel):
|
||||
model_id = "embed-demo"
|
||||
batch_size = 10
|
||||
@@ -118,8 +141,13 @@ def mock_model():
|
||||
return MockModel()
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def async_mock_model():
|
||||
return AsyncMockModel()
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def register_embed_demo_model(embed_demo, mock_model):
|
||||
def register_embed_demo_model(embed_demo, mock_model, async_mock_model):
|
||||
class MockModelsPlugin:
|
||||
__name__ = "MockModelsPlugin"
|
||||
|
||||
@@ -131,7 +159,7 @@ def register_embed_demo_model(embed_demo, mock_model):
|
||||
|
||||
@llm.hookimpl
|
||||
def register_models(self, register):
|
||||
register(mock_model)
|
||||
register(mock_model, async_model=async_mock_model)
|
||||
|
||||
pm.register(MockModelsPlugin(), name="undo-mock-models-plugin")
|
||||
try:
|
||||
|
||||
在新工单中引用