Jay V 8 mesi fa
parent
commit
1384a5e3e6

+ 73 - 0
packages/web/src/components/Share.tsx

@@ -16,6 +16,7 @@ import { IconOpenAI, IconGemini, IconAnthropic } from "./icons/custom"
 import {
   IconCpuChip,
   IconSparkles,
+  IconGlobeAlt,
   IconQueueList,
   IconUserCircle,
   IconChevronDown,
@@ -1283,6 +1284,78 @@ export default function Share(props: { api: string }) {
                             )
                           }}
                         </Match>
+                        {/* Fetch tool */}
+                        <Match
+                          when={
+                            msg.role === "assistant" &&
+                            part.type === "tool-invocation" &&
+                            part.toolInvocation.toolName === "opencode_webfetch" &&
+                            part
+                          }
+                        >
+                          {(part) => {
+                            const metadata = createMemo(() => msg.metadata?.tool[part().toolInvocation.toolCallId])
+                            const args = part().toolInvocation.args
+                            const url = args.url
+                            const format = args.format
+                            const hasError = metadata()?.error
+                            const result = part().toolInvocation.state === "result" && part().toolInvocation.result
+
+                            const duration = createMemo(() =>
+                              DateTime.fromMillis(metadata()?.time.end || 0).diff(
+                                DateTime.fromMillis(metadata()?.time.start || 0),
+                              ).toMillis(),
+                            )
+
+                            return (
+                              <div data-section="part" data-part-type="tool-fetch">
+                                <div data-section="decoration">
+                                  <div title="Web fetch">
+                                    <IconGlobeAlt width={18} height={18} />
+                                  </div>
+                                  <div></div>
+                                </div>
+                                <div data-section="content">
+                                  <div data-part-tool-body>
+                                    <span data-part-title data-size="md">
+                                      <span data-element-label>Fetch</span>
+                                      <b>{url}</b>
+                                    </span>
+                                    <Switch>
+                                      <Match when={hasError}>
+                                        <div data-part-tool-result>
+                                          <TextPart
+                                            expand
+                                            text={result}
+                                            data-size="sm"
+                                            data-color="dimmed"
+                                          />
+                                        </div>
+                                      </Match>
+                                      <Match when={result}>
+                                        <div data-part-tool-result>
+                                          <ResultsButton
+                                            results={results()}
+                                            onClick={() => showResults((e) => !e)}
+                                          />
+                                          <Show when={results()}>
+                                            <div data-part-tool-code>
+                                              <CodeBlock
+                                                lang={format || "text"}
+                                                code={result}
+                                              />
+                                            </div>
+                                          </Show>
+                                        </div>
+                                      </Match>
+                                    </Switch>
+                                  </div>
+                                  <ToolFooter time={duration()} />
+                                </div>
+                              </div>
+                            )
+                          }}
+                        </Match>
                         {/* Tool call */}
                         <Match
                           when={

+ 6 - 2
packages/web/src/components/share.module.css

@@ -316,7 +316,8 @@
 
   [data-part-type="tool-list"],
   [data-part-type="tool-glob"],
-  [data-part-type="tool-read"] {
+  [data-part-type="tool-read"],
+  [data-part-type="tool-fetch"] {
     & > [data-section="content"] > [data-part-tool-body] {
       gap: 0.5rem;
     }
@@ -349,7 +350,8 @@
     }
   }
 
-  [data-part-type="tool-read"] {
+  [data-part-type="tool-read"],
+  [data-part-type="tool-fetch"] {
     [data-part-tool-result] {
       [data-part-tool-code] {
         border: 1px solid var(--sl-color-divider);
@@ -359,6 +361,8 @@
         pre {
           line-height: 1.6;
           font-size: 0.75rem;
+          white-space: pre-wrap;
+          word-break: break-word;
         }
       }
     }