# JobHandlerKeys

> Tracon documentation. Tracon is a .NET package family that adds a control
> plane on Microsoft Agent Framework, published as NuGet packages that run
> inside your own ASP.NET Core application.
>
> Page: https://tracon.dev/api/tracon.jobhandlerkeys/
> Summary: JobHandlerKeys: The built-in job handler keys, plus validation for the keys a consumer registers.

<div class="api-provenance">Namespace Tracon · Assembly <code>Tracon.Abstractions.dll</code></div>

The built-in job handler keys, plus validation for the keys a consumer
registers.

```csharp
public static class JobHandlerKeys
```

<dl class="api-relations"><dt>Inheritance</dt><dd><a href="https://learn.microsoft.com/dotnet/api/system.object">object</a> ← <a href="/api/tracon.jobhandlerkeys/">JobHandlerKeys</a></dd><dt>Inherited Members</dt><dd><a href="https://learn.microsoft.com/dotnet/api/system.object.gettype">object.GetType()</a>, <a href="https://learn.microsoft.com/dotnet/api/system.object.memberwiseclone">object.MemberwiseClone()</a>, <a href="https://learn.microsoft.com/dotnet/api/system.object.tostring">object.ToString()</a>, <a href="https://learn.microsoft.com/dotnet/api/system.object.equals#system-object-equals(system-object)">object.Equals(object?)</a>, <a href="https://learn.microsoft.com/dotnet/api/system.object.equals#system-object-equals(system-object-system-object)">object.Equals(object?, object?)</a>, <a href="https://learn.microsoft.com/dotnet/api/system.object.referenceequals">object.ReferenceEquals(object?, object?)</a>, <a href="https://learn.microsoft.com/dotnet/api/system.object.gethashcode">object.GetHashCode()</a></dd></dl>

## Remarks

A handler key is a job's identity: it is both how the job is classified
([JobRecord.HandlerKey](/api/tracon.jobrecord/#Tracon_JobRecord_HandlerKey), the `handlerKey` query filter,
the `tracon.job.handler_key` metric tag) and how the background
worker picks the [IJobHandler](/api/tracon.ijobhandler/) that executes it. There is no
second field; a key registered with
`AddJobHandler<T>(key)` is dispatched by exact, ordinal match,
so registration order never decides the winner.

Grouping is done with the namespace prefix: everything Tracon ships
starts with `tracon.`, and a consumer picks its own prefix
(`contoso.`). [JobRecord.Lane](/api/tracon.jobrecord/#Tracon_JobRecord_Lane) (capacity) and
[JobRecord.TargetName](/api/tracon.jobrecord/#Tracon_JobRecord_TargetName) (the handler's input) stay separate
from the key.

## Fields

### <a id="Tracon_JobHandlerKeys_AgentBatch"></a> AgentBatch

Runs an agent as a batch over a set of inputs.

```csharp
public const string AgentBatch = "tracon.agent-batch"
```

#### Field Value

 [string](https://learn.microsoft.com/dotnet/api/system.string)

### <a id="Tracon_JobHandlerKeys_AgentRun"></a> AgentRun

A single queued (durable) agent run.

```csharp
public const string AgentRun = "tracon.agent-run"
```

#### Field Value

 [string](https://learn.microsoft.com/dotnet/api/system.string)

#### Remarks

Runs started with `Prefer: respond-async` run under this key.
Unlike [JobHandlerKeys.AgentBatch](/api/tracon.jobhandlerkeys/#Tracon_JobHandlerKeys_AgentBatch), it does not require an item set, and
the run identifier is generated IN ADVANCE by the caller (the HTTP
layer) — [JobRecord.Id](/api/tracon.jobrecord/#Tracon_JobRecord_Id) carries the same value as the run
identifier.

### <a id="Tracon_JobHandlerKeys_ApprovalResume"></a> ApprovalResume

A new run that resumes a queued run after an approval decision.

```csharp
public const string ApprovalResume = "tracon.approval-resume"
```

#### Field Value

 [string](https://learn.microsoft.com/dotnet/api/system.string)

#### Remarks

separate from [JobHandlerKeys.AgentRun](/api/tracon.jobhandlerkeys/#Tracon_JobHandlerKeys_AgentRun): the old run row closed with
[RunStatus.AwaitingApproval](/api/tracon.runstatus/) never changes again (the same
principle as [RunStatus.AwaitingInput](/api/tracon.runstatus/)); this job opens a
new `runs` row with a new run identifier. The payload carries the
identifier of the [PendingApproval](/api/tracon.pendingapproval/) record whose decision
was made.

### <a id="Tracon_JobHandlerKeys_Eval"></a> Eval

An evaluation (eval) run over a suite's cases.

```csharp
public const string Eval = "tracon.eval"
```

#### Field Value

 [string](https://learn.microsoft.com/dotnet/api/system.string)

### <a id="Tracon_JobHandlerKeys_OnlineEval"></a> OnlineEval

Scores a sampled production run.

```csharp
public const string OnlineEval = "tracon.online-eval"
```

#### Field Value

 [string](https://learn.microsoft.com/dotnet/api/system.string)

#### Remarks

The payload is empty or for diagnostics; the identifier of the run to
score is the job item itself ([JobItemRecord.Input](/api/tracon.jobitemrecord/#Tracon_JobItemRecord_Input)) — the
same pattern as how the [JobHandlerKeys.Eval](/api/tracon.jobhandlerkeys/#Tracon_JobHandlerKeys_Eval) job carries a case identifier.

### <a id="Tracon_JobHandlerKeys_ReservedPrefix"></a> ReservedPrefix

The prefix reserved for the handlers Tracon itself ships.

```csharp
public const string ReservedPrefix = "tracon."
```

#### Field Value

 [string](https://learn.microsoft.com/dotnet/api/system.string)

#### Remarks

Registering a consumer handler under this prefix throws at startup, so
a built-in key can never be shadowed by accident.

### <a id="Tracon_JobHandlerKeys_Retention"></a> Retention

A retention sweep. [JobRecord.TargetName](/api/tracon.jobrecord/#Tracon_JobRecord_TargetName) is either a
specific [RetentionTargets](/api/tracon.retentiontargets/) value or `"*"`, which
processes all enabled policies.

```csharp
public const string Retention = "tracon.retention"
```

#### Field Value

 [string](https://learn.microsoft.com/dotnet/api/system.string)

### <a id="Tracon_JobHandlerKeys_RunContinuation"></a> RunContinuation

A new run, in the SAME session, that continues an interrupted run.

```csharp
public const string RunContinuation = "tracon.run-continuation"
```

#### Field Value

 [string](https://learn.microsoft.com/dotnet/api/system.string)

#### Remarks

separate from [JobHandlerKeys.AgentRun](/api/tracon.jobhandlerkeys/#Tracon_JobHandlerKeys_AgentRun) and [JobHandlerKeys.ApprovalResume](/api/tracon.jobhandlerkeys/#Tracon_JobHandlerKeys_ApprovalResume):
triggered by orphaned-run reconciliation, not by a client request. The
old run row stays [RunStatus.Failed](/api/tracon.runstatus/) and never changes
again; this job opens a new `runs` row whose
`ContinuedFromRunId` points at it.

### <a id="Tracon_JobHandlerKeys_WebhookDelivery"></a> WebhookDelivery

A single webhook delivery attempt. The payload carries the delivery
record's identifier; the body is read from the
`webhook_deliveries` table.

```csharp
public const string WebhookDelivery = "tracon.webhook-delivery"
```

#### Field Value

 [string](https://learn.microsoft.com/dotnet/api/system.string)

### <a id="Tracon_JobHandlerKeys_Workflow"></a> Workflow

Runs a workflow once for each pending item of the job.

```csharp
public const string Workflow = "tracon.workflow"
```

#### Field Value

 [string](https://learn.microsoft.com/dotnet/api/system.string)

#### Remarks

The handler starts runs. It does not answer a pending request: that goes
through the respond endpoint.

When `TraconWorkflowOptions.ResumeInterruptedRuns` is on, the handler
writes the run identifier on the item before the run starts. A job leased
again after a crash or a shutdown finds that item still pending and resumes
its run from the latest checkpoint instead of starting it again.

### <a id="Tracon_JobHandlerKeys_WorkflowRun"></a> WorkflowRun

One queued workflow operation: a run, a resume or a response to a pending
request, started with `Prefer: respond-async`.

```csharp
public const string WorkflowRun = "tracon.workflow-run"
```

#### Field Value

 [string](https://learn.microsoft.com/dotnet/api/system.string)

#### Remarks

The HTTP layer checks the caller (attribution, authorization, session
ownership, quota, parameters, the response's shape) BEFORE it queues the
job, and generates the run identifier in advance:
[JobRecord.Id](/api/tracon.jobrecord/#Tracon_JobRecord_Id) carries the same value as the run identifier, as
for [JobHandlerKeys.AgentRun](/api/tracon.jobhandlerkeys/#Tracon_JobHandlerKeys_AgentRun). The job has no items.

This key cannot be scheduled over HTTP. Its payload names the run and the
operation to apply, and the checks above run only when the job is queued;
a payload written by hand would skip them.

## Properties

### <a id="Tracon_JobHandlerKeys_BuiltIn"></a> BuiltIn

Every key Tracon itself ships, in no particular order.

```csharp
public static IReadOnlyList<string> BuiltIn { get; }
```

#### Property Value

 [IReadOnlyList](https://learn.microsoft.com/dotnet/api/system.collections.generic.ireadonlylist\-1)<[string](https://learn.microsoft.com/dotnet/api/system.string)\>

## Methods

### <a id="Tracon_JobHandlerKeys_IsReserved_System_String_"></a> IsReserved\(string?\)

Checks whether `key` falls inside the
[JobHandlerKeys.ReservedPrefix](/api/tracon.jobhandlerkeys/#Tracon_JobHandlerKeys_ReservedPrefix) namespace.

```csharp
public static bool IsReserved(string? key)
```

#### Parameters

`key` [string](https://learn.microsoft.com/dotnet/api/system.string)?

The candidate key.

#### Returns

 [bool](https://learn.microsoft.com/dotnet/api/system.boolean)

[true](https://learn.microsoft.com/dotnet/csharp/language-reference/builtin-types/bool) if the key is reserved for Tracon.

### <a id="Tracon_JobHandlerKeys_IsValidKey_System_String_"></a> IsValidKey\(string?\)

Checks whether `key` is a valid handler key: 1-128
characters, lowercase ASCII letters, digits, `.`, `_`, or
`-`, starting with a letter or digit.

```csharp
public static bool IsValidKey(string? key)
```

#### Parameters

`key` [string](https://learn.microsoft.com/dotnet/api/system.string)?

The candidate key.

#### Returns

 [bool](https://learn.microsoft.com/dotnet/api/system.boolean)

[true](https://learn.microsoft.com/dotnet/csharp/language-reference/builtin-types/bool) if the key is valid.

#### Remarks

Uppercase letters are rejected, not normalized — the same reasoning as
[JobLanes.IsValidName](/api/tracon.joblanes/#Tracon_JobLanes_IsValidName_System_String_). Keys are compared ordinally
everywhere (dispatch, queries, metric tags), so allowing case variants
would let `"Contoso.Report"` and `"contoso.report"` silently
become two different handlers, and a job queued under one of them would
never find its handler.
