From 622f8bc0095635adf037cacd9fdbb5a524b66fe0 Mon Sep 17 00:00:00 2001 From: KIMB-technologies Date: Wed, 18 Sep 2024 16:32:01 +0200 Subject: [PATCH] Notes 18.09. --- Dockerfile | 3 + Readme.md | 71 --------------------- Requests.md | 132 +++++++++++++++++++++++++++++++++++++++ docker-compose.yml | 21 +++++++ src/agent/agent.py | 57 +++++++++++++++++ src/agent/basic_agent.py | 80 ++++++++++++++++++++++++ src/agent/o_types.py | 43 +++++++++++++ 7 files changed, 336 insertions(+), 71 deletions(-) create mode 100644 Dockerfile create mode 100644 Requests.md create mode 100644 docker-compose.yml create mode 100644 src/agent/agent.py create mode 100644 src/agent/basic_agent.py create mode 100644 src/agent/o_types.py diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..c0ab7de --- /dev/null +++ b/Dockerfile @@ -0,0 +1,3 @@ +FROM git.chai.uni-hamburg.de/ums-agenten/base-process:cpu + +RUN apt install my-pkg \ No newline at end of file diff --git a/Readme.md b/Readme.md index 89bdbd9..3d8bb56 100644 --- a/Readme.md +++ b/Readme.md @@ -1,73 +1,2 @@ # Agenten-Plattform -## Allgemein -- Docker Container - - Ein Manager-Agent - - Viele Worker-Agenten -- JSON Post Requests -- Studis erstellen Worker-Agenten - - Library vorgegeben - - HTTP-Server für Tasks, Ergebnisse per HTTP an Manager - - Worker registriert sich beim Manager mit - - Seiner IP/ HTTP Schnittstelle - - Seinen Fähigkeiten (Capabilities) - -## Agent Capabilities -- -- Vorverarbeitung -- Evaluation - -## Example -- Manager und einfache Worker - - -## Requests - -``` -{ - "type" : "register" // "unregister", - "body" : { - "capabilities" : [""], - "endpoint" : "10.0.0.12:8080" - }, - "sender-id" : "worker1", - "comment" : "", - "error" : false -} -``` - -``` -{ - "type" : "task", - "task-id" : "t12", - "capability" : "", - "body" : { - - }, - "sender-id" : "manager", - "comment" : "", - "error" : false -} -``` - -``` -{ - "type" : "response", - "task-id" : "t12" - "body" : { - - }, - "sender-id" : "worker1", - "comment" : "", - "error" : false -} -``` - -## Aufgabe -- Online-Escape-Room -- Unterlagen, die zum "Ausgang" führen -- Eingabe: Unterlagen für Rätsel (Audio, Text, Bilder, ...) [ZIP, JSON] - - Vorverarbeitung: Agent je für Audio, Text, Bild (→ alles textlich) - - Analyse: - - Ausgabe: Lösung & Erklärung -- Ziel: Finde Lösung mit Erklärung \ No newline at end of file diff --git a/Requests.md b/Requests.md new file mode 100644 index 0000000..f402b9f --- /dev/null +++ b/Requests.md @@ -0,0 +1,132 @@ +### Ablauf +1. Daten und Rästel eingeben + - an Management von Benutzer (oder als Subrätsel) + ```json + { + "id" : "xyz", + "riddle" : { + "context" : "The values of the variables of the following math problem are given in the text document as written numbers.", + "question" : "What is x+y?", + "solution_before" : "", # if trial > 0 + "review_before": "" # if trial > 0 + }, + "trial" : 0, # did we try this before + "steps" : { + "extract" : true, + "solve" : true, + "validate": true, + }, + "data" : [ + { + "type" : "text", + "file" : "./my-test.txt" + }, + ... + ] + } + ``` +2. Daten verteilen (`if "extract" : true`) + - an alle "🤖 Daten einlesen" vom Management + ```json + { + "id" : "xyz", + "data" : [ + { + "type" : "text", + "file" : "./my-test.txt" + }, + ... + ] + } + ``` +3. Verarbeitete Daten annehmen (`if "extract" : true|false`) + - von allen "🤖 Daten einlesen" an Management + ```json + { + "id" : "xyz", + "data" : [ + { + "type" : "text", + "file" : "./my-test.txt", + "extraction" : "./my-test.json" # schema für alle gleich + }, + ... + ] + } + ``` +4. Rätsel lösen (`if "solve" : true|false`) + - an (alle) "🤖 Lösung bestimmen" von Management + ```json + { + "id" : "xyz", + "riddle" : { ... }, + "data" : [ + { + "type" : "text", + "file" : "./my-test.txt", + "extraction" : "./my-test.json" + }, + ... + ] + } + ``` + - Muss ein "Subrätsel" erzeugen (können), wenn weitere Datenanalyse notwenig ist + - Mit einer Submenge der Daten bzw. konkreten Fragen etc. +5. Lösung eines Rätsel annehmen (`if "solve" : true`) + - von (alle) "🤖 Lösung bestimmen" an Management + ```json + { + "id" : "xyz", + "solution" : "26", + "explanation" : "x = 12, y = 14, ...", + "sub_riddles" : [ # optional + "xyz-1", + "xyz-2" + ], + "used_data" : [ # optional + { + "type" : "text", + "file" : "./my-test.txt", + "extraction" : "./my-test.json" + }, + ... + ] + } + ``` +6. Lösung validieren lassen (`if "validate": true`) + - an (alle) "🤖 Lösung validieren" durch Management + ```json + { + "id" : "xyz", + "riddle" : { ... } + "solution" : "26", + "explanation" : "x = 12, y = 14, ...", + "sub_riddles" : [ # optional + "xyz-1", + "xyz-2" + ], + "used_data" : [ # optional + { + "type" : "text", + "file" : "./my-test.txt", + "extraction" : "./my-test.json" + }, + ... + ] + } + ``` +7. Validierung annehmen (`if "validate": true`) + - von (alle) "🤖 Lösung validieren" an Management + ```json + { + "id" : "xyz", + "solution" : "26", + "explanation" : "x = 12, y = 14, ...", + "accept" : false # or true + "review" : "y does not match Y" + } + ``` +8. Ausgabe oder Wiedervorlage + - von Management an User oder als neues Riddle + - `if "accept" : false`: Neues Riddle mit `trial+1`, `solution_before`, `review_before` + - `if "accept" : true`: User bekommt `solution, explanation, review` \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..765be11 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,21 @@ + +services: + management: + image: git.chai.uni-hamburg.de/ums-agenten/management:latest + ports: + - + environment: + - AGENTS_PROCESS=http://agent_process_1:3001,http://agent_process_2:3001 + - AGENTS_SOLVE=http://agent_solve_1:3001 + - AGENTS_GATEKEEPER=http://agent_gatekeeper_1:3001 + volumes: + - /xxx/: + + agent_process_1: + image: git.chai.uni-hamburg.de/ums-agenten/base-process:cpu + #image: git.chai.uni-hamburg.de/ums-agenten/base-process:gpu + build: . + environment: + - MANAGEMENT=http://management:3001 + volumes: + - /xxx/:/ums-agenten/shared/ \ No newline at end of file diff --git a/src/agent/agent.py b/src/agent/agent.py new file mode 100644 index 0000000..d6ba862 --- /dev/null +++ b/src/agent/agent.py @@ -0,0 +1,57 @@ + +from abc import abstractmethod +from typing import List, Dict + +from o_types import * + +class Agent(): + + def process_result(): + pass + + # hier die Kommunikation mit dem Management Server + +""" ===== """ + +class ProcessAgent(Agent): + TYPE:str = None + + @abstractmethod + def on_process_data(self, data:List[Data]): + pass + +class TextAgentExample(ProcessAgent): + TYPE = Data.TYPE_TEXT + def on_process_data(self, data:List[Data]): + # Studi Code + self.process_result(Data(...)) + +class ImageAgentExample(ProcessAgent): + TYPE = Data.TYPE_IMAGE + +class AudioAgentExample(ProcessAgent): + TYPE = Data.TYPE_AUDIO + +""" ===== """ + +class SolveAgent(Agent): + + @abstractmethod + def on_riddle_data(self, riddle:Riddle, data:List[Data]): + pass + + # Studi Code + + self.new_riddle(Riddle('x', 'y', 'z')) + self.send_riddle_result(...) + +""" ===== """ + +class GatekeeperAgent(Agent): + + @abstractmethod + def on_result_check(self, xyz): + + # Studi Code + + self.send_check_result(accept=True|False, ...) \ No newline at end of file diff --git a/src/agent/basic_agent.py b/src/agent/basic_agent.py new file mode 100644 index 0000000..a0608ad --- /dev/null +++ b/src/agent/basic_agent.py @@ -0,0 +1,80 @@ + +from agent import Agent + +class ProcessTextAgent(Agent): + + TYPE = "text" or "image" + + + def on_process_data(self, data:List[Dict]): + return filter(lambda x: x["type"] == self.TYPE, data) + + # {type: "text", "file" : ""} + +class ExampleAgent(ProcessTextAgent): + + + def on_process_data(self, data:List[Dict]): + # {type: "text", "file" : ""} + + self.after_process_data(result) + + + +# disk -> 123 +# agent 1 disk -> 123 + +class Agent: + def request_management(self, request): + request.get(os.gentenv('MANAGEMENT'), data) + # https ... + + def write_result(...): + self.request_management.write(...) + + def read_result(...): + self.request_management.read(...) + + +class ProcessAgent(Agent): + TYPE : str = None + + def on_process_data(self, data:List[Dict]): + pass + +class TextAgent(ProcessAgent): + TYPE = 'text' + text_data = self.on_process_data() + + def on_process_data(self, data:List[Dict]): + text_data = filter_text_data() + processed_data = text_func1(text_data) + + self.write_result(processed_data) + + def text_func1(): + ... + + def text_func2(): + ... + + def text_func3(): + ... + +class ImageAgent(ProcessAgent): + TYPE = 'image' + + image_data = self.on_process_data() + + + def on_process_data(self, data:list[Dict]) + image_data = filter_image_data() + + def image_func1(): + ... + + ... + + + + diff --git a/src/agent/o_types.py b/src/agent/o_types.py new file mode 100644 index 0000000..7eae870 --- /dev/null +++ b/src/agent/o_types.py @@ -0,0 +1,43 @@ + +from typing import List + +class Riddle(): + + def __init__(self): + self.id = "" # -> management.get_riddle_by_id(id) + self.parent_id = "" # ?! + + self.context = "1234" + self.question = "12" + + self.data:List[Data] = [] + + def from_json(json): + return Riddle(json) + + def to_json(self): + return { + "context" : self.context, + "question" : self.question, + "solution_before" : "", # if trial > 0 + "review_before": "" # if trial > 0 + } + +class Data(): + + TYPE_TEXT = "text" + TYPE_AUDIO = "audio" + TYPE_IMAGE = "image" + + def __init__(self): + self.type = 1 + self.file = 2 + self.extraction = 3 + + def to_json(self): + return { + "type" : self.type, + "file" : self.file, + "extraction" : self.extraction + } + \ No newline at end of file