Skip to content

Support Togo runtime and flow inputs#24557

Open
AAraKKe wants to merge 1 commit into
loa/openmetrics-ai-genfrom
aarakke/togo-runtime-support
Open

Support Togo runtime and flow inputs#24557
AAraKKe wants to merge 1 commit into
loa/openmetrics-ai-genfrom
aarakke/togo-runtime-support

Conversation

@AAraKKe

@AAraKKe AAraKKe commented Jul 15, 2026

Copy link
Copy Markdown
Collaborator

What does this PR do?

Adds the reusable runtime and configuration support needed by interactive Togo clients: asynchronous orchestrator execution, phase-scoped callbacks across agents and goal checks, improved failure reporting, and typed launch-input metadata propagated through the distributed configuration engine.

Motivation

The Togo TUI runs inside Textual's event loop and needs every callback attributed to the correct phase, including concurrent phases. It also needs descriptions and typed launch inputs from the configuration engine without restoring the removed monolithic flow configuration path.

Review checklist (to be filled by reviewers)

  • Feature or bugfix MUST have appropriate tests (unit, integration, e2e)
  • Add qa/required if this PR needs QA validation, or qa/skip-qa if it does not. Exactly one of the two is required.
  • If you need to backport this PR to another branch, you can add the backport/<branch-name> label to the PR and it will automatically open a backport PR once it is merged

@dd-octo-sts dd-octo-sts Bot added the ddev label Jul 15, 2026
@AAraKKe AAraKKe added the qa/skip-qa Automatically skip this PR for the next QA label Jul 15, 2026
@AAraKKe AAraKKe changed the title Add Togo runtime and flow input support Support Togo runtime and flow inputs Jul 15, 2026

AAraKKe commented Jul 15, 2026

Copy link
Copy Markdown
Collaborator Author

This stack of pull requests is managed by Graphite. Learn more about stacking.

@AAraKKe AAraKKe mentioned this pull request Jul 15, 2026
3 tasks
@datadog-datadog-prod-us1-2

datadog-datadog-prod-us1-2 Bot commented Jul 15, 2026

Copy link
Copy Markdown

Tests  Code Coverage

🎉 All green!

🧪 All tests passed
❄️ No new flaky tests detected

🎯 Code Coverage (details)
Patch Coverage: 95.40%
Overall Coverage: 88.84%

This comment will be updated automatically if new data arrives.
🔗 Commit SHA: f2c5d77 | Docs | Datadog PR Page | Give us feedback!

@AAraKKe AAraKKe force-pushed the aarakke/togo-runtime-support branch from 430449b to 43e744c Compare July 15, 2026 12:42
@AAraKKe AAraKKe marked this pull request as ready for review July 15, 2026 12:53
@AAraKKe AAraKKe requested a review from a team as a code owner July 15, 2026 12:53
@AAraKKe AAraKKe force-pushed the aarakke/togo-runtime-support branch 3 times, most recently from 4b754a2 to 489104f Compare July 15, 2026 14:28

@luisorofino luisorofino left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you!! Every change make sense, but I have a few comments that I am sure will be answered with the next PR of the TUI. Just want to make sure that they are not bugs.

My biggest concern is the one about the inputs of the inspect_endpoint phase.

Approving but looking forward to answers for those comments.


model_config = ConfigDict(extra="forbid", populate_by_name=True)
name: str = Field(pattern=VARIABLE_NAME_PATTERN)
label: str

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: couldn't we have label as optional with default value the input's name, so that we don't have to provide it if we don't care about how "pretty" it looks?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That label is the one shown in the input above

Image

Not providing it is a pretty bad ux, we should care how "pretty" it looks xD

Image

I can change it but I really think we should force it to make sure it is clear what it is from the ux point of view. Otherwise you are going to be either exposing internal names that might not describe what you want or using huge names everywhere so the label generated looks good.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, makes sense. I guess my question was more thinking about running the command without the TUI, that was the not "caring for pretty".

But makes sense since its not such a big deal and that way we force in most cases to have that better ux.

Comment thread ddev/src/ddev/ai/config/models.py
return ResolvedFlow(
name=flow_name,
description=fc.description,
inputs=fc.inputs,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question: Currently these two new fields aren't consumed anywhere. I guess that in the next PR they will be used, right?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment generated by Claude for a question I had related to this inputs field:

Related to this and to ResolvedFlow.inputs/convert_inputs: the scalar FlowInput model can't express what inspect_endpoint now consumes, so it's unclear how the TUI would ever produce the flow's very first phase input.

After #24493 (AI-7019), inspect_endpoint no longer reads a single endpoint_url. It reads one runtime variable, inspect_input, whose value is a JSON string that deserializes into a pydantic InspectInput — a list of {name, url} endpoints (a single endpoint is just a one-element list). See inspect_endpoint.py (context.get("inspect_input")) and the InspectInput/EndpointSpec models.

The input layer this PR adds can't produce that value:

  • FlowInput is scalar-only — string | number | boolean | path — and convert_inputs returns a flat dict[str, str]. There is no list/object/repeatable-group type, so there's no way to declare "N (name, url) endpoints" and have convert_inputs assemble them into the inspect_input JSON blob the phase requires.
  • The tests confirm the gap: every inspect_endpoint test hand-builds {"inspect_input": json.dumps({"endpoints": [...]})} via _inspect_input_var and injects it directly as runtime_variables — none route through convert_inputs. The flow YAML doesn't declare an inputs: block yet either.

So how is the TUI meant to wire endpoints into inspect_input? As the model stands the only options are both unsatisfying: (1) declare a single string input named inspect_input and make the user paste raw JSON, throwing away the typed-input UX; or (2) extend FlowInput with a structured/repeatable type plus a mapping from that group to the inspect_input variable — neither of which exists here.

@AAraKKe AAraKKe Jul 15, 2026

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, they are consumed by the tui.

A json is a string that is parsed into a dict. Not sure why we couldn't be able to provide the input as a string?

This comment

(1) declare a single string input named inspect_input and make the user paste raw JSON, throwing away the typed-input UX;

completely ignores the fact that the user needs to provide this when calling the tool anyway. The user is not "using the typed ux" when providing the list of inputs. We will never ask an user to "build your own code calling this class with this to run a flow". It was always supposed to be a json. If this is an issue then we should rethink the multiple endpoint input to not be a json right? Even without the tui... how was the user supposed to provide this input in a raw cli if not as a json string?

If you want it be a nice json.. then given a path. Say, hey this is the "input config" input, which is a path, read the path and load the json from the file.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it. Makes sense. It's true that there is probably not a better solution rather than just providing the raw json str as input. Sorry for my confusion!

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would not be surprised if a tool asked me for a file here though. I.e. we probably modify this and have either a single endpoint or multiple endpoints, and if we have multiple endpoints provide a json configuration file. The phase could then read any of those and build the input from that.

Comment thread ddev/tests/ai/agent/test_build.py Outdated
assert tool._process_factory is sentinel_process_factory


def test_build_runtime_propagates_scope_to_spawn_tool(file_registry):

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: I think we should test that we propagate scope to ToolRegistry, not to that specific spawn tool. Because if we leave it like this, this is also testing that ToolRegistry propagates scope to the tool, but that behavior shouldnt be tested here.

Another smell is: why only spawn_subagent tool, and not spawn_identical_subagents??

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very likely because when I built this spanw_subagent existed but not the identical subagents and never rebuilt these tests. Will include that.

Because if we leave it like this, this is also testing that ToolRegistry propagates scope to the tool, but that behavior shouldn't be tested here.

I am not sure I understand this part. Do you mean that this shouldn't be in this test_build file or that it should not be tested? We are testing that scoped is propagated all the way doing from the build_runtime. Creating the build runtime and ensuring that the scope is in the tools that will need it is the proper test to build right? What would be your proposal?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated. The AgentRuntimeFactory test now verifies that the complete context, including scope, is passed to ToolRegistry.from_names() without inspecting a concrete tool. ToolRegistry has separate parameterized coverage for both spawn_subagent and spawn_identical_subagents, verifying that each receives the parent scope, agent config, and process factory. This keeps each test at the boundary owned by that component.

@AAraKKe AAraKKe force-pushed the aarakke/togo-runtime-support branch from 489104f to f2c5d77 Compare July 15, 2026 15:50
@dd-octo-sts

dd-octo-sts Bot commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Validation Report

All 21 validations passed.

Show details
Validation Description Status
agent-reqs Verify check versions match the Agent requirements file
ci Validate CI configuration and code coverage settings
codeowners Validate every integration has a CODEOWNERS entry
config Validate default configuration files against spec.yaml
dep Verify dependency pins are consistent and Agent-compatible
http Validate integrations use the HTTP wrapper correctly
imports Validate check imports do not use deprecated modules
integration-style Validate check code style conventions
jmx-metrics Validate JMX metrics definition files and config
labeler Validate PR labeler config matches integration directories
legacy-signature Validate no integration uses the legacy Agent check signature
license-headers Validate Python files have proper license headers
licenses Validate third-party license attribution list
metadata Validate metadata.csv metric definitions
models Validate configuration data models match spec.yaml
openmetrics Validate OpenMetrics integrations disable the metric limit
package Validate Python package metadata and naming
qa-label Validate the pull request declares whether it needs QA for the next Agent release
readmes Validate README files have required sections
saved-views Validate saved view JSON file structure and fields
version Validate version consistency between package and changelog

View full run

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ddev qa/skip-qa Automatically skip this PR for the next QA team/agent-integrations

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants