Vokturz commited on
Commit
d26ad91
·
1 Parent(s): bd85b1e

Enhancing modelcode modal

Browse files
public/javascript-logo.svg ADDED
public/python-logo.svg ADDED
src/components/ModelCode.tsx CHANGED
@@ -1,8 +1,9 @@
1
- import { ExternalLink } from 'lucide-react'
2
  import Modal from './Modal'
3
  import MarkdownRenderer from './MarkdownRenderer'
4
  import { useModel } from '@/contexts/ModelContext'
5
- import { useTextGeneration } from '@/contexts/TextGenerationContext'
 
6
 
7
  interface ModelCodeProps {
8
  isCodeModalOpen: boolean
@@ -10,6 +11,7 @@ interface ModelCodeProps {
10
  }
11
 
12
  const ModelCode = ({ isCodeModalOpen, setIsCodeModalOpen }: ModelCodeProps) => {
 
13
  const { modelInfo, pipeline, selectedQuantization } = useModel()
14
  if (!modelInfo) return null
15
 
@@ -31,6 +33,7 @@ const ModelCode = ({ isCodeModalOpen, setIsCodeModalOpen }: ModelCodeProps) => {
31
  let classType = 'classifier'
32
  let exampleData = 'I love this product!'
33
  let config = {}
 
34
  switch (pipeline) {
35
  case 'text-classification':
36
  classType = 'classifier'
@@ -58,7 +61,7 @@ const ModelCode = ({ isCodeModalOpen, setIsCodeModalOpen }: ModelCodeProps) => {
58
  break
59
  case 'feature-extraction':
60
  classType = 'generator'
61
- exampleData = 'I love this product!'
62
  config = {
63
  pooling: 'mean',
64
  normalize: true
@@ -73,7 +76,7 @@ const ModelCode = ({ isCodeModalOpen, setIsCodeModalOpen }: ModelCodeProps) => {
73
  break
74
  }
75
 
76
- const code = `import { pipeline } from '@huggingface/transformers';
77
 
78
  const ${classType} = pipeline('${pipeline}', '${modelInfo.name}', {
79
  dtype: '${selectedQuantization}',
@@ -83,7 +86,30 @@ const result = await ${classType}('${exampleData}', ${JSON.stringify(config, nul
83
  console.log(result);
84
  `
85
 
86
- console.log(modelInfo.widgetData)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
87
 
88
  return (
89
  <>
@@ -94,19 +120,68 @@ console.log(result);
94
  maxWidth="5xl"
95
  >
96
  <div className="text-sm max-w-none px-4">
97
- <MarkdownRenderer content={`\`\`\`typescript\n${code}\n\`\`\``} />
98
- </div>
99
- {/* More information link */}
100
- <div className="mt-4">
101
- <a
102
- className="text-blue-500 hover:underline"
103
- href={`https://huggingface.co/${modelInfo.name}`}
104
- target="_blank"
105
- rel="noopener noreferrer"
106
- >
107
- Learn more about this model on Hugging Face
108
- </a>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
109
  </div>
 
 
 
 
 
 
 
 
110
  </Modal>
111
  </>
112
  )
 
1
+ import { Copy, CopyCheck, ExternalLink, Link } from 'lucide-react'
2
  import Modal from './Modal'
3
  import MarkdownRenderer from './MarkdownRenderer'
4
  import { useModel } from '@/contexts/ModelContext'
5
+ import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert'
6
+ import { useState } from 'react'
7
 
8
  interface ModelCodeProps {
9
  isCodeModalOpen: boolean
 
11
  }
12
 
13
  const ModelCode = ({ isCodeModalOpen, setIsCodeModalOpen }: ModelCodeProps) => {
14
+ const [isCopied, setIsCopied] = useState(false)
15
  const { modelInfo, pipeline, selectedQuantization } = useModel()
16
  if (!modelInfo) return null
17
 
 
33
  let classType = 'classifier'
34
  let exampleData = 'I love this product!'
35
  let config = {}
36
+
37
  switch (pipeline) {
38
  case 'text-classification':
39
  classType = 'classifier'
 
61
  break
62
  case 'feature-extraction':
63
  classType = 'generator'
64
+ exampleData = 'This is a simple test'
65
  config = {
66
  pooling: 'mean',
67
  normalize: true
 
76
  break
77
  }
78
 
79
+ const jsCode = `import { pipeline } from '@huggingface/transformers';
80
 
81
  const ${classType} = pipeline('${pipeline}', '${modelInfo.name}', {
82
  dtype: '${selectedQuantization}',
 
86
  console.log(result);
87
  `
88
 
89
+ const configPython = Object.entries(config)
90
+ .map(
91
+ ([key, value]) =>
92
+ `${key}=${value === true ? 'True' : typeof value === 'string' ? "'" + value + "'" : value}`
93
+ )
94
+ .join(', ')
95
+
96
+ const pythonCode = `from transformers import pipeline
97
+
98
+ ${classType} = pipeline("${pipeline}", model="${modelInfo.name}")
99
+ result = ${classType}("${exampleData}", ${configPython})
100
+ print(result)
101
+ `
102
+
103
+ const copyToClipboard = (text: string) => {
104
+ navigator.clipboard.writeText(text)
105
+ setIsCopied(true)
106
+ setTimeout(() => setIsCopied(false), 2000)
107
+ }
108
+
109
+ const pipelineName = pipeline
110
+ .split('-')
111
+ .map((word, index) => word.charAt(0).toUpperCase() + word.slice(1))
112
+ .join('')
113
 
114
  return (
115
  <>
 
120
  maxWidth="5xl"
121
  >
122
  <div className="text-sm max-w-none px-4">
123
+ <div className="flex flex-row">
124
+ <img src="/javascript-logo.svg" className="w-6 h-6 mr-1 rounded" />
125
+ <h2 className="text-lg font-medium mb-2">Javascript</h2>
126
+ </div>
127
+ <div className="flex flex-row items-center text-sm hover:underline text-foreground/60">
128
+ <Link className="h-3 w-3 mr-2" />
129
+ <a
130
+ href={`https://huggingface.co/docs/transformers.js/api/pipelines#pipelines${pipeline.replace(/-/g, '')}pipeline`}
131
+ target="_blank"
132
+ rel="noopener noreferrer"
133
+ >
134
+ Read about {pipeline} Pipeline Documentation for Javascript
135
+ </a>
136
+ </div>
137
+ <div className="relative">
138
+ <div className="absolute right-0 top-0 mt-2 mr-2">
139
+ <button
140
+ onClick={() => copyToClipboard(jsCode)}
141
+ className="text-gray-500 hover:text-gray-700 p-1 text-xs"
142
+ >
143
+ <Copy className="w-4 h-4" />
144
+ </button>
145
+ </div>
146
+ <MarkdownRenderer content={`\`\`\`javascript\n${jsCode}\n\`\`\``} />
147
+ </div>
148
+
149
+ <div className="mt-6">
150
+ <div className="flex flex-row">
151
+ <img src="/python-logo.svg" className="w-6 h-6 mr-1" />
152
+ <h2 className="text-lg font-medium mb-2">Python</h2>
153
+ </div>
154
+ <a
155
+ className="text-sm hover:underline text-foreground/60"
156
+ href={`https://huggingface.co/docs/transformers/en/main_classes/pipelines#transformers.${pipelineName}Pipeline`}
157
+ target="_blank"
158
+ rel="noopener noreferrer"
159
+ >
160
+ Read about {pipeline} Pipeline Documentation for Python
161
+ </a>
162
+ <div className="relative">
163
+ <div className="absolute right-0 top-0 mt-2 mr-2">
164
+ <button
165
+ onClick={() => copyToClipboard(pythonCode)}
166
+ className="text-gray-500 hover:text-gray-700 p-1 text-xs"
167
+ >
168
+ <Copy className="w-4 h-4" />
169
+ </button>
170
+ </div>
171
+ <MarkdownRenderer
172
+ content={`\`\`\`python\n${pythonCode}\n\`\`\``}
173
+ />
174
+ </div>
175
+ </div>
176
  </div>
177
+ {isCopied && (
178
+ <div className="absolute top-2 left-1/2 transform -translate-x-1/2">
179
+ <Alert>
180
+ <CopyCheck className="w-4 h-4 opacity-60" />
181
+ <AlertDescription>Copied!</AlertDescription>
182
+ </Alert>
183
+ </div>
184
+ )}
185
  </Modal>
186
  </>
187
  )
src/components/ui/alert.tsx ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import * as React from 'react'
2
+ import { cva, type VariantProps } from 'class-variance-authority'
3
+
4
+ import { cn } from '@/lib/utils'
5
+
6
+ const alertVariants = cva(
7
+ 'relative w-full rounded-lg border px-4 py-3 text-sm grid has-[>svg]:grid-cols-[calc(var(--spacing)*4)_1fr] grid-cols-[0_1fr] has-[>svg]:gap-x-3 gap-y-0.5 items-start [&>svg]:size-4 [&>svg]:translate-y-0.5 [&>svg]:text-current',
8
+ {
9
+ variants: {
10
+ variant: {
11
+ default: 'bg-background text-card-foreground',
12
+ destructive:
13
+ 'text-destructive bg-background [&>svg]:text-current *:data-[slot=alert-description]:text-destructive/90'
14
+ }
15
+ },
16
+ defaultVariants: {
17
+ variant: 'default'
18
+ }
19
+ }
20
+ )
21
+
22
+ function Alert({
23
+ className,
24
+ variant,
25
+ ...props
26
+ }: React.ComponentProps<'div'> & VariantProps<typeof alertVariants>) {
27
+ return (
28
+ <div
29
+ data-slot="alert"
30
+ role="alert"
31
+ className={cn(alertVariants({ variant }), className)}
32
+ {...props}
33
+ />
34
+ )
35
+ }
36
+
37
+ function AlertTitle({ className, ...props }: React.ComponentProps<'div'>) {
38
+ return (
39
+ <div
40
+ data-slot="alert-title"
41
+ className={cn(
42
+ 'col-start-2 line-clamp-1 min-h-4 font-medium tracking-tight',
43
+ className
44
+ )}
45
+ {...props}
46
+ />
47
+ )
48
+ }
49
+
50
+ function AlertDescription({
51
+ className,
52
+ ...props
53
+ }: React.ComponentProps<'div'>) {
54
+ return (
55
+ <div
56
+ data-slot="alert-description"
57
+ className={cn(
58
+ 'text-muted-foreground col-start-2 grid justify-items-start gap-1 text-sm [&_p]:leading-relaxed',
59
+ className
60
+ )}
61
+ {...props}
62
+ />
63
+ )
64
+ }
65
+
66
+ export { Alert, AlertTitle, AlertDescription }
src/index.css CHANGED
@@ -87,7 +87,7 @@ code {
87
  --radius: 0.625rem;
88
  --background: oklch(0.98 0.01 220);
89
  --foreground: oklch(0.145 0 0);
90
- --card: oklch(1 0 0);
91
  --card-foreground: oklch(0.145 0 0);
92
  --popover: oklch(1 0 0);
93
  --popover-foreground: oklch(0.145 0 0);
@@ -125,7 +125,7 @@ code {
125
  .dark {
126
  --background: oklch(0.12 0.02 260);
127
  --foreground: oklch(0.985 0 0);
128
- --card: oklch(0.18 0.03 260);
129
  --card-foreground: oklch(0.985 0 0);
130
  --popover: oklch(0.18 0.03 260);
131
  --popover-foreground: oklch(0.985 0 0);
 
87
  --radius: 0.625rem;
88
  --background: oklch(0.98 0.01 220);
89
  --foreground: oklch(0.145 0 0);
90
+ --card: oklch(0.7 0.12 260);
91
  --card-foreground: oklch(0.145 0 0);
92
  --popover: oklch(1 0 0);
93
  --popover-foreground: oklch(0.145 0 0);
 
125
  .dark {
126
  --background: oklch(0.12 0.02 260);
127
  --foreground: oklch(0.985 0 0);
128
+ --card: oklch(0.7 0.12 260);
129
  --card-foreground: oklch(0.985 0 0);
130
  --popover: oklch(0.18 0.03 260);
131
  --popover-foreground: oklch(0.985 0 0);