1+ /*---------------------------------------------------------------------------------------------
2+ * Copyright (c) Microsoft Corporation. All rights reserved.
3+ * Licensed under the MIT License. See License.txt in the project root for license information.
4+ *--------------------------------------------------------------------------------------------*/
5+
6+ import { BasePromptElementProps , PromptElement , Raw } from '@vscode/prompt-tsx' ;
7+ import { CustomDataPartMimeTypes } from './endpointTypes' ;
8+
9+ interface IResponseOutputMessageIdOpaque {
10+ type : typeof CustomDataPartMimeTypes . ResponseOutputMessageId ;
11+ responseOutputMessageId : string ;
12+ }
13+
14+ interface ILegacyPhaseDataOpaque {
15+ type : typeof CustomDataPartMimeTypes . PhaseData ;
16+ responseOutputMessageId ?: string ;
17+ }
18+
19+ export interface IResponseOutputMessageIdContainerProps extends BasePromptElementProps {
20+ responseOutputMessageId : string ;
21+ }
22+
23+ /**
24+ * Helper element to embed a Responses API output message ID into assistant messages
25+ * as an opaque content part.
26+ */
27+ export class ResponseOutputMessageIdContainer extends PromptElement < IResponseOutputMessageIdContainerProps > {
28+ render ( ) {
29+ const { responseOutputMessageId } = this . props ;
30+ const container : IResponseOutputMessageIdOpaque = {
31+ type : CustomDataPartMimeTypes . ResponseOutputMessageId ,
32+ responseOutputMessageId,
33+ } ;
34+ return < opaque value = { container } /> ;
35+ }
36+ }
37+
38+ /**
39+ * Attempts to parse a Raw opaque content part into a Responses API output message ID.
40+ * Falls back to legacy phase payloads that stored the ID alongside the phase.
41+ */
42+ export function rawPartAsResponseOutputMessageId ( part : Raw . ChatCompletionContentPartOpaque ) : string | undefined {
43+ const value = part . value as unknown ;
44+ if ( ! value || typeof value !== 'object' ) {
45+ return ;
46+ }
47+
48+ const data = value as IResponseOutputMessageIdOpaque | ILegacyPhaseDataOpaque ;
49+ if (
50+ data . type === CustomDataPartMimeTypes . ResponseOutputMessageId
51+ && typeof data . responseOutputMessageId === 'string'
52+ ) {
53+ return data . responseOutputMessageId ;
54+ }
55+
56+ if (
57+ data . type === CustomDataPartMimeTypes . PhaseData
58+ && typeof data . responseOutputMessageId === 'string'
59+ ) {
60+ return data . responseOutputMessageId ;
61+ }
62+
63+ return ;
64+ }
65+
66+ export function encodeResponseOutputMessageId ( responseOutputMessageId : string ) : Uint8Array {
67+ return new TextEncoder ( ) . encode ( responseOutputMessageId ) ;
68+ }
69+
70+ export function decodeResponseOutputMessageId ( data : Uint8Array ) : string {
71+ const decoded = new TextDecoder ( ) . decode ( data ) ;
72+ try {
73+ const parsed = JSON . parse ( decoded ) as Partial <
74+ IResponseOutputMessageIdOpaque
75+ > ;
76+ if ( typeof parsed . responseOutputMessageId === 'string' ) {
77+ return parsed . responseOutputMessageId ;
78+ }
79+ } catch {
80+ // Backward compatibility with plain string payloads.
81+ }
82+
83+ return decoded ;
84+ }
0 commit comments