Skip to content

Commit

Permalink
Merge branch 'dev' into landing-iterate
Browse files Browse the repository at this point in the history
  • Loading branch information
confxsd authored Jun 27, 2024
2 parents 0367f82 + aac8438 commit f32258b
Show file tree
Hide file tree
Showing 11 changed files with 98 additions and 67 deletions.
27 changes: 19 additions & 8 deletions api/src/agents/basic_assistant.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,17 +33,28 @@ export const handleUserMessage = async (
});

try {
// Find the index of the item with the specific id
const questionIndex = messages.findIndex((m) => m.id === message.id);

// If the item is found, filter out the item and all subsequent items
const chat_history =
questionIndex !== -1
? messages.filter((_, index) => index <= questionIndex)
: messages;

const chatRequest = {
indexIds: reqIndexIds,
input: {
question: messages.at(-1).content,
chat_history: messages.slice(0, -1).map((c) => {
return {
id: c.id,
role: c.role,
content: c.content,
};
}),
question: messages[questionIndex].content,
chat_history: chat_history
.filter((m) => m.id !== message.id)
.map((c) => {
return {
id: c.id,
role: c.role,
content: c.content,
};
}),
},
};
let resp = await axios.post(
Expand Down
11 changes: 11 additions & 0 deletions api/src/libs/indexer.js
Original file line number Diff line number Diff line change
Expand Up @@ -359,14 +359,25 @@ class Indexer {
if (!message) {
return;
}

// Only listen user mesages for now.
if (
message.role === `assistant` &&
message.controllerDID.id === agentDID.id
) {
return;
}

const conversation = await conversationService.getConversation(
message.conversationId,
);
if (!conversation) {
return;
}
message.conversation = conversation;

if (
message &&
message.role === `user` &&
message.content &&
message.content.length > 0
Expand Down
6 changes: 6 additions & 0 deletions api/src/services/did.js
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,12 @@ export class DIDService {
const wallet = did.split(":").slice(-1).pop();
const ensProfile = await getENSProfileByWallet(wallet);
if (ensProfile) {
if (ensProfile.image && ensProfile.image.startsWith(`ipfs://`)) {
ensProfile.image = ensProfile.image.replace(
`ipfs://`,
`https://ipfs.io/ipfs/`,
);
}
return {
id: did,
name: ensProfile.ensName,
Expand Down
14 changes: 14 additions & 0 deletions api/src/services/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ export class IndexService {
});
index.did = did;
}
index.hasItems =
index.items && index.items.edges && index.items.edges.length > 0;
delete index.items;

index.controllerDID = await this.didService.getProfile(
index.controllerDID.id,
Expand Down Expand Up @@ -84,6 +87,17 @@ export class IndexService {
createdAt
updatedAt
deletedAt
items(first:1, filters: {
where: {
deletedAt: {isNull: true}
}
}) {
edges {
node {
id
}
}
}
controllerDID {
id
profile {
Expand Down
9 changes: 7 additions & 2 deletions indexer/src/chat/controller/chat.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,13 @@ export class ChatController {
Logger.log(`Processing ${JSON.stringify(body)}`, 'chatController:stream');
const stream = await this.chatService.stream(body);

for await (const chunk of stream) {
chunk.answer && res.write(chunk.answer);
if (stream && stream[Symbol.asyncIterator]) {
for await (const chunk of stream) {
chunk.answer && res.write(chunk.answer);
}
} else {
console.log(JSON.stringify(body));
throw new TypeError('Stream is not an async iterable');
}

res.end();
Expand Down
46 changes: 19 additions & 27 deletions web-app/src/app/[...id]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,15 @@ import IndexConversationSection from "components/sections/IndexConversation";
import UserConversationSection from "components/sections/UserConversation";
import "./app.css";
import { useEffect } from "react";
import { useAuth } from "@/context/AuthContext";
import { useAppSelector } from "@/store/store";
import { useAppDispatch, useAppSelector } from "@/store/store";
import { selectView } from "@/store/slices/appViewSlice";
import { selectIndex } from "@/store/slices/indexSlice";
import { selectConversation } from "@/store/slices/conversationSlice";
import { selectDID } from "@/store/slices/didSlice";
import { toggleUserIndex } from "@/store/api";

const Discovery = () => {
const { api: apiService, ready: apiReady } = useApi();
const { session } = useAuth();
const view = useAppSelector(selectView);
const index = useAppSelector(selectIndex);
const did = useAppSelector(selectDID);
const conversation = useAppSelector(selectConversation);

const dispatch = useAppDispatch();

useEffect(() => {
if (typeof window !== "undefined") {
Expand All @@ -34,34 +29,31 @@ const Discovery = () => {

useEffect(() => {
if (typeof window !== "undefined") {
if (!apiReady || !session) return;

if (!apiReady || !apiService) return;
const isFirstLogin = localStorage.getItem("isFirstLogin") === null;
const isMainnet =
process.env.NEXT_PUBLIC_API_URL === "https://index.network/api";

if (isFirstLogin) {
if (isMainnet && isFirstLogin) {
localStorage.setItem("isFirstLogin", "false");
} else {
return;
}

if (isMainnet) {
apiService?.starIndex(
const indexes = [
"kjzl6kcym7w8y6b1fncbo7p7h2v6tei9llby5ai9n7wj09oy1aeae7hqsc1io0j",
true,
);
apiService?.starIndex(
"kjzl6kcym7w8y63ksezbl4z1frr3xd0d9fg6nfmuwr1n0ue2xc4j7dtejvl4527",
true,
);
apiService?.starIndex(
"kjzl6kcym7w8y8lefkkbpl44q6jh1zu78gaq2zp18we4wdgz1tz9vxyx213ochh",
true,
);
];
indexes.forEach((indexID) => {
dispatch(
toggleUserIndex({
indexID,
api: apiService,
toggleType: "star",
value: true,
}),
);
});
}
}
}, [session, apiReady]);
}, [apiService, apiReady, dispatch]);

return (
<DiscoveryLayout>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,21 +28,19 @@ const TAB_TITLES = {

export default function TabContainer() {
const [tabKey, setTabKey] = useState<string>(TabKey.Chat);
const { id, items, loading } = useAppSelector(selectIndex);
const { data: indexData, loading } = useAppSelector(selectIndex);

useEffect(() => {
if (!items) return;
if (!indexData) return;

if (loading) {
return;
}

if (items.data && items.data.length === 0) {
if (!indexData.hasItems) {
setTabKey(TabKey.Index);
} else {
setTabKey(TabKey.Chat);
}
}, [items, loading]);
}, [loading, indexData]);

const renderTabContent = useCallback(() => {
switch (tabKey) {
Expand Down
3 changes: 0 additions & 3 deletions web-app/src/components/sections/landing/BigText.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
import Header from "@/components/base/Header";
import Freizeit from "@/fonts/loader";

const BigTextSection = () => {
return (
<section className="mb-8 mt-8">
Expand Down
4 changes: 0 additions & 4 deletions web-app/src/components/sections/landing/Hero.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,6 @@ const HeroSection = () => {
</div>

<div className="lg:pt-32 font-secondary z-10 flex flex-col items-center justify-center gap-4 px-8 text-center lg:w-[575px] lg:items-start lg:px-0 lg:pr-6 ">
{/* <h1 className="hidden md:block md:text-center lg:text-start font-title text-[1.9rem] leading-[2.25rem] md:text-5xl md:leading-[4rem]">
The First Discovery Protocol <br /> for{" "}
<span className="text-highlightBlue">{typingText}|</span>
</h1> */}
<h1 className="font-title text-center lg:text-start text-[1.9rem] leading-[2.25rem] md:text-4xl lg:text-5xl lg:leading-[3.6rem]">
The First <br />
Discovery Protocol <br /> for{" "}
Expand Down
32 changes: 16 additions & 16 deletions web-app/src/components/sections/landing/HowItWorks/data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,15 @@ const data = [
<br/>
Your index functions as a decentralized vector database, enabling natural language interactions.`,
codeBlock: `const index = await client.createIndex({
  title: "Publishing"
title: "Publishing"
});
const doc = await client.createDocument({
  title: "The future of publishing",
  body: "Publishers of all types, from news to music,
are unhappy that consumers won't pay for content
anymore. At least, that's how they see it."
title: "The future of publishing",
body: "Publishers of all types, from news to music,
are unhappy that consumers won't pay for
content anymore. At least, that's how they
see it."
});
await index.addItem(doc.id);
Expand All @@ -25,9 +26,10 @@ await index.addItem(doc.id);
content: `Query multiple indexes using natural language with any model to get knowledge-linked responses.
<br/>
<br/>
Compose your queries with other indexes for memory, intent, knowledge, social and identity graphs.<br/>
<br/>Share your index with your audience, allowing them to explore and discover your knowledge.
`,
Compose your queries with other indexes for memory, intent, knowledge, social and identity graphs.
<br/>
<br/>
Share your index with your audience, allowing them to explore and discover your knowledge.`,
codeBlock: `const response = await client.query({
sources: [
"did:ens:mainnet:index.eth",
Expand All @@ -40,9 +42,8 @@ await index.addItem(doc.id);
},
{
content: `Invite both agents and other users into conversations, bring multiple agents to cooperate and compete for relevance.
<br /><br />Start private conversations, which will be stored encrypted with blockchain-backed privacy.
<br /><br />Start public conversations that are discoverable by other other people's conversations or anywhere else it is contextually relevant.
`,
<br /><br />Start private conversations, which will be stored encrypted with blockchain-backed privacy.
<br /><br />Start public conversations that are discoverable by other people's conversations or anywhere else it is contextually relevant.`,
codeBlock: `const conversation = await client.createConversation({
sources: [
"did:ens:mainnet:index.eth",
Expand All @@ -62,11 +63,10 @@ conversation.listen((message) => {
`,
},
{
content: `Start contextual subscriptions, listen events in indexes using natural language.
<br />
<br /> The event-driven architecture creates a reactive environment for agents, allowing them to hear and respond to each other.
`,
codeBlock: `await client.listenIndexUpdates({
content: `Start contextual subscriptions, listen to events in indexes using natural language.
<br />
<br />The event-driven architecture creates a reactive environment for agents, allowing them to hear and respond to each other.`,
codeBlock: `await client.listen({
sources: [
"did:ens:mainnet:index.eth",
"did:ens:mainnet:vitalik.eth",
Expand Down
3 changes: 2 additions & 1 deletion web-app/src/store/slices/indexSlice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ const indexSlice = createSlice({
state.loading = true;
})
.addCase(fetchIndex.fulfilled, (state, action) => {
// state.loading = false;
state.loading = false;
state.data = action.payload;
})
.addCase(fetchIndex.rejected, (state, action) => {
Expand Down Expand Up @@ -80,6 +80,7 @@ const indexSlice = createSlice({
})
.addCase(addItem.fulfilled, (state, action) => {
state.items.data.push(action.payload);
state.data.hasItems = true;
state.addItemLoading = false;
})
.addCase(addItem.rejected, (state, action) => {
Expand Down

0 comments on commit f32258b

Please sign in to comment.