Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

initial version of API server #60

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions adala/agents/base.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from pydantic import BaseModel, Field, SkipValidation, field_validator, model_validator
from abc import ABC, abstractmethod
from typing import Any, Optional, List, Dict, Union, Tuple
from typing import Any, Optional, List, Dict, Union, Tuple, Callable
from rich import print

from adala.environments.base import Environment, StaticEnvironment, EnvironmentFeedback
Expand Down Expand Up @@ -205,6 +205,7 @@ def run(
predictions = self.skills.apply(input, runtime=runtime)
return predictions


def select_skill_to_train(
self, feedback: EnvironmentFeedback, accuracy_threshold: float
) -> Tuple[str, str, float]:
Expand Down Expand Up @@ -234,6 +235,7 @@ def select_skill_to_train(

return train_skill_name, train_skill_output, acc_score


def learn(
self,
learning_iterations: int = 3,
Expand All @@ -243,6 +245,7 @@ def learn(
num_feedbacks: Optional[int] = None,
runtime: Optional[str] = None,
teacher_runtime: Optional[str] = None,
log_results_func: Optional[Callable[..., dict]] = None
):
"""
Enables the agent to learn and improve its skills based on interactions with its environment.
Expand Down Expand Up @@ -290,7 +293,7 @@ def learn(
skill = self.skills[skill_name]
if skill.frozen:
continue

print_text(
f'Skill output to improve: "{skill_output}" (Skill="{skill_name}")\n'
f"Accuracy = {accuracy[skill_output] * 100:0.2f}%",
Expand All @@ -307,6 +310,10 @@ def learn(
else:
print_text(skill.instructions, style="bold green")

log_results_func(learning_iterations=learning_iterations, current_iteration=iteration,
inputs=inputs, predictions=predictions, feedback=feedback, train_skill_name=skill_name,
messages=None, new_instructions=skill.instructions)

if skill_name == first_skill_with_errors:
break

Expand Down
85 changes: 85 additions & 0 deletions adala/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@


import argparse
# from flask import Flask
import threading
import os
import signal
import time
import sqlite3

import argparse
from fastapi import FastAPI, UploadFile, File, HTTPException
from starlette.responses import JSONResponse

from adala.web.server import Server # , app
# import adala.api
# from data_processing import DataProcessing


parser = argparse.ArgumentParser(description="ADALA Command Line Interface")
subparsers = parser.add_subparsers(dest='command')
server = Server()
# data_processing = DataProcessing()
# utility = Utility()

# Server
server_instance = Server() # args.port)
server_parser = subparsers.add_parser('server')
server_parser.add_argument('--port', type=int, default=8000)
server_parser.set_defaults(func=server.start)


# restart_parser.set_defaults(func=server.start)

# server_instance.start()

# Restart
restart_parser = subparsers.add_parser('restart')
restart_parser.add_argument('--port', type=int, default=8000)
restart_parser.set_defaults(func=server.restart)

# Shutdown
shutdown_parser = subparsers.add_parser('shutdown')
shutdown_parser.set_defaults(func=server.shutdown)

# Send data
send_parser = subparsers.add_parser('send')
send_parser.add_argument('--file', required=True, help='Path to data file')
# send_parser.set_defaults(func=data_processing.send)

# Predict
predict_parser = subparsers.add_parser('predict')
predict_parser.add_argument('--file', required=True, help='Path to test data file')
predict_parser.add_argument('--output', required=True, help='Path to save the output')
# predict_parser.set_defaults(func=data_processing.predict)

# List models
list_models_parser = subparsers.add_parser('list-models')
# list_models_parser.set_defaults(func=utility.list_models)

# List agents
list_agents_parser = subparsers.add_parser('list-agents')
# list_agents_parser.set_defaults(func=utility.list_agents)

# Logs
logs_parser = subparsers.add_parser('logs')
logs_parser.add_argument('--tail', type=int, default=10)
# logs_parser.set_defaults(func=utility.logs)

# Metrics
metrics_parser = subparsers.add_parser('metrics')
# metrics_parser.set_defaults(func=utility.metrics)

# Help
help_parser = subparsers.add_parser('help')
help_parser.add_argument('command', type=str, help='Command to get help for')
# help_parser.set_defaults(func=utility.help)


if __name__ == "__main__":
args = parser.parse_args()
if hasattr(args, 'func'):
args.func(args)
else:
parser.print_help()
Empty file added adala/web/__init__.py
Empty file.
51 changes: 51 additions & 0 deletions adala/web/api.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@

import json

from pydantic import BaseModel, Field
from typing import Dict, List, Optional
from starlette.status import HTTP_201_CREATED

from fastapi import FastAPI, UploadFile, File, HTTPException
from fastapi import APIRouter

from fastapi.responses import HTMLResponse
from fastapi import FastAPI, HTTPException
from starlette.status import (
HTTP_400_BAD_REQUEST,
HTTP_403_FORBIDDEN,
HTTP_404_NOT_FOUND,
HTTP_201_CREATED
)

from adala.web.routes import runtimes, agents, skills, versions, envs

router = APIRouter()

router.include_router(router=agents.router, tags=["Agents"], prefix="/api/agents")
router.include_router(router=skills.router, tags=["Skills"], prefix="/api/skills")
router.include_router(router=versions.router, tags=["Versions"], prefix="/api/skills")
router.include_router(router=runtimes.router, tags=["Runtimes"], prefix="/api/runtimes")
router.include_router(router=envs.router, tags=["Environments"], prefix="/api/envs")


# db = Database()
# db.connect()

# from .data_processing import DataProcessing


# @router.post("/upload/")
# async def upload_api(file: UploadFile = File(...)):
# # with open(f"/temp/path/{file.filename}", "wb") as buffer:
# # buffer.write(file.file.read())
# # data_processing = DataProcessing()
# # return data_processing.send(f"/temp/path/{file.filename}")
# pass

@router.get('/web')
async def index():
# Serve the index.html file
with open('static/index.html', 'r') as f:
html_content = f.read()
return HTMLResponse(content=html_content, status_code=200)

124 changes: 124 additions & 0 deletions adala/web/connector.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@

import json
import pandas as pd

from pathlib import Path
from adala.agents import Agent

import adala.runtimes
import adala.skills
import adala.environments
import adala.skills.skillset

from .settings import UPLOAD_PATH

def create_adala_instance(agent):
""" """
## load runtimes
print(agent.runtimes)
runtimes = {}

# this should be an attribute on the model and configurable through the UI.
default_runtime = ""

for rt in agent.runtimes:
class_obj = getattr(adala.runtimes, rt.rt_class_name)
print(rt.runtime_params)
print(rt.runtime_params)
params = {}
if rt.runtime_params is not None:
params = json.loads(rt.runtime_params)

instance = class_obj(**params)
runtimes[rt.name] = instance

default_runtime = rt.name


skills = {}
skills_map = {}

for sk in agent.skills:
kwargs = {}
if sk.skill_params:
kwargs = json.loads(sk.skill_params)

field_schema = None
if sk.field_schema:
field_schema = json.loads(sk.field_schema)

class_obj = getattr(adala.skills, sk.sk_class_name)

print(kwargs)
print(sk)

instance = class_obj(name=sk.name,
# description=sk.description,
instructions=sk.instructions,
input_template=sk.input_template,
output_template=sk.output_template,
field_schema=field_schema,
**kwargs)

skills_map[sk.name] = sk
skills[sk.name] = instance

print(skills)

skills_group_class = getattr(adala.skills.skillset, agent.skills_group_class_name)

print(skills_group_class)
print(agent.skills_group_class_name)

sk_group_obj = skills_group_class(skills=skills)

print(runtimes)

# ENVs

filename = Path(UPLOAD_PATH) / agent.envs[0].local_filename
train_df = pd.read_csv(filename)

env = agent.envs[0]
env_class = getattr(adala.environments, env.env_class_name)
env_obj = env_class(df=train_df)


# train_df = pd.DataFrame([
# ["It was the negative first impressions, and then it started working.", "Positive"],
# ["Not loud enough and doesn't turn on like it should.", "Negative"],
# ["I don't know what to say.", "Neutral"],
# ["Manager was rude, but the most important that mic shows very flat frequency response.", "Positive"],
# ["The phone doesn't seem to accept anything except CBR mp3s.", "Negative"],
# ["I tried it before, I bought this device for my son.", "Neutral"],
# ], columns=["text", "sentiment"])

# # Test dataset
# test_df = pd.DataFrame([
# "All three broke within two months of use.",
# "The device worked for a long time, can't say anything bad.",
# "Just a random line of text."
# ], columns=["text"])

adala_agent = Agent(
# connect to a dataset
environment=env_obj,

# define a skill
skills=sk_group_obj,

# define all the different runtimes your skills may use
runtimes = runtimes,

default_runtime=default_runtime,

# NOTE! If you have access to GPT-4, you can uncomment the lines bellow for better results
# default_teacher_runtime='openai-gpt4',
# teacher_runtimes = {
# 'openai-gpt4': OpenAIRuntime(model='gpt-4')
# }
)

return adala_agent, skills_map, runtimes, env_obj
# print(agent)
# print(agent.skills)
Loading