RuntimeMetadata { get; set; }
+
///
/// Gets or Sets PollCount
///
@@ -436,6 +445,7 @@ public override string ToString()
sb.Append(" Iteration: ").Append(Iteration).Append("\n");
sb.Append(" LoopOverTask: ").Append(LoopOverTask).Append("\n");
sb.Append(" OutputData: ").Append(OutputData).Append("\n");
+ sb.Append(" RuntimeMetadata: ").Append(RuntimeMetadata).Append("\n");
sb.Append(" PollCount: ").Append(PollCount).Append("\n");
sb.Append(" QueueWaitTime: ").Append(QueueWaitTime).Append("\n");
sb.Append(" RateLimitFrequencyInSeconds: ").Append(RateLimitFrequencyInSeconds).Append("\n");
@@ -569,6 +579,12 @@ public bool Equals(Task input)
input.OutputData != null &&
this.OutputData.SequenceEqual(input.OutputData)
) &&
+ (
+ this.RuntimeMetadata == input.RuntimeMetadata ||
+ this.RuntimeMetadata != null &&
+ input.RuntimeMetadata != null &&
+ this.RuntimeMetadata.SequenceEqual(input.RuntimeMetadata)
+ ) &&
(
this.PollCount == input.PollCount ||
(this.PollCount != null &&
@@ -743,6 +759,8 @@ public override int GetHashCode()
hashCode = hashCode * 59 + this.LoopOverTask.GetHashCode();
if (this.OutputData != null)
hashCode = hashCode * 59 + this.OutputData.GetHashCode();
+ if (this.RuntimeMetadata != null)
+ hashCode = hashCode * 59 + this.RuntimeMetadata.GetHashCode();
if (this.PollCount != null)
hashCode = hashCode * 59 + this.PollCount.GetHashCode();
if (this.QueueWaitTime != null)
diff --git a/Tests/Client/TaskRuntimeMetadataTests.cs b/Tests/Client/TaskRuntimeMetadataTests.cs
new file mode 100644
index 00000000..8959d421
--- /dev/null
+++ b/Tests/Client/TaskRuntimeMetadataTests.cs
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2025 Conductor Authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
+ * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+using System.Collections.Generic;
+using Newtonsoft.Json;
+using Xunit;
+using ModelTask = Conductor.Client.Models.Task;
+
+namespace Tests.Client
+{
+ ///
+ /// The server delivers host-resolved secret values on Task.runtimeMetadata (wire-only, never
+ /// persisted) when a worker's TaskDef.runtimeMetadata declares secret names (conductor-oss PR
+ /// #1255). Verify the client model round-trips the field and omits it when empty.
+ ///
+ public class TaskRuntimeMetadataTests
+ {
+ [Fact]
+ public void RuntimeMetadata_RoundTrips()
+ {
+ var task = new ModelTask(
+ taskId: "t1",
+ runtimeMetadata: new Dictionary
+ {
+ { "GITHUB_TOKEN", "ghp_secret" },
+ { "GH_APP_ID", "42" }
+ });
+
+ var json = JsonConvert.SerializeObject(task);
+ Assert.Contains("\"runtimeMetadata\"", json);
+
+ var back = JsonConvert.DeserializeObject(json);
+ Assert.Equal("ghp_secret", back.RuntimeMetadata["GITHUB_TOKEN"]);
+ Assert.Equal("42", back.RuntimeMetadata["GH_APP_ID"]);
+ }
+
+ [Fact]
+ public void RuntimeMetadata_OmittedWhenEmpty()
+ {
+ var json = JsonConvert.SerializeObject(new ModelTask(taskId: "t1"));
+ Assert.DoesNotContain("runtimeMetadata", json);
+ }
+ }
+}