Skip to main content
Version: 2.5

tSM AI and Agent Runtime

Version scope

The browser-facing tsm-ai service, top-bar chat, and SpEL assistant are the tSM 2.4 foundation. Form, TQL, and BPMN assistants, contextual business profiles, Agent Runtime, and durable Agent Runs describe the unreleased tSM 2.5 extension.

tsm-ai is the deployable AI backend for tSM. It provides one authenticated REST/SSE facade for the application, owns AI conversations and inference orchestration, and hosts the Agent Runtime used by process automation. Agent Runtime is a module of tsm-ai; it uses the same deployment, identity integration, model-provider configuration, and operational platform as the interactive assistants.

The architecture keeps the following responsibilities explicit:

  • the deployment edge publishes /tsm-ai/api through tenant ingress or a tSM Gateway route and forwards it to the tsm-ai facade.
  • tSM Gateway is the inbound Script protocol boundary. tSM 2.5 adds an A2A server adapter beside the existing configured Script MCP adapter in the same Gateway deployment. It is not in the outbound A2A path.
  • tsm-ai owns conversations, Assistant and Agent Profiles, Action Definitions, context assembly, model inference, Agent Runs, evidence, usage, validated AI results, and the outbound A2A client runtime with its durable local invocation view.
  • the embedded Process Engine owns BPMN state, local transactions, durable wait states, authorization gates, retries, approval, and recovery inside each process-enabled microservice.
  • a remote A2A server owns its authoritative outbound A2A Task; tsm-ai stores the protocol correlation and verified local projection, while the Process Engine stores the BPMN activity and mapped business state.

Capability Evolution

CapabilitytSM 2.4 foundationtSM 2.5 extension
Application entry pointTop-bar AI chat and SpEL editor surfaceUniversal contextual shell resolved by Assistant Profile
Public AI APIAuthenticated REST/SSE facade under /tsm-ai/apiShared facade for contextual assistants and run inspection
AI runtimesSpEL assistant in the facade processForm, TQL, and BPMN authoring modules plus Agent Runtime for business and process execution
StateServer-side conversation threads and assistant telemetryDurable Agent Runs, Outbound A2A Invocations, evidence, proposals, usage, and outcomes
ConfigurationCapability and model configurationManaged Assistant/Agent Profiles, certified context providers, tools and Action Definitions, policies, limits, and the remote Agent Registry
Process integrationExisting Process Designer and deterministic BPMN runtimeBPMN authoring assistance, internal Agent Tasks/Agentic Subprocesses, and outbound A2A Agent Tasks through durable request/result contracts

Component Model

The architecture is shown in several focused views so that service ownership remains readable.

Service Boundaries

Application, internal-agent, and outbound A2A traffic converges in tsm-ai:

Inbound Script publication is a separate Gateway path:

The browser, embedded Process Engine, and outbound A2A client all use tsm-ai. Only an external client invoking a published tSM Script enters through tSM Gateway. A deployment edge may route the browser API through Gateway, but that reverse-proxy route does not make Gateway part of AI runtime or outbound A2A state ownership.

Implementation Ownership

The product capability spans several deployable components, but each executable responsibility has one owner. Implementing an Agent Task, Agentic Subprocess, or A2A Agent Task therefore requires a coordinated contract rather than moving BPMN execution into tsm-ai.

Executable responsibilityOwning component
Agent Profile resolution, context assembly, model inference, result validation, and durable Agent Runstsm-ai
SpEL, Form, TQL, and BPMN authoring agentsBuilt-in modules of the tsm-ai microservice
BPMN element behavior, process transactions, wait states, activity dispatch, approval, retry, incidents, and continuationEmbedded Process Engine
Outbound A2A discovery, authentication, protocol transport, update normalization, and Outbound A2A InvocationsOutbound A2A Client Runtime in tsm-ai
Authoritative outbound A2A Task and its business executionRegistered remote A2A server
Inbound MCP/A2A publication, protocol authentication, routing, and Inbound A2A Task LedgertSM Gateway
Business reads and side effects exposed as certified context providers or toolsOwning domain microservice

An Agent Profile is executable only through tsm-ai. A process definition references the profile and exchanges durable commands and outcomes with that service; it does not embed prompts, provider credentials, or model SDK configuration. Conversely, tsm-ai can propose a process-scoped Tool Call but cannot move a BPMN token or bypass the Process Engine's authorization and transaction boundary.

Interactive and Authoring Components

The facade and all four authoring agents are delivered in the same tsm-ai microservice. They use one shared invocation engine and model-provider boundary while retaining certified domain tools, context providers, and deterministic finish gates. An internal deterministic helper does not create a separate browser-facing assistant service. Knowledge and grounding MCP services in this AI stack are internal context sources; they are distinct from customer-configured inbound Script MCP bindings hosted by tSM Gateway.

Process and Outbound A2A Components

Internal model execution uses Agent Runtime and creates an Agent Run:

Remote-agent delegation uses the outbound A2A client and creates an Outbound A2A Invocation:

Both execution modules live in the same tsm-ai microservice and share identity, configuration, telemetry, credentials, transport, and operations infrastructure. They keep different records: an internal model execution creates an Agent Run, while remote delegation creates an Outbound A2A Invocation that mirrors the protocol state owned by the remote server.

Request Paths

Interactive AI

  1. The browser calls the same-origin /tsm-ai/api base configured by apiUrls.tsmAI.
  2. Tenant ingress or the configured tSM Gateway route forwards the request to the tsm-ai REST/SSE facade; the facade validates the authenticated identity.
  3. tsm-ai validates the user identity, resolves and pins the assistant capability for a new conversation, verifies an existing pinned resolution and contextKey, or safely adopts a legacy conversation at its first post-upgrade request.
  4. The selected runtime performs inference and streams structured progress, content, artifacts, and a terminal result over SSE.
  5. tsm-ai stores the bounded conversation and operational metadata under the tenant, user, and assistant scope.

Process-initiated Agent Run

  1. The embedded Process Engine creates an Agent Task or enters an Agentic Subprocess and commits its BPMN wait state together with a durable outbound request.
  2. Agent Runtime deterministically validates admission, resolves the referenced Agent Profile UUID to its latest valid state, pins id + JaVers commitId, and idempotently creates the QUEUED Run for that activity attempt. An identical redelivery returns the stored decision.
  3. tsm-ai publishes AgentRunAdmissionResult. A rejection contains a safe typed configuration, authorization, deadline, or contract problem and creates no Run; acceptance keeps the process activity waiting while a runtime worker claims the Run.
  4. The runtime assembles authorized context and evidence, invokes the configured model, and validates each proposed tool call or final result against its typed contract.
  5. For an Agentic Subprocess, the Process Engine atomically admits each Tool proposal batch, returns one initial disposition per independent call, and only then dispatches process activities or creates bound approvals.
  6. Once every call in that proposal is terminal, one complete ordered Tool Outcome vector is returned to the same Agent Run and may start its next model episode.
  7. Agent Runtime publishes one idempotent typed completion, business failure, or technical failure. The originating engine correlates it and advances the committed process instance.

Durable Transport and Kafka

Kafka is the primary durable command and event transport between the Process Engine and tsm-ai. It starts work only after the owning service has committed its local state; it is not the authoritative Agent Run store, a BPMN state store, or the scheduler for model work.

The initial contract uses two physical topics:

  • ${tsm.kafka.prefix}-tsm-agent-run-commands from the Process Engine to tsm-ai;
  • ${tsm.kafka.prefix}-tsm-agent-run-events from tsm-ai to the Process Engine.

Both start with three partitions and seven-day retention. Messages are versioned JSON limited to 256 KiB, with no external schema registry and no separate retry topic. PostgreSQL owns retry timing; unreadable records follow the platform ${tsm.kafka.prefix}-tsm-dlq path.

Each producer writes its state transition and an outbox record in one local database transaction. The consumer validates and deduplicates the message, commits its own state transition and any reply outbox record, and only then acknowledges delivery. This avoids a distributed transaction across the two services while preserving the BPMN wait-state boundary.

Delivery is intentionally at least once. Stable message, Run, invocation, activity, and Tool Call identifiers make repeated delivery idempotent; aggregate sequence/version detects late or conflicting messages. The architecture does not claim end-to-end exactly-once delivery.

For internal Run scheduling, tsm-ai persists QUEUED and runnableAt together with an outbox notification. Kafka provides a low-latency wake-up, but a worker claims only a due PostgreSQL row under a lease. A periodic reconciler also finds due Runs and expired leases. Consequently, a lost wake-up delays work only until reconciliation; it cannot erase the Run. Durable backoff never holds a sleeping worker or an open model/provider call.

Kafka messages contain bounded typed business data and governed references to larger artifacts. They do not carry token deltas, SSE heartbeats, model credentials, unrestricted process variables, complete prompts, or large artifact bodies. The relational records owned by the Process Engine and tsm-ai remain the source of truth.

The transport is used as follows:

  • an Agent Task exchanges start, admission, cancellation, and terminal outcome messages;
  • an Agentic Subprocess additionally exchanges Tool Call proposal and Tool Outcome batches between model episodes;
  • an outbound A2A Agent Task uses Kafka only between the Process Engine and tsm-ai; the remote boundary initially uses A2A 1.0 JSON-RPC over HTTPS to the remote tSM Gateway, exact-message retry before remote Task identity is known, and GetTask polling after taskId is persisted;
  • inbound A2A publication through tSM Gateway is a separate transaction and delivery path.

Interactive editor and business-assistant conversations continue to use REST/SSE and do not route token streaming through Kafka. Deployments may provide an authenticated internal REST adapter for process messages, but it must preserve the same commit-before-dispatch, correlation, idempotency, ordering, and tenant-isolation semantics.

Process Command and Event Contract

The Process Engine and tsm-ai use one transport-neutral, versioned contract. Kafka and an optional internal REST adapter carry the same envelopes and invoke the same admission logic; transport acknowledgement is not business acceptance.

MessageDirectionPurpose
StartAgentRunProcess Engine → tsm-aiRequest one Agent Task or Agentic Subprocess activity attempt
AgentRunAdmissionResulttsm-ai → Process EngineReturn the persisted acceptance, effective active-work budget, and applicable activity deadline/unbounded marker, or a typed rejection; duplicate starts return the original decision
AgentToolCallsProposedtsm-ai → Process EnginePublish one correlated Agentic Subprocess decision batch
AgentToolBatchAdmissionResultProcess Engine → tsm-aiConfirm atomic batch admission and one initial disposition per Tool Call without resuming reasoning
SubmitAgentToolOutcomesProcess Engine → tsm-aiReturn one complete ordered terminal outcome vector and make the active waiting Run eligible for another episode
CancelAgentRunProcess Engine → tsm-aiRequest idempotent cancellation without deleting audit history
AgentRunOutcometsm-ai → Process EngineReturn the Run's single immutable terminal outcome

Every envelope contains contract and payload-schema versions, tenant and authenticated source, message and idempotency identities, Run/process/activity/attempt correlation, producer sequence, causation and trace context, creation time, the owning activity's deadline or explicit unbounded marker, and a canonical payload hash. Payloads contain only bounded typed values and governed references. The delegated business identity is a reference, not the transport service account or a bearer token.

Admission performs deterministic schema, tenant/source, deadline, idempotency, profile, authorization-eligibility, input-contract, and limit checks. Acceptance atomically persists the pinned QUEUED Run, its effective active-work budget, the Process Engine's activity deadline or explicit unbounded marker, and its admission event. Profile, tenant, and platform policy narrow the active-work budget; they do not invent a wall-clock estimate for an external wait. A safely correlatable rejection persists a typed problem but creates no Run. Infrastructure failure produces neither decision nor acknowledgement, so normal transport redelivery can try again.

Within a supported wire major, additive changes are rolled out to consumers before producers emit them. Breaking field or semantic changes use a new wire major and a dual-read migration. Unknown fields outside registered extensions, unknown message/enum values, and incompatible versions are rejected rather than guessed. The shared contract version is independent of a service release.

The first Tool Batch contract accepts the complete proposal atomically but tracks each Tool Call independently as scheduled, waiting for approval, or rejected. Calls in one v1 batch must be semantically independent; result-dependent work requires another model episode. Approval grant permits execution, while denial, expiry, and cancellation become typed Tool Outcomes. Only one complete outcome vector can resume reasoning. Partial progress remains operational state, and an indeterminate mutating effect requires review or incident handling.

Cross-service process control contains only Run admission, Tool proposal/batch admission/outcome coordination, cancellation, A2A updates, and terminal outcomes. Provider progress, token streaming, repair attempts, scheduler notifications, and leases remain in tsm-ai operations and Run inspection. A duplicate message is a no-op, reuse of an idempotency key with a different payload is a conflict, and a late result can never advance an already completed or canceled BPMN activity.

Agent-to-Agent Integration

Inbound publication and outbound delegation use different service boundaries:

  • Inbound A2A Script Binding: tSM Gateway exposes the Agent Card and A2A server endpoint. A TASK request creates an entry in its Inbound A2A Task Ledger. The configured Script receives a transferable replyRef, and the responsible integration publishes progress and a terminal response through @a2a.reply.
  • Outbound A2A Agent Task: tsm-ai resolves the registered remote agent, acts as the A2A client, stores a durable Outbound A2A Invocation, and normalizes polled Task snapshots. The remote A2A server remains authoritative for its Task. The embedded Process Engine owns the BPMN wait state, state/result mapping, and any configured response listener.
  • Inbound Script protocols: tSM 2.5 hosts MCP and A2A server adapters in the same tSM Gateway and applies shared identity, tenant-routing, audit, rate-limit, and observability controls there.

Inbound publication is configured through A2A Script Bindings. Outbound delegation and its listener contract are configured by the A2A Agent Task.

Agent Runtime

Agent Runtime turns a valid Agent Profile and a typed request into an auditable result. It provides the common execution layer for both a single Agent Task and a bounded Agentic Subprocess.

Its responsibilities are:

  • resolve and pin the Agent Profile UUID and JaVers commit plus exact certified model, provider, Tool, and schema references;
  • assemble server-side context under the delegated caller, process initiator, or approved business service principal;
  • apply classification, redaction, provider egress, and evidence policies;
  • invoke model providers with configured credentials and bounded provider-attempt retries inside the same Agent Run;
  • expose only the typed tools allowed for the current process scope;
  • validate proposals, Tool Calls, Tool Outcomes, and final results;
  • account for turns, tokens, cost, active duration, concurrency, and configured hard limits;
  • persist Agent Run state and publish idempotent terminal outcomes;
  • produce telemetry and replayable operational evidence without storing hidden model reasoning.

Agent Runtime submits validated proposals to the Process Engine boundary. The engine applies the business authorization, approval, activity dispatch, BPMN activity retry, incident handling, and compensation defined by the process.

Outbound A2A Client Runtime

The Outbound A2A Client Runtime is a separate module inside tsm-ai. It resolves a pinned remote Agent Card and Skill from the Agent Registry, sends A2A requests, receives updates, validates Messages and Artifacts, and reconciles uncertain delivery with the authoritative remote Task.

The first supported transport is A2A 1.0 JSONRPC over HTTPS. It implements SendMessage, GetTask, and CancelTask; bounded GetTask polling provides update delivery and restart recovery after a taskId is known. Streaming, subscription, and push notifications can be added later as latency optimizations without changing the invocation aggregate or process contract.

The first integration is tSM-to-tSM: tsm-ai calls the remote installation's tSM Gateway with the existing X-API-Key and X-Tenant-Id headers. That Gateway performs its normal exchange through remote user management and strips the key before forwarding. The key comes only from the configured Secret/Vault reference. The local Gateway is not an egress proxy, and tsm-ai adds no separate OAuth, token, password, or credential-management implementation.

The initial registry admits only remote agents whose onboarding test proves that retrying an identical SendMessage with the same messageId, contextId, and canonical payload is idempotent. If delivery is uncertain before a response supplies taskId, tsm-ai may retry only that exact message; it never generates a replacement identity or changed payload. GetTask cannot recover an unknown Task because it requires taskId. An approved ListTasks(contextId) capability may help an operator or reconciler find candidates, but it is auxiliary evidence and never the sole duplicate- prevention guarantee. Once taskId is known, GetTask becomes the authoritative reconciliation path.

Every HTTP attempt has a 30-second timeout. Polling is persisted after 2, 5, and 10 seconds and then every 30 seconds, with one lease owner per remote Task. It survives restart and follows the BPMN activity deadline or an explicit governed UNBOUNDED choice. Once local cancellation is accepted, a later remote completion remains audit-only and cannot advance the workflow; unconfirmed or indeterminate effects require review rather than an assumed rollback.

One remote delegation creates an Outbound A2A Invocation with a stable a2aInvocationId. The record contains the selected registry/card versions, local messageId, remote taskId and contextId, normalized updates, delivery attempts, Artifact references, and the last verified state. It is a local protocol projection, not an internal Agent Run and not the authoritative remote Task.

For every changed canonical Task projection, tsm-ai derives a stable local updateId, assigns the next updateSequence, and publishes a typed response to the owning Process Engine. Repeated poll snapshots reuse the same identity. These fields are local deduplication data, not A2A protocol fields. The Process Engine applies its configured state mapping and optional A2A State Response Listener. Outbound details are defined in A2A Agent Task.

Agent Registry entries are normal code-table entities with UUID, change-counter version, validity, derived valid, and JaVers audit. They have listing/detail/in-place editing and a bounded Verify onboarding action, but no draft, publish, retire, raw credential, arbitrary header, or test-prompt editor. Verification is bound to the current JaVers commit and proves the selected interface, Skill mapping, and exact-Message idempotency; a dispatch-relevant edit makes it stale.

Agent Profile

An Agent Profile is the reusable behavioral identity and maximum execution capability for internal model work. It defines instructions, certified model and contract references, available context providers and Tools, execution limits, and fixed result handling.

Behavioral identity, not a security principal

An Agent Profile never authenticates a request and never grants a privilege. Every context provider, model route, Tool, Action, and business object is authorized at its owning boundary under the actual caller, process initiator, or explicitly configured service identity.

An Assistant Profile, Agent Task, or Agentic Subprocess may narrow what the Agent Profile allows. It cannot add a provider or Tool, raise a limit, change certified code, or bypass authorization.

Standard Entity and Version History

Agent Profile and Assistant Profile are separate standard tSM code-table entities:

FieldMeaning
idServer-created UUID used by references
versionOptimistic-lock value incremented by every successful edit
codeUnique code in that entity table; editable for tenant profiles
name and descriptionBase display values with standard localizationData
dataTagsStandard searchable tags; they do not change runtime behavior
validityFrom and validityToOptional standard validity interval
validRead-only value derived from the validity interval
originServer-owned BUILT_IN or TENANT
audit fieldsStandard inserted/edited users and timestamps

The technical version is not a publication version. Profiles have no DRAFT, PUBLISHED, or RETIRED state and no Validate, Publish, Retire, release-assignment, evaluation, or test-console workflow. A complete profile is validated when it is created or updated.

New conversations and Agent Runs use the latest currently valid entity state. Admission pins the exact profile id + JaVers commitId. JaVers is the authoritative history used to display changes, restore old content as a new audited change, and reconstruct a pinned state. A later edit affects new admissions only. If required historical state is unavailable, execution fails instead of silently using the current row.

A tenant profile may be physically deleted only when it has never been used or retained by an Assistant Profile, BPMN definition, conversation, Agent Run, or another dependency. Otherwise an administrator ends its validity. Built-in profiles are stored in the same tables with stable UUIDs and codes, registered idempotently from source-controlled definitions, and are read-only through the API.

Certified Components

Profiles compose only server-certified components. Each component has an exact versioned reference, typed contract, localized metadata, and compatibility information. The initial registries cover:

  • instruction fragments and intent policies;
  • Model Policies;
  • input, result, and artifact contracts;
  • validators and finish gates;
  • Context Providers;
  • Tool Definitions;
  • Surface Descriptors;
  • Action Definitions.

A profile cannot embed executable Kotlin, scripts, provider endpoints, credentials, arbitrary HTTP calls, or Angular components. TSM-UI obtains each component kind from its own typed filtering/LOV endpoint. Implementations may share an internal registry abstraction, but there is no generic component editor.

SpEL, Form, TQL, and BPMN use built-in profiles over these same contracts. Existing editor routes remain compatibility bindings. The first migration is TQL; its built-in profile must preserve the current create, edit, debug, explain, Tool allow-list, artifact extraction, and live-validation behavior before the common profile path is used more broadly.

Agent Profile Configuration

The profile-specific configuration is:

AreaContract
Supported invocationsRequired non-empty selection of ASSISTANT, AGENT_TASK, and AGENTIC_SUBPROCESS
InstructionsOrdered certified instruction-fragment references plus optional completion rules
Intent behaviorOptional certified intent policy and a non-empty allowed subset
ModelRequired certified Model Policy, required capabilities, and optional narrower call timeout/provider-attempt count
ContractsRequired input/result contracts, optional artifact contract, and ordered validators
Context ProvidersCertified provider rows with use, typed mapping, timeout, freshness, size, and evidence requirements
ToolsExact Tool references with positive invocation ceilings and optional narrower timeout for INLINE Tools
LimitsRequired active-duration, model-turn, Tool-call, and token ceilings; optional accounting-currency cost ceiling
Response policyRepair count plus fixed choices for invalid result and oversized checkpoint

Instructions are not one editable raw system prompt. instructionRefs is a required ordered, duplicate-free list of certified instruction fragments. completionRules is optional and bounded; it may constrain completion but cannot grant a provider, Tool, capability, or privilege.

The Model Policy owns provider/model selection, endpoint, credentials, supported capabilities, and maximum call behavior. An Agent Profile can only select the certified policy and narrow supported values. Input and result contracts are mandatory. An artifact contract is optional and requires a compatible validator.

Central tenant/platform configuration owns data zones, redaction, persistence, retention, authorization, and feature flags. There is no profile dataPolicyRef. A profile's evidenceRequired provider setting still determines whether returned facts must carry evidence.

Context Providers

Each Context Provider row contains:

FieldMeaning
providerRefExact certified provider
useREQUIRED, DEFAULT, or AVAILABLE
inputMappingProvider-input target mapped from the Agent input contract
timeoutFinite technical timeout no wider than the provider ceiling
maxAgeMaximum accepted cache age
maxBytesMaximum result size
evidenceRequiredWhether evidence is mandatory

The editor presents a structured target/source mapping rather than a free expression editor. Stored mappings use a restricted exact-member JSONPath representation with no functions, predicates, wildcards, recursion, scripts, or network calls.

A required provider is always selected. Its failure returns BLOCKED and prevents a model call. A failed selected default or available provider returns PARTIAL with a visible warning. Stale data older than maxAge is not silently used.

Tools and Actions

executionMode, risk, contracts, privileges, handler, and approval behavior belong to the certified Tool or Action Definition, not to a profile.

Tool modeRuntime behavior
INLINEFinite synchronous read or deterministic validation in the current model Episode
PROCESS_ACTIVITYTyped proposal executed and owned by the Process Engine
ACTION_PROPOSALTyped proposal returned to UI/API for preview and confirmation or process hand-off

An allowed Tool row stores only toolRef, maxInvocations, and an optional timeout for INLINE. The profile timeout may narrow but never widen the certified timeout. PROCESS_ACTIVITY and ACTION_PROPOSAL reject a profile timeout because their external wait is owned durably by the Process Engine or Action workflow.

An Action Definition binds one exact ACTION_PROPOSAL Tool, proposal and confirmation contracts, risk/approval behavior, executor, and stable presentationRef. An Assistant may enable the action only when the bound Tool occurs in the Agent Profile allow-list. The server returns typed proposal data. TSM-UI maps known presentation references to hard-wired Angular preview components and never executes server-supplied UI definitions.

Limits and Outcomes

maxActiveDuration, maxModelTurns, maxToolCalls, and maxTotalTokens are required positive ceilings. maxCost is optional and uses the platform/tenant accounting ISO currency; the currency is shown read-only and no profile-specific FX conversion occurs. The effective value is always the minimum of Agent Profile, BPMN invocation where applicable, tenant, and platform limits. Queueing, backoff, and external WAITING do not consume active duration, while retries and resumed Episodes retain aggregate budgets.

responsePolicy contains only:

  • maxRepairAttempts;
  • onInvalidResult: REQUIRE_REVIEW or FAILED;
  • onCheckpointTooLarge: LIMIT_EXCEEDED or REQUIRE_REVIEW.

Other result codes are fixed: policy refusal is REJECTED, ordinary budget exhaustion is LIMIT_EXCEEDED, cancellation is CANCELED, and revoked authorization is AUTHORIZATION_REVOKED.

Example Agent Profile

{
"schemaVersion": "1",
"id": "7bdd902c-584a-4e74-a28b-3e9cd59fb4eb",
"version": 3,
"code": "customer-care-triage",
"name": "Customer Care Triage",
"description": "Return a grounded next-step recommendation for a customer issue.",
"origin": "TENANT",
"validityFrom": null,
"validityTo": null,
"valid": true,
"dataTags": ["customer-care", "triage"],
"localizationData": {},
"supportedInvocations": ["ASSISTANT", "AGENT_TASK", "AGENTIC_SUBPROCESS"],
"instructions": {
"instructionRefs": ["instruction/customer-care@1"],
"completionRules": ["Attach evidence to every recommended business decision."]
},
"behaviorPolicy": {
"intentPolicyRef": "intent/customer-care@1",
"allowedIntents": ["summarize", "classify", "recommend"]
},
"modelPolicy": {
"policyRef": "model-policy/governed-reasoning@4",
"capabilities": ["STRUCTURED_OUTPUT", "TOOL_CALLING"],
"callTimeout": "PT45S",
"maxProviderAttempts": 2
},
"contracts": {
"inputContractRef": "schema/customer-care-input@2",
"resultContractRef": "schema/customer-care-result@3",
"validatorRefs": ["validator/evidence-reference@1"]
},
"contextPolicy": {
"providers": [
{
"providerRef": "context/customer-summary@3",
"use": "REQUIRED",
"inputMapping": {"customerId": "$.customerId"},
"timeout": "PT3S",
"maxAge": "PT5M",
"maxBytes": 65536,
"evidenceRequired": true
}
]
},
"toolPolicy": {
"allowedTools": [
{
"toolRef": "tool/ticket-read-details@2",
"maxInvocations": 2,
"timeout": "PT10S"
}
]
},
"limits": {
"maxActiveDuration": "PT5M",
"maxModelTurns": 6,
"maxToolCalls": 5,
"maxTotalTokens": 36000,
"maxCost": {"amount": 0.25, "currency": "EUR"}
},
"responsePolicy": {
"maxRepairAttempts": 1,
"onInvalidResult": "REQUIRE_REVIEW",
"onCheckpointTooLarge": "LIMIT_EXCEEDED"
}
}

Management API and TSM-UI

The backend exposes one full CRUD resource per profile type:

GET    /agent-profiles/page
GET /agent-profiles/{id}
POST /agent-profiles
PUT /agent-profiles/{id}
DELETE /agent-profiles/{id}

GET /assistant-profiles/page
GET /assistant-profiles/{id}
POST /assistant-profiles
PUT /assistant-profiles/{id}
DELETE /assistant-profiles/{id}

Page endpoints use standard tSM Filtering and Spring Page responses. POST validates a complete new tenant entity. PUT is a full replacement containing the current version; there is no PATCH or section-specific endpoint. Profile components still edit in place: each saved section merges into the latest whole DTO and sends one full PUT. Standard status handling is 201/200/204, with 400 validation, 403 permission/origin, 404 missing resource, and 409 version, code, dependency, or ambiguity conflicts.

TSM-UI adds three entries under AI agent: Agent Profiles, Assistant Profiles, and Agent Runs. Profile routes follow the established ListingProfile master/detail pattern:

/ai-agent/agent-profiles
/ai-agent/agent-profiles/detail/:id
/ai-agent/agent-profiles/:id
/ai-agent/assistant-profiles
/ai-agent/assistant-profiles/detail/:id
/ai-agent/assistant-profiles/:id

Both profile listings initially show every validity state and sort by code ASC. Agent Profile columns are code, name, origin, supported invocations, valid, version, and last change. Assistant Profile columns are code, name, origin, referenced Agent Profile, matched surfaces, priority, valid, version, and last change. Data tags are available but hidden by default. Filtering supports full-text code/name/description, origin, validity, and data tags; Agent adds invocation type, while Assistant adds Agent Profile and exact surface.

Create uses one structured dialog and one complete POST. Name generates code while the code field is still pristine. Detail uses the standard header, master/detail or standalone route, tsm-form-inplace cards/tables, people/date information, loading state, validation, toasts, and the standard last-write-wins API v2 update behavior.

Agent Profile detail tabs are:

  1. Basic;
  2. Instructions and behavior;
  3. Model and contracts;
  4. Context Providers;
  5. Tools;
  6. Limits and outcome;
  7. Audit.

Assistant Profile detail tabs are:

  1. Basic;
  2. Surfaces;
  3. Scenario;
  4. Context and actions;
  5. Audit.

Audit displays JaVers history and diff. Restore copies selected historical content into the current entity and saves it as a new audited change through normal validation. Built-in profiles cannot be edited, restored, or deleted. Listing rows are not inline-editable, and the UI contains no Validate, Publish, Retire, Assign, Test, manual Run retry, or manual Run resume action.

Management permissions are exactly:

Ai.AgentProfile.ViewList    Ai.AssistantProfile.ViewList
Ai.AgentProfile.View Ai.AssistantProfile.View
Ai.AgentProfile.Add Ai.AssistantProfile.Add
Ai.AgentProfile.Edit Ai.AssistantProfile.Edit
Ai.AgentProfile.Delete Ai.AssistantProfile.Delete

Relationship to Assistant Profile

An Assistant Profile configures a user-facing scenario: exact surfaces, localized profile name and description, starter questions, scenario goal and input mapping, inherited provider selection, and enabled actions. It stores the Agent Profile UUID without a version. A new conversation resolves the current valid Assistant and Agent versions and pins both. BPMN uses the Agent Profile directly because its goal, mapping, limits, and continuation are defined by the process element. A remote A2A Agent Card is a separate protocol identity and is not an Agent Profile.

Agent Run

An Agent Run is the durable execution record for one internal agent activity. It links:

  • the process instance, activity, tenant, correlation, and delegated identity;
  • immutable profile and contract versions;
  • the accepted context snapshot and evidence references;
  • model turns, validated proposals, Tool Calls, Tool Outcomes, and approvals;
  • usage, limits, retries, incidents, cancellation, and the terminal typed result.

Process variables hold the small typed result and stable references. A semantic checkpoint is limited to 256 KiB and 32,000 normalized tokens. Large transcripts, evidence, and generated artifacts use tsm-dms with ownerType=AgentRun, immutable version/hash metadata, at most 25 MiB per artifact and 100 MiB per Run. Downloads reauthorize through tsm-ai; no raw public DMS URL is returned. Duplicate requests with the same idempotency identity return the recorded Run transition and never create another execution attempt.

Every Run has one of four lifecycle states:

StateMeaning
QUEUEDDurable work is eligible at runnableAt and awaits a worker lease.
RUNNINGOne worker owns the lease and executes the current model episode.
WAITINGThe lease is released while a persisted process activity, approval, or external observation is outstanding.
TERMINALOne immutable typed AgentOutcome and reason have been committed.

Specific labels such as WAITING_TOOL and WAITING_APPROVAL are views derived from the pending operation. Timeout, cancellation request, retry eligibility, and lease expiry are persisted fields, not additional lifecycle states. A terminal Run never returns to QUEUED.

tsm-ai owns provider retry and restart recovery inside the same Run. A provider retry keeps the same model episode, creates a new Provider Attempt, and consumes the original active-time, token, and cost budgets. The Process Engine owns retry of a terminal BPMN Agent Task or whole Agentic Subprocess: it persists its retry decision and creates a linked new Run with a new agentRunId, higher activity attempt, and the remaining activity-level budget. Retrying one Agent Tool activity inside a waiting Agentic Subprocess does not create a new Run.

Inspection API and TSM-UI

Run inspection is an additive browser contract; existing chat routes and SSE event types remain compatible. The resource shape is:

POST /api/v2/agent-runs
GET /api/v2/agent-runs/search
GET /api/v2/agent-runs/page
GET /api/v2/agent-runs/{runId}
GET /api/v2/agent-runs/{runId}/events?after={sequence}&limit={limit}
GET /api/v2/agent-runs/{runId}/events/stream?after={sequence}
GET /api/v2/agent-runs/{runId}/artifacts/{artifactId}/content
POST /api/v2/agent-runs/{runId}/cancel

The artifact content route accepts only the artifact UUID returned by the authorized Run detail or events. It repeats Run, tenant, owner, and data-classification authorization, verifies the stored DMS identity and SHA-256, and streams the original safe content with length, filename, and ETag headers. It never redirects to DMS or exposes a raw DMS URL; unavailable or corrupt retained content fails closed and raises an operational incident.

Creation requires an Idempotency-Key. Reuse with the same canonical payload returns the same Run; reuse with a different payload returns 409 Conflict. Cancellation is an explicit command and does not delete audit history or claim to undo a side effect.

Every durable semantic event has a monotonically increasing sequence within its Run. JSON replay and SSE use the same cursor; SSE writes the sequence as id, accepts Last-Event-ID, and switches from replay to live delivery atomically so reconnect cannot lose an event. A Run snapshot includes lastEventSequence. If retention has removed the requested history, the API returns 410 EVENT_CURSOR_EXPIRED with the earliest available and current sequence so the client can reload the snapshot and show the gap. Token deltas and heartbeats are never durable semantic events.

TSM-UI provides:

  • Agent Profiles and Assistant Profiles listings and detail editors using the standard tSM configuration listing/profile UX described above;
  • an Agent Runs listing filtered by tenant-visible profile, state, owner, process/business correlation, and time;
  • a Run detail with Overview, Execution, Timeline, Tools and operations, Evidence and artifacts, Usage, and Audit tabs.

The UI routes are /ai-agent/agent-runs, /ai-agent/agent-runs/detail/:id, and /ai-agent/agent-runs/:id. The execution diagram is a dedicated read-only ngDiagram view that TSM-UI derives from the same sanitized typed semantic events used by Timeline; the server does not return a separate graph or executable UI. TSM-UI maps event/node kinds to hard-wired Angular templates, groups retries under their logical operation, and lets users expand Episodes or inspect bounded node details. JSON replay fills any gap before SSE resumes live updates. Timeline remains the precise audit view; the diagram is an operational summary and neither exposes hidden model reasoning.

The Run listing shows Run ID, pinned Agent Profile, invocation kind, status plus wait/outcome reason, owner, process/business correlation, start time, and last change. Run detail is read-only except for the explicit Cancel action.

Access uses Ai.AgentRun.ViewList, Ai.AgentRun.View, Ai.AgentRun.Cancel, and Ai.AgentRun.ViewTechnicalDetails in addition to tenant/owner and central data-classification checks. Cancel is available only for an authorized non-terminal Run. There is no manual retry, resume, edit, or delete action. The backend filters every listing, snapshot, event, artifact, and command; hiding a field or action in the client is not authorization.

Deadlines, Cancellation, and Late Results

Deadline ownership follows state ownership:

Timed workAuthoritative owner
Optional BPMN activity deadline and aggregate retry windowProcess Engine
Agent Run active-work budget, model-provider attempt, and inline Tool timeouttsm-ai Agent Runtime
Process Tool activity and approval expiryProcess Engine
Local Outbound A2A Invocationtsm-ai Outbound A2A Client Runtime
Remote A2A TaskRemote agent

StartAgentRun carries the Process Engine's absolute activityDeadline or an explicit UNBOUNDED marker together with the remaining aggregate budgets. Admission separately pins the most restrictive maxActiveDuration from the Agent Profile, activity, tenant, and platform policy. Active duration measures actual tsm-ai episode work, provider attempts, and inline Tools; QUEUED, durable retry backoff, and WAITING do not consume it. Turns, tokens, calls, and cost keep their aggregate ceilings across retry and resume.

An intentionally long external operation is represented as PROCESS_ACTIVITY or ACTION_PROPOSAL: it returns durable correlation quickly, the Run checkpoints and waits without a worker, and a later terminal observation starts a new episode. The Process Engine or action owner controls that wait and any business deadline. UNBOUNDED is allowed only when chosen explicitly and paired with status monitoring, privileged cancellation, and an escalation/incident path; it is not the default. A remote or human wait may therefore last an unknown time without pretending that its duration can be predicted.

This never permits an unbounded synchronous call. Every model request, context provider, and INLINE Tool keeps a finite technical timeout and a fenced late result. If a microservice operation can take arbitrarily long, it must expose an asynchronous operation or be isolated behind a process adapter rather than executed inline.

Every owner stores its configured deadline or explicit unbounded decision and uses its database scheduler/reconciler to enforce bounded work. Kafka or an in-memory timer may wake work sooner but is not the timer or source of truth. Operation and approval deadlines cannot extend beyond a bounded owning activity deadline. Claiming or resuming work and committing or applying a result recheck the applicable active budget and owner deadline, so a delayed timer cannot make a late result valid.

There is no distributed timestamp contest between services. Within an owned aggregate, the first valid terminal transition committed to its database is final. If tsm-ai commits a result first, a later cancel is an idempotent no-op. If cancellation or active-budget exhaustion commits first, a later provider result is retained only as late audit evidence and cannot change the outcome or start another episode. Agent Runtime attempts best-effort provider cancellation, but correctness relies on this persisted terminal fence rather than successful interruption.

The Process Engine independently applies AgentRunOutcome only while the correlated BPMN activity attempt is waiting. A locally committed timeout, cancellation, or other terminal path makes a later outcome audit-only. Consequently, an Agent Run may truthfully end as RESULT while its BPMN attempt is already TIMED_OUT: the work completed too late for that process attempt, and no second continuation occurs.

Exhausting active runtime maps to LIMIT_EXCEEDED / MAX_ACTIVE_DURATION; exhausted provider timeouts map to FAILED / MODEL_TIMEOUT; unsafe interrupted provider work maps to FAILED / INTERRUPTED. A Process Engine activity deadline remains its own process outcome, and a later Run result is audit-only for that expired activity. Approval expiry remains the per-call Tool Outcome TIMED_OUT / APPROVAL_EXPIRED.

These records are relational. tsm-ai stores the Run, episodes, Provider Attempts, operations, semantic events, and inbox/outbox in the ai schema. The Process Engine stores BPMN activity attempts, backoff, incidents, and aggregate retry budgets in its owning schema. Kafka connects their committed transitions; sharing one PostgreSQL database does not create cross-schema ownership.

State Ownership

StateAuthoritative ownerStored correlation or view
AI conversation and assistant messagestsm-aiUI holds the active conversation ID
Agent Profile and pinned runtime policytsm-aiProcess request references Agent Profile UUID; accepted Run stores UUID + JaVers commit ID
Internal Agent Runtsm-ai Agent RuntimeProcess stores agentRunId and typed outcome
BPMN instance, wait state, incident, approval, compensationEmbedded Process EngineAgent Run stores activity correlation
Process business entity and side effectOwning domain microserviceEngine and Agent Run keep stable references
Inbound A2A TasktSM Gateway A2A Task LedgerScript/integration holds replyRef
Outbound A2A TaskRemote A2A servertsm-ai keeps the Outbound A2A Invocation and verified protocol projection; Process Engine keeps the BPMN activity, accepted update sequence, listener history, and mapped result

This ownership model gives every restart and reconciliation path one authoritative source. The Operations view joins these records by stable identifiers while preserving each owner's lifecycle.

Deployment and Startup

tsm-ai runs as a separately deployable tSM microservice. Its public facade listens on the application service port and exposes /health and /capabilities; tenant ingress or tSM Gateway maps the public /tsm-ai/api prefix to that facade. The facade, built-in authoring modules, Agent Runtime, and outbound A2A client share this deployment and scale as one service. A future internal split must preserve the same ownership and public contracts and must not expose worker-specific browser routes.

Agent Runtime and the Outbound A2A Client Runtime are enabled inside the same tsm-ai deployment. Internal process execution therefore requires:

  1. a healthy tsm-ai service with Agent Runtime enabled;
  2. model-provider and identity integration configured for the tenant;
  3. access to the platform PostgreSQL database with the ai schema migrated for the deployed tsm-ai version;
  4. the process request/result transport;
  5. at least one currently valid Agent Profile UUID referenced by the BPMN element;
  6. authenticated transport identity between domain microservices and tsm-ai, kept separate from the delegated business authorization principal;
  7. an inbound Gateway adapter only when a Script MCP or inbound A2A Script Binding is published.

Outbound A2A additionally requires a current valid and conformance-verified Agent Registry entry, a server-side API-key reference, permitted network egress from tsm-ai to the remote tSM Gateway, and a durable Outbound A2A Invocation store. It does not route through the local Gateway.

Multiple replicas consume durable notifications and share the Run store. A restart or redelivery uses the stable request identity to recover or return the same Agent Run; an explicit Process Engine retry after a terminal outcome uses a new linked Run. Readiness includes runtime configuration, required storage, transport connectivity, and the availability policy for configured model providers.

Security, Reliability, and Operations

The architecture enforces the following guarantees:

  • tenant, user/service identity, profile, context provider, tool, and business-resource access are authorized at their owning boundary;
  • profile, schema, tool, and model-policy versions remain pinned for the lifetime of a run;
  • external calls start after a committed wait state and use stable idempotency and correlation IDs;
  • duplicate or late results are recorded once and cannot advance a process twice;
  • secrets, access tokens, and unrestricted process variables stay outside prompts and A2A content;
  • sensitive operations follow the process-defined preview, User Task approval, verification, and compensation path;
  • hard limits cover model turns, tool calls, active duration, finite synchronous-call timeouts, repetition, parallelism, tokens, and cost;
  • cancellation records its outcome and triggers the configured verification or compensation path.

Retention uses the existing tSM operational pattern: configurable scheduled jobs, ShedLock, and bounded batches. Policies are independent for conversations, relational Run operational state, immutable audit fields, artifacts/evidence, Elasticsearch telemetry/search projections, and feedback. Each store is cleaned by its owning adapter; deleting a conversation does not implicitly delete or retain every correlated record. Where policy requires it, sensitive payload redaction or anonymization precedes final hard deletion while stable correlation and the minimum required audit fields remain for their separately configured period.

The default retention is 365 days after last conversation activity and 365 days after a Run or Outbound A2A Invocation becomes terminal, including linked Episodes, events, checkpoints, and DMS artifacts. Content-free technical idempotency receipts default to 400 days. Each cleanup class is configurable and may be disabled; active conversations/actions and non-terminal Runs/invocations are never time-deleted. The standard infrastructure jointly backs up PostgreSQL and DMS with compatible restore points. The first durable production slice proves RPO <= 15 minutes and RTO <= 4 hours; a missing artifact or indeterminate effect after restore requires review and is never silently recreated or repeated. Elasticsearch projections are rebuildable and not authoritative backup state.

Docker-first phase gates

Each implementation phase keeps its executable integration tests and deterministic fixtures in tsm-ai under integration-tests/phase-gates. The canonical PowerShell and shell launchers build the candidate tsm-ai image and run cumulative Phase 1-through-N black-box tests locally; CI then reruns the same command. A missing Docker Engine, unhealthy service, migration failure, aborted test, or required skipped test fails the gate; it is never reported as a successful skip.

The Docker stack uses real pinned PostgreSQL, Kafka, and Elasticsearch services. Version-aligned deterministic simulators stand in for models, Customer/User Group services, DMS, the Process Engine, and the remote tSM Gateway/A2A peer, so the required tests do not call a paid model, mutable tenant, or arbitrary network service. Fault injection covers disconnects, ambiguous responses, container restart, lease loss, and recovery. The candidate application is tested through REST/SSE, Kafka, and the typed external boundaries rather than by invoking Spring controllers in-process.

The cumulative gates prove:

  • Phase 1: PostgreSQL/Flyway/JaVers, built-in and tenant Profile lifecycle, API/permissions/audit, restart-safe registration, and TQL compatibility behavior;
  • Phase 2: resolution, safe Customer/User Group context, PostgreSQL conversations, SSE and turn idempotency, permissions, attachments, actions, cleanup, and operation with Elasticsearch down;
  • Phase 3: Kafka topology/contracts, durable Agent Run restart/reconciliation/lease/cancellation, DMS artifact integrity/download, event replay/SSE reconnect, and non-terminal retention;
  • Phase 4: Agent Registry verification, remote-Gateway headers and secret isolation, exact SendMessage retry, durable polling/restart/deduplication, and cancellation/late-result races.

TSM-UI and the Process Engine retain their own component, Playwright, and consumer-contract tests in their owning repositories using the same checked-in DTO, SSE, REST, and Kafka fixtures. CI must run the applicable Docker phase gate before pushing or deploying the candidate image. A tenant smoke test or production recovery drill is additional evidence and cannot replace this repository-owned gate.

Operations join the agentRunId, a2aInvocationId, process instance/activity IDs, conversation ID, remote A2A identifiers, local update sequence, state-listener attempts, and distributed trace. Operators can inspect profile versions, provider status, evidence, tool and approval history, protocol delivery, usage, result validation, retries, and incidents. Authorized actions retry, cancel, escalate, reconcile, or compensate from the authoritative owner.

Operational acceptance combines reviewed semantic outcomes with deterministic assertions for data boundaries, Tool scope, schemas, approval, idempotency, side effects, limits, recovery, and final process state. It is project delivery evidence, not a separate Profile Evaluation entity or release workflow.