@roll-agent/relay-protocol 0.3.3 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/dist/control.d.ts +73 -0
  2. package/dist/control.js +18 -0
  3. package/dist/index.d.ts +1971 -3
  4. package/dist/index.js +184 -4
  5. package/dist/schema/roll-relay-protocol-v1.2.schema.json +4436 -0
  6. package/fixtures/v1.2/invalid-approval-projection-raw-input-leak.json +19 -0
  7. package/fixtures/v1.2/invalid-authentication-local-only.json +12 -0
  8. package/fixtures/v1.2/invalid-file-picker-local-only.json +12 -0
  9. package/fixtures/v1.2/invalid-interaction-cancelled-reason-leak.json +10 -0
  10. package/fixtures/v1.2/invalid-interaction-resolved-result-leak.json +18 -0
  11. package/fixtures/v1.2/invalid-legacy-approval-candidate.json +7 -0
  12. package/fixtures/v1.2/invalid-legacy-approval-respond.json +7 -0
  13. package/fixtures/v1.2/invalid-n-minus-one-device-connect.json +6 -0
  14. package/fixtures/v1.2/invalid-non-normal-sensitivity.json +21 -0
  15. package/fixtures/v1.2/invalid-runtime-event-tool-input-leak.json +22 -0
  16. package/fixtures/v1.2/invalid-runtime-event-tool-output-leak.json +21 -0
  17. package/fixtures/v1.2/invalid-user-input-projection-secret-leak.json +22 -0
  18. package/fixtures/v1.2/manifest.json +479 -0
  19. package/fixtures/v1.2/valid-device-connect.json +6 -0
  20. package/fixtures/v1.2/valid-interaction-cancelled.json +9 -0
  21. package/fixtures/v1.2/valid-interaction-candidate-user-input.json +25 -0
  22. package/fixtures/v1.2/valid-interaction-request-approval.json +17 -0
  23. package/fixtures/v1.2/valid-interaction-request-user-input.json +40 -0
  24. package/fixtures/v1.2/valid-interaction-resolved.json +9 -0
  25. package/fixtures/v1.2/valid-runtime-ack.json +5 -0
  26. package/fixtures/v1.2/valid-runtime-encrypted-interaction.json +10 -0
  27. package/fixtures/v1.2/valid-runtime-event-runtime-n-minus-one.json +16 -0
  28. package/fixtures/v1.2/valid-runtime-event.json +16 -0
  29. package/fixtures/v1.2/valid-runtime-gap.json +7 -0
  30. package/fixtures/v1.2/valid-runtime-request.json +10 -0
  31. package/fixtures/v1.2/valid-runtime-response.json +8 -0
  32. package/package.json +5 -4
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
- import { RUNTIME_SERVER_REQUEST_METHODS, TOOL_OUTCOME_KINDS, approvalIdSchema, approvalExplanationSchema, approvalRequestResultSchema, getApprovalExplanation, interactionIdSchema, jsonValueSchema, normalizeUserInputResult, operationGetResultSchema, operationViewSchema, pendingApprovalSchema, projectThreadSnapshotForVersion, runtimeEventEnvelopeSchema, runtimeEventEnvelopeV11Schema, runtimeMethodSchemasV11, runtimeInstanceIdSchema, streamIdSchema, threadIdSchema, threadSnapshotV11Schema, timestampSchema, turnIdSchema, userInputFormSchema, userInputResultSchema, } from "@roll-agent/protocol";
1
+ import { RUNTIME_SERVER_REQUEST_METHODS, TOOL_OUTCOME_KINDS, approvalIdSchema, approvalExplanationSchema, approvalRequestResultSchema, getApprovalExplanation, interactionIdSchema, jsonValueSchema, normalizeUserInputResult, operationGetResultSchema, operationViewV15Schema, operationIdSchema, operationResultGetParamsSchema, operationResultGetResultSchema, appOutputDescriptorSchema, runtimeMethodSchemasV15, operationViewSchema, pendingApprovalSchema, projectThreadSnapshotForVersion, runtimeEventEnvelopeSchema, runtimeEventEnvelopeV11Schema, runtimeMethodSchemasV11, runtimeInstanceIdSchema, streamIdSchema, threadIdSchema, threadSnapshotV11Schema, timestampSchema, turnIdSchema, userInputFormSchema, userInputResultSchema, } from "@roll-agent/protocol";
2
2
  import { z } from "zod/v4";
3
- export const SUPPORTED_RELAY_PROTOCOL_VERSIONS = ["1.1", "1.0"];
3
+ export const SUPPORTED_RELAY_PROTOCOL_VERSIONS = ["1.2", "1.1", "1.0"];
4
4
  export const LATEST_RELAY_PROTOCOL_VERSION = SUPPORTED_RELAY_PROTOCOL_VERSIONS[0];
5
5
  /** @deprecated Legacy generic Relay exports remain pinned to Wire 1.0. */
6
6
  export const RELAY_PROTOCOL_VERSION = "1.0";
@@ -637,7 +637,9 @@ function redactRelayPendingApprovalV11(approval) {
637
637
  }
638
638
  /** Projects a Runtime snapshot into the allowlisted Relay Wire 1.1 query shape. */
639
639
  export function projectRelayThreadSnapshotV11(value) {
640
- const legacySnapshot = threadSnapshotV11Schema.safeParse(value);
640
+ const legacySnapshot = z
641
+ .union([threadSnapshotV11Schema, relayThreadSnapshotSchemaV12])
642
+ .safeParse(value);
641
643
  const snapshot = legacySnapshot.success
642
644
  ? legacySnapshot.data
643
645
  : projectThreadSnapshotForVersion("1.1", value);
@@ -655,7 +657,12 @@ export function projectRelayThreadSnapshotV11(value) {
655
657
  }
656
658
  /** Projects an operation query result without local display or outcome details. */
657
659
  export function projectRelayOperationGetResultV11(value) {
658
- const result = operationGetResultSchema.parse(value);
660
+ const result = z
661
+ .union([
662
+ operationGetResultSchema,
663
+ z.object({ operation: operationViewV15Schema.nullable() }).strict(),
664
+ ])
665
+ .parse(value);
659
666
  return operationGetResultSchema.parse({
660
667
  operation: result.operation === null ? null : redactRelayOperationViewV11(result.operation),
661
668
  });
@@ -804,7 +811,161 @@ export const relayMessageSchemaV11 = z.discriminatedUnion("type", [
804
811
  relayInteractionResolvedSchemaV11,
805
812
  relayInteractionCancelledSchemaV11,
806
813
  ]);
814
+ /** Wire 1.2 carries complete App results only through an explicit query. */
815
+ export const RELAY_REQUEST_METHODS_V12 = {
816
+ ...RELAY_REQUEST_METHODS_V11,
817
+ operationResultGet: "operation.result.get",
818
+ };
819
+ export const RELAY_REQUEST_METHOD_VALUES_V12 = [
820
+ ...RELAY_REQUEST_METHOD_VALUES_V11,
821
+ RELAY_REQUEST_METHODS_V12.operationResultGet,
822
+ ];
823
+ export const RELAY_REQUEST_METHOD_DISPOSITIONS_V12 = {
824
+ ...RELAY_REQUEST_METHOD_DISPOSITIONS_V11,
825
+ [RELAY_REQUEST_METHODS_V12.operationResultGet]: "query",
826
+ };
827
+ export const relayOperationViewSchemaV12 = operationViewV15Schema.def.innerType
828
+ .extend({ appOutput: appOutputDescriptorSchema.optional() })
829
+ .readonly();
830
+ export const relayThreadSnapshotSchemaV12 = threadSnapshotV11Schema.def.innerType
831
+ .extend({
832
+ operations: z
833
+ .object({
834
+ items: z.array(relayOperationViewSchemaV12),
835
+ nextBeforeSequence: z.number().int().nonnegative().nullable(),
836
+ })
837
+ .strict()
838
+ .readonly(),
839
+ })
840
+ .strict()
841
+ .readonly();
842
+ export const relayRequestMethodSchemasV12 = {
843
+ ...relayRequestMethodSchemasV11,
844
+ "thread.open": {
845
+ ...relayRequestMethodSchemasV11["thread.open"],
846
+ result: relayThreadSnapshotSchemaV12,
847
+ },
848
+ "thread.snapshot": {
849
+ ...relayRequestMethodSchemasV11["thread.snapshot"],
850
+ result: relayThreadSnapshotSchemaV12,
851
+ },
852
+ "thread.capabilities": runtimeMethodSchemasV15["thread.capabilities"],
853
+ "operation.get": {
854
+ ...relayRequestMethodSchemasV11["operation.get"],
855
+ result: z.object({ operation: relayOperationViewSchemaV12.nullable() }).strict().readonly(),
856
+ },
857
+ "operation.result.get": {
858
+ params: operationResultGetParamsSchema,
859
+ result: operationResultGetResultSchema,
860
+ },
861
+ };
862
+ export const relayToolCompletedSchemaV12 = z
863
+ .object({
864
+ type: z.literal("tool.completed"),
865
+ toolCallId: z.string().min(1),
866
+ agentName: z.string().min(1),
867
+ toolName: z.string().min(1),
868
+ outcome: relaySafeToolOutcomeSchemaV11.optional(),
869
+ appOutput: appOutputDescriptorSchema.optional(),
870
+ operationId: operationIdSchema.optional(),
871
+ })
872
+ .strict()
873
+ .readonly();
874
+ export const relayRuntimeEventEnvelopeSchemaV12 = relayRuntimeEventEnvelopeSchemaV11.def.innerType
875
+ .extend({
876
+ event: z.union([relayTimelineEventSchemaV11, relayToolCompletedSchemaV12]),
877
+ })
878
+ .strict()
879
+ .readonly();
880
+ export const relayDeviceConnectSchemaV12 = relayDeviceConnectSchemaV11.def.innerType
881
+ .extend({ protocolVersion: z.literal("1.2") })
882
+ .strict()
883
+ .readonly();
884
+ export const relayRuntimeRequestSchemaV12 = relayRuntimeRequestSchemaV11.def.innerType
885
+ .extend({ method: z.enum(RELAY_REQUEST_METHOD_VALUES_V12) })
886
+ .strict()
887
+ .readonly();
888
+ export const relayRuntimeEventSchemaV12 = relayRuntimeEventSchemaV11.def.innerType
889
+ .extend({ event: relayRuntimeEventEnvelopeSchemaV12 })
890
+ .strict()
891
+ .readonly();
892
+ export const relayMessageSchemaV12 = z.discriminatedUnion("type", [
893
+ relayDeviceConnectSchemaV12,
894
+ relayRuntimeRequestSchemaV12,
895
+ relayRuntimeResponseSchemaV11,
896
+ relayRuntimeEventSchemaV12,
897
+ relayAckSchemaV11,
898
+ relayGapSchemaV11,
899
+ relayEncryptedMessageSchemaV11,
900
+ relayInteractionRequestSchemaV11,
901
+ relayInteractionResolvedSchemaV11,
902
+ relayInteractionCancelledSchemaV11,
903
+ ]);
904
+ export function projectRelayThreadSnapshotV12(value) {
905
+ const legacy = projectRelayThreadSnapshotV11(value);
906
+ const source = z
907
+ .object({ operations: z.object({ items: z.array(relayOperationViewSchemaV12) }) })
908
+ .parse(value);
909
+ const descriptors = new Map(source.operations.items.map((operation) => [operation.id, operation.appOutput]));
910
+ return relayThreadSnapshotSchemaV12.parse({
911
+ ...legacy,
912
+ operations: {
913
+ ...legacy.operations,
914
+ items: legacy.operations.items.map((operation) => ({
915
+ ...operation,
916
+ appOutput: descriptors.get(operation.id) ?? { status: "not_provided" },
917
+ })),
918
+ },
919
+ });
920
+ }
921
+ export function projectRelayOperationGetResultV12(value) {
922
+ const result = relayRequestMethodSchemasV12["operation.get"].result.parse(value);
923
+ return {
924
+ operation: result.operation === null
925
+ ? null
926
+ : { ...result.operation, outcome: { kind: result.operation.outcome.kind }, display: null },
927
+ };
928
+ }
929
+ export function projectRuntimeEventEnvelopeForRelayV12(value) {
930
+ const base = projectRuntimeEventEnvelopeForRelayV11(value);
931
+ if (!base)
932
+ return undefined;
933
+ if (base.event.type !== "tool.completed")
934
+ return base;
935
+ const source = z
936
+ .object({
937
+ event: z.object({
938
+ appOutput: appOutputDescriptorSchema.optional(),
939
+ operationId: operationIdSchema.optional(),
940
+ }),
941
+ })
942
+ .parse(value);
943
+ return relayRuntimeEventEnvelopeSchemaV12.parse({
944
+ ...base,
945
+ event: { ...base.event, ...source.event },
946
+ });
947
+ }
948
+ /** Downgrade before delivery to a 1.1 browser; never leaks new descriptor fields. */
949
+ export function projectRelayMessageV12ToV11(message) {
950
+ if (message.type === "device.connect") {
951
+ return relayDeviceConnectSchemaV11.parse({ ...message, protocolVersion: "1.1" });
952
+ }
953
+ if (message.type === "runtime.event" && message.event.event.type === "tool.completed") {
954
+ const { appOutput: _appOutput, operationId: _operationId, ...event } = relayToolCompletedSchemaV12.parse(message.event.event);
955
+ return relayMessageSchemaV11.parse({ ...message, event: { ...message.event, event } });
956
+ }
957
+ return relayMessageSchemaV11.parse(message);
958
+ }
807
959
  export const RELAY_PROTOCOL_REGISTRY = {
960
+ "1.2": {
961
+ messageTypes: RELAY_MESSAGE_TYPE_VALUES_V11,
962
+ messageSchema: relayMessageSchemaV12,
963
+ requestMethods: RELAY_REQUEST_METHOD_VALUES_V12,
964
+ requestMethodSchemas: relayRequestMethodSchemasV12,
965
+ requestMethodDispositions: RELAY_REQUEST_METHOD_DISPOSITIONS_V12,
966
+ mutationMethods: RELAY_MUTATION_REQUEST_METHODS_V11,
967
+ localOnlyMethods: RELAY_LOCAL_ONLY_REQUEST_METHODS_V11,
968
+ },
808
969
  "1.1": {
809
970
  messageTypes: RELAY_MESSAGE_TYPE_VALUES_V11,
810
971
  messageSchema: relayMessageSchemaV11,
@@ -940,3 +1101,22 @@ export function classifyRelayAck(state) {
940
1101
  }
941
1102
  return state.incomingThrough > state.acknowledgedThrough ? "advance" : "duplicate";
942
1103
  }
1104
+ /** Keep legacy capability payloads free of unsupported App-output claims. */
1105
+ export function projectRelayCapabilitiesV11(value) {
1106
+ const result = jsonValueSchema.parse(value);
1107
+ if (result === null || typeof result !== "object" || Array.isArray(result))
1108
+ return result;
1109
+ const manifest = result.manifest;
1110
+ if (manifest === null || typeof manifest !== "object" || Array.isArray(manifest))
1111
+ return result;
1112
+ const { appOutput: _appOutput, ...legacy } = manifest;
1113
+ if (Array.isArray(legacy.tools)) {
1114
+ legacy.tools = legacy.tools.map((tool) => {
1115
+ if (tool === null || typeof tool !== "object" || Array.isArray(tool))
1116
+ return tool;
1117
+ const { appOutput: _declaration, ...retained } = tool;
1118
+ return retained;
1119
+ });
1120
+ }
1121
+ return { ...result, manifest: legacy };
1122
+ }