iointel 1.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- iointel/__init__.py +25 -0
- iointel/client/__init__.py +0 -0
- iointel/client/client.py +168 -0
- iointel/src/__init__.py +0 -0
- iointel/src/agent_methods/__init__.py +0 -0
- iointel/src/agent_methods/agents/__init__.py +0 -0
- iointel/src/agent_methods/agents/agents_factory.py +111 -0
- iointel/src/agent_methods/data_models/__init__.py +0 -0
- iointel/src/agent_methods/data_models/datamodels.py +333 -0
- iointel/src/agent_methods/prompts/__init__.py +0 -0
- iointel/src/agent_methods/prompts/instructions.py +28 -0
- iointel/src/agent_methods/tools/__init__.py +0 -0
- iointel/src/agent_methods/tools/tools.py +9 -0
- iointel/src/agents.py +106 -0
- iointel/src/chainables.py +117 -0
- iointel/src/code_parsers/__init__.py +0 -0
- iointel/src/code_parsers/jscode_parser.py +209 -0
- iointel/src/code_parsers/pycode_parser.py +138 -0
- iointel/src/handlers.py +213 -0
- iointel/src/memory.py +172 -0
- iointel/src/sandbox.py +258 -0
- iointel/src/task.py +160 -0
- iointel/src/workflow.py +725 -0
- iointel-1.0.0.dist-info/METADATA +311 -0
- iointel-1.0.0.dist-info/RECORD +27 -0
- iointel-1.0.0.dist-info/WHEEL +4 -0
- iointel-1.0.0.dist-info/licenses/LICENSE +202 -0
iointel/__init__.py
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
|
|
2
|
+
from .src.agents import Agent
|
|
3
|
+
from .src.memory import AsyncMemory, AsyncPostgresMemoryProvider, Memory, PostgresMemoryProvider
|
|
4
|
+
from .src.workflow import Workflow, run_agents
|
|
5
|
+
from .src.agent_methods.data_models.datamodels import PersonaConfig
|
|
6
|
+
from .src.handlers import AsyncLoggingHandler, LoggingHandler
|
|
7
|
+
from .client import client
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
__all__ = [
|
|
11
|
+
"Agent",
|
|
12
|
+
"AsyncMemory",
|
|
13
|
+
"AsyncPostgresMemoryProvider",
|
|
14
|
+
"Memory",
|
|
15
|
+
"PostgresMemoryProvider",
|
|
16
|
+
"Workflow",
|
|
17
|
+
"run_agents",
|
|
18
|
+
"PersonaConfig",
|
|
19
|
+
"AsyncLoggingHandler",
|
|
20
|
+
"LoggingHandler",
|
|
21
|
+
"client"
|
|
22
|
+
]
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
__version__="1.0.0"
|
|
File without changes
|
iointel/client/client.py
ADDED
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import requests
|
|
2
|
+
import os
|
|
3
|
+
import time
|
|
4
|
+
from typing import Optional, List
|
|
5
|
+
from functools import partial
|
|
6
|
+
|
|
7
|
+
BASE_URL = os.getenv("OPENAI_API_BASE_URL", "").rstrip("/")
|
|
8
|
+
API_KEY = os.getenv("OPENAI_API_KEY")
|
|
9
|
+
BASE_MCP_URL = os.getenv("BASE_MCP_URL")
|
|
10
|
+
try:
|
|
11
|
+
SLOW_MODE_SLEEP = int(os.getenv("SLOW_MODE_SLEEP"))
|
|
12
|
+
except (ValueError, TypeError):
|
|
13
|
+
SLOW_MODE_SLEEP = -1
|
|
14
|
+
|
|
15
|
+
def __make_api_call(method, **kwargs) -> dict:
|
|
16
|
+
start = time.time()
|
|
17
|
+
url = kwargs.pop("url", f"{BASE_URL}/workflows/run")
|
|
18
|
+
headers = kwargs.pop("headers", {})
|
|
19
|
+
if "Authorization" not in headers:
|
|
20
|
+
headers["Authorization"] = f"Bearer {API_KEY}"
|
|
21
|
+
response = requests.request(method, url, headers=headers, **kwargs)
|
|
22
|
+
response.raise_for_status()
|
|
23
|
+
result = response.json()
|
|
24
|
+
if (remain := SLOW_MODE_SLEEP - (time.time() - start)) > 0:
|
|
25
|
+
# HACK avoid triggering rate limit protection if told so
|
|
26
|
+
# by making sure each `__make_api_call()` takes at least `SLOW_MODE_SLEEP` seconds
|
|
27
|
+
time.sleep(remain)
|
|
28
|
+
return result
|
|
29
|
+
__make_post_call = partial(__make_api_call, method="POST")
|
|
30
|
+
__make_get_call = partial(__make_api_call, method="GET")
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def schedule_task(task: str) -> dict:
|
|
34
|
+
raise NotImplementedError()
|
|
35
|
+
# payload = {"task": task}
|
|
36
|
+
# return __make_post_call(json=payload)
|
|
37
|
+
|
|
38
|
+
def run_council_task(task: str) -> dict:
|
|
39
|
+
raise NotImplementedError()
|
|
40
|
+
# return __make_post_call(json=payload)
|
|
41
|
+
|
|
42
|
+
def run_reasoning_task(text: str) -> dict:
|
|
43
|
+
payload = {
|
|
44
|
+
"text": text,
|
|
45
|
+
"agent_names": ["reasoning_agent"],
|
|
46
|
+
"args": {
|
|
47
|
+
"type": "solve_with_reasoning"
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return __make_post_call(json=payload)
|
|
51
|
+
|
|
52
|
+
def summarize_task(text: str) -> dict:
|
|
53
|
+
payload = {
|
|
54
|
+
"text": text,
|
|
55
|
+
"agent_names": ["summary_agent"],
|
|
56
|
+
"args": {
|
|
57
|
+
"type": "summarize_text"
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return __make_post_call(json=payload)
|
|
61
|
+
|
|
62
|
+
def sentiment_analysis(text: str) -> dict:
|
|
63
|
+
payload = {
|
|
64
|
+
"text": text,
|
|
65
|
+
"agent_names": ["sentiment_analysis_agent"],
|
|
66
|
+
"args": {
|
|
67
|
+
"type": "sentiment"
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return __make_post_call(json=payload)
|
|
71
|
+
|
|
72
|
+
def extract_entities(text: str) -> dict:
|
|
73
|
+
payload = {
|
|
74
|
+
"text": text,
|
|
75
|
+
"agent_names": ["extractor"],
|
|
76
|
+
"args": {
|
|
77
|
+
"type": "extract_categorized_entities"
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
return __make_post_call(json=payload)
|
|
81
|
+
|
|
82
|
+
def translate_text_task(text: str, target_language: str) -> dict:
|
|
83
|
+
payload = {
|
|
84
|
+
"text": text,
|
|
85
|
+
"agent_names": ["translation_agent"],
|
|
86
|
+
"args": {
|
|
87
|
+
"type": "translate_text",
|
|
88
|
+
"target_language": target_language
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return __make_post_call(json=payload)
|
|
92
|
+
|
|
93
|
+
def classify_text(text: str, classify_by: list[str]) -> dict:
|
|
94
|
+
payload = {
|
|
95
|
+
"text": text,
|
|
96
|
+
"agent_names": ["classification_agent"],
|
|
97
|
+
"args": {
|
|
98
|
+
"type": "classify",
|
|
99
|
+
"classify_by": classify_by
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
return __make_post_call(json=payload)
|
|
103
|
+
|
|
104
|
+
def moderation_task(text: str, threshold: float = 0.5) -> dict:
|
|
105
|
+
payload = {
|
|
106
|
+
"text": text,
|
|
107
|
+
"agent_names": ["moderation_agent"],
|
|
108
|
+
"args": {
|
|
109
|
+
"type": "moderation",
|
|
110
|
+
"threshold": threshold
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
return __make_post_call(json=payload)
|
|
114
|
+
|
|
115
|
+
def custom_workflow(
|
|
116
|
+
text: str,
|
|
117
|
+
name: str,
|
|
118
|
+
objective: str,
|
|
119
|
+
instructions: str = "",
|
|
120
|
+
agents: Optional[List[str]] = None,
|
|
121
|
+
context: Optional[dict] = None
|
|
122
|
+
) -> dict:
|
|
123
|
+
|
|
124
|
+
payload = {
|
|
125
|
+
"text": text,
|
|
126
|
+
"agent_names": agents or ["custom_agent"],
|
|
127
|
+
"args": {
|
|
128
|
+
"type": "custom",
|
|
129
|
+
"name": name,
|
|
130
|
+
"objective": objective,
|
|
131
|
+
"instructions": instructions,
|
|
132
|
+
"context": context or {},
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
return __make_post_call(json=payload)
|
|
136
|
+
|
|
137
|
+
def get_tools() -> dict:
|
|
138
|
+
response = requests.get(f"{BASE_MCP_URL}/mcp/tools")
|
|
139
|
+
response.raise_for_status()
|
|
140
|
+
return response.json()
|
|
141
|
+
|
|
142
|
+
def get_servers() -> dict:
|
|
143
|
+
response = requests.get(f"{BASE_MCP_URL}/mcp/servers")
|
|
144
|
+
response.raise_for_status()
|
|
145
|
+
return response.json()
|
|
146
|
+
|
|
147
|
+
def get_agents() -> dict:
|
|
148
|
+
return __make_get_call(url=f"{BASE_URL}/agents/")
|
|
149
|
+
|
|
150
|
+
def upload_workflow_file(file_path: str) -> dict:
|
|
151
|
+
"""
|
|
152
|
+
Uploads a workflow file to the server.
|
|
153
|
+
This file may contain either JSON or YAML content, which the server
|
|
154
|
+
will parse and validate as a WorkflowDefinition.
|
|
155
|
+
|
|
156
|
+
:param file_path: Local path to the file to upload.
|
|
157
|
+
:return: JSON response from the server as a dict.
|
|
158
|
+
:raises: HTTPError if the request fails.
|
|
159
|
+
"""
|
|
160
|
+
|
|
161
|
+
raise NotImplementedError()
|
|
162
|
+
# with open(file_path, "rb") as f:
|
|
163
|
+
# return __make_post_call(
|
|
164
|
+
# url=f"{BASE_URL}/workflows/run-file",
|
|
165
|
+
# files={"yaml_file":
|
|
166
|
+
# (os.path.basename(file_path),
|
|
167
|
+
# f,
|
|
168
|
+
# "application/octet-stream")})
|
iointel/src/__init__.py
ADDED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import os
|
|
2
|
+
|
|
3
|
+
from iointel import Agent
|
|
4
|
+
from ..data_models.datamodels import AgentParams
|
|
5
|
+
from typing import Optional
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
AGENT_SPECS = {
|
|
10
|
+
"reminder_agent": {
|
|
11
|
+
"name": "Reminder Agent",
|
|
12
|
+
"instructions": "A simple agent that sends reminders."
|
|
13
|
+
},
|
|
14
|
+
"leader": {
|
|
15
|
+
"name": "Leader",
|
|
16
|
+
"instructions": """
|
|
17
|
+
You are the council leader,
|
|
18
|
+
you lead the council and provide guidance,
|
|
19
|
+
and administer the voting process.
|
|
20
|
+
"""
|
|
21
|
+
},
|
|
22
|
+
"council_member1": {
|
|
23
|
+
"name": "Council Member 1",
|
|
24
|
+
"instructions": "You are a council member who provides input and votes on decisions."
|
|
25
|
+
},
|
|
26
|
+
"council_member2": {
|
|
27
|
+
"name": "Council Member 2",
|
|
28
|
+
"instructions": "You are a council member who provides input and votes on decisions."
|
|
29
|
+
},
|
|
30
|
+
"council_member3": {
|
|
31
|
+
"name": "Council Member 3",
|
|
32
|
+
"instructions": "You are a council member who provides input and votes on decisions."
|
|
33
|
+
},
|
|
34
|
+
"coder": {
|
|
35
|
+
"name": "Coder",
|
|
36
|
+
"instructions": "You are an expert python coder who provides code for the task."
|
|
37
|
+
},
|
|
38
|
+
"agent_maker": {
|
|
39
|
+
"name": "Agent Maker",
|
|
40
|
+
"instructions": "You create agents that can perform tasks from the provided code."
|
|
41
|
+
},
|
|
42
|
+
"reasoning_agent": {
|
|
43
|
+
"name": "Reasoning Agent",
|
|
44
|
+
"instructions": "You are an agent that performs reasoning steps."
|
|
45
|
+
},
|
|
46
|
+
"docker_sandbox_agent": {
|
|
47
|
+
"name": "Docker Sandbox Agent",
|
|
48
|
+
"instructions": "You are an agent that runs code in a docker sandbox."
|
|
49
|
+
},
|
|
50
|
+
"summary_agent": {
|
|
51
|
+
"name": "Summary Agent",
|
|
52
|
+
"instructions": "You are an agent that summarizes text."
|
|
53
|
+
},
|
|
54
|
+
"sentiment_analysis_agent": {
|
|
55
|
+
"name": "Sentiment Analysis Agent",
|
|
56
|
+
"instructions": "You are an agent that performs unbiased sentiment analysis on text."
|
|
57
|
+
},
|
|
58
|
+
"extractor": {
|
|
59
|
+
"name": "Named Entity Recognizer",
|
|
60
|
+
"instructions": "You are an agent that extracts named entities from text."
|
|
61
|
+
},
|
|
62
|
+
"default_agent": {
|
|
63
|
+
"name": "Default Agent",
|
|
64
|
+
"instructions": "You are an agent that does a lot of different things, you are dynamic."
|
|
65
|
+
},
|
|
66
|
+
"moderation_agent": {
|
|
67
|
+
"name": "Moderation Agent",
|
|
68
|
+
"instructions": "You are an agent that moderates content."
|
|
69
|
+
},
|
|
70
|
+
"classification_agent": {
|
|
71
|
+
"name": "Classification Agent",
|
|
72
|
+
"instructions": "You are an agent that is an expert in classifying things."
|
|
73
|
+
},
|
|
74
|
+
"translation_agent": {
|
|
75
|
+
"name": "Translation Agent",
|
|
76
|
+
"instructions": "You are an agent that is a polyglot of multiple languages and is an expert in translating text."
|
|
77
|
+
},
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
def create_agent(params: AgentParams) -> Agent:
|
|
81
|
+
"""
|
|
82
|
+
Create a Agent instance from the given AgentParams.
|
|
83
|
+
"""
|
|
84
|
+
#return Agent(name=params.name, instructions=params.instructions, persona=params.persona, tools=params.tools)
|
|
85
|
+
return Agent(**params.model_dump(exclude_none=True))
|
|
86
|
+
|
|
87
|
+
def create_agents():
|
|
88
|
+
return {
|
|
89
|
+
agent_key: create_agent(
|
|
90
|
+
AgentParams(
|
|
91
|
+
name=spec["name"],
|
|
92
|
+
instructions=spec["instructions"]
|
|
93
|
+
)
|
|
94
|
+
)
|
|
95
|
+
for agent_key, spec in AGENT_SPECS.items()
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
AGENTS = create_agents() if os.environ.get('LIBRARY_MODE', '').lower() != 'true' else {}
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
def get_agent(agent_name: str, agent_params: Optional[AgentParams] = None) -> Agent:
|
|
103
|
+
if agent_params is None:
|
|
104
|
+
agent_params = AgentParams(name="", instructions="")
|
|
105
|
+
|
|
106
|
+
# Merge or set the default name/instructions
|
|
107
|
+
spec = AGENT_SPECS.get(agent_name, AGENT_SPECS["default_agent"])
|
|
108
|
+
agent_params.name = agent_params.name or spec["name"]
|
|
109
|
+
agent_params.instructions = agent_params.instructions or spec["instructions"]
|
|
110
|
+
|
|
111
|
+
return create_agent(agent_params)
|
|
File without changes
|
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
from pydantic import BaseModel, Field
|
|
3
|
+
from typing import List, Annotated, Optional,Union, Callable
|
|
4
|
+
from datetime import datetime
|
|
5
|
+
import controlflow
|
|
6
|
+
from controlflow.memory.memory import Memory
|
|
7
|
+
from controlflow.memory.async_memory import AsyncMemory
|
|
8
|
+
if sys.version_info < (3, 12):
|
|
9
|
+
from typing_extensions import TypedDict
|
|
10
|
+
else:
|
|
11
|
+
from typing import TypedDict
|
|
12
|
+
|
|
13
|
+
class PersonaConfig(BaseModel):
|
|
14
|
+
"""
|
|
15
|
+
A configuration object that describes an agent's persona or character.
|
|
16
|
+
"""
|
|
17
|
+
name: Optional[str] = Field(
|
|
18
|
+
None,
|
|
19
|
+
description="If the persona has a specific name or nickname."
|
|
20
|
+
)
|
|
21
|
+
age: Optional[int] = Field(
|
|
22
|
+
None,
|
|
23
|
+
description="Approximate age of the persona (if relevant).",
|
|
24
|
+
ge=1
|
|
25
|
+
)
|
|
26
|
+
role: Optional[str] = Field(
|
|
27
|
+
None,
|
|
28
|
+
description="General role or type, e.g. 'a brave knight', 'a friendly teacher', etc."
|
|
29
|
+
)
|
|
30
|
+
style: Optional[str] = Field(
|
|
31
|
+
None,
|
|
32
|
+
description="A short description of the agent's style or demeanor (e.g., 'formal and polite')."
|
|
33
|
+
)
|
|
34
|
+
domain_knowledge: List[str] = Field(
|
|
35
|
+
default_factory=list,
|
|
36
|
+
description="List of domains or special areas of expertise the agent has."
|
|
37
|
+
)
|
|
38
|
+
quirks: Optional[str] = Field(
|
|
39
|
+
None,
|
|
40
|
+
description="Any unique quirks or mannerisms, e.g. 'likes using puns' or 'always references coffee.'"
|
|
41
|
+
)
|
|
42
|
+
bio: Optional[str] = Field(
|
|
43
|
+
None,
|
|
44
|
+
description="A short biography or personal background for the persona."
|
|
45
|
+
)
|
|
46
|
+
lore: Optional[str] = Field(
|
|
47
|
+
None,
|
|
48
|
+
description="In-universe lore or backstory, e.g. 'grew up in a small village with magical powers.'"
|
|
49
|
+
)
|
|
50
|
+
personality: Optional[str] = Field(
|
|
51
|
+
None,
|
|
52
|
+
description="A more direct statement of the persona's emotional or psychological traits."
|
|
53
|
+
)
|
|
54
|
+
conversation_style: Optional[str] = Field(
|
|
55
|
+
None,
|
|
56
|
+
description="How the character speaks in conversation, e.g., 'often uses slang' or 'very verbose and flowery.'"
|
|
57
|
+
)
|
|
58
|
+
description: Optional[str] = Field(
|
|
59
|
+
None,
|
|
60
|
+
description="A general descriptive text, e.g., 'A tall, lean figure wearing a cloak, with a stern demeanor.'"
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
friendliness: Optional[float] = Field(
|
|
64
|
+
None,
|
|
65
|
+
description="How friendly the agent is, from 0 (hostile) to 1 (friendly).",
|
|
66
|
+
ge=0,
|
|
67
|
+
le=1
|
|
68
|
+
)
|
|
69
|
+
creativity: Optional[float] = Field(
|
|
70
|
+
None,
|
|
71
|
+
description="How creative the agent is, from 0 (very logical) to 1 (very creative).",
|
|
72
|
+
ge=0,
|
|
73
|
+
le=1
|
|
74
|
+
)
|
|
75
|
+
curiosity: Optional[float] = Field(
|
|
76
|
+
None,
|
|
77
|
+
description="How curious the agent is, from 0 (disinterested) to 1 (very curious).",
|
|
78
|
+
ge=0,
|
|
79
|
+
le=1
|
|
80
|
+
)
|
|
81
|
+
empathy: Optional[float] = Field(
|
|
82
|
+
None,
|
|
83
|
+
description="How empathetic the agent is, from 0 (cold) to 1 (very empathetic).",
|
|
84
|
+
ge=0,
|
|
85
|
+
le=1
|
|
86
|
+
)
|
|
87
|
+
humor: Optional[float] = Field(
|
|
88
|
+
None,
|
|
89
|
+
description="How humorous the agent is, from 0 (serious) to 1 (very humorous).",
|
|
90
|
+
ge=0,
|
|
91
|
+
le=1
|
|
92
|
+
)
|
|
93
|
+
formality: Optional[float] = Field(
|
|
94
|
+
None,
|
|
95
|
+
description="How formal the agent is, from 0 (very casual) to 1 (very formal).",
|
|
96
|
+
ge=0,
|
|
97
|
+
le=1
|
|
98
|
+
)
|
|
99
|
+
emotional_stability: Optional[float] = Field(
|
|
100
|
+
None,
|
|
101
|
+
description="How emotionally stable the agent is, from 0 (very emotional) to 1 (very stable).",
|
|
102
|
+
ge=0,
|
|
103
|
+
le=1
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
def to_system_instructions(self) -> str:
|
|
107
|
+
"""
|
|
108
|
+
Combine fields into a single string that can be appended to the system instructions.
|
|
109
|
+
Each field is optional; only non-empty fields get appended.
|
|
110
|
+
"""
|
|
111
|
+
lines = []
|
|
112
|
+
|
|
113
|
+
# 1. Possibly greet with a name or reference it
|
|
114
|
+
if self.name:
|
|
115
|
+
lines.append(f"Your name is {self.name}.")
|
|
116
|
+
|
|
117
|
+
# 2. Age or approximate range
|
|
118
|
+
if self.age is not None:
|
|
119
|
+
lines.append(f"You are {self.age} years old (approximately).")
|
|
120
|
+
|
|
121
|
+
# 3. High-level role or type
|
|
122
|
+
if self.role:
|
|
123
|
+
lines.append(f"You are {self.role}.")
|
|
124
|
+
|
|
125
|
+
# 4. Style or demeanor
|
|
126
|
+
if self.style:
|
|
127
|
+
lines.append(f"Your style or demeanor is: {self.style}.")
|
|
128
|
+
|
|
129
|
+
# 5. Domain knowledge
|
|
130
|
+
if self.domain_knowledge:
|
|
131
|
+
knowledge_str = ", ".join(self.domain_knowledge)
|
|
132
|
+
lines.append(f"You have expertise or knowledge in: {knowledge_str}.")
|
|
133
|
+
|
|
134
|
+
# 6. Quirks
|
|
135
|
+
if self.quirks:
|
|
136
|
+
lines.append(f"You have the following quirks: {self.quirks}.")
|
|
137
|
+
|
|
138
|
+
# 7. Bio
|
|
139
|
+
if self.bio:
|
|
140
|
+
lines.append(f"Personal background: {self.bio}.")
|
|
141
|
+
|
|
142
|
+
# 8. Lore
|
|
143
|
+
if self.lore:
|
|
144
|
+
lines.append(f"Additional lore/backstory: {self.lore}.")
|
|
145
|
+
|
|
146
|
+
# 9. Personality
|
|
147
|
+
if self.personality:
|
|
148
|
+
lines.append(f"Your personality traits: {self.personality}.")
|
|
149
|
+
|
|
150
|
+
# 10. Conversation style
|
|
151
|
+
if self.conversation_style:
|
|
152
|
+
lines.append(f"In conversation, you speak in this style: {self.conversation_style}.")
|
|
153
|
+
|
|
154
|
+
# 11. General description
|
|
155
|
+
if self.description:
|
|
156
|
+
lines.append(f"General description: {self.description}.")
|
|
157
|
+
|
|
158
|
+
# 12. Personality traits
|
|
159
|
+
if self.friendliness is not None:
|
|
160
|
+
lines.append(f"Your overall Friendliness from 0 to 1 is: {self.friendliness}")
|
|
161
|
+
|
|
162
|
+
if self.creativity is not None:
|
|
163
|
+
lines.append(f"Your overall Creativity from 0 to 1 is: {self.creativity}")
|
|
164
|
+
|
|
165
|
+
if self.curiosity is not None:
|
|
166
|
+
lines.append(f"Your overall Curiosity from 0 to 1 is: {self.curiosity}")
|
|
167
|
+
|
|
168
|
+
if self.empathy is not None:
|
|
169
|
+
lines.append(f"Your overall Empathy from 0 to 1 is: {self.empathy}")
|
|
170
|
+
|
|
171
|
+
if self.humor is not None:
|
|
172
|
+
lines.append(f"Your overall Humor from 0 to 1 is: {self.humor}")
|
|
173
|
+
|
|
174
|
+
if self.formality is not None:
|
|
175
|
+
lines.append(f"Your overall Formality from 0 to 1 is: {self.formality}")
|
|
176
|
+
|
|
177
|
+
if self.emotional_stability is not None:
|
|
178
|
+
lines.append(f"Your overall Emotional stability from 0 to 1 is: {self.emotional_stability}")
|
|
179
|
+
|
|
180
|
+
# Return them joined by newlines, or any separator you prefer
|
|
181
|
+
return "\n".join(lines)
|
|
182
|
+
|
|
183
|
+
##agent params###
|
|
184
|
+
class AgentParams(BaseModel):
|
|
185
|
+
name: str
|
|
186
|
+
instructions: str
|
|
187
|
+
description: Optional[str] = None
|
|
188
|
+
persona: Optional[PersonaConfig] = None
|
|
189
|
+
model: Optional[Callable] = None
|
|
190
|
+
tools: Optional[List[str]] | Optional[List[Callable]] = Field(default_factory=list)
|
|
191
|
+
llm_rules: Optional[controlflow.llm.rules.LLMRules] = None
|
|
192
|
+
interactive: Optional[bool] = False
|
|
193
|
+
memories: Optional[list[Memory]] | Optional[list[AsyncMemory]] = Field(default_factory=list)
|
|
194
|
+
|
|
195
|
+
#reasoning agent
|
|
196
|
+
class ReasoningStep(BaseModel):
|
|
197
|
+
explanation: str = Field(
|
|
198
|
+
description="""
|
|
199
|
+
A brief (<5 words) description of what you intend to
|
|
200
|
+
achieve in this step, to display to the user.
|
|
201
|
+
"""
|
|
202
|
+
)
|
|
203
|
+
reasoning: str = Field(
|
|
204
|
+
description="A single step of reasoning, not more than 1 or 2 sentences."
|
|
205
|
+
)
|
|
206
|
+
found_validated_solution: bool
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
##summary
|
|
210
|
+
class SummaryResult(BaseModel):
|
|
211
|
+
summary: str
|
|
212
|
+
key_points: List[str]
|
|
213
|
+
|
|
214
|
+
#translation
|
|
215
|
+
class TranslationResult(BaseModel):
|
|
216
|
+
translated: str
|
|
217
|
+
target_language: str
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
Activation = Annotated[float, Field(ge=0, le=1)]
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
class ModerationException(Exception):
|
|
224
|
+
"""Exception raised when a message is not allowed."""
|
|
225
|
+
|
|
226
|
+
...
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
class ViolationActivation(TypedDict):
|
|
230
|
+
"""Violation activation."""
|
|
231
|
+
|
|
232
|
+
extreme_profanity: Annotated[Activation, Field(description="hell / damn are fine")]
|
|
233
|
+
sexually_explicit: Activation
|
|
234
|
+
hate_speech: Activation
|
|
235
|
+
harassment: Activation
|
|
236
|
+
self_harm: Activation
|
|
237
|
+
dangerous_content: Activation
|
|
238
|
+
|
|
239
|
+
|
|
240
|
+
class WorkflowStep(BaseModel):
|
|
241
|
+
type: str
|
|
242
|
+
name: Optional[str] = None
|
|
243
|
+
objective: Optional[str] = None
|
|
244
|
+
instructions: Optional[str] = None
|
|
245
|
+
text: Optional[str] = None # for this step’s prompt
|
|
246
|
+
context: Optional[dict] = None
|
|
247
|
+
target_language: Optional[str] = None
|
|
248
|
+
|
|
249
|
+
class WorkflowDefinition(BaseModel):
|
|
250
|
+
"""
|
|
251
|
+
The top-level structure of the YAML.
|
|
252
|
+
name: A human-readable name for the workflow
|
|
253
|
+
agents: The agent definitions
|
|
254
|
+
workflow: The list of steps
|
|
255
|
+
"""
|
|
256
|
+
name: str
|
|
257
|
+
text: Optional[str] = None # This holds the main text/prompt
|
|
258
|
+
agents: Optional[List[AgentParams]] = None
|
|
259
|
+
workflow: List[WorkflowStep] = Field(default_factory=list)
|
|
260
|
+
|
|
261
|
+
|
|
262
|
+
|
|
263
|
+
### logging handlers
|
|
264
|
+
|
|
265
|
+
class BaseEventModel(BaseModel):
|
|
266
|
+
"""
|
|
267
|
+
A base model to capture common fields or structure for all events.
|
|
268
|
+
"""
|
|
269
|
+
timestamp: datetime = Field(default_factory=datetime.utcnow)
|
|
270
|
+
|
|
271
|
+
class AgentMessageEvent(BaseEventModel):
|
|
272
|
+
event_type: str = "agent_message"
|
|
273
|
+
agent_name: str
|
|
274
|
+
content: str
|
|
275
|
+
|
|
276
|
+
class UserMessageEvent(BaseEventModel):
|
|
277
|
+
event_type: str = "user_message"
|
|
278
|
+
content: str
|
|
279
|
+
|
|
280
|
+
class OrchestratorMessageEvent(BaseEventModel):
|
|
281
|
+
event_type: str = "orchestrator_message"
|
|
282
|
+
content: str
|
|
283
|
+
|
|
284
|
+
class ToolCallEvent(BaseEventModel):
|
|
285
|
+
event_type: str = "tool_call"
|
|
286
|
+
tool_name: str
|
|
287
|
+
|
|
288
|
+
class ToolResultEvent(BaseEventModel):
|
|
289
|
+
event_type: str = "tool_result"
|
|
290
|
+
tool_name: str
|
|
291
|
+
result: str
|
|
292
|
+
|
|
293
|
+
class OrchestratorStartEvent(BaseEventModel):
|
|
294
|
+
event_type: str = "orchestrator_start"
|
|
295
|
+
|
|
296
|
+
class OrchestratorEndEvent(BaseEventModel):
|
|
297
|
+
event_type: str = "orchestrator_end"
|
|
298
|
+
|
|
299
|
+
class AgentMessageDeltaEvent(BaseEventModel):
|
|
300
|
+
event_type: str = "agent_message_delta"
|
|
301
|
+
delta: str
|
|
302
|
+
|
|
303
|
+
class OrchestratorErrorEvent(BaseEventModel):
|
|
304
|
+
event_type: str = "orchestrator_error"
|
|
305
|
+
error: str
|
|
306
|
+
|
|
307
|
+
class EndTurnEvent(BaseEventModel):
|
|
308
|
+
event_type: str = "end_turn"
|
|
309
|
+
|
|
310
|
+
class CatchallEvent(BaseEventModel):
|
|
311
|
+
event_type: str = "catch-all"
|
|
312
|
+
details: dict = {}
|
|
313
|
+
|
|
314
|
+
# Union of all event models
|
|
315
|
+
EventModelUnion = Union[
|
|
316
|
+
AgentMessageEvent,
|
|
317
|
+
UserMessageEvent,
|
|
318
|
+
OrchestratorMessageEvent,
|
|
319
|
+
ToolCallEvent,
|
|
320
|
+
ToolResultEvent,
|
|
321
|
+
OrchestratorStartEvent,
|
|
322
|
+
OrchestratorEndEvent,
|
|
323
|
+
AgentMessageDeltaEvent,
|
|
324
|
+
OrchestratorErrorEvent,
|
|
325
|
+
EndTurnEvent,
|
|
326
|
+
CatchallEvent
|
|
327
|
+
]
|
|
328
|
+
|
|
329
|
+
class EventsLog(BaseModel):
|
|
330
|
+
"""
|
|
331
|
+
Main aggregator for all events.
|
|
332
|
+
"""
|
|
333
|
+
events: List[EventModelUnion] = []
|
|
File without changes
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
REASONING_INSTRUCTIONS = """
|
|
2
|
+
You are working on solving a difficult problem (the `goal`). Based
|
|
3
|
+
on your previous thoughts and the overall goal, please perform **one
|
|
4
|
+
reasoning step** that advances you closer to a solution. Document
|
|
5
|
+
your thought process and any intermediate steps you take.
|
|
6
|
+
|
|
7
|
+
After marking this task complete for a single step, you will be
|
|
8
|
+
given a new reasoning task to continue working on the problem. The
|
|
9
|
+
loop will continue until you have a valid solution.
|
|
10
|
+
|
|
11
|
+
Complete the task as soon as you have a valid solution.
|
|
12
|
+
|
|
13
|
+
**Guidelines**
|
|
14
|
+
|
|
15
|
+
- You will not be able to brute force a solution exhaustively. You
|
|
16
|
+
must use your reasoning ability to make a plan that lets you make
|
|
17
|
+
progress.
|
|
18
|
+
- Each step should be focused on a specific aspect of the problem,
|
|
19
|
+
either advancing your understanding of the problem or validating a
|
|
20
|
+
solution.
|
|
21
|
+
- You should build on previous steps without repeating them.
|
|
22
|
+
- Since you will iterate your reasoning, you can explore multiple
|
|
23
|
+
approaches in different steps.
|
|
24
|
+
- Use logical and analytical thinking to reason through the problem.
|
|
25
|
+
- Ensure that your solution is valid and meets all requirements.
|
|
26
|
+
- If you find yourself spinning your wheels, take a step back and
|
|
27
|
+
re-evaluate your approach.
|
|
28
|
+
"""
|
|
File without changes
|