Skip to content

feat: let @nexus.source and @nexus.api-omit name their target - #329

Closed
moetemp wants to merge 1 commit into
moe/up/python-rpc-optionsfrom
moe/up/source-targets
Closed

moetemp wants to merge 1 commit into
moe/up/python-rpc-optionsfrom
moe/up/source-targets

Conversation

@moetemp

@moetemp moetemp commented Oct 28, 2026

Copy link
Copy Markdown
Contributor

What changed?

This PR lets @nexus.source and @nexus.api-omit name the generation target that they apply to.

/// @nexus.source target="workflow" python="workflow_producer()"
/// @nexus.source target="client" python="client_producer()"
producer: option<producer>,

/// @nexus.api-omit target="workflow"
/// @nexus.source target="client" python="local_activity_failed_tasks()"
failed-tasks: list<s64>,

In each target, a field is one of three things. A source of that target fills it, the call leaves it unset, or the convenience API takes it as a parameter.

  • Target code runs a targeted source, never the model. The convenience function of an operation runs the sources of its target before it builds the request. The private operations of each target (the Workflow function, the client's _<service>_<operation> method) also fill each optional or list field that the request leaves unset. So a resource method and SDK code get the sources, and a field that SDK code sets keeps its value.
  • A source may read definition, the definition argument of an operation that returns a resource with @nexus.definition. The Workflow create of the stream sample takes its id from workflow_stream_id(definition).
  • A source with no target stays the model's default, as before, and the client target takes that field as a parameter.
  • Go, TypeScript and .NET have only the Workflow target, so they read the Workflow source and api-omit, and they ignore the client ones. A TypeScript model now keeps a targeted field as a plain field, so its converter never calls the source. Java has no sources.
  • An api-omit may now leave a required list or map empty. The .NET model keeps such a field out of its constructor, with an empty default.

nexgen refuses an unknown target, two sources for one target, a source with no target next to a targeted one, a source and an api-omit for the same target, an api-omit on another required field, a source that reads definition where the call has none (or that names no target), and a resource method parameter that names a sourced or api-omitted request field. Such a parameter had no effect before.

The stream sample takes the sources and api-omits of Brook's next WIT. Its publish and close lose the parameters of those fields. The sample support code gives the sources, since Brook's runtime isn't here. The TypeScript models now name an omitted field by its TypeScript name in the input type of an operation, which a field with a dash broke.

This PR also fixes a TypeScript test of #326, which read the first mock call, not the last, so it didn't check the typed decode.

It replaces moetemp#76. It sits on #328. The stack is #308, #310, #311, #297, #296, #303, #304, #309, #318, #319, #320, #321, #322, #323, #324, #325, #326, #327, #328, then this PR.

Why?

The client target shares the models with the Workflow target. A Workflow helper as the default of a shared model fails when client code builds the model, with Not in workflow event loop. Brook's context fields differ per context. In a Workflow the producer is the run, in an Activity it is the attempt, and in a client it is the client. Some fields are for the transport only. moetemp#76 added the targets, but it still ran the sources as model defaults.

How did you test it?

Python tests build a Workflow create with a fake Workflow context and check the id from the definition and the owner from the run. Others check that a client append fills the producer from a fake Activity context, that a resource method gets the client's source, and that SDK code keeps its own producer. A TypeScript test checks the sources of a Workflow create. A .NET compile check creates a Stream with only a definition. A unit test checks the roles of the stream fields, and rejection fixtures cover each refusal.
cargo validate passes.

A field takes a source or an api-omit for the Workflow or the client target. Target code runs a
targeted source, so a model built outside a Workflow never calls a Workflow helper.
@moetemp

moetemp commented Oct 28, 2026

Copy link
Copy Markdown
Contributor Author

Moved to moetemp/nexgen#84 for review first. It comes back here after that.

@moetemp moetemp closed this Oct 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant