| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
package Sim::Agent; |
|
2
|
|
|
|
|
|
|
|
|
3
|
1
|
|
|
1
|
|
343147
|
use strict; |
|
|
1
|
|
|
|
|
3
|
|
|
|
1
|
|
|
|
|
43
|
|
|
4
|
1
|
|
|
1
|
|
5
|
use warnings; |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
105
|
|
|
5
|
|
|
|
|
|
|
|
|
6
|
|
|
|
|
|
|
our $VERSION = '0.009'; |
|
7
|
|
|
|
|
|
|
|
|
8
|
1
|
|
|
1
|
|
592
|
use Sim::Agent::Parser; |
|
|
1
|
|
|
|
|
4
|
|
|
|
1
|
|
|
|
|
45
|
|
|
9
|
1
|
|
|
1
|
|
570
|
use Sim::Agent::Compiler; |
|
|
1
|
|
|
|
|
4
|
|
|
|
1
|
|
|
|
|
44
|
|
|
10
|
1
|
|
|
1
|
|
640
|
use Sim::Agent::Runner; |
|
|
1
|
|
|
|
|
3
|
|
|
|
1
|
|
|
|
|
46
|
|
|
11
|
1
|
|
|
1
|
|
578
|
use Sim::Agent::Journal; |
|
|
1
|
|
|
|
|
4
|
|
|
|
1
|
|
|
|
|
314
|
|
|
12
|
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
sub new |
|
14
|
|
|
|
|
|
|
{ |
|
15
|
0
|
|
|
0
|
0
|
|
my ($class, %opts) = @_; |
|
16
|
|
|
|
|
|
|
|
|
17
|
0
|
0
|
|
|
|
|
die "plan required" unless $opts{plan}; |
|
18
|
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
my $self = |
|
20
|
|
|
|
|
|
|
{ |
|
21
|
|
|
|
|
|
|
plan => $opts{plan}, |
|
22
|
0
|
|
0
|
|
|
|
dev => $opts{dev} || 0, |
|
23
|
|
|
|
|
|
|
}; |
|
24
|
|
|
|
|
|
|
|
|
25
|
0
|
|
|
|
|
|
bless $self, $class; |
|
26
|
0
|
|
|
|
|
|
return $self; |
|
27
|
|
|
|
|
|
|
} |
|
28
|
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
sub run |
|
30
|
|
|
|
|
|
|
{ |
|
31
|
0
|
|
|
0
|
0
|
|
my ($self) = @_; |
|
32
|
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
# ---------------------------- |
|
34
|
|
|
|
|
|
|
# Parse |
|
35
|
|
|
|
|
|
|
# ---------------------------- |
|
36
|
0
|
|
|
|
|
|
my $parser = Sim::Agent::Parser->new; |
|
37
|
0
|
|
|
|
|
|
my $ast = $parser->parse_file($self->{plan}); |
|
38
|
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
# ---------------------------- |
|
40
|
|
|
|
|
|
|
# Compile |
|
41
|
|
|
|
|
|
|
# ---------------------------- |
|
42
|
0
|
|
|
|
|
|
my $compiler = Sim::Agent::Compiler->new; |
|
43
|
0
|
|
|
|
|
|
my $graph = $compiler->compile($ast); |
|
44
|
|
|
|
|
|
|
|
|
45
|
|
|
|
|
|
|
# ---------------------------- |
|
46
|
|
|
|
|
|
|
# Journal |
|
47
|
|
|
|
|
|
|
# ---------------------------- |
|
48
|
0
|
|
|
|
|
|
my $journal = Sim::Agent::Journal->new; |
|
49
|
0
|
|
|
|
|
|
$journal->archive_plan($self->{plan}); |
|
50
|
|
|
|
|
|
|
|
|
51
|
|
|
|
|
|
|
# ---------------------------- |
|
52
|
|
|
|
|
|
|
# Runner |
|
53
|
|
|
|
|
|
|
# ---------------------------- |
|
54
|
|
|
|
|
|
|
my $runner = Sim::Agent::Runner->new( |
|
55
|
|
|
|
|
|
|
graph => $graph, |
|
56
|
|
|
|
|
|
|
journal => $journal, |
|
57
|
|
|
|
|
|
|
dev => $self->{dev}, |
|
58
|
0
|
|
|
|
|
|
); |
|
59
|
|
|
|
|
|
|
|
|
60
|
0
|
|
|
|
|
|
$runner->run; |
|
61
|
|
|
|
|
|
|
} |
|
62
|
|
|
|
|
|
|
|
|
63
|
|
|
|
|
|
|
1; |
|
64
|
|
|
|
|
|
|
|
|
65
|
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
=pod |
|
67
|
|
|
|
|
|
|
|
|
68
|
|
|
|
|
|
|
=head1 NAME |
|
69
|
|
|
|
|
|
|
|
|
70
|
|
|
|
|
|
|
Sim::Agent - Deterministic Orchestration Framework for Structured LLM Agent Experiments |
|
71
|
|
|
|
|
|
|
|
|
72
|
|
|
|
|
|
|
=head1 SYNOPSIS |
|
73
|
|
|
|
|
|
|
|
|
74
|
|
|
|
|
|
|
use Sim::Agent; |
|
75
|
|
|
|
|
|
|
|
|
76
|
|
|
|
|
|
|
my $sim = Sim::Agent->new(plan => 'plan.sexpr'); |
|
77
|
|
|
|
|
|
|
$sim->run; |
|
78
|
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
=head1 ABSTRACT |
|
80
|
|
|
|
|
|
|
|
|
81
|
|
|
|
|
|
|
Sim::Agent is a deterministic, single-threaded orchestration framework for |
|
82
|
|
|
|
|
|
|
Large Language Model (LLM) agents defined through a strict S-expression DSL. |
|
83
|
|
|
|
|
|
|
It is designed for controlled experimentation, auditability, and explicit |
|
84
|
|
|
|
|
|
|
coordination semantics rather than autonomous or emergent behavior. |
|
85
|
|
|
|
|
|
|
|
|
86
|
|
|
|
|
|
|
The system enforces explicit topology, bounded self-reflection, critic gating, |
|
87
|
|
|
|
|
|
|
and reproducible journaling. It is particularly suited for research scenarios |
|
88
|
|
|
|
|
|
|
where repeatability, traceability, and architectural clarity are required. |
|
89
|
|
|
|
|
|
|
|
|
90
|
|
|
|
|
|
|
=head1 MOTIVATION |
|
91
|
|
|
|
|
|
|
|
|
92
|
|
|
|
|
|
|
Contemporary LLM agent frameworks often prioritize flexibility and autonomy |
|
93
|
|
|
|
|
|
|
over determinism and inspectability. This introduces: |
|
94
|
|
|
|
|
|
|
|
|
95
|
|
|
|
|
|
|
=over 4 |
|
96
|
|
|
|
|
|
|
|
|
97
|
|
|
|
|
|
|
=item * |
|
98
|
|
|
|
|
|
|
|
|
99
|
|
|
|
|
|
|
Implicit control flow |
|
100
|
|
|
|
|
|
|
|
|
101
|
|
|
|
|
|
|
=item * |
|
102
|
|
|
|
|
|
|
|
|
103
|
|
|
|
|
|
|
Non-reproducible behavior |
|
104
|
|
|
|
|
|
|
|
|
105
|
|
|
|
|
|
|
=item * |
|
106
|
|
|
|
|
|
|
|
|
107
|
|
|
|
|
|
|
Unbounded reflection loops |
|
108
|
|
|
|
|
|
|
|
|
109
|
|
|
|
|
|
|
=item * |
|
110
|
|
|
|
|
|
|
|
|
111
|
|
|
|
|
|
|
Opaque state transitions |
|
112
|
|
|
|
|
|
|
|
|
113
|
|
|
|
|
|
|
=item * |
|
114
|
|
|
|
|
|
|
|
|
115
|
|
|
|
|
|
|
Hidden concurrency |
|
116
|
|
|
|
|
|
|
|
|
117
|
|
|
|
|
|
|
=back |
|
118
|
|
|
|
|
|
|
|
|
119
|
|
|
|
|
|
|
Sim::Agent is intentionally designed in opposition to these tendencies. |
|
120
|
|
|
|
|
|
|
It treats agent orchestration as a formally structured computational graph |
|
121
|
|
|
|
|
|
|
with explicit routing, bounded cycles, and file-backed journaling. |
|
122
|
|
|
|
|
|
|
|
|
123
|
|
|
|
|
|
|
The framework is not intended to simulate cognition; it is intended to |
|
124
|
|
|
|
|
|
|
simulate coordination. |
|
125
|
|
|
|
|
|
|
|
|
126
|
|
|
|
|
|
|
=head1 DESIGN PRINCIPLES |
|
127
|
|
|
|
|
|
|
|
|
128
|
|
|
|
|
|
|
=head2 1. Determinism |
|
129
|
|
|
|
|
|
|
|
|
130
|
|
|
|
|
|
|
Scheduling is FIFO and single-threaded. There is no concurrency, |
|
131
|
|
|
|
|
|
|
no asynchronous dispatch, and no hidden background processes. |
|
132
|
|
|
|
|
|
|
|
|
133
|
|
|
|
|
|
|
=head2 2. Explicit Topology |
|
134
|
|
|
|
|
|
|
|
|
135
|
|
|
|
|
|
|
All control flow is declared in a strict S-expression DSL. There are |
|
136
|
|
|
|
|
|
|
no implicit retries, no emergent routing rules, and no hidden dependencies. |
|
137
|
|
|
|
|
|
|
|
|
138
|
|
|
|
|
|
|
=head2 3. Bounded Self-Reflection |
|
139
|
|
|
|
|
|
|
|
|
140
|
|
|
|
|
|
|
Workers may self-criticize and revise their outputs, but cycles are |
|
141
|
|
|
|
|
|
|
explicitly bounded via C. |
|
142
|
|
|
|
|
|
|
|
|
143
|
|
|
|
|
|
|
=head2 4. Critic Gating |
|
144
|
|
|
|
|
|
|
|
|
145
|
|
|
|
|
|
|
Critics determine whether outputs propagate forward in the graph. |
|
146
|
|
|
|
|
|
|
Critics return structured status: |
|
147
|
|
|
|
|
|
|
|
|
148
|
|
|
|
|
|
|
{ status => 'ok' } |
|
149
|
|
|
|
|
|
|
{ status => 'fail', critique => '...' } |
|
150
|
|
|
|
|
|
|
|
|
151
|
|
|
|
|
|
|
=head2 5. Ping-Pong Protection |
|
152
|
|
|
|
|
|
|
|
|
153
|
|
|
|
|
|
|
Repeated critic-worker failure loops are bounded by C. |
|
154
|
|
|
|
|
|
|
Upon exhaustion, flow proceeds with taint annotation. |
|
155
|
|
|
|
|
|
|
|
|
156
|
|
|
|
|
|
|
=head2 6. Auditability |
|
157
|
|
|
|
|
|
|
|
|
158
|
|
|
|
|
|
|
Every run produces a time-stamped journal directory containing: |
|
159
|
|
|
|
|
|
|
|
|
160
|
|
|
|
|
|
|
=over 4 |
|
161
|
|
|
|
|
|
|
|
|
162
|
|
|
|
|
|
|
=item * |
|
163
|
|
|
|
|
|
|
|
|
164
|
|
|
|
|
|
|
Archived plan |
|
165
|
|
|
|
|
|
|
|
|
166
|
|
|
|
|
|
|
=item * |
|
167
|
|
|
|
|
|
|
|
|
168
|
|
|
|
|
|
|
Prompts and outputs per agent |
|
169
|
|
|
|
|
|
|
|
|
170
|
|
|
|
|
|
|
=item * |
|
171
|
|
|
|
|
|
|
|
|
172
|
|
|
|
|
|
|
Execution log |
|
173
|
|
|
|
|
|
|
|
|
174
|
|
|
|
|
|
|
=back |
|
175
|
|
|
|
|
|
|
|
|
176
|
|
|
|
|
|
|
The journal provides full replay-level transparency. |
|
177
|
|
|
|
|
|
|
|
|
178
|
|
|
|
|
|
|
=head2 7. No Hidden State |
|
179
|
|
|
|
|
|
|
|
|
180
|
|
|
|
|
|
|
State is owned by the Runner and passed explicitly between agents. |
|
181
|
|
|
|
|
|
|
There is no shared mutable global context. |
|
182
|
|
|
|
|
|
|
|
|
183
|
|
|
|
|
|
|
=head1 ARCHITECTURE |
|
184
|
|
|
|
|
|
|
|
|
185
|
|
|
|
|
|
|
The system is composed of: |
|
186
|
|
|
|
|
|
|
|
|
187
|
|
|
|
|
|
|
=over 4 |
|
188
|
|
|
|
|
|
|
|
|
189
|
|
|
|
|
|
|
=item Parser |
|
190
|
|
|
|
|
|
|
|
|
191
|
|
|
|
|
|
|
Tokenizes and parses the S-expression DSL into an AST. |
|
192
|
|
|
|
|
|
|
|
|
193
|
|
|
|
|
|
|
=item Compiler |
|
194
|
|
|
|
|
|
|
|
|
195
|
|
|
|
|
|
|
Validates references, resolves routing, injects default limits, |
|
196
|
|
|
|
|
|
|
and constructs the executable graph. |
|
197
|
|
|
|
|
|
|
|
|
198
|
|
|
|
|
|
|
=item Runner |
|
199
|
|
|
|
|
|
|
|
|
200
|
|
|
|
|
|
|
Owns execution state, performs scheduling, invokes hooks, |
|
201
|
|
|
|
|
|
|
handles LLM calls, and manages routing. |
|
202
|
|
|
|
|
|
|
|
|
203
|
|
|
|
|
|
|
=item Engine |
|
204
|
|
|
|
|
|
|
|
|
205
|
|
|
|
|
|
|
Pure helper logic for guard checks and dependency resolution. |
|
206
|
|
|
|
|
|
|
|
|
207
|
|
|
|
|
|
|
=item Hook System |
|
208
|
|
|
|
|
|
|
|
|
209
|
|
|
|
|
|
|
Loads dynamic hook files returning coderefs for prompts, |
|
210
|
|
|
|
|
|
|
self-critique, revision, and critic parsing. |
|
211
|
|
|
|
|
|
|
|
|
212
|
|
|
|
|
|
|
=item Journal |
|
213
|
|
|
|
|
|
|
|
|
214
|
|
|
|
|
|
|
Creates and manages run directories and structured logging. |
|
215
|
|
|
|
|
|
|
|
|
216
|
|
|
|
|
|
|
=item LLM Adapter |
|
217
|
|
|
|
|
|
|
|
|
218
|
|
|
|
|
|
|
Current implementation uses shell-based Ollama invocation. |
|
219
|
|
|
|
|
|
|
Adapters are intentionally isolated from orchestration logic. |
|
220
|
|
|
|
|
|
|
|
|
221
|
|
|
|
|
|
|
=back |
|
222
|
|
|
|
|
|
|
|
|
223
|
|
|
|
|
|
|
=head1 DSL OVERVIEW |
|
224
|
|
|
|
|
|
|
|
|
225
|
|
|
|
|
|
|
Plans are defined as S-expressions: |
|
226
|
|
|
|
|
|
|
|
|
227
|
|
|
|
|
|
|
(system |
|
228
|
|
|
|
|
|
|
(limits ...) |
|
229
|
|
|
|
|
|
|
(entry Worker1) |
|
230
|
|
|
|
|
|
|
(agent Worker1 ...) |
|
231
|
|
|
|
|
|
|
(agent Critic1 ...) |
|
232
|
|
|
|
|
|
|
) |
|
233
|
|
|
|
|
|
|
|
|
234
|
|
|
|
|
|
|
The DSL is declarative. The graph is compiled before execution. |
|
235
|
|
|
|
|
|
|
Invalid references are rejected at compile time. |
|
236
|
|
|
|
|
|
|
|
|
237
|
|
|
|
|
|
|
=head1 RESEARCH APPLICATIONS |
|
238
|
|
|
|
|
|
|
|
|
239
|
|
|
|
|
|
|
Sim::Agent is appropriate for: |
|
240
|
|
|
|
|
|
|
|
|
241
|
|
|
|
|
|
|
=over 4 |
|
242
|
|
|
|
|
|
|
|
|
243
|
|
|
|
|
|
|
=item * |
|
244
|
|
|
|
|
|
|
|
|
245
|
|
|
|
|
|
|
Structured evaluation of agent topologies |
|
246
|
|
|
|
|
|
|
|
|
247
|
|
|
|
|
|
|
=item * |
|
248
|
|
|
|
|
|
|
|
|
249
|
|
|
|
|
|
|
Controlled experiments in critic-based validation |
|
250
|
|
|
|
|
|
|
|
|
251
|
|
|
|
|
|
|
=item * |
|
252
|
|
|
|
|
|
|
|
|
253
|
|
|
|
|
|
|
Deterministic comparison of orchestration strategies |
|
254
|
|
|
|
|
|
|
|
|
255
|
|
|
|
|
|
|
=item * |
|
256
|
|
|
|
|
|
|
|
|
257
|
|
|
|
|
|
|
Exploration of bounded self-improvement cycles |
|
258
|
|
|
|
|
|
|
|
|
259
|
|
|
|
|
|
|
=item * |
|
260
|
|
|
|
|
|
|
|
|
261
|
|
|
|
|
|
|
Reproducible LLM workflow research |
|
262
|
|
|
|
|
|
|
|
|
263
|
|
|
|
|
|
|
=back |
|
264
|
|
|
|
|
|
|
|
|
265
|
|
|
|
|
|
|
It is not intended as a production automation system. |
|
266
|
|
|
|
|
|
|
It is a research instrument. |
|
267
|
|
|
|
|
|
|
|
|
268
|
|
|
|
|
|
|
=head1 LIMITATIONS |
|
269
|
|
|
|
|
|
|
|
|
270
|
|
|
|
|
|
|
=over 4 |
|
271
|
|
|
|
|
|
|
|
|
272
|
|
|
|
|
|
|
=item * |
|
273
|
|
|
|
|
|
|
|
|
274
|
|
|
|
|
|
|
No concurrency |
|
275
|
|
|
|
|
|
|
|
|
276
|
|
|
|
|
|
|
=item * |
|
277
|
|
|
|
|
|
|
|
|
278
|
|
|
|
|
|
|
No distributed execution |
|
279
|
|
|
|
|
|
|
|
|
280
|
|
|
|
|
|
|
=item * |
|
281
|
|
|
|
|
|
|
|
|
282
|
|
|
|
|
|
|
No web browsing or tool autonomy |
|
283
|
|
|
|
|
|
|
|
|
284
|
|
|
|
|
|
|
=item * |
|
285
|
|
|
|
|
|
|
|
|
286
|
|
|
|
|
|
|
LLM-dependent variability in content (though structure is enforced) |
|
287
|
|
|
|
|
|
|
|
|
288
|
|
|
|
|
|
|
=back |
|
289
|
|
|
|
|
|
|
|
|
290
|
|
|
|
|
|
|
These constraints are deliberate. |
|
291
|
|
|
|
|
|
|
|
|
292
|
|
|
|
|
|
|
=head1 PHILOSOPHY |
|
293
|
|
|
|
|
|
|
|
|
294
|
|
|
|
|
|
|
Sim::Agent rejects "vibe coding" and emergent orchestration. |
|
295
|
|
|
|
|
|
|
Every transition is declared. Every loop is bounded. |
|
296
|
|
|
|
|
|
|
Every output is journaled. |
|
297
|
|
|
|
|
|
|
|
|
298
|
|
|
|
|
|
|
The framework assumes that coordination, not creativity, |
|
299
|
|
|
|
|
|
|
is the primary engineering challenge in multi-agent systems. |
|
300
|
|
|
|
|
|
|
|
|
301
|
|
|
|
|
|
|
=head1 FUTURE DIRECTIONS |
|
302
|
|
|
|
|
|
|
|
|
303
|
|
|
|
|
|
|
Potential research extensions include: |
|
304
|
|
|
|
|
|
|
|
|
305
|
|
|
|
|
|
|
=over 4 |
|
306
|
|
|
|
|
|
|
|
|
307
|
|
|
|
|
|
|
=item * |
|
308
|
|
|
|
|
|
|
|
|
309
|
|
|
|
|
|
|
Deterministic replay mode |
|
310
|
|
|
|
|
|
|
|
|
311
|
|
|
|
|
|
|
=item * |
|
312
|
|
|
|
|
|
|
|
|
313
|
|
|
|
|
|
|
Formal schema declaration in DSL |
|
314
|
|
|
|
|
|
|
|
|
315
|
|
|
|
|
|
|
=item * |
|
316
|
|
|
|
|
|
|
|
|
317
|
|
|
|
|
|
|
Structured journal export (e.g., JSON traces) |
|
318
|
|
|
|
|
|
|
|
|
319
|
|
|
|
|
|
|
=item * |
|
320
|
|
|
|
|
|
|
|
|
321
|
|
|
|
|
|
|
Model-agnostic adapter abstraction |
|
322
|
|
|
|
|
|
|
|
|
323
|
|
|
|
|
|
|
=item * |
|
324
|
|
|
|
|
|
|
|
|
325
|
|
|
|
|
|
|
Patch-based self-improvement experiments under controlled conditions |
|
326
|
|
|
|
|
|
|
|
|
327
|
|
|
|
|
|
|
=back |
|
328
|
|
|
|
|
|
|
|
|
329
|
|
|
|
|
|
|
=head1 AUTHOR |
|
330
|
|
|
|
|
|
|
|
|
331
|
|
|
|
|
|
|
Gian Luca Brunetti (2026), gianluca.brunetti@gmail.com |
|
332
|
|
|
|
|
|
|
|
|
333
|
|
|
|
|
|
|
AI tools were used to accelerate drafting and refactoring. No changes were merged without human review; the maintainer remains the sole accountable party for correctness, security, and licensing compliance. |
|
334
|
|
|
|
|
|
|
|
|
335
|
|
|
|
|
|
|
=head1 LICENSE |
|
336
|
|
|
|
|
|
|
|
|
337
|
|
|
|
|
|
|
GNU General Public License, Version 3. |
|
338
|
|
|
|
|
|
|
|
|
339
|
|
|
|
|
|
|
=cut |