UpperHand Workbench โ Vendor Onboarding Packet
This packet describes the client/server contract for an agent joining the Workbench. The extension pages define published requirements. Identity transport and feedback discovery are still draft profiles; a green probe alone does not certify an integration. See conformance for the acceptance evidence and current diagnostic limits.
1. Service boundaries
The Workbench owns chat, its conversation history, agent registration, and the resident coordinator agent. Each specialist owns its model loop, tools, data, entitlements, and task history. The coordinator calls specialists through the same public A2A interface as a pinned conversation; it does not import their code or read their databases.
| Surface | Owner | Contract |
|---|---|---|
GET /.well-known/agent-card.json |
Every agent | Public AgentCard; capabilities, interfaces and security schemes |
| A2A JSON-RPC interface | Every agent | Absolute URL advertised in the card; /api/a2a/jsonrpc is a convention, not a mandated path |
| Health endpoint | Service | Public, without secrets; path belongs in the service's deployment documentation |
| OAuth token endpoint | Authorization server | Machine access tokens; declared security scheme, operator-approved trust |
| Optional MCP endpoint | Agent/tool service | Tools and interactive UI resources; independently declared and authenticated |
| Optional web views | Agent | Agent-hosted HTTPS pages declared by Views v1 |
The card is the capability source of truth. Registration supplies URL and policy, not invented skills or views. Clients may cache cards only within their HTTP freshness lifetime; revoking a capability must not leave an indefinitely stale navigation entry.
Server provisioning, repository layout and deployment procedures belong in GDE-001, under engineering standards STD-007, STD-008, STD-009 and STD-010. Each service's deployment document records its real environment URLs, trust configuration, secret references and operational owner. This packet does not prescribe a host, database vendor or internal framework.
2. A2A versions are different wire contracts
Use A2A v1.0 for new integrations.
Serve the legacy dialect as well while Workbench clients migrate. The
official @a2a-js/sdk 1.3.0 supports both on one JSON-RPC endpoint. Test
the deployed SDK version; do not infer wire compatibility from a card's
version string alone.
| Wire detail | v1.0 | Legacy 0.3 |
|---|---|---|
| Request header | A2A-Version: 1.0 |
Omitted for the SDK's compatibility default |
| Blocking send | SendMessage |
message/send |
| Streaming send | SendStreamingMessage |
message/stream |
| Task lookup | GetTask |
tasks/get |
| User role | ROLE_USER |
user |
| Part | {text, mediaType} or {data, mediaType} |
kind: "text" or kind: "data"; media type also in metadata.mediaType for legacy UpperHand clients |
| Stream result | Wrapper with task, message, artifactUpdate or statusUpdate |
Bare object discriminated by kind |
| Completed state | TASK_STATE_COMPLETED |
completed; status event uses final |
v1.0 request (send with the version header):
{
"jsonrpc": "2.0",
"id": "request-1",
"method": "SendStreamingMessage",
"params": {
"message": {
"messageId": "message-1",
"contextId": "conversation-1--specialist",
"role": "ROLE_USER",
"parts": [{ "text": "Describe your available studies.", "mediaType": "text/plain" }]
}
}
}
The equivalent legacy request uses a different method, role and Part:
{
"jsonrpc": "2.0",
"id": "request-1",
"method": "message/stream",
"params": {
"message": {
"messageId": "message-1",
"contextId": "conversation-1--specialist",
"role": "user",
"parts": [{ "kind": "text", "text": "Describe your available studies." }]
}
}
}
Treat contextId as opaque. Send only the new user turn on follow-ups and
retain the returned context; each specialist owns its conversation state.
Workbench uses stable child contexts such as <conversation>--<slug>.
Document any service length limits rather than assuming a UUID schema.
For task streams, emit the Task before its updates and output artifacts before the terminal status. Preserve Part ordering. Persist tasks and check ownership on lookup as on invocation. When streaming recovery or cancellation is unsupported, report that explicitly and use authorized task polling where supported; do not silently start another run.
Compatibility exception: the deployed Versant surface uses a bespoke
{task,event} SSE envelope even though its card advertises 1.0. Workbench
currently adapts to that envelope. This is not the SDK 0.3 or v1 wire
contract and is not a template for a new server. Workbench's SDK adapter
remains an integration gate for agents such as Roblox.
3. Typed output and optional UI
| Extension | Requirement | Purpose |
|---|---|---|
| Citations v1 | Every quantitative claim | Re-runnable provenance in application/vnd.upperhand.citations+json |
| Refusals v1 | When an agent declines | Advertised rules and application/vnd.upperhand.refusal+json Parts |
| Data source v1 | Recommended | Dataset identity |
| Views v1 | Optional | External page and downloads links |
Return readable text alongside typed data. In v1 a data Part's data
contains the JSON value directly. A refusal is a successful protocol
result with text and typed refusal data, not a JSON-RPC error. Preserve
the originating specialist task reference when the coordinator forwards
an artifact or citation.
The engineering standard's four-field tool result (text, json, ui,
citation) is an internal tool convention, not a replacement A2A envelope.
Serialize it into protocol Parts. MCP and its interactive UI resources
are optional unless an integration needs interactive tiles; text and
typed-data agents do not need an MCP server just to participate.
Views v1 declares links hosted and authenticated by the agent, not embedded Workbench panels. Unknown view kinds are ignored. Report authoring, parameterized embedded views, and durable automation jobs do not yet have published UpperHand contracts. A card entry or installed coding skill does not provide those runtimes.
4. Identity and feedback need explicit agreement
Discovery is public; invocation is authenticated. Machine access uses OAuth2 client credentials with the token URL and scopes declared in the card. Trust configuration and registration are operator-approved; a card or unverified JWT must not choose trusted issuers or JWKS endpoints. See STD-009.
Calls also need verified human identity and the specialist's own entitlement check. The proposed custom signed-grant header is documented in the identity draft, including machine-client binding and unresolved issuer decisions. It is not the IETF ID-JAG token-exchange flow. Do not claim either profile is implemented merely because two JWTs verify.
Feedback belongs to the specialist run that produced the answer, under the original authenticated owner, not just a parent Workbench task. The feedback draft records the Roblox pilot behavior and the discovery decisions still needed. No published feedback extension currently promises automatic routing.
5. Onboarding evidence
Use the conformance checklist to distinguish public discovery from authenticated interoperability. Record the service commit, environment, SDK version, dialects and test evidence. A local orb portal is a development endpoint, not a production deployment.
Before enabling an agent, resolve identity and endpoint discovery, exercise direct and coordinator-routed calls, and verify task isolation, typed output, follow-ups and recovery on the deployed environment. Keep missing capabilities disabled rather than inventing them in the registry.