@@ -64,6 +64,8 @@ protected function mapMessage(Message $message): void
6464 protected function mapSystemMessage (SystemMessage $ message ): void
6565 {
6666 $ cacheType = $ message ->providerOptions ('cacheType ' );
67+ // OpenRouter supports extended cache TTL (e.g. '1h') via cacheTtl provider option
68+ $ cacheTtl = $ message ->providerOptions ('cacheTtl ' );
6769
6870 // OpenRouter supports cache_control in content array format (same as Anthropic)
6971 if ($ cacheType ) {
@@ -73,7 +75,10 @@ protected function mapSystemMessage(SystemMessage $message): void
7375 [
7476 'type ' => 'text ' ,
7577 'text ' => $ message ->content ,
76- 'cache_control ' => ['type ' => $ cacheType instanceof BackedEnum ? $ cacheType ->value : $ cacheType ],
78+ 'cache_control ' => array_filter ([
79+ 'type ' => $ cacheType instanceof BackedEnum ? $ cacheType ->value : $ cacheType ,
80+ 'ttl ' => $ cacheTtl ,
81+ ]),
7782 ],
7883 ],
7984 ];
@@ -88,7 +93,11 @@ protected function mapSystemMessage(SystemMessage $message): void
8893 protected function mapToolResultMessage (ToolResultMessage $ message ): void
8994 {
9095 $ cacheType = $ message ->providerOptions ('cacheType ' );
91- $ cacheControl = $ cacheType ? ['type ' => $ cacheType instanceof BackedEnum ? $ cacheType ->value : $ cacheType ] : null ;
96+ $ cacheTtl = $ message ->providerOptions ('cacheTtl ' );
97+ $ cacheControl = $ cacheType ? array_filter ([
98+ 'type ' => $ cacheType instanceof BackedEnum ? $ cacheType ->value : $ cacheType ,
99+ 'ttl ' => $ cacheTtl ,
100+ ]) : null ;
92101
93102 $ toolResults = $ message ->toolResults ;
94103 $ totalResults = count ($ toolResults );
@@ -126,7 +135,11 @@ protected function mapToolResultMessage(ToolResultMessage $message): void
126135 protected function mapUserMessage (UserMessage $ message ): void
127136 {
128137 $ cacheType = $ message ->providerOptions ('cacheType ' );
129- $ cacheControl = $ cacheType ? ['type ' => $ cacheType instanceof BackedEnum ? $ cacheType ->value : $ cacheType ] : null ;
138+ $ cacheTtl = $ message ->providerOptions ('cacheTtl ' );
139+ $ cacheControl = $ cacheType ? array_filter ([
140+ 'type ' => $ cacheType instanceof BackedEnum ? $ cacheType ->value : $ cacheType ,
141+ 'ttl ' => $ cacheTtl ,
142+ ]) : null ;
130143
131144 $ imageParts = array_map (fn (Image $ image ): array => (new ImageMapper ($ image ))->toPayload (), $ message ->images ());
132145 // NOTE: mirrored from Gemini's multimodal mapper so we stay consistent across providers.
@@ -153,6 +166,7 @@ protected function mapUserMessage(UserMessage $message): void
153166 protected function mapAssistantMessage (AssistantMessage $ message ): void
154167 {
155168 $ cacheType = $ message ->providerOptions ('cacheType ' );
169+ $ cacheTtl = $ message ->providerOptions ('cacheTtl ' );
156170
157171 $ toolCalls = array_map (fn (ToolCall $ toolCall ): array => [
158172 'id ' => $ toolCall ->id ,
@@ -171,7 +185,10 @@ protected function mapAssistantMessage(AssistantMessage $message): void
171185 [
172186 'type ' => 'text ' ,
173187 'text ' => $ message ->content ,
174- 'cache_control ' => ['type ' => $ cacheType instanceof BackedEnum ? $ cacheType ->value : $ cacheType ],
188+ 'cache_control ' => array_filter ([
189+ 'type ' => $ cacheType instanceof BackedEnum ? $ cacheType ->value : $ cacheType ,
190+ 'ttl ' => $ cacheTtl ,
191+ ]),
175192 ],
176193 ],
177194 'tool_calls ' => $ toolCalls ,
0 commit comments