Skip to content

Commit

Permalink
Merge branch 'main' into doug/engine-stamped-request-ids
Browse files Browse the repository at this point in the history
  • Loading branch information
douglas-reid authored Oct 10, 2023
2 parents 2d6423f + 0abbe43 commit 130e159
Show file tree
Hide file tree
Showing 7 changed files with 677 additions and 2 deletions.
18 changes: 18 additions & 0 deletions src/steamship/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,24 @@

from .client import Steamship # isort:skip

SUPPORTED_PYTHON_VERSIONS = [(3, 10)]
SUPPORTED_PYTHON_VERSION_NAMES = [f"{major}.{minor}" for major, minor in SUPPORTED_PYTHON_VERSIONS]


def is_supported_python_version() -> bool:
import sys

major, minor, _, _, _ = sys.version_info
for supported_version in SUPPORTED_PYTHON_VERSIONS:
s_major, s_minor = supported_version
supported = (major == s_major) and (s_minor is None or s_minor == minor)
if supported:
break
else:
return False
return True


__all__ = [
"Steamship",
"Configuration",
Expand Down
108 changes: 108 additions & 0 deletions src/steamship/agents/llms/steamship_llm.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
import logging
from pprint import pformat
from typing import List, Optional

from steamship import Block, File, MimeTypes, PluginInstance, Steamship, SteamshipError, Tag
from steamship.data import GenerationTag, TagKind
from steamship.plugin.capabilities import (
Capability,
CapabilityPluginRequest,
CapabilityPluginResponse,
)


class SteamshipLLM:
"""A class wrapping LLM plugins."""

def __init__(self, plugin_instance: PluginInstance):
self.client = plugin_instance.client
self.plugin_instance = plugin_instance

class Impls:
@staticmethod
def gpt(
client: Steamship,
plugin_version: Optional[str] = None,
model: str = "gpt-4",
temperature: float = 0.4,
max_tokens: int = 256,
**kwargs,
):
gpt = client.use_plugin(
"gpt-4",
version=plugin_version,
config={
"model": model,
"temperature": temperature,
"max_tokens": max_tokens,
**kwargs,
},
)
return SteamshipLLM(gpt)

def generate(
self,
messages: List[Block],
capabilities: List[Capability] = None,
assert_capabilities: bool = True,
**kwargs,
) -> List[Block]:
"""
Call the LLM plugin's generate method. Generate requests for plugin capabilities based on input parameters.
:param messages: Messages to be passed to the LLM to construct the prompt.
:param capabilities: Capabilities that will be asked of the LLM. See the docstring for
steamship.plugins.capabilities.
If default_capabilities was provided at construction, those capabilities will be requested unless overridden
by this parameter.
:param assert_capabilities: If True (default), raise a SteamshipError if the LLM plugin did not respond with a
block that asserts what level capabilities were fulfilled at.
:param kwargs: Options that can be passed to the LLM model as other parameters.
:return: a List of Blocks that are returned from the plugin.
"""
file_ids = {b.file_id for b in messages}
block_ids = None
temp_file = None
if len(file_ids) != 1 and next(iter(file_ids)) is not None:
file_id = next(iter(file_ids))
block_ids = [b.id for b in messages]
else:
temp_file = File.create(
client=self.client,
blocks=messages,
tags=[Tag(kind=TagKind.GENERATION, name=GenerationTag.PROMPT_COMPLETION)],
)
file_id = temp_file.id

request_block = CapabilityPluginRequest(requested_capabilities=capabilities).create_block(
client=self.client, file_id=file_id
)
if block_ids:
block_ids.append(request_block.id)

try:
generation_task = self.plugin_instance.generate(
input_file_id=file_id, input_file_block_index_list=block_ids, options=kwargs
)
generation_task.wait()

for block in generation_task.output.blocks:
if block.mime_type == MimeTypes.STEAMSHIP_PLUGIN_CAPABILITIES_RESPONSE:
if logging.DEBUG >= logging.root.getEffectiveLevel():
response = CapabilityPluginResponse.from_block(block)
logging.debug(
f"Plugin capability fulfillment:\n\n{pformat(response.json())}"
)
break
else:
if assert_capabilities:
version_string = f"{self.plugin_instance.plugin_handle}, v.{self.plugin_instance.plugin_version_handle}"
raise SteamshipError(
f"Asserting capabilities are used, but capability response was not returned by plugin ({version_string})"
)
finally:
if temp_file:
temp_file.delete()

return generation_task.output.blocks
15 changes: 14 additions & 1 deletion src/steamship/base/mime_types.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
from enum import Enum

STEAMSHIP_PREFIX = "application/vnd.steamship-block"


class MimeTypes(str, Enum):
UNKNOWN = "unknown"
Expand All @@ -19,7 +21,7 @@ class MimeTypes(str, Enum):
PPTX = "application/vnd.openxmlformats-officedocument.presentationml.presentation"
RTF = "application/rtf"
BINARY = "application/octet-stream"
STEAMSHIP_BLOCK_JSON = "application/vnd.steamship-block.json.v1"
STEAMSHIP_BLOCK_JSON = f"{STEAMSHIP_PREFIX}.json.v1"
WAV = "audio/wav"
MP3 = "audio/mp3"
OGG_AUDIO = "audio/ogg"
Expand All @@ -30,6 +32,17 @@ class MimeTypes(str, Enum):
WEBM_AUDIO = "audio/webm"
FILE_JSON = "fileJson"

# This block contains information that isn't part of the payload to/from a plugin, but instead is json-formatted
# information about if/how the plugin supports certain behaviors.
STEAMSHIP_PLUGIN_CAPABILITIES_REQUEST = f"{STEAMSHIP_PREFIX}.plugin-capabilities-request+json"
STEAMSHIP_PLUGIN_CAPABILITIES_RESPONSE = f"{STEAMSHIP_PREFIX}.plugin-capabilities-response+json"
STEAMSHIP_PLUGIN_FUNCTION_CALL_INVOCATION = (
f"{STEAMSHIP_PREFIX}.function-calling-support-invocation+json"
)
STEAMSHIP_PLUGIN_FUNCTION_CALL_RESULT = (
f"{STEAMSHIP_PREFIX}.function-calling-support-result+json"
)

@classmethod
def has_value(cls, value):
return value in cls._value2member_map_
Expand Down
11 changes: 10 additions & 1 deletion src/steamship/cli/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,16 @@

@click.group()
def cli():
pass
if not steamship.is_supported_python_version():
click.echo("⚠️ ⚠️ ⚠️️️️️️️️️️️")
click.echo(f"Running on unsupported Python version: {sys.version}")
click.echo(
"Steamship runtime supports only the following versions; you may see irregular behavior otherwise:"
)
for supported_name in steamship.SUPPORTED_PYTHON_VERSION_NAMES:
click.echo(f" {supported_name}")
click.echo("Please develop against supported Python versions.")
click.echo("⚠️ ⚠️ ⚠️️️️️️️️️️️")


def initialize(suppress_message: bool = False):
Expand Down
4 changes: 4 additions & 0 deletions src/steamship/data/block.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

from steamship import MimeTypes, SteamshipError
from steamship.base.client import Client
from steamship.base.mime_types import STEAMSHIP_PREFIX
from steamship.base.model import CamelModel
from steamship.base.request import DeleteRequest, IdentifierRequest, Request
from steamship.base.response import Response
Expand Down Expand Up @@ -218,6 +219,9 @@ def is_audio(self):
MimeTypes.OGG_AUDIO,
]

def is_steamship_internal(self):
return self.mime_type.startswith(STEAMSHIP_PREFIX)

def is_video(self):
"""Return whether this is a video Block."""
return self.mime_type in [MimeTypes.MP4_VIDEO, MimeTypes.WEBM_VIDEO, MimeTypes.OGG_VIDEO]
Expand Down
Loading

0 comments on commit 130e159

Please sign in to comment.