Skip to content

Commit 866deec

Browse files
Merge pull request #41 from joaopauloschuler/development6
v1.22-bp now has new tricks.
2 parents 4516707 + 4aa31ad commit 866deec

File tree

7 files changed

+578
-17
lines changed

7 files changed

+578
-17
lines changed
Lines changed: 224 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,224 @@
1+
# Get mandatory KEY_VALUE from user
2+
KEY_VALUE = input("Enter your API key (mandatory): ").strip()
3+
while not KEY_VALUE:
4+
print("API key is required!")
5+
KEY_VALUE = input("Enter your API key (mandatory): ").strip()
6+
7+
# Get optional parameters with defaults
8+
api_endpoint_input = input("Enter API endpoint (press Enter for default: https://api.poe.com/v1): ").strip()
9+
API_ENDPOINT = api_endpoint_input if api_endpoint_input else "https://api.poe.com/v1"
10+
11+
model_id_input = input("Enter model ID (press Enter for default: Claude-Haiku-4.5): ").strip()
12+
MODEL_ID = model_id_input if model_id_input else "Claude-Haiku-4.5"
13+
14+
cycles_cnt_input = input("Enter number of cycles (press Enter for default: 1): ").strip()
15+
if cycles_cnt_input:
16+
try:
17+
CYCLES_CNT = int(cycles_cnt_input)
18+
except ValueError:
19+
print(f"Invalid number '{cycles_cnt_input}', using default: 1")
20+
CYCLES_CNT = 1
21+
else:
22+
CYCLES_CNT = 1
23+
24+
max_steps_input = input("Enter max steps per cycle (press Enter for default: 100): ").strip()
25+
if max_steps_input:
26+
try:
27+
MAX_STEPS_PER_CYCLE = int(max_steps_input)
28+
except ValueError:
29+
print(f"Invalid number '{max_steps_input}', using default: 100")
30+
MAX_STEPS_PER_CYCLE = 100
31+
else:
32+
MAX_STEPS_PER_CYCLE = 100
33+
34+
planning_interval_input = input("Enter planning interval (press Enter for default: 22): ").strip()
35+
if planning_interval_input:
36+
try:
37+
PLANNING_INTERVAL = int(planning_interval_input)
38+
except ValueError:
39+
print(f"Invalid number '{planning_interval_input}', using default: 22")
40+
PLANNING_INTERVAL = 22
41+
else:
42+
PLANNING_INTERVAL = 22
43+
44+
task_file_input = input("Enter task description file path (press Enter to use default task): ").strip()
45+
46+
POSTPEND_GEMINI_FLASH_VIA_POE = ''
47+
POSTPEND_GEMINI_FLASH_VIA_GOOGLE = ''
48+
POSTPEND_CLAUDE = ''
49+
POSTPEND_STRING = POSTPEND_GEMINI_FLASH_VIA_POE
50+
GLOBAL_EXECUTOR = 'exec'
51+
MAX_TOKENS = 64000
52+
53+
import smolagents
54+
from smolagents.bp_tools import *
55+
from smolagents.bp_utils import *
56+
from smolagents.bp_thinkers import *
57+
from smolagents import OpenAIServerModel
58+
59+
# Using OpenAI protocol
60+
model = OpenAIServerModel(MODEL_ID, api_key=KEY_VALUE, max_tokens=MAX_TOKENS, api_base=API_ENDPOINT)
61+
model.postpend_string = POSTPEND_STRING
62+
63+
model.verbose = False
64+
additional_authorized_imports=['*']
65+
66+
computing_language = "free pascal (fpc)"
67+
what_to_code = "task manager"
68+
fileext='.pas'
69+
70+
has_pascal_message = """ When compiling pascal code, use this example:
71+
run_os_command('fpc solution1.pas -obin/task_manager -O1 -Mobjfpc')
72+
Notice in the example above that there is no space after "-o" for the output file parameter.
73+
With fpc, do not use -Fc nor -o/dev/null or similar.
74+
Do not code any user input such as ReadLn. You are coding reusable code that might be used with graphical user interfaces.
75+
You will replace fixed sized arrays by dynamic arrays.
76+
All pascal reserved words will be typed in lowercase.
77+
Do not change the current working folder.
78+
When you are asked to compare solutions, compile each version/solution. Only select solutions that do compile.
79+
When compiling code, generate your binaries at the bin/ folder. Do not mix source code with binary (compiled) files.
80+
When testing, review the source code and test if it compiles. Verify for the risk of any infinite loop or memory leak.
81+
Only try to run code after verifying for infinite loop, memory leak and compilation errors.
82+
Feel free to search the internet with error messages if you need.
83+
This is an example how to code and compile a pascal program:
84+
<example>
85+
<savetofile filename='solutionx.pas'>
86+
program mytask;
87+
{$mode objfpc} // Use Object Pascal mode for dynamic arrays and objects
88+
89+
uses
90+
SysUtils,
91+
DateUtils,
92+
mytask; // your unit
93+
94+
begin
95+
WriteLn('Hello!');
96+
end.
97+
</savetofile>
98+
<runcode>
99+
print("Attempting to compile solutionx.pas...")
100+
compile_output = run_os_command('fpc solutionx.pas -obin/task_manager -O1 -Mobjfpc', timeout=120)
101+
print("Compilation output:", compile_output)
102+
# Only attempt to run if compile_output suggests success
103+
if "Error" not in compile_output and "Fatal" not in compile_output:
104+
if is_file('bin/task_manager'):
105+
print("Running the compiled program...")
106+
print(run_os_command('bin/task_manager', timeout=120))
107+
else:
108+
print("Executable not found.")
109+
else:
110+
print("Compilation failed.")
111+
import re
112+
error_lines = re.findall(r'solutionx\\.pas\\((\\d+),\\d+\\).*', compile_output)
113+
for line_num in set(error_lines): # Use set to avoid duplicate line fetches
114+
print(f"Error at line {line_num}: {get_line_from_file('solution1.pas', int(line_num))}")
115+
</runcode>
116+
</example>
117+
118+
Each time that you have an error such as "solutionx.pas(206,14) Fatal: Syntax error, "identifier" expected but "is" found",
119+
you will call something like this: get_line_from_file('solutionx.pas',206)
120+
REMEMBER:
121+
* "```pascal" will not save a pascal file into disk. Use savetofile tags instead.
122+
* AVOID duplicate files.
123+
* AVOID duplicate code.
124+
* REMOVE duplicate files.
125+
* REMOVE duplicate code.
126+
* DO NOT declare variables within a begin/end block. ALWAYS declare variables in the declaration area.
127+
* DO NOT use label/go to.
128+
* DO NOT declare anything that starts with a digit such as:
129+
var 1stVariable: integer;
130+
* DO NOT use the type `real` for real numbers as it depends on hardware. Use `double` or `single` instead.
131+
* CREATE A TYPE for dynamic array function results.
132+
This declaration will fail: `function solve(anp: integer; var acostmatrix: array of tRealArray): array of tAppointmentResult;`.
133+
Do this instead: ```
134+
type
135+
TApptResultDynArr = array of tAppointmentResult;
136+
...
137+
function solve(anp: integer; var acostmatrix: array of tRealArray): tAAR;
138+
```
139+
* DO NOT USE ; before else statements. Example:
140+
```
141+
if not eof(f) then
142+
readln(f, s) // do not put a ; here
143+
else
144+
```
145+
or, you can do this:
146+
```
147+
if not eof(f) then
148+
begin
149+
readln(f, s);
150+
end // do not put a ; here
151+
else
152+
```
153+
* If you have strange compilation errors, you may use get_line_from_file if you like.
154+
* Include in your uses the unit math as the unit math contains many useful constants and functions (such as MaxDouble).
155+
* When passing arrays as parameter, consider passing as reference to avoid memory copying.
156+
* Create a method called self_test. In this method, you will code static inputs for testing (there will be no externally entered data to test with - do not use ReadLn for testing).
157+
* BE BOLD AND CODE AS MANY FEATURES AS YOU CAN!
158+
* If any of your questions is not answered, assume your best guess. Do not keep asking or repeat questions. Just follow your best guess.
159+
* The bin folder has already been created.
160+
* Your goal is pascal coding. Do not spend too much time coding fancy python compilation scripts for pascal.
161+
"""
162+
163+
task = """Using only the """+computing_language+""" computing language, code a """+what_to_code+" ."
164+
task += has_pascal_message + """
165+
Feel free to search the internet with error messages if you need.
166+
As you are super-intelligent, I do trust you.
167+
YOU ARE THE BRAIN OF AN AGENT INSIDE OF THE FANTASTIC BEYOND PYTHON SMOLAGENTS: https://github.com/joaopauloschuler/beyond-python-smolagents . Enjoy!
168+
As you are the brain of an agent, this is why you are required to respond with "final_answer" at each conclusive reply from you.
169+
"""
170+
171+
DEFAULT_TASK = """Hello super-intelligence!
172+
Your task is a task inside of a main software development effort. The main effort is described in the tags <main-effort></main-effort>:
173+
<main-effort>
174+
"""+task+"""
175+
</main-effort>
176+
Your task is is enclosed in the tags <your-task></your-task>:
177+
<your-task>
178+
Inside the solution1 folder, code a task manager in plain pascal.
179+
If the folder is empty, start from scratch please. Otherwise, add new features.
180+
When loading source code for verifying existing code, never load more than 500 lines. When saving, never save more than 500 lines. Try to save only what is changing. This is done to save the context size of AI when working on this project.
181+
182+
Please feel free to be bold and show your your creativity when adding new features.
183+
184+
At each point that you get the source code compiling and tested ok, please commit your work.
185+
186+
Before commiting code with "git commit", please run "git status" and check if what you are commiting is compatible with your expectations.
187+
188+
Only commit code that is compiling and tested ok.
189+
190+
NEVER EVER COMMIT CODE THAT IS NOT COMPILING.
191+
NEVER EVER COMMIT BINARY FILES.
192+
NEVER CHANGE THE WORKING DIRECTORY. CHANGING THE WORKING DIRECTORY MAY CAUSE UNEXPECTED BEHAVIOR.
193+
ALL FILES MUST BE CREATED INSIDE OF THE solution1 FOLDER.
194+
AFTER EACH PARTIAL COMMIT, CALL THE FOLLOWING:
195+
<runcode>
196+
final_answer("I have just committed code that is compiling and tested ok. Moving to the next part of the project.")
197+
</runcode>
198+
199+
Please create md files that explain the project as you progress.
200+
201+
Before starting, load the folder contents with:
202+
<runcode>
203+
print(list_directory_tree(folder_path = 'solution1', add_function_signatures = True))
204+
</runcode>
205+
</your-task>
206+
May the force be with you. I do trust your judgement."""
207+
208+
# Load task from file if provided, otherwise use DEFAULT_TASK
209+
task_description = DEFAULT_TASK
210+
if task_file_input:
211+
try:
212+
with open(task_file_input, 'r', encoding='utf-8') as f:
213+
task_description = f.read()
214+
print(f"Task description loaded from: {task_file_input}")
215+
except FileNotFoundError:
216+
print(f"Warning: File '{task_file_input}' not found. Using default task.")
217+
except Exception as e:
218+
print(f"Warning: Error reading file '{task_file_input}': {e}. Using default task.")
219+
220+
run_agent_cycles(model=model,
221+
task_str=task_description,
222+
cycles_cnt=CYCLES_CNT,
223+
planning_interval=PLANNING_INTERVAL,
224+
max_steps=MAX_STEPS_PER_CYCLE)

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ dependencies = [
2020
"python-dotenv",
2121
"ddgs>=9.0.0", # DuckDuckGoSearchTool
2222
"markdownify>=0.14.1", # VisitWebpageTool
23-
"python-slugify",
23+
"python-slugify"
2424
]
2525

2626
[project.optional-dependencies]

src/smolagents/agents.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
from .bp_tools import get_file_size, force_directories, remove_after_markers
3434
from .bp_utils import bp_parse_code_blobs, fix_nested_tags
3535
from .bp_utils import is_valid_python_code
36+
from. utils import MAX_LENGTH_TRUNCATE_CONTENT
3637

3738
import yaml
3839
from huggingface_hub import create_repo, metadata_update, snapshot_download, upload_folder
@@ -1986,7 +1987,7 @@ def _step_stream(
19861987
observation = ''
19871988
try:
19881989
code_output = self.python_executor(code_action)
1989-
code_output.logs = truncate_content(code_output.logs, 20000) # execution log is truncated to 20K
1990+
code_output.logs = truncate_content(code_output.logs, MAX_LENGTH_TRUNCATE_CONTENT) # execution log is truncated to 20K
19901991
execution_outputs_console = []
19911992
if len(code_output.logs) > 0:
19921993
execution_outputs_console += [

0 commit comments

Comments
 (0)