bugfix
This commit is contained in:
parent
218166c41c
commit
4099c30156
18
pyproject.toml
Normal file
18
pyproject.toml
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
[build-system]
|
||||||
|
requires = ["setuptools>=61.0"]
|
||||||
|
build-backend = "setuptools.build_meta"
|
||||||
|
|
||||||
|
[project]
|
||||||
|
name = "skillagent"
|
||||||
|
version = "0.1.0"
|
||||||
|
description = "Agent + Skillkit integration module with multi-skill, multi-script support"
|
||||||
|
authors = [
|
||||||
|
{ name="Your Name", email="you@example.com" }
|
||||||
|
]
|
||||||
|
readme = "README.md"
|
||||||
|
requires-python = ">=3.10"
|
||||||
|
dependencies = [
|
||||||
|
"pydantic>=1.10",
|
||||||
|
"skillkit",
|
||||||
|
"aiohttp"
|
||||||
|
]
|
||||||
0
skillagent/__init__.py
Normal file
0
skillagent/__init__.py
Normal file
43
skillagent/agent.py
Normal file
43
skillagent/agent.py
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
import os, json
|
||||||
|
from typing import Dict
|
||||||
|
from pydantic import ValidationError
|
||||||
|
|
||||||
|
class DAGNode:
|
||||||
|
def __init__(self, skill, script=None, params=None):
|
||||||
|
self.skill = skill
|
||||||
|
self.script = script
|
||||||
|
self.params = params or {}
|
||||||
|
self.state = "pending"
|
||||||
|
self.missing = []
|
||||||
|
|
||||||
|
class SkillAgent:
|
||||||
|
def __init__(self, skill_loader, skillkit_wrapper, llm):
|
||||||
|
self.skill_loader = skill_loader
|
||||||
|
self.skillkit = skillkit_wrapper
|
||||||
|
self.llm = llm
|
||||||
|
self.dag = []
|
||||||
|
|
||||||
|
async def plan(self, user_text: str):
|
||||||
|
skills = self.skill_loader.list_skills()
|
||||||
|
skill_docs = "\n".join([open(os.path.join(self.skill_loader.skillspath, s, "skill.md"), encoding="utf-8").read() for s in skills])
|
||||||
|
prompt = f"""
|
||||||
|
User request: {user_text}
|
||||||
|
Available Skills:
|
||||||
|
{skill_docs}
|
||||||
|
|
||||||
|
Task: choose the most suitable skill and script. Output JSON: {{ "skill": "<skill_name>", "script": "<script_name>" }}
|
||||||
|
"""
|
||||||
|
raw = await self.llm.complete(prompt)
|
||||||
|
data = json.loads(raw)
|
||||||
|
node = DAGNode(skill=data["skill"], script=data["script"])
|
||||||
|
self.dag.append(node)
|
||||||
|
return node
|
||||||
|
|
||||||
|
async def resume(self, node: DAGNode, user_params: dict = None, schema=None):
|
||||||
|
try:
|
||||||
|
validated = schema(**(user_params or node.params))
|
||||||
|
node.params = validated.dict()
|
||||||
|
except ValidationError as e:
|
||||||
|
node.missing = [err['loc'][0] for err in e.errors()]
|
||||||
|
return node.missing
|
||||||
|
return self.skillkit.invoke_skill(node.skill, node.script, node.params)
|
||||||
12
skillagent/schemas/generic_schemas.py
Normal file
12
skillagent/schemas/generic_schemas.py
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
from pydantic import BaseModel
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
|
class SliderParams(BaseModel):
|
||||||
|
min: int
|
||||||
|
max: int
|
||||||
|
step: Optional[int] = 1
|
||||||
|
default: Optional[int] = 0
|
||||||
|
|
||||||
|
class ButtonParams(BaseModel):
|
||||||
|
label: str
|
||||||
|
color: Optional[str] = "blue"
|
||||||
25
skillagent/skill_loader.py
Normal file
25
skillagent/skill_loader.py
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
import os, re
|
||||||
|
from typing import List, Dict
|
||||||
|
|
||||||
|
class SkillLoader:
|
||||||
|
def __init__(self, skillspath: str):
|
||||||
|
self.skillspath = skillspath
|
||||||
|
|
||||||
|
def list_skills(self) -> List[str]:
|
||||||
|
return [name for name in os.listdir(self.skillspath)
|
||||||
|
if os.path.isdir(os.path.join(self.skillspath, name))]
|
||||||
|
|
||||||
|
def parse_skill_md(self, skill_name: str) -> List[Dict]:
|
||||||
|
md_path = os.path.join(self.skillspath, skill_name, "skill.md")
|
||||||
|
if not os.path.exists(md_path):
|
||||||
|
return []
|
||||||
|
scripts = []
|
||||||
|
md_text = open(md_path, encoding="utf-8").read()
|
||||||
|
script_blocks = re.findall(r"### (.+?)\n- 功能: (.+?)\n- 参数: (.+)", md_text)
|
||||||
|
for name, desc, params in script_blocks:
|
||||||
|
scripts.append({
|
||||||
|
"name": name.strip(),
|
||||||
|
"description": desc.strip(),
|
||||||
|
"params": [p.strip() for p in params.split(",")]
|
||||||
|
})
|
||||||
|
return scripts
|
||||||
7
skillagent/skillkit_wrapper.py
Normal file
7
skillagent/skillkit_wrapper.py
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
class SkillkitWrapper:
|
||||||
|
def __init__(self, skillkit_client):
|
||||||
|
self.client = skillkit_client
|
||||||
|
|
||||||
|
def invoke_skill(self, skill: str, script: str, params: dict):
|
||||||
|
print(f"Invoking skill={skill}, script={script}, params={params}")
|
||||||
|
return self.client.invoke_skill(skill, params)
|
||||||
10
skillagent/utils.py
Normal file
10
skillagent/utils.py
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
import os
|
||||||
|
|
||||||
|
def feed_doc_layer(skillspath: str, skill_name: str, layer: str, script_name: str = None):
|
||||||
|
base_path = os.path.join(skillspath, skill_name)
|
||||||
|
if layer == "skill":
|
||||||
|
return open(os.path.join(base_path, "skill.md"), encoding="utf-8").read()
|
||||||
|
elif layer == "script" and script_name:
|
||||||
|
return open(os.path.join(base_path, "scripts", f"{script_name}.md"), encoding="utf-8").read()
|
||||||
|
elif layer == "example" and script_name:
|
||||||
|
return open(os.path.join(base_path, "examples", f"{script_name}_example.md"), encoding="utf-8").read()
|
||||||
Loading…
x
Reference in New Issue
Block a user