chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,118 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
|
||||
import httpx
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
from semantic_kernel.functions.kernel_function_decorator import kernel_function
|
||||
|
||||
# region GitHub Models
|
||||
|
||||
|
||||
class Repo(BaseModel):
|
||||
id: int = Field(..., alias="id")
|
||||
name: str = Field(..., alias="full_name")
|
||||
description: str | None = Field(default=None, alias="description")
|
||||
url: str = Field(..., alias="html_url")
|
||||
|
||||
|
||||
class User(BaseModel):
|
||||
id: int = Field(..., alias="id")
|
||||
login: str = Field(..., alias="login")
|
||||
name: str | None = Field(default=None, alias="name")
|
||||
company: str | None = Field(default=None, alias="company")
|
||||
url: str = Field(..., alias="html_url")
|
||||
|
||||
|
||||
class Label(BaseModel):
|
||||
id: int = Field(..., alias="id")
|
||||
name: str = Field(..., alias="name")
|
||||
description: str | None = Field(default=None, alias="description")
|
||||
|
||||
|
||||
class Issue(BaseModel):
|
||||
id: int = Field(..., alias="id")
|
||||
number: int = Field(..., alias="number")
|
||||
url: str = Field(..., alias="html_url")
|
||||
title: str = Field(..., alias="title")
|
||||
state: str = Field(..., alias="state")
|
||||
labels: list[Label] = Field(..., alias="labels")
|
||||
when_created: str | None = Field(default=None, alias="created_at")
|
||||
when_closed: str | None = Field(default=None, alias="closed_at")
|
||||
|
||||
|
||||
class IssueDetail(Issue):
|
||||
body: str | None = Field(default=None, alias="body")
|
||||
|
||||
|
||||
# endregion
|
||||
|
||||
|
||||
class GitHubSettings(BaseModel):
|
||||
base_url: str = "https://api.github.com"
|
||||
token: str
|
||||
|
||||
|
||||
class GitHubPlugin:
|
||||
def __init__(self, settings: GitHubSettings):
|
||||
self.settings = settings
|
||||
|
||||
@kernel_function
|
||||
async def get_user_profile(self) -> "User":
|
||||
async with self.create_client() as client:
|
||||
response = await self.make_request(client, "/user")
|
||||
return User(**response)
|
||||
|
||||
@kernel_function
|
||||
async def get_repository(self, organization: str, repo: str) -> "Repo":
|
||||
async with self.create_client() as client:
|
||||
response = await self.make_request(client, f"/repos/{organization}/{repo}")
|
||||
return Repo(**response)
|
||||
|
||||
@kernel_function
|
||||
async def get_issues(
|
||||
self,
|
||||
organization: str,
|
||||
repo: str,
|
||||
max_results: int | None = None,
|
||||
state: str = "",
|
||||
label: str = "",
|
||||
assignee: str = "",
|
||||
) -> list["Issue"]:
|
||||
async with self.create_client() as client:
|
||||
path = f"/repos/{organization}/{repo}/issues?"
|
||||
path = self.build_query(path, "state", state)
|
||||
path = self.build_query(path, "assignee", assignee)
|
||||
path = self.build_query(path, "labels", label)
|
||||
path = self.build_query(path, "per_page", str(max_results) if max_results else "")
|
||||
response = await self.make_request(client, path)
|
||||
return [Issue(**issue) for issue in response]
|
||||
|
||||
@kernel_function
|
||||
async def get_issue_detail(self, organization: str, repo: str, issue_id: int) -> "IssueDetail":
|
||||
async with self.create_client() as client:
|
||||
path = f"/repos/{organization}/{repo}/issues/{issue_id}"
|
||||
response = await self.make_request(client, path)
|
||||
return IssueDetail(**response)
|
||||
|
||||
def create_client(self) -> httpx.AsyncClient:
|
||||
headers = {
|
||||
"User-Agent": "request",
|
||||
"Accept": "application/vnd.github+json",
|
||||
"Authorization": f"Bearer {self.settings.token}",
|
||||
"X-GitHub-Api-Version": "2022-11-28",
|
||||
}
|
||||
return httpx.AsyncClient(base_url=self.settings.base_url, headers=headers, timeout=5)
|
||||
|
||||
@staticmethod
|
||||
def build_query(path: str, key: str, value: str) -> str:
|
||||
if value:
|
||||
return f"{path}{key}={value}&"
|
||||
return path
|
||||
|
||||
@staticmethod
|
||||
async def make_request(client: httpx.AsyncClient, path: str) -> dict:
|
||||
print(f"REQUEST: {path}\n")
|
||||
response = await client.get(path)
|
||||
response.raise_for_status()
|
||||
return response.json()
|
||||
@@ -0,0 +1,76 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
# <defineClass>
|
||||
import math
|
||||
from typing import Annotated
|
||||
|
||||
from semantic_kernel.functions.kernel_function_decorator import kernel_function
|
||||
|
||||
|
||||
class Math:
|
||||
# </defineClass>
|
||||
"""
|
||||
Description: MathPlugin provides a set of functions to make Math calculations.
|
||||
|
||||
Usage:
|
||||
kernel.add_plugin(MathPlugin(), plugin_name="math")
|
||||
|
||||
Examples:
|
||||
{{math.Add}} => Returns the sum of input and amount (provided in the KernelArguments)
|
||||
{{math.Subtract}} => Returns the difference of input and amount (provided in the KernelArguments)
|
||||
{{math.Multiply}} => Returns the multiplication of input and number2 (provided in the KernelArguments)
|
||||
{{math.Divide}} => Returns the division of input and number2 (provided in the KernelArguments)
|
||||
"""
|
||||
|
||||
@kernel_function(
|
||||
description="Divide two numbers.",
|
||||
name="Divide",
|
||||
)
|
||||
def divide(
|
||||
self,
|
||||
number1: Annotated[float, "the first number to divide from"],
|
||||
number2: Annotated[float, "the second number to by"],
|
||||
) -> Annotated[float, "The output is a float"]:
|
||||
return float(number1) / float(number2)
|
||||
|
||||
@kernel_function(
|
||||
description="Multiply two numbers. When increasing by a percentage, don't forget to add 1 to the percentage.",
|
||||
name="Multiply",
|
||||
)
|
||||
def multiply(
|
||||
self,
|
||||
number1: Annotated[float, "the first number to multiply"],
|
||||
number2: Annotated[float, "the second number to multiply"],
|
||||
) -> Annotated[float, "The output is a float"]:
|
||||
return float(number1) * float(number2)
|
||||
|
||||
# <defineFunction>
|
||||
@kernel_function(
|
||||
description="Takes the square root of a number",
|
||||
name="Sqrt",
|
||||
)
|
||||
def square_root(
|
||||
self,
|
||||
number1: Annotated[float, "the number to take the square root of"],
|
||||
) -> Annotated[float, "The output is a float"]:
|
||||
return math.sqrt(float(number1))
|
||||
|
||||
# </defineFunction>
|
||||
|
||||
@kernel_function(name="Add")
|
||||
def add(
|
||||
self,
|
||||
number1: Annotated[float, "the first number to add"],
|
||||
number2: Annotated[float, "the second number to add"],
|
||||
) -> Annotated[float, "the output is a float"]:
|
||||
return float(number1) + float(number2)
|
||||
|
||||
@kernel_function(
|
||||
description="Subtracts value to a value",
|
||||
name="Subtract",
|
||||
)
|
||||
def subtract(
|
||||
self,
|
||||
number1: Annotated[float, "the first number"],
|
||||
number2: Annotated[float, "the number to subtract"],
|
||||
) -> Annotated[float, "the output is a float"]:
|
||||
return float(number1) - float(number2)
|
||||
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"schema": 1,
|
||||
"description": "Gets the intent of the user.",
|
||||
"execution_settings": {
|
||||
"default": {
|
||||
"max_tokens": 200,
|
||||
"temperature": 0.5,
|
||||
"top_p": 0.0,
|
||||
"presence_penalty": 0.0,
|
||||
"frequency_penalty": 0.0
|
||||
}
|
||||
},
|
||||
"input_variables": [
|
||||
{
|
||||
"name": "input",
|
||||
"description": "The user's request.",
|
||||
"default": ""
|
||||
},
|
||||
{
|
||||
"name": "history",
|
||||
"description": "The history of the conversation.",
|
||||
"default": ""
|
||||
},
|
||||
{
|
||||
"name": "options",
|
||||
"description": "The options to choose from.",
|
||||
"default": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
[History]
|
||||
{{$history}}
|
||||
|
||||
User: {{$input}}
|
||||
|
||||
---------------------------------------------
|
||||
|
||||
Provide the intent of the user. The intent should be one of the following: {{$options}}
|
||||
|
||||
INTENT:
|
||||
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"schema": 1,
|
||||
"description": "Turn a scenario into a short and entertaining poem.",
|
||||
"execution_settings": {
|
||||
"default": {
|
||||
"max_tokens": 200,
|
||||
"temperature": 0.7,
|
||||
"top_p": 0.0,
|
||||
"presence_penalty": 0.0,
|
||||
"frequency_penalty": 0.0
|
||||
}
|
||||
},
|
||||
"input_variables": [
|
||||
{
|
||||
"name": "input",
|
||||
"description": "The scenario to turn into a poem.",
|
||||
"default": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
Generate a short funny poem or limerick to explain the given event. Be creative and be funny. Let your imagination run wild.
|
||||
Event:{{$input}}
|
||||
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"schema": 1,
|
||||
"description": "Summarizes the conversation.",
|
||||
"execution_settings": {
|
||||
"default": {
|
||||
"max_tokens": 4000,
|
||||
"temperature": 0.3
|
||||
}
|
||||
},
|
||||
"input_variables": [
|
||||
{
|
||||
"name": "input",
|
||||
"description": "The user's request.",
|
||||
"default": ""
|
||||
},
|
||||
{
|
||||
"name": "history",
|
||||
"description": "The history of the conversation.",
|
||||
"default": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
{{ConversationSummaryPlugin.SummarizeConversation $history}}
|
||||
User: {{$request}}
|
||||
Assistant:
|
||||
Reference in New Issue
Block a user