This is a fascinating and highly consequential architectural question.
You are proposing adding **behavior (function execution)** directly into the
parameter resolution phase, rather than restricting it to the `EXECUTE_TOOL`
nodes.
Let's break down the implications of adding a syntax like `[[locals.this_user->
logout]]` into the AST.
### The Problem with Inline Function Calls
If we implement `->` to execute functions during the `resolveParams()` step,
we fundamentally break the "Hexagonal Architecture" and the deterministic
nature of the pure state machine.
Here is why:
1. **Hidden Side Effects:** The core principle of our engine is that all I/O
and state mutations happen explicitly via `EXECUTE_TOOL` (which yields to the
Host) or `MATH_OP` (which alters local memory). If a parameter string
evaluation can trigger `->logout`, a simple data-read operation is suddenly
causing a system side-effect.
2. **Synchronous Blocking:** The `resolveParams()` function is a synchronous
`while` loop. If `->logout` requires network I/O (like invalidating a token on
a server), the `AgentCore` cannot pause and yield during a string replacement.
It would freeze the thread.
3. **Core Dump Corruption:** If the agent halts immediately after resolving
`[[locals.this_user->logout]]` but before emitting the primary syscall, the
system state has mutated (the user is logged out), but the `intent_log` has no
record of the `EXECUTE_TOOL` that caused it. Resuming the core dump will fail
because the environment is now out of sync with the event log.
### The Data-Oriented Alternative
In a strict Event-Sourced model, **data and actions must be strictly
separated.**
If `this_user` is an object in local memory, it should only contain *data*
(e.g., `{"id": "user_992", "session_token": "abc"}`). It should not contain
methods.
If you want to log a user out, that must be a distinct node in the AST,
explicitly telling the Host Environment to execute that action.
```json
/ The Data-Oriented (Safe) Way
{
"type": "EXECUTE_TOOL",
"tool_name": "logout_user",
"params": {
// We strictly read data using the dot notation
"token": "[[locals.this_user.session_token]]"
},
"next": "node_05"
}
```
### When to Use "Functions" in the AST
There is *one* scenario where inline functions are acceptable: **Pure Data
Transformation**.
Sometimes, you need to format data before sending it to a tool, and you don't
want to waste an entire AST node just to do a regex replace or to lowercase a
string.
For this, instead of object methods (`->`), you use **Pipeline Operators
(`|`)** to apply pure, synchronous, side-effect-free helper functions.
**Syntax Example: `[[locals.user_name | lowercase]]**`
If we want to support this, we modify the `resolveParams()` parser to
recognize the pipe `|` and apply a strict whitelist of pure JS functions (like
`toUpperCase`, `trim`, `uriEncode`).
```javascript
/ Adding pure pipelines to the resolveString parser:
const resolveString = (str) => {
let currentStr = str;
const innerBracketRegex = /\[\[([^\[\]]+)\]\]/g;
while (innerBracketRegex.test(currentStr)) {
currentStr = currentStr.replace(innerBracketRegex, (match, pathStr) =>
{
// Split by pipe to separate the path from the formatter functions
const parts = pathStr.split('|').map(p => p.trim());
const dataPath = parts[0];
const formatters = parts.slice(1);
// 1. Resolve the data
const keys = dataPath.split('.');
let value = keys.reduce((acc, key) => (acc && acc[key] !==
undefined) ? acc[key] : null, context);
if (value === null) return "";
// 2. Apply pure formatters sequentially
formatters.forEach(formatter => {
if (formatter === 'lowercase') value = String(value).toLowerCas
e();
if (formatter === 'trim') value = String(value).trim();
if (formatter === 'url_encode') value = encodeURIComponent(Stri
ng(value));
});
return value;
});
}
return currentStr;
};
```
### Summary
* **Rule of Thumb:** If it causes a side-effect (network request, file write,
database update), it **must** be an `EXECUTE_TOOL` node yielding to the host.
* **Reading Data:** Use `[[locals.variable.property]]`.
* **Transforming Data (Pure):** Use pipeline syntax `[[locals.variable.property
| uppercase]]`.
By adhering to this separation, your AST remains fully deterministic, your
core dumps remain perfectly restorable, and your JSON engine stays lean.