Skip to content

Actor ops (FlowpadApp)

FlowpadApp is the root actor of the FlowPad page. This page enumerates the contract that an external caller (LLM agent, CLI, sibling actor) must conform to when invoking it.

Class metadata

ts
// projects/matrix-3/packages/flowpad/src/FlowpadApp.ts:101-110
export class FlowpadApp extends MatrixActor {
  static description = 'FlowPad — visual pipeline editor for composing data flows across actors. Run examples, write custom Omega Lisp code, and see results in real time.';

  static skills = {
    'flow-composition': {
      description: 'Compose and run actor data-flow examples or custom Omega Lisp flows.',
      ops: ['selectExample', 'runFlow', 'runFromCode', 'setTargetMount'],
    },
  };
}

Accepts

FlowpadApp.ts:111-119:

OpParamsHandlerReturns
runFlow{ exampleIndex?: number }onRunFlowResult of executing the named example.
runFromCode{ code: string, modeHint?: string, sourceFormatHint?: string }onRunFromCodeResult of compiling+executing the source.
selectExample{ index: number }onSelectExamplevoid. Sets _selectedExample.
setTargetMount{ mount: string }onSetTargetMountvoid. Sets _targetMount.
loadExample{ name: string }onLoadExampleThe DSL/network-pattern source code as a string, or null.
clearResults{}onClearResultsvoid. Clears _stageData.
snapshot.tree.oracle{} (or any)onSnapshotTreeOracleA snapshot object describing this page's surface.

Emits

FlowpadApp.ts:121-127:

EventPayloadWhen
flowStarted{ flowId: string }At the start of a run.
executionPlanned{ flowId, language, irKind, adapterPath }After the source compiles to IR.
flowCompleted{ flowId, result }On successful execution.
flowError{ flowId, error }On any thrown error during compile or execute.
exampleLoaded{ name, code }When loadExample finds a matching DSL or network-pattern example.

Op-by-op detail

runFromCode

ts
async onRunFromCode(params: { code: string; modeHint?: string; sourceFormatHint?: string })

Pipeline:

  1. Generate flowId = 'flow-' + Date.now().
  2. Clear _stageData.
  3. Emit flowStarted { flowId }.
  4. compileSourceToCanonicalIR({ source: params.code, defaultTargetMount: this._targetMount, modeHint, sourceFormatHint }).
  5. Emit executionPlanned { flowId, language, irKind, adapterPath } where adapterPath is formatAdapterPath(compiled.adapterPath).
  6. executeCanonicalIR(this._context!.derive('_runner'), compiled.ir).
  7. Emit flowCompleted { flowId, result } and return result.
  8. On any throw, emit flowError { flowId, error: String(error) } and re-throw.

runFlow

ts
async onRunFlow(params?: { exampleIndex?: number })

Uses the built-in _examples[exampleIndex] (or _selectedExample if exampleIndex is missing). Builds a plan with FlowBuilder, sends RunFlow to the flow-runner child mount, emits flowCompleted / flowError. The five built-in examples are Basic Query, Filter & Map, Query Tree, Scheme Eval, Security Policy.

loadExample

ts
onLoadExample(params: { name: string }): string | null

Looks up params.name in DSL_EXAMPLES first; if not found, in NETWORK_PATTERNS (mapped via 'Network: Parallel Fetch'parallelFetch, etc.). Emits exampleLoaded { name, code } and returns the source. Returns null if no example matches.

selectExample / setTargetMount / clearResults

These are state-only mutators. They write to _selectedExample, _targetMount, and _stageData respectively. They do not emit (no caller currently subscribes).

snapshot.tree.oracle

Returns a structured snapshot for agent targeting. Shape:

ts
{
  mount: string,                   // this page's mount or 'flowpad-page'
  tag: 'flowpad-app',
  accepts: Array<{
    op: string,
    params: Array<[name: string, type: string]>
  }>,
  emits: string[],
  tokens: {},
  cognitiveState: {
    selectedExample: number,
    targetMount: string,
    availableExamples: Array<{ index: number, name: string, description: string }>
  },
  children: Array<{
    mount: string,
    tag: string,
    accepts: [], emits: [], tokens: {}, cognitiveState: {}, children: []
  }>
}

snapshot.tree.oracle is itself filtered out of the accepts list returned by the snapshot to avoid recursion.

Lifecycle

onBootstrap (FlowpadApp.ts:212-246) registers the eleven service children + five VLM bootstrap nodes, then calls sendToChild('lisp', 'registerService', { mount: childMount }) for every child except lisp itself. This makes the LISP/VLM evaluators aware of the available service mounts so (introspect "./db"), (call "./db" "Query" ...), etc. work without further registration.

Calling from outside FlowPad

A sibling actor or external client can invoke FlowpadApp like any other Matrix actor:

bash
# Via mx-cli
matrix invoke flowpad-page runFromCode \
  '{"code":"flow().fromValue({}).viaRemote(\"./db\",\"Query\")"}'

# Via mx-cli with a built-in example
matrix invoke flowpad-page runFlow '{"exampleIndex":0}'

# Via mx-cli to discover ops
matrix invoke flowpad-page snapshot.tree.oracle '{}'

For browser code (e.g., another package's shell):

ts
await RequestReply.execute(context, 'flowpad-page', 'runFromCode', { code });

Per-stage timeout policy

Embedded in _executeRemoteCall (FlowpadApp.ts:336-340):

ts
const isCrossRoot = mount.includes('/');
const timeoutMs = isCrossRoot ? 30000 : mount.includes('vlm') ? 10000 : 5000;

A cross-root call (e.g. $CATALOG_TARGET resolved to AUTHORITY/system.catalog) gets 30s; a VLM mount gets 10s; everything else is 5s. There is no API to override these per-call.

See also

Source: projects/matrix-3/packages/flowpad/src/FlowpadApp.ts:101-425.