@@ -294,265 +294,6 @@ private struct StopRespondingButton: View {
294294 }
295295}
296296
297- private struct Instruction : View {
298- let chat : StoreOf < Chat >
299-
300- var body : some View {
301- Group {
302- Markdown (
303- """
304- You can use plugins to perform various tasks.
305-
306- | Plugin Name | Description |
307- | --- | --- |
308- | `/run` | Runs a command under the project root |
309- | `/math` | Solves a math problem in natural language |
310- | `/search` | Searches on Bing and summarizes the results |
311- | `/shortcut(name)` | Runs a shortcut from the Shortcuts.app, with the previous message as input |
312- | `/shortcutInput(name)` | Runs a shortcut and uses its result as a new message |
313-
314- To use plugins, you can prefix a message with `/pluginName`.
315- """
316- )
317- . modifier ( InstructionModifier ( ) )
318-
319- Markdown (
320- """
321- You can use scopes to give the bot extra abilities.
322-
323- | Scope Name | Abilities |
324- | --- | --- |
325- | `@file` | Read the metadata of the editing file |
326- | `@code` | Read the code and metadata in the editing file |
327- | `@sense`| Experimental. Read the relevant code of the focused editor |
328- | `@project` | Experimental. Access content of the project |
329- | `@web` (beta) | Search on Bing or query from a web page |
330-
331- To use scopes, you can prefix a message with `@code`.
332-
333- You can use shorthand to represent a scope, such as `@c`, and enable multiple scopes with `@c+web`.
334- """
335- )
336- . modifier ( InstructionModifier ( ) )
337-
338- WithViewStore ( chat, observe: \. chatMenu. defaultScopes) { viewStore in
339- Markdown (
340- """
341- Hello, I am your AI programming assistant. I can identify issues, explain and even improve code.
342-
343- \( {
344- if viewStore. state. isEmpty {
345- return " No scope is enabled by default "
346- } else {
347- let scopes = viewStore. state. map ( \. rawValue) . sorted ( )
348- . joined ( separator: " , " )
349- return " Default scopes: ` \( scopes) ` "
350- }
351- } ( ) )
352- """
353- )
354- . modifier ( InstructionModifier ( ) )
355- }
356- }
357- }
358-
359- struct InstructionModifier : ViewModifier {
360- @AppStorage ( \. chatFontSize) var chatFontSize
361-
362- func body( content: Content ) -> some View {
363- content
364- . textSelection ( . enabled)
365- . markdownTheme ( . custom( fontSize: chatFontSize) )
366- . opacity ( 0.8 )
367- . frame ( maxWidth: . infinity, alignment: . leading)
368- . padding ( )
369- . overlay {
370- RoundedRectangle ( cornerRadius: 8 )
371- . stroke ( Color ( nsColor: . separatorColor) , lineWidth: 1 )
372- }
373- }
374- }
375- }
376-
377- private struct UserMessage : View {
378- let id : String
379- let text : String
380- let chat : StoreOf < Chat >
381- @Environment ( \. colorScheme) var colorScheme
382- @AppStorage ( \. chatFontSize) var chatFontSize
383- @AppStorage ( \. chatCodeFontSize) var chatCodeFontSize
384-
385- var body : some View {
386- Markdown ( text)
387- . textSelection ( . enabled)
388- . markdownTheme ( . custom( fontSize: chatFontSize) )
389- . markdownCodeSyntaxHighlighter (
390- ChatCodeSyntaxHighlighter (
391- brightMode: colorScheme != . dark,
392- fontSize: chatCodeFontSize
393- )
394- )
395- . frame ( alignment: . leading)
396- . padding ( )
397- . background {
398- RoundedCorners ( tl: r, tr: r, bl: r, br: 0 )
399- . fill ( Color . userChatContentBackground)
400- }
401- . overlay {
402- RoundedCorners ( tl: r, tr: r, bl: r, br: 0 )
403- . stroke ( Color ( nsColor: . separatorColor) , lineWidth: 1 )
404- }
405- . padding ( . leading)
406- . padding ( . trailing, 8 )
407- . shadow ( color: . black. opacity ( 0.1 ) , radius: 2 )
408- . frame ( maxWidth: . infinity, alignment: . trailing)
409- . contextMenu {
410- Button ( " Copy " ) {
411- NSPasteboard . general. clearContents ( )
412- NSPasteboard . general. setString ( text, forType: . string)
413- }
414-
415- Button ( " Send Again " ) {
416- chat. send ( . resendMessageButtonTapped( id) )
417- }
418-
419- Button ( " Set as Extra System Prompt " ) {
420- chat. send ( . setAsExtraPromptButtonTapped( id) )
421- }
422-
423- Divider ( )
424-
425- Button ( " Delete " ) {
426- chat. send ( . deleteMessageButtonTapped( id) )
427- }
428- }
429- }
430- }
431-
432- private struct BotMessage : View {
433- let id : String
434- let text : String
435- let references : [ DisplayedChatMessage . Reference ]
436- let chat : StoreOf < Chat >
437- @Environment ( \. colorScheme) var colorScheme
438- @AppStorage ( \. chatFontSize) var chatFontSize
439- @AppStorage ( \. chatCodeFontSize) var chatCodeFontSize
440-
441- @State var isReferencesPresented = false
442- @State var isReferencesHovered = false
443-
444- var body : some View {
445- HStack ( alignment: . bottom, spacing: 2 ) {
446- VStack ( alignment: . leading, spacing: 16 ) {
447- if !references. isEmpty {
448- Button ( action: {
449- isReferencesPresented. toggle ( )
450- } , label: {
451- HStack ( spacing: 4 ) {
452- Image ( systemName: " plus.circle " )
453- Text ( " Used \( references. count) references " )
454- }
455- . padding ( 8 )
456- . background {
457- RoundedRectangle ( cornerRadius: r - 4 )
458- . foregroundStyle ( Color ( isReferencesHovered ? . black : . clear) )
459-
460- }
461- . overlay {
462- RoundedRectangle ( cornerRadius: r - 4 )
463- . stroke ( Color ( nsColor: . separatorColor) , lineWidth: 1 )
464- }
465- . foregroundStyle ( . secondary)
466- } )
467- . buttonStyle ( . plain)
468- . popover ( isPresented: $isReferencesPresented, arrowEdge: . trailing) {
469- ReferenceList ( references: references)
470- }
471- }
472-
473- Markdown ( text)
474- . textSelection ( . enabled)
475- . markdownTheme ( . custom( fontSize: chatFontSize) )
476- . markdownCodeSyntaxHighlighter (
477- ChatCodeSyntaxHighlighter (
478- brightMode: colorScheme != . dark,
479- fontSize: chatCodeFontSize
480- )
481- )
482- }
483- . frame ( alignment: . trailing)
484- . padding ( )
485- . background {
486- RoundedCorners ( tl: r, tr: r, bl: 0 , br: r)
487- . fill ( Color . contentBackground)
488- }
489- . overlay {
490- RoundedCorners ( tl: r, tr: r, bl: 0 , br: r)
491- . stroke ( Color ( nsColor: . separatorColor) , lineWidth: 1 )
492- }
493- . padding ( . leading, 8 )
494- . shadow ( color: . black. opacity ( 0.1 ) , radius: 2 )
495- . contextMenu {
496- Button ( " Copy " ) {
497- NSPasteboard . general. clearContents ( )
498- NSPasteboard . general. setString ( text, forType: . string)
499- }
500-
501- Button ( " Set as Extra System Prompt " ) {
502- chat. send ( . setAsExtraPromptButtonTapped( id) )
503- }
504-
505- Divider ( )
506-
507- Button ( " Delete " ) {
508- chat. send ( . deleteMessageButtonTapped( id) )
509- }
510- }
511-
512- CopyButton {
513- NSPasteboard . general. clearContents ( )
514- NSPasteboard . general. setString ( text, forType: . string)
515- }
516- }
517- . frame ( maxWidth: . infinity, alignment: . leading)
518- . padding ( . trailing, 2 )
519- }
520- }
521-
522- struct ReferenceList : View {
523- let references : [ DisplayedChatMessage . Reference ]
524- var body : some View {
525- ScrollView {
526- VStack {
527- ForEach ( 0 ..< references. endIndex, id: \. self) { index in
528- let reference = references [ index]
529- HStack ( spacing: 8 ) {
530- Text ( reference. title)
531- Text ( reference. subtitle)
532- . foregroundStyle ( . secondary)
533- }
534- }
535- }
536- . padding ( )
537- . frame ( maxHeight: 500 )
538- }
539- }
540- }
541-
542- struct FunctionMessage : View {
543- let id : String
544- let text : String
545- @AppStorage ( \. chatFontSize) var chatFontSize
546-
547- var body : some View {
548- Markdown ( text)
549- . textSelection ( . enabled)
550- . markdownTheme ( . functionCall( fontSize: chatFontSize) )
551- . padding ( . vertical, 2 )
552- . padding ( . trailing, 2 )
553- }
554- }
555-
556297struct ChatPanelInputArea : View {
557298 let chat : StoreOf < Chat >
558299 @FocusState var focusedField : Chat . State . Field ?
@@ -675,62 +416,6 @@ struct ChatPanelInputArea: View {
675416 }
676417}
677418
678- struct RoundedCorners : Shape {
679- var tl : CGFloat = 0.0
680- var tr : CGFloat = 0.0
681- var bl : CGFloat = 0.0
682- var br : CGFloat = 0.0
683-
684- func path( in rect: CGRect ) -> Path {
685- Path { path in
686-
687- let w = rect. size. width
688- let h = rect. size. height
689-
690- // Make sure we do not exceed the size of the rectangle
691- let tr = min ( min ( self . tr, h / 2 ) , w / 2 )
692- let tl = min ( min ( self . tl, h / 2 ) , w / 2 )
693- let bl = min ( min ( self . bl, h / 2 ) , w / 2 )
694- let br = min ( min ( self . br, h / 2 ) , w / 2 )
695-
696- path. move ( to: CGPoint ( x: w / 2.0 , y: 0 ) )
697- path. addLine ( to: CGPoint ( x: w - tr, y: 0 ) )
698- path. addArc (
699- center: CGPoint ( x: w - tr, y: tr) ,
700- radius: tr,
701- startAngle: Angle ( degrees: - 90 ) ,
702- endAngle: Angle ( degrees: 0 ) ,
703- clockwise: false
704- )
705- path. addLine ( to: CGPoint ( x: w, y: h - br) )
706- path. addArc (
707- center: CGPoint ( x: w - br, y: h - br) ,
708- radius: br,
709- startAngle: Angle ( degrees: 0 ) ,
710- endAngle: Angle ( degrees: 90 ) ,
711- clockwise: false
712- )
713- path. addLine ( to: CGPoint ( x: bl, y: h) )
714- path. addArc (
715- center: CGPoint ( x: bl, y: h - bl) ,
716- radius: bl,
717- startAngle: Angle ( degrees: 90 ) ,
718- endAngle: Angle ( degrees: 180 ) ,
719- clockwise: false
720- )
721- path. addLine ( to: CGPoint ( x: 0 , y: tl) )
722- path. addArc (
723- center: CGPoint ( x: tl, y: tl) ,
724- radius: tl,
725- startAngle: Angle ( degrees: 180 ) ,
726- endAngle: Angle ( degrees: 270 ) ,
727- clockwise: false
728- )
729- path. closeSubpath ( )
730- }
731- }
732- }
733-
734419// MARK: - Previews
735420
736421struct ChatPanel_Preview : PreviewProvider {
0 commit comments