Skip to content

tekla agent declares a watch command (lifecycle: start, stream) but the aware-tekla bridge implements no watch verb — real event-triggered apps still can't fire #176

@pawellisowski

Description

@pawellisowski

Gap

#172 (PR #173, v0.49.0) landed CliInvoker::invoke_stream, so the host-agnostic streaming transport now works: a lifecycle: start source streams newline-delimited JSON through aware app run for real (not just --simulate). PR #173 explicitly scoped out the other half — "The host watch sidecars (tekla et al.) that emit the event stream remain a separate agent-binary deliverable." This issue tracks that remaining half for tekla.

The tekla agent manifest advertises a watch command, but the aware-tekla bridge binary does not implement a watch verb. So the canonical event-trigger example (tekla.watch) still cannot fire on live model events — the transport is ready, but nothing emits the stream.

Evidence (verified in aware-aeco @ 30052c828, branch main — from source)

The command is declared (stateful: true, streaming output):

  • 20-agents/aeco/engineering/tekla/manifest.yaml:24stateful: true
  • 20-agents/aeco/engineering/tekla/manifest.yaml:125-139 — the watch command:
    watch:
      lifecycle: start
      category: curated
      description: Subscribe to ModelObjectChanged events on the active Tekla model.
      inputs:
        filter: { type: enum, values: [all, welded, bolted, assembly, drawing], default: all }
      outputs:
        type: stream
        schema: { guid: string, mark: string, type: string, ... }

The bridge implements no such verb:

  • cli-tekla/Program.cs:123-138 — the verb switch handles only send-status, list-instances, launch, close, exec. Any other verb hits the default case:
    default:
        Console.Error.WriteLine($"aware-tekla: unknown verb '{verb}'. Try --help.");
        return 2;
    So invoking the bridge with watch exits non-zero with unknown verb 'watch'.

The transport is ready and would call it:

Repro

Any app whose source node is tekla.watch:

  1. aware app run <tekla-watch-app> (no --simulate) → orchestrator reaches invoke_stream → spawns aware-tekla with the watch command → bridge returns unknown verb 'watch' (exit 2) → run fails before any event is delivered.
  2. aware app run <tekla-watch-app> --simulate → one synthesized placeholder event flows through once (topology validates), nothing real fires.

Observed: the bridge has no watch verb; a real (non-simulated) tekla.watch run fails immediately.
Expected: aware-tekla watch is a long-running process that Connect()s to the active Tekla model, subscribes to the Tekla Open API event model (ModelObjectChanged, model load/unload), and writes newline-delimited JSON events ({ guid, mark, type, ... }) to stdout — which invoke_stream now consumes — staying up until the run is stopped.

What's needed (concretely)

  1. A watch verb in cli-tekla (a lifecycle: start long-running mode): connect to the live model, subscribe to model events, and emit one JSONL line per event on stdout, honoring the filter enum from the manifest. Clean shutdown on stream stop / stdin close (the transport's stop kills the child).
  2. A small end-to-end check mirroring Implement CliInvoker::invoke_stream (streaming/stateful-agent transport) #173's: a real tekla.watch run delivers ≥1 event through the provenance trace when the model changes, and exits cleanly on stop.
  3. (Nice to have, per Implement invoke_stream (streaming/stateful-agent transport) so event-triggered apps can run #172 item 4 / precedent aware connect --device-code: emit device code + verification URL as JSON and signal completion (so a thin UI can display the flow) #143) a machine-readable "listening" vs "fired" signal on the stream so a thin UI can show live trigger state.

Use case (floless.app)

floless.app ships timer routines today (a daemon fires aware app run on a schedule). The planned next step is event-triggered routines — a workflow whose first node is tekla.watch auto-runs on the event, with the floless.app daemon hosting the long-running run. With #172 done, floless.app can build/test that "On trigger" kind against any JSONL-emitting stateful agent now, but the flagship Tekla example needs this bridge verb to fire on real model events. floless.app deliberately will not build a parallel polling engine — it aligns with AWARE's event model.

Cross-refs

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions