Skip to content

[per-component-executor] - Typed manifest parameter values (beyond string→string) #1444

Description

@JoshuaRowePhantom

Typed manifest parameter values (beyond string → string)

Motivated by #1432 (per-component-executor-binding), but independent and non-blocking — see "Relationship to #1432" below.

Summary

Manifest parameter values are modelled everywhere as IReadOnlyDictionary<string, string>. That is correct for the current templating use (${param} text substitution) but blocks first-class support for parameter kinds whose value is not a string — e.g. the executor kind (a structured selection), and future numeric/boolean/enum/secret-reference/object parameters. This item introduces a richer, typed parameter-value model with lossless persistence and back-compat, so parameter kinds can carry structured values without stringly-typed encoding.

Relationship to #1432

The per-component-executor feature does not depend on this item. Per the M7 cohesion decision, the executor parameter's selection is recorded in a dedicated typed channel (parameter-selections: { <name>: <JsonElement> }) that feeds executor-bindings, leaving the string templating parameter-values map untouched. This item generalises that idea to all parameter kinds and would later let the executor selection migrate from the dedicated channel into the unified typed map. It can be scheduled independently.

Root Cause / Current State

  • AgentDefinitionParameterSubstitutor.Substitute(AgentManifest, IReadOnlyDictionary<string,string>?) (Phantom.Workspaces.Llm.Core/AgentDefinitionParameterSubstitutor.cs:15-17) performs ${name} regex substitution — inherently string-valued.
  • The string→string shape is threaded through ~20 sites, including CreateAgentChatRequest.Parameters, CreateAgentDefinitionRequest.Parameters, AcquireAgentChatRequest.Parameters, AgentDefinitionResolver.Parameters, AgentDefinitionToolExtractor, AgentChat.UpdateParameterValues (AgentChat.cs:671), SlashCommandContext.CurrentParameterValues, the Launchpad/StartAgentSession VMs, OpenAgentSessionShortcutHandler (reads/merges a string dict), and the persistence path AgentSessionEntityFactory.CreateEntityData(... IReadOnlyDictionary<string,string>? parameterValues ...) (Data.Core/AgentSessionEntityFactory.cs:46) plus the Mongo/Web persistence DTOs.

Affected Files (indicative)

File Contribution
Phantom.Workspaces.Llm.Core/AgentDefinitionParameterSubstitutor.cs Project a typed value to its string form for ${} substitution (text params only).
Phantom.Workspaces.Llm.Core/CreateAgentChatRequest.cs, CreateAgentDefinitionRequest.cs, Services/AgentDefinitionResolver.cs, Services/AcquireAgentChatRequest.cs Widen Parameters to the typed value model.
Phantom.Workspaces.Data.Core/AgentSessionEntityFactory.cs + Mongo/Web persistence DTOs Persist typed values; read legacy string values as ParameterValue.String.
Phantom.Workspaces/ViewModels/*Launchpad*, OpenAgentSessionShortcutHandler.cs, SlashCommands/* Produce/consume typed values; string params unaffected.

Design / Fix (sketch)

Introduce a discriminated ParameterValue (e.g. String, Number, Bool, Json) with:

  • string AsTemplateString() — used by the substitutor for ${} (text/directory params only; structured params are not substitutable and error if referenced in a template).
  • Lossless JSON round-trip for persistence.
  • Back-compat readers: a persisted bare-string value deserialises as ParameterValue.String; the writer may continue emitting bare strings for string params to avoid churn, or emit a tagged form — decide and test both read paths.

Thread IReadOnlyDictionary<string, ParameterValue> through the parameter pipeline, keeping string params behaviourally identical.

Considered / Background: (a) Overloading parameter-values with JSON-encoded strings — rejected as stringly-typed and concern-mixing. (b) A dedicated per-kind side channel (what #1432 uses for executor now) — good for one kind, but does not generalise; this item is the general solution.

Expected Tests

Test Name Class What It Verifies
ParameterValue_LegacyStringMap_ReadsAsStringValues ParameterValueTests (Phantom.Workspaces.Llm.Core.Tests) A persisted legacy string→string parameter-values block loads with each entry as ParameterValue.String (back-compat).
ParameterValue_RoundTrips_AllKinds ParameterValueTests String/number/bool/json values persist and reload losslessly.
Substitutor_StringParam_UnchangedBehaviour AgentDefinitionParameterSubstitutorTests ${text-param} substitution is identical to the current string-only behaviour.
Substitutor_StructuredParamInTemplate_Errors AgentDefinitionParameterSubstitutorTests Referencing a non-string parameter inside a ${} template fails clearly.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions