@@ -123,9 +123,13 @@ local function generate_diagnostics(diagnostics)
123123end
124124
125125--- Generate messages for the given selection
126- --- @param selection CopilotChat.select.selection
126+ --- @param selection CopilotChat.select.selection ?
127127--- @return table<CopilotChat.Provider.input>
128128local function generate_selection_messages (selection )
129+ if not selection then
130+ return {}
131+ end
132+
129133 local filename = selection .filename or ' unknown'
130134 local filetype = selection .filetype or ' text'
131135 local content = selection .content
@@ -171,9 +175,13 @@ local function generate_selection_messages(selection)
171175end
172176
173177--- Generate messages for the given embeddings
174- --- @param embeddings table<CopilotChat.context.embed>
178+ --- @param embeddings table<CopilotChat.context.embed> ?
175179--- @return table<CopilotChat.Provider.input>
176180local function generate_embeddings_messages (embeddings )
181+ if not embeddings then
182+ return {}
183+ end
184+
177185 return vim .tbl_map (function (embedding )
178186 local out = string.format (
179187 ' # FILE:%s CONTEXT\n ```%s\n %s\n ```' ,
@@ -459,34 +467,26 @@ function Client:ask(prompt, opts)
459467 opts .agent = nil
460468 end
461469
462- local contexts = opts .contexts
463- local embeddings = opts .embeddings or {}
464- local selection = opts .selection or {}
465- local system_prompt = opts .system_prompt
466- local model = opts .model
467- local agent = opts .agent
468- local temperature = opts .temperature
469- local on_progress = opts .on_progress
470470 local job_id = utils .uuid ()
471471
472- log .debug (' Model:' , model )
473- log .debug (' Agent:' , agent )
472+ log .debug (' Model:' , opts . model )
473+ log .debug (' Agent:' , opts . agent )
474474
475475 local models = self :fetch_models ()
476- local model_config = models [model ]
476+ local model_config = models [opts . model ]
477477 if not model_config then
478- error (' Model not found: ' .. model )
478+ error (' Model not found: ' .. opts . model )
479479 end
480480
481481 local agents = self :fetch_agents ()
482- local agent_config = agent and agents [agent ]
483- if agent and not agent_config then
484- error (' Agent not found: ' .. agent )
482+ local agent_config = opts . agent and agents [opts . agent ]
483+ if opts . agent and not agent_config then
484+ error (' Agent not found: ' .. opts . agent )
485485 end
486486
487487 local provider_name = model_config .provider
488488 if not provider_name then
489- error (' Provider not found for model: ' .. model )
489+ error (' Provider not found for model: ' .. opts . model )
490490 end
491491 local provider = self .providers [provider_name ]
492492 if not provider then
@@ -500,7 +500,7 @@ function Client:ask(prompt, opts)
500500 agent = agent_config and vim .tbl_extend (' force' , agent_config , {
501501 id = opts .agent and opts .agent :gsub (' :' .. provider_name .. ' $' , ' ' ),
502502 }),
503- temperature = temperature ,
503+ temperature = opts . temperature ,
504504 }
505505
506506 local max_tokens = model_config .max_input_tokens
@@ -521,8 +521,8 @@ function Client:ask(prompt, opts)
521521
522522 local references = utils .ordered_map ()
523523 local generated_messages = {}
524- local selection_messages = generate_selection_messages (selection )
525- local embeddings_messages = generate_embeddings_messages (embeddings )
524+ local selection_messages = generate_selection_messages (opts . selection )
525+ local embeddings_messages = generate_embeddings_messages (opts . embeddings )
526526
527527 for _ , message in ipairs (selection_messages ) do
528528 table.insert (generated_messages , message )
@@ -541,7 +541,7 @@ function Client:ask(prompt, opts)
541541
542542 -- Count required tokens that we cannot reduce
543543 local prompt_tokens = tiktoken .count (prompt )
544- local system_tokens = tiktoken .count (system_prompt )
544+ local system_tokens = tiktoken .count (opts . system_prompt )
545545 local memory_tokens = self .memory and tiktoken .count (self .memory .content ) or 0
546546 local required_tokens = prompt_tokens + system_tokens + selection_tokens + memory_tokens
547547
@@ -560,7 +560,7 @@ function Client:ask(prompt, opts)
560560 -- If we're over history limit, trigger summarization
561561 if history_tokens > history_limit then
562562 if opts .store_history and # history >= 4 then
563- self :summarize_history (model )
563+ self :summarize_history (opts . model )
564564
565565 -- Recalculate history and tokens
566566 history =
@@ -611,12 +611,12 @@ function Client:ask(prompt, opts)
611611 local last_message = nil
612612 local errored = false
613613 local finished = false
614- local full_response = ' '
614+ local response_buffer = utils . string_buffer ()
615615
616616 local function finish_stream (err , job )
617617 if err then
618618 errored = true
619- full_response = err
619+ response_buffer : set ( err )
620620 end
621621
622622 log .debug (' Finishing stream' , err )
@@ -657,9 +657,9 @@ function Client:ask(prompt, opts)
657657 end
658658
659659 if out .content then
660- full_response = full_response .. out .content
661- if on_progress then
662- on_progress (out .content )
660+ response_buffer : add ( out .content )
661+ if opts . on_progress then
662+ opts . on_progress (out .content )
663663 end
664664 end
665665
@@ -714,7 +714,14 @@ function Client:ask(prompt, opts)
714714
715715 local headers = self :authenticate (provider_name )
716716 local request = provider .prepare_input (
717- generate_ask_request (history , self .memory , contexts , prompt , system_prompt , generated_messages ),
717+ generate_ask_request (
718+ history ,
719+ self .memory ,
720+ opts .contexts ,
721+ prompt ,
722+ opts .system_prompt ,
723+ generated_messages
724+ ),
718725 options
719726 )
720727 local is_stream = request .stream
@@ -761,13 +768,17 @@ function Client:ask(prompt, opts)
761768 return
762769 end
763770
771+ local response_text = response_buffer :tostring ()
772+ log .trace (' Response text:\n ' , response_text )
773+ log .debug (' Response message:\n ' , vim .inspect (last_message ))
774+
764775 if errored then
765- error (full_response )
776+ error (response_text )
766777 return
767778 end
768779
769780 if is_stream then
770- if utils .empty (full_response ) then
781+ if utils .empty (response_text ) then
771782 for _ , line in ipairs (vim .split (response .body , ' \n ' )) do
772783 parse_stream_line (line )
773784 end
@@ -776,27 +787,24 @@ function Client:ask(prompt, opts)
776787 parse_line (response .body )
777788 end
778789
779- if utils .empty (full_response ) then
790+ if utils .empty (response_text ) then
780791 error (' Failed to get response: empty response' )
781792 return
782793 end
783794
784- log .trace (' Response content:\n ' , full_response )
785- log .debug (' Response message:\n ' , vim .inspect (last_message ))
786-
787795 if opts .store_history then
788796 table.insert (self .history , {
789797 content = prompt ,
790798 role = ' user' ,
791799 })
792800
793801 table.insert (self .history , {
794- content = full_response ,
802+ content = response_text ,
795803 role = ' assistant' ,
796804 })
797805 end
798806
799- return full_response ,
807+ return response_text ,
800808 references :values (),
801809 last_message and last_message .total_tokens or 0 ,
802810 max_tokens
0 commit comments