-
Notifications
You must be signed in to change notification settings - Fork 454
end: add approval policy schema #807
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| --- | ||
| "@truefoundry/trueforge-sdk": patch | ||
| --- | ||
|
|
||
| Regenerate SDK from updated OpenAPI spec. | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| --- | ||
| "@truefoundry/trueforge-core": patch | ||
| "@truefoundry/trueforge": patch | ||
| --- | ||
|
|
||
| Add `user.tool_approval_policy` send-event schema (`allow_session`, optional ISO `expire_at`). Send-only like `user.tool_approval` / `user.tool_response` — not on the durable stream. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,17 +1,26 @@ | ||
| /** | ||
| * Inbound send-event payloads for tip HITL (client → harness), distinct from the | ||
| * stream log ({@link PersistedTurnEvent} / session_event). | ||
| * Inbound send-event payloads (client → harness), distinct from the stream log | ||
| * ({@link PersistedTurnEvent} / session_event). | ||
| * | ||
| * Public send is session-scoped (`POST …/sessions/{id}/events`) with required | ||
| * body `turn_id` (one batch → one tip) plus `SessionInboundEventItem`s; rows stamp that | ||
| * tip id. v1 union is tip-only; approval policies may relax `turn_id` later. | ||
| * Public send is session-scoped (`POST …/sessions/{id}/events`) with body | ||
| * `turn_id` + items. Tip HITL uses approval/tool_response; sticky policies use | ||
| * `user.tool_approval_policy` (session `allow_session`, optional expiry; may later | ||
| * relax tip binding). Per-call allow/deny stays on `user.tool_approval`. | ||
| * `user.message` stays on createTurn / steer. | ||
| */ | ||
| import { z } from '@hono/zod-openapi'; | ||
| import { UserToolApprovalMessageSchema, UserToolResponseMessageSchema } from '../../core/events/schema'; | ||
| import { | ||
| UserToolApprovalMessageSchema, | ||
| UserToolApprovalPolicyMessageSchema, | ||
| UserToolResponseMessageSchema, | ||
| } from '../../core/events/schema'; | ||
|
|
||
| export const SessionInboundEventItemSchema = z | ||
| .discriminatedUnion('type', [UserToolApprovalMessageSchema, UserToolResponseMessageSchema]) | ||
| .openapi('SessionInboundEventItem'); | ||
| .discriminatedUnion('type', [ | ||
| UserToolApprovalMessageSchema, | ||
| UserToolResponseMessageSchema, | ||
| UserToolApprovalPolicyMessageSchema, | ||
| ]) | ||
| .openapi('SendTurnEventItem'); | ||
|
|
||
| export type SessionInboundEventItem = z.infer<typeof SessionInboundEventItemSchema>; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -40,6 +40,7 @@ export const EventType = { | |
| TOOL_RESPONSE_REQUIRED: 'tool.response_required', | ||
| USER_TOOL_APPROVAL: 'user.tool_approval', | ||
| USER_TOOL_RESPONSE: 'user.tool_response', | ||
| USER_TOOL_APPROVAL_POLICY: 'user.tool_approval_policy', | ||
| USER_MESSAGE: 'user.message', | ||
| } as const; | ||
|
|
||
|
|
@@ -96,6 +97,37 @@ export const UserToolResponseMessageSchema = z | |
| }) | ||
| .openapi('UserToolResponseEvent'); | ||
|
|
||
| export const ToolApprovalPolicyAllowSessionSchema = z | ||
| .object({ | ||
| type: z.literal('allow_session').describe('Allow matching tool calls for the rest of this session.'), | ||
| expire_at: z | ||
| .string() | ||
| .optional() | ||
| .describe('ISO 8601 timestamp when this session allow expires. Omit to allow for the whole session.'), | ||
| }) | ||
| .openapi('ToolApprovalPolicyAllowSession'); | ||
|
|
||
| export const ToolApprovalPolicyItemSchema = z | ||
| .object({ | ||
| server: z.string().min(1, 'server is required').describe('MCP server name the tool belongs to.'), | ||
| tool_name: z.string().min(1, 'tool_name is required').describe('Tool name this policy applies to.'), | ||
| action: z.discriminatedUnion('type', [ToolApprovalPolicyAllowSessionSchema]), | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Single-variant action unionLow Severity The Triggered by project rule: @truefoundry/trueforge review rules Reviewed by Cursor Bugbot for commit f2e3aa5. Configure here. |
||
| }) | ||
| .openapi('ToolApprovalPolicyItem'); | ||
|
|
||
| /** | ||
| * Client inbound sticky approval policy (send-event only; not on the durable stream). | ||
| * Same pattern as {@link UserToolApprovalMessageSchema} / {@link UserToolResponseMessageSchema}. | ||
| */ | ||
| export const UserToolApprovalPolicyMessageSchema = z | ||
| .object({ | ||
| type: z | ||
| .literal(EventType.USER_TOOL_APPROVAL_POLICY) | ||
| .describe('Sticky allow-session policy for matching tools (optional expiry).'), | ||
| policies: z.array(ToolApprovalPolicyItemSchema).min(1).describe('One or more (server, tool_name) policy entries.'), | ||
| }) | ||
| .openapi('UserToolApprovalPolicyEvent'); | ||
|
|
||
| export const TextContentPartSchema = z | ||
| .object({ | ||
| type: z.literal('text').describe('Text content part.'), | ||
|
|
@@ -373,6 +405,8 @@ export type AgentInfo = z.infer<typeof AgentInfoSchema>; | |
| export type ApprovalDecision = z.infer<typeof ApprovalDecisionSchema>; | ||
| export type UserToolApprovalMessage = z.infer<typeof UserToolApprovalMessageSchema>; | ||
| export type UserToolResponseMessage = z.infer<typeof UserToolResponseMessageSchema>; | ||
| export type ToolApprovalPolicyItem = z.infer<typeof ToolApprovalPolicyItemSchema>; | ||
| export type UserToolApprovalPolicyMessage = z.infer<typeof UserToolApprovalPolicyMessageSchema>; | ||
| export type AgentApprovalDecisionMessage = z.infer<typeof AgentApprovalDecisionMessageSchema>; | ||
| export type InputTokensBreakdown = z.infer<typeof InputTokensBreakdownSchema>; | ||
| export type ModelMessageUsage = z.infer<typeof ModelMessageUsageSchema>; | ||
|
|
||


There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SDK changeset without SDK regen
Low Severity
This changeset bumps
@truefoundry/trueforge-sdkfor an OpenAPI regen that is not in the PR. The new send-event schema is not wired to a route, and neitheropenapi.jsonnor the SDK were regenerated, so merge would publish an empty SDK patch.Triggered by project rule: TrueForge review rules
Reviewed by Cursor Bugbot for commit b981228. Configure here.