Skip to content

C# SDK: task-update-v2, OSS auth, interceptors, high-level clients, schema registration#136

Open
manan164 wants to merge 19 commits intomainfrom
csharp-sdk-improvement-plan
Open

C# SDK: task-update-v2, OSS auth, interceptors, high-level clients, schema registration#136
manan164 wants to merge 19 commits intomainfrom
csharp-sdk-improvement-plan

Conversation

@manan164
Copy link
Copy Markdown
Collaborator

@manan164 manan164 commented Mar 18, 2026

Changes

  • task-update-v2: Uses PUT /tasks/{taskId} to update a task and fetch the next one in a single call. Falls back to v1 on HTTP 404/405 (sticky — v2 is not retried after first failure).

  • OSS auth auto-disable: Token endpoint returning 404/405 disables auth silently. No config change needed for OSS Conductor.

  • HTTP interceptors: IConductorInterceptor interface with BeforeRequest / AfterResponse hooks for tracing, custom headers, and logging. Register via configuration.Interceptors.

  • High-level clients: IOrkesWorkflowClient, IOrkesTaskClient, and related interfaces with ergonomic wrappers over the generated API layer.

  • Auto schema registration: [WorkerTask(RegisterTaskDef = true)] triggers task definition registration on worker startup. Non-fatal on failure.

Tests

201 unit tests passing. UpdateTaskV2FallbackTests covers v2 success, 404/405 fallback, sticky fallback, and 500 non-fallback cases.

manan164 and others added 13 commits February 25, 2026 15:12
Gap analysis comparing C# SDK against the Python SDK reference
implementation, covering bugs, missing clients, task types, worker
framework, metrics, events, testing, examples, and documentation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1. Fix namespace typo in LlmIndexText.cs (DefinitaskNametion -> Definition)
2. Fix duplicate key bug in LlmChatComplete.cs (MAXTOKENS -> STOPWORDS for StopWords)
3. Fix inverted cancellation check in WorkflowTaskExecutor.cs (== -> !=)
4. Preserve stack trace in WorkflowTaskService.cs (throw ex -> throw)
5. Fix filename typo IWorkflowTaskCoodinator -> IWorkflowTaskCoordinator
6. Fix broken using in VectorDbHelloWorld.cs (cascading from #1)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Interfaces: IWorkflowClient, ITaskClient, IMetadataClient, ISchedulerClient,
ISecretClient, IAuthorizationClient, IPromptClient, IIntegrationClient,
IEventClient - each wrapping the raw API clients with cleaner APIs.

Orkes implementations delegate to the underlying auto-generated API clients.
OrkesClients factory creates all clients from a single Configuration.

Void-returning async API methods are wrapped with Task.Run() to provide
proper Task-based async signatures on the high-level interfaces.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ow, Inline, LlmStoreEmbeddings, LlmSearchEmbeddings, GetDocument, GenerateImage, GenerateAudio, ListMcpTools, CallMcpTool, ToolCall, ToolSpec

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…, lease extension, pause/resume

- Adaptive exponential backoff on empty poll queues (configurable multiplier and max interval)
- Worker health check tracking (consecutive errors, task counts, timestamps)
- IsHealthy() and GetHealthStatuses() on coordinator for monitoring
- Lease extension timer for long-running tasks (> configurable threshold)
- Runtime pause/resume via environment variable checking
- New configuration options in WorkflowTaskExecutorConfiguration

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…rics

Provides counters and histograms for:
- Task polling (count, success, empty, error, latency)
- Task execution (count, success, error, latency)
- Task updates (count, error, retry, latency)
- Worker restarts and payload sizes
- API calls (count, error, latency)
Includes TimingScope helper for latency measurement.
Integrates with OpenTelemetry and Prometheus exporters.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- ITaskRunnerEventListener: poll, execution, and update lifecycle events
- IWorkflowEventListener: workflow start, complete, fail, terminate, pause, resume events
- EventDispatcher: singleton with thread-safe listener registration and dispatch
- Safe exception handling in dispatch to prevent listener errors from affecting workers

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
LLM Providers: Anthropic, AWS Bedrock, Cohere, Grok, Mistral, Ollama, Perplexity
Vector DBs: PostgreSQL/pgvector, MongoDB
Each provider has enum value and configuration class with environment variable support.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Test coverage for:
- Phase 1: Bug fix regression tests (namespace, stopwords key, cancellation, stacktrace, interface name)
- Phase 2: OrkesClients factory and client interface tests
- Phase 3: All 13 new task type DSL tests (HttpPoll, Kafka, StartWorkflow, Inline, LLM tasks, MCP, Tool)
- Phase 4: Worker monitor health checks, executor configuration defaults
- Phase 5: Metrics counters, histograms, timing scope, MeterListener integration
- Phase 6: Event dispatcher registration, unregistration, multi-listener, error isolation
- Phase 7: AI provider enums, config classes for all 9 new providers + 2 vector DBs

All 106 tests pass.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…async dispatch

Phase 4: Auto-restart with configurable max retries and delay, 3-tier
configuration (code < global env vars < worker-specific env vars)
Phase 5: MetricsConfig for toggling metric categories, WorkerMetrics
per-worker helper with consistent tagging and timing scopes
Phase 6: Async event dispatch methods (DispatchTaskRunnerEventAsync,
DispatchWorkflowEventAsync)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Examples added:
- KitchenSink: all task types in one workflow
- WorkerConfiguration: worker config with annotations, env overrides
- EventListener: event listener registration and dispatch
- Metrics: metrics recording, MeterListener, TimingScope
- HumanInLoopChat: human-in-the-loop chat with LLM + HumanTask
- MultiAgentChat: multi-agent collaboration (research, writing, review)
- WorkflowTestExample: workflow testing with TaskMock
- WorkerDiscovery: assembly scanning for IWorkflowTask implementations
- AspNetCoreIntegration: DI patterns, controllers, BackgroundService
- MetadataJourney: full metadata CRUD lifecycle
- ScheduleJourney: scheduler operations
- PromptJourney: prompt template CRUD and testing
- AuthorizationJourney: apps, users, groups, permissions
- McpAgentExample: MCP agent workflow
- RagPipelineExample: RAG ingestion and query pipelines
- WorkflowOps: complete workflow lifecycle operations

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
New test files:
- SerializationTests: 30 tests for model JSON round-trip (WorkflowDef,
  TaskDef, WorkflowTask, Task, TaskResult, StartWorkflowRequest,
  Workflow, WorkflowStatus, SubWorkflowParams, TaskMock, WorkflowTestRequest)
- HighLevelClientTests: 25 tests for mocked client interfaces
  (IWorkflowClient, ITaskClient, IMetadataClient, ISchedulerClient,
  ISecretClient, IPromptClient, IAuthorizationClient)
- WorkerFrameworkTests: 20 tests for worker config edge cases
  (exponential backoff, auto-restart, lease extension, pause/resume,
  3-tier config, health status)
- WorkflowBuilderTests: 31 tests for ConductorWorkflow builder and
  all task type DSLs (Simple, HTTP, HttpPoll, Switch, ForkJoin,
  DoWhile/Loop, SubWorkflow, Wait, Terminate, Inline, JQ, Kafka,
  StartWorkflow, LLM tasks, MCP tasks)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- README.md: comprehensive rewrite with quick-start, features overview,
  task types table, AI/LLM section, examples table, documentation links
- workers.md: expanded with all worker features (auto-discovery, annotated
  workers, health checks, event listeners, metrics)
- workflow.md: expanded with all task types, workflow operations,
  workflow testing, AI/LLM workflows, RAG pipeline, MCP agent
- worker_configuration.md: new guide covering exponential backoff,
  auto-restart, lease extension, pause/resume, 3-tier config, health checks
- metrics.md: new guide covering all metrics, WorkerMetrics helper,
  MetricsConfig, MeterListener, OpenTelemetry/Prometheus integration

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@manan164 manan164 marked this pull request as draft March 18, 2026 05:25
@codecov
Copy link
Copy Markdown

codecov bot commented Mar 18, 2026

Codecov Report

❌ Patch coverage is 44.16168% with 746 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
Conductor/Client/Worker/WorkflowTaskExecutor.cs 15.56% 179 Missing ⚠️
Conductor/Client/Orkes/OrkesAuthorizationClient.cs 9.63% 75 Missing ⚠️
Conductor/Client/Telemetry/WorkerMetrics.cs 0.00% 72 Missing ⚠️
Conductor/Api/TaskResourceApi.cs 0.00% 64 Missing ⚠️
Conductor/Client/Orkes/OrkesWorkflowClient.cs 10.20% 44 Missing ⚠️
Conductor/Client/Worker/WorkflowTaskCoordinator.cs 0.00% 41 Missing ⚠️
Conductor/Client/Orkes/OrkesIntegrationClient.cs 9.52% 38 Missing ⚠️
Conductor/Client/Orkes/OrkesSecretClient.cs 10.52% 34 Missing ⚠️
Conductor/Client/Orkes/OrkesMetadataClient.cs 13.15% 33 Missing ⚠️
Conductor/Client/Orkes/OrkesSchedulerClient.cs 12.90% 27 Missing ⚠️
... and 15 more
Flag Coverage Δ
unittests 9.07% <44.16%> (-10.88%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
Conductor/Client/Configuration.cs 26.73% <100.00%> (-20.27%) ⬇️
...onductor/Client/Interfaces/IWorkflowTaskMonitor.cs 100.00% <100.00%> (ø)
Conductor/Client/Models/WorkflowTask.cs 66.95% <ø> (ø)
Conductor/Client/Orkes/OrkesClients.cs 100.00% <100.00%> (ø)
Conductor/Client/Worker/WorkflowTaskMonitor.cs 100.00% <100.00%> (ø)
Conductor/Definition/TaskType/HttpPollTask.cs 100.00% <100.00%> (ø)
Conductor/Definition/TaskType/InlineTask.cs 100.00% <100.00%> (ø)
Conductor/Definition/TaskType/KafkaPublishTask.cs 100.00% <100.00%> (ø)
...or/Definition/TaskType/LlmTasks/CallMcpToolTask.cs 100.00% <100.00%> (ø)
.../Definition/TaskType/LlmTasks/GenerateAudioTask.cs 100.00% <100.00%> (ø)
... and 35 more

... and 60 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

manan164 and others added 5 commits March 18, 2026 21:42
…uto-registration

- task-update-v2: UpdateTaskV2 on TaskResourceApi (PUT /tasks/{taskId}) returns next task
  in one call; WorkflowTaskHttpClient falls back to v1 on 404/405/501 with a sticky flag
  so the server is only probed once; WorkflowTaskExecutor feeds the returned next task
  directly into ProcessTask, skipping an extra poll round-trip

- OSS auth auto-disable: TokenHandler sets _authDisabled on 404/405 from the token
  endpoint and returns null for all subsequent requests, enabling zero-config OSS usage

- Interceptors: new IConductorInterceptor interface (BeforeRequest/AfterResponse);
  Configuration.Interceptors list wired into ApiClient sync and async call paths

- Auto schema registration: [WorkerTask] gains RegisterTaskDef, Description, and
  TimeoutSeconds properties; WorkflowTaskCoordinator accepts optional IMetadataClient
  and batch-registers annotated task defs on startup; new
  AddConductorWorkerWithMetadata DI helper wires everything up
Mirrors Python SDK fix (PRs #387 and #388). When the server returns 404
(endpoint not found) or 405 (Method Not Allowed on older Conductor 4.x),
_useUpdateV2 is set to false permanently so v2 is never retried.
Subsequent calls go directly to v1 without probing the server again.

Also adds InternalsVisibleTo for test project and upgrades test TFM to net10.0.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ecLog in WorkflowTaskExecutor

- Add NonRetryableException class: thrown by workers to mark task as FAILED_WITH_TERMINAL_ERROR with no retries
- Wire ConductorMetrics counters/histograms at every poll, execute, and update-task path (was dead code)
- Wire EventDispatcher.Instance at every key lifecycle event (OnPolling, OnPollSuccess, OnPollEmpty, OnPollError, OnTaskExecutionStarted, OnTaskExecutionCompleted, OnTaskExecutionFailed, OnTaskUpdateSent, OnTaskUpdateFailed)
- Catch NonRetryableException separately and set FAILEDWITHTERMINALERROR status
- Append TaskExecLog with full stack trace (e.ToString()) on both NonRetryable and regular failures

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Remove _useUpdateV2 flag and unreachable catch clause from WorkflowTaskExecutor;
  the v2→v1 fallback is owned entirely by WorkflowTaskHttpClient which catches
  404/405/501 before they can propagate, making the executor-level flag dead code
- Remove duplicate Content-Type header from UpdateTaskV2/UpdateTaskV2Async; RestSharp
  sets it via the contentType argument to CallApi, adding it to localVarHeaderParams
  was redundant and inconsistent with all other methods in the file
- Revert test project target framework from net10.0 back to net8.0
- Revert Dockerfile base image from sdk:10.0 back to sdk:8.0
- Move task-update-v2 fallback (_useUpdateV2 flag) from WorkflowTaskHttpClient
  back into WorkflowTaskExecutor so unit tests mocking IWorkflowTaskClient
  can properly exercise the sticky fallback behaviour
@manan164 manan164 changed the title Csharp sdk improvements C# SDK: task-update-v2, OSS auth, interceptors, high-level clients, schema registration Mar 23, 2026
- Add Testcontainers-based integration tests against conductoross/conductor-standalone:3.15.0
  covering workflow lifecycle (start, pause, resume, terminate) and task
  poll/complete/fail flows
- Mark cloud-dependent tests with [Trait("Category", "CloudIntegration")] so
  they are excluded from the default CI run (require live Orkes server)
- Add integration_tests CI job that runs the new tests directly with dotnet test,
  letting Testcontainers manage the Docker lifecycle
- Remove || true from unit test step now that cloud tests are excluded; unit
  test failures will correctly fail the build
- Update Dockerfile test filter to exclude both CloudIntegration and Integration
  categories from the Docker-based unit test run
@manan164 manan164 marked this pull request as ready for review March 23, 2026 15:26
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