Skip to content

Commit

Permalink
feat(llms): first iteration, oracle search flow (#1311)
Browse files Browse the repository at this point in the history
  • Loading branch information
happylolonly authored Oct 2, 2024
1 parent 7f1ed2b commit 233c0f6
Show file tree
Hide file tree
Showing 22 changed files with 550 additions and 97 deletions.
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@
"workbox-webpack-plugin": "^7.1.0"
},
"dependencies": {
"@ai-sdk/openai": "^0.0.63",
"@apollo/client": "^3.9.4",
"@chainsafe/libp2p-noise": "^13.0.1",
"@chainsafe/libp2p-yamux": "^5.0.0",
Expand Down Expand Up @@ -172,6 +173,7 @@
"@milkdown/theme-nord": "^7.5.0",
"@multiformats/multiaddr": "^11.4.0",
"@nftstorage/ipfs-cluster": "^5.0.1",
"@openrouter/ai-sdk-provider": "^0.0.5",
"@reduxjs/toolkit": "^1.9.3",
"@storybook/addon-designs": "^7.0.4",
"@tableflip/react-inspector": "^2.3.0",
Expand All @@ -186,6 +188,7 @@
"@types/react-router-dom": "^5.3.3",
"@uniswap/sdk": "^3.0.3",
"@xenova/transformers": "^2.17.0",
"ai": "^3.4.7",
"apollo-boost": "^0.4.7",
"bech32": "^1.1.3",
"big.js": "^5.2.2",
Expand Down
2 changes: 1 addition & 1 deletion src/components/containerGradient/saber/index.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ $saber-border-width: 2px;
@if ($borderColor == 'color') {
border-#{$position}: $saber-border-width
solid
rgb(var(--color-r), var(--color-g), var(--color-b));
rgb(var(--color-r), var(--color-g), var(--color-b)) !important;
} @else {
border-#{$position}: $saber-border-width solid white;
}
Expand Down
35 changes: 35 additions & 0 deletions src/containers/Search/LLMSpark/LLMSpark.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
@import '../../../components/containerGradient/saber/index.module';

.wrapper {
position: relative;

* {
color: white;
}

> div:last-of-type {
@include saber('purple', left, 'color');
@include saber('purple', right, 'color');
}
}

.left,
.right {
position: absolute;
z-index: 1;
padding: 10px;
top: calc(45% - (40px / 2));
}

.left {
right: 100%;
display: flex;
align-items: center;
gap: 7px 10px;
font-size: 14px;
}

.right {
padding-top: 15px;
left: 100%;
}
126 changes: 126 additions & 0 deletions src/containers/Search/LLMSpark/LLMSpark.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
import { createOpenRouter } from '@openrouter/ai-sdk-provider';
import { useQuery } from '@tanstack/react-query';
import { generateText } from 'ai';
import { Link, useNavigate, useSearchParams } from 'react-router-dom';
import { Display } from 'src/components';
import useAddToIPFS from 'src/features/ipfs/hooks/useAddToIPFS';
import { routes } from 'src/routes';
import TextMarkdown from 'src/components/TextMarkdown';
import { useHover } from 'src/hooks/useHover';
import Loader2 from 'src/components/ui/Loader2';
import useGetIPFSHash from 'src/features/ipfs/hooks/useGetIPFSHash';
import { isCID } from 'src/utils/ipfs/helpers';
import { isDevEnv } from 'src/utils/dev';
import { testVar } from '.';
import styles from './LLMSpark.module.scss';

// WIP

const provider = createOpenRouter({
['a' + 'piK' + 'ey']: `sk-or-v1-${atob(testVar)}`,
});

const modelName = isDevEnv()
? 'meta-llama/llama-3-8b-instruct:free'
: 'openai/gpt-4o-mini';

const model = provider.chat(modelName);

export async function llmRequest(prompt) {
const { text } = await generateText({
model,
prompt,
});

return text;
}

function useLLMResponse(text) {
const { data, isLoading, error } = useQuery(
['llm', text],
async () => {
return llmRequest(`what is ${text}`);
},
{
enabled: Boolean(text),
}
);

return {
data,
isLoading,
error,
};
}

export function useIsLLMPageParam() {
const [searchParams] = useSearchParams();

const isLLM = searchParams.get('llm') === 'true';

return isLLM;
}

export function LLMAvatar() {
return (
<div
style={{
display: 'flex',
alignItems: 'center',
}}
>
<img
src="https://robohash.org/llama"
style={{
width: '20px',
height: '20px',
borderRadius: '50%',
marginRight: '5px',
}}
/>
{model.modelId}
</div>
);
}

function LLMSpark({ searchText }: { searchText: string }) {
const { data, isLoading } = useLLMResponse(searchText);
const { execute } = useAddToIPFS(data);

const [ref, hovering] = useHover();

const cid = useGetIPFSHash(data);

const navigate = useNavigate();

if (isCID(searchText)) {
return null;
}

return (
<Link
ref={ref}
className={styles.wrapper}
to={routes.oracle.ask.getLink(cid)}
onClick={async (e) => {
e.preventDefault();

const hash = await execute();

navigate(`${routes.oracle.ask.getLink(hash)}?llm=true`);
}}
>
{hovering && (
<div className={styles.left}>
<LLMAvatar />
</div>
)}
<Display color={isLoading ? 'yellow' : 'purple'}>
{isLoading && <Loader2 text="llm is generating response" />}
{data && <TextMarkdown preview>{data}</TextMarkdown>}
</Display>
</Link>
);
}

export default LLMSpark;
4 changes: 4 additions & 0 deletions src/containers/Search/LLMSpark/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
const var1 = 'NzFlZjJiOGVlZDRlNDYyOWNjZDY5YzQzZDljMjEwMzJhZGJhYmI5MGI1ZW';
const var2 = 'ZiMzBlZmVjMmRhZDE5MjNiODFmNQ';

export const testVar = var1 + var2;
36 changes: 24 additions & 12 deletions src/containers/Search/SearchResults.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import {
matchPath,
useLocation,
useNavigate,
useParams,
useSearchParams,
} from 'react-router-dom';
Expand All @@ -15,15 +14,17 @@ import { useDevice } from 'src/contexts/device';
import { IpfsContentType } from 'src/services/ipfs/types';

import useIsOnline from 'src/hooks/useIsOnline';
import { getSearchQuery } from 'src/utils/search/utils';
import { routes } from 'src/routes';
import { ActionBar, Button } from 'src/components';
import ActionBarContainer from './ActionBarContainer';
import Filters from './Filters/Filters';
import styles from './SearchResults.module.scss';
import FirstItems from './_FirstItems.refactor';
import { initialContentTypeFilterState } from './constants';
import { getSearchQuery } from 'src/utils/search/utils';
import useSearchData from './hooks/useSearchData';
import { LinksTypeFilter, SortBy } from './types';
import { routes } from 'src/routes';
import LLMSpark, { useIsLLMPageParam } from './LLMSpark/LLMSpark';

const sortByLSKey = 'search-sort';
const NEURON_SEARCH_KEY = 'neuron';
Expand All @@ -44,6 +45,8 @@ function SearchResults({
const [searchParams, setSearchParams] = useSearchParams();
const [neuron, setNeuron] = useState(searchParams.get(NEURON_SEARCH_KEY));

const isLLM = useIsLLMPageParam();

const location = useLocation();

const query = propQuery || q || cid || '';
Expand Down Expand Up @@ -189,6 +192,7 @@ function SearchResults({
/>

<div className={styles.search}>
{!isLLM && <LLMSpark searchText={query} />}
<FirstItems query={query} />

{isInitialLoading ? (
Expand All @@ -214,15 +218,23 @@ function SearchResults({

{!mobile && (
<div className={styles.actionBar}>
<ActionBarContainer
textBtn={actionBarTextBtn}
keywordHash={keywordHash}
update={() => {
refetch();
setRankLink(null);
}}
rankLink={rankLink}
/>
{isLLM ? (
<ActionBar>
<Button link={`${routes.studio.path}?cid=${keywordHash}`}>
Edit & Cyberlink
</Button>
</ActionBar>
) : (
<ActionBarContainer
textBtn={actionBarTextBtn}
keywordHash={keywordHash}
update={() => {
refetch();
setRankLink(null);
}}
rankLink={rankLink}
/>
)}
</div>
)}
</>
Expand Down
2 changes: 1 addition & 1 deletion src/containers/ipfs/IPFS.module.scss
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
.wrapper {
.particle {
min-height: 200px;
}
29 changes: 22 additions & 7 deletions src/containers/ipfs/components/AdviserMeta/AdviserMeta.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ import { timeSince, formatCurrency } from 'src/utils/utils';
import useRank from 'src/features/cyberlinks/rank/useRank';
import { Link } from 'react-router-dom';
import { routes } from 'src/routes';
import {
LLMAvatar,
useIsLLMPageParam,
} from 'src/containers/Search/LLMSpark/LLMSpark';
import useGetCreator from '../../hooks/useGetCreator';
import { PREFIXES } from '../metaInfo';
import styles from './AdviserMeta.module.scss';
Expand All @@ -17,6 +21,8 @@ function AdviserMeta({ cid, type, size }: Props) {
const { creator } = useGetCreator(cid);
const rank = useRank(cid);

const isLLM = useIsLLMPageParam();

return (
<div className={styles.meta}>
<div className={styles.left}>
Expand All @@ -38,14 +44,23 @@ function AdviserMeta({ cid, type, size }: Props) {
</div>
)}
</div>
{creator && (
<div className={styles.center}>
<span className={styles.date}>
{timeSince(Date.now() - Date.parse(creator.timestamp))} ago
</span>
<Account sizeAvatar="20px" address={creator.address} avatar />
</div>

{isLLM ? (
<LLMAvatar />
) : (
// eslint-disable-next-line react/jsx-no-useless-fragment
<>
{creator && (
<div className={styles.center}>
<span className={styles.date}>
{timeSince(Date.now() - Date.parse(creator.timestamp))} ago
</span>
<Account sizeAvatar="20px" address={creator.address} avatar />
</div>
)}
</>
)}

<div className={styles.right}>
<span>
🟥 {size ? formatCurrency(size, 'B', 0, PREFIXES) : 'unknown'}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
.wrapper {
max-width: 62%;
margin: 20px auto;
}

.itemLinks {
display: flex;
list-style-type: none;
justify-content: center;
font-size: 16px;
}

.itemText {
font-size: 14px;
display: block;
}

.itemLink {
margin: 0 5px;

// white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
max-width: 140px;
display: -webkit-box;
-webkit-line-clamp: 1;
-webkit-box-orient: vertical;
}
Loading

0 comments on commit 233c0f6

Please sign in to comment.