github / github/copilot-sdk

Support structured outputs (JSON schema) per message, passed through to provider

Aperta
#1,185 2 commenti 18 reazioni 0 assegnatari Vedi su GitHub
enhancement
Lingua principale
Java
Stelle
10.5k
Fork
1.5k
Merge medio
1g 11h
PR unite (30g)
128

Descrizione

## Summary

The Copilot SDK should expose first-class support for **structured outputs** (JSON schema–constrained responses) when targeting model providers that natively support the feature — OpenAI (`response_format: { type: "json_schema", ... }`) and Anthropic (structured output / tool-schema). The schema must be settable **per message** and passed through unchanged to the provider.

## Motivation

The primary use case is **deterministic agent flows that operate on the output of Copilot Studio agents**.

In Copilot Studio, an agent turn is frequently a step inside a larger orchestrated agent flow — its output is not just rendered to a user, it's fed into:

- Agent flows that expect specific fields in the output
- Routing/branching logic that switches on a category, intent, or decision

These consumers require **stable, schema-validated JSON** from the agent turn. Today the SDK only emits free-form assistant text, which forces every agent flow to either:

1. Post-parse model prose with regex / JSON-extraction heuristics — brittle and silently breaks when the model rephrases.
2. Coerce JSON via a fake single-tool tool-call — adds a round-trip per turn, pollutes tool-use telemetry, and confuses `preToolUse` hooks and authoring UX.
3. Rewrite the outgoing HTTP body in an LLM interceptor to inject `response_format` — fights the SDK's own retry/streaming logic and is unsupported.

Both OpenAI and Anthropic already accept a JSON schema directly on the request. The SDK is the only layer blocking Copilot Studio from getting deterministic agent output end-to-end.

## Proposed API

Structured output must be **per message**, because different turns in an agent flow need different schemas (classify → plan → extract → summarize).

```ts
await session.sendMessage({
content: "Classify this support ticket.",
responseFormat: {
type: "json_schema",
schema: {
name: "TicketClassification",
strict: true,
schema: {
type: "object",
properties: {
category: { type: "string", enum: ["billing", "technical", "other"] },
priority: { type: "string", enum: ["low", "medium", "high"] },
summary: { type: "string" }
},
required: ["category", "priority", "summary"],
additionalProperties: false
}
}
}
});
```

### Requirements

1. **Per-message setting** — `responseFormat` accepted on `sendMessage` / equivalent. Optional; absent ⇒ current behavior.
2. **Schema passthrough** — Forwarded verbatim to the provider request:
- OpenAI BYOM: `response_format: { type: "json_schema", json_schema: }`
- Anthropic BYOM: equivalent structured output / tool-schema mechanism
3. **Typed result on the assistant message** — Parsed JSON exposed on the resulting message (e.g., `message.structuredOutput`) so agent flows can bind to fields without re-parsing.
4. **Streaming compatible** — Final structured payload available on turn completion.
5. **Hook/interceptor friendly** — `preToolUse` hooks and raw-HTTP interceptors observe the schema in the outgoing body unchanged.
6. **Provider capability check** — Clear error if the target provider does not support structured output (rather than silently dropping the field).

## Non-goals

- Inventing a new schema dialect — accept JSON Schema as the providers do.
- Cross-provider schema translation beyond what each provider natively accepts.

## Acceptance criteria

- [ ] `responseFormat` (JSON schema) accepted on per-message send APIs
- [ ] Forwarded verbatim to OpenAI and Anthropic provider requests
- [ ] Sructured payload exposed on the resulting assistant message
- [ ] Works with streaming and with existing hook/interceptor surfaces
- [ ] Clear error when targeting a provider that doesn't support it

## References

- OpenAI Structured Outputs: https://platform.openai.com/docs/guides/structured-outputs
- Anthropic structured output / tool schemas: https://docs.anthropic.com/en/docs/build-with-claude/tool-use

Guida per i contributori

Apri la guida per i contributori

Valutazione

Questa issue non è ancora stata valutata.

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.