# Welcome to Cortex

Customizing AI copilots for your specific use cases

## Overview

**Cortex** is a powerful AI application development platform that allows anyone to create customized AI assistants for themselves or their users. Cortex is built with three design principles in mind:

1. **Personalize**: Create custom AI assistants tailored to each team's unique needs.
2. **Streamline**: Provide a robust environment ready for immediate deployment and scalable growth.
3. **Safeguard**: Maintain an unwavering commitment to data privacy.

If you are a non-developer, look into [Copilot](/fundamentals/copilot). If you are a developer, look into [Callable](/fundamentals/callable).&#x20;

## Get Started

We've put together some helpful guides for you to get setup with our product quickly and easily.

{% content-ref url="/pages/B4JPZCz94oNC1kNGnfXf" %}
[Making your first Copilot](/product-guides/making-your-first-copilot)
{% endcontent-ref %}

{% content-ref url="/pages/3rXYGale4wcCXeKq8BMZ" %}
[Making your first Callable](/product-guides/making-your-first-callable)
{% endcontent-ref %}

## Quick links

{% content-ref url="/pages/21HxFlQyzDYdwcypgfPI" %}
[Understanding Cortex Architecture](/overview/understanding-cortex-architecture)
{% endcontent-ref %}

{% content-ref url="/pages/YEJtHvOajezWcGSn60H2" %}
[Callable](/fundamentals/callable)
{% endcontent-ref %}


# Understanding Cortex Architecture

## How Cortex work

**Cortex** can be seen as having three layers

* **Callable:** The infrastructure that handles all LLM-based workflows. It follows serverless function architecture (like AWS Lambda) that enables maximum scalability&#x20;
* **Knowledge:** Managed vector database for fast information retrieval and near real-time syncing
* **Client Interface**
  * **Copilot:** is a managed UI that enables end-users to conveniently interact with AI applications
  * **API:** API and SDK clients are provided to support developers who wish to directly interact with their callables to power their own products

<figure><img src="https://3035252822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FeiBCAl6qTuG0sZpeXLxC%2Fuploads%2FMF7Dsxo4rxK9X6gShV5r%2Fimage.png?alt=media&amp;token=dfc6c313-9447-4cb4-ab1f-bbd775707ff5" alt=""><figcaption></figcaption></figure>

### A Basic Workflow

When the end user interacts with a **Copilot**, a few things happen in the background:

1. Cortex Copilot client compiles users' input into a standard format defined by its UI standard protocol and includes session history. Since Callable is designed to be stateless and serverless, the copilot server will be responsible to store the history.&#x20;
2. The Copilot client sends an API request to a specific Callable
3. The Callable is triggered and performs its predefined programming.&#x20;
   1. The Callable interacts with Knowledge to retrieve relevant information
   2. The Callable sends requests to the language model services
4. The Callable returns a response in a predefined format to Copilot, and Copilot displays the messages to users.


# Making your first Copilot

Copilots are UI-based AI assistants that are designed for **non-developers** to create their own customizable AI assistants. This tutorial guides you through the process!

## 1. Create a knowledge

One of the powerful features of Cortex is to let AI interact with your own data. Knowledge is where you store your data.&#x20;

Head to the knowledge tab here and create a knowledge

<figure><img src="https://3035252822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FeiBCAl6qTuG0sZpeXLxC%2Fuploads%2FWmqIxvo1cYYq3RJEBmiB%2Fimage.png?alt=media&amp;token=a4a20526-f2b6-43c9-9ea2-599c251067d6" alt=""><figcaption></figcaption></figure>

Cortex supports multiple upload options. You can directly upload your pdf, or Word doc, give the URLs of a particular website or connect with third-party applications like Notion and Slack, and we will sync up the knowledge automatically.&#x20;

<figure><img src="https://3035252822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FeiBCAl6qTuG0sZpeXLxC%2Fuploads%2FpA33atprke40iqRokbiw%2Fimage.png?alt=media&amp;token=487057f5-c64a-4645-a6d9-a469b7015189" alt=""><figcaption></figcaption></figure>

If you want to learn more about how knowledge works. Go to [Knowledge](/fundamentals/knowledge)

Navigate through the rest of the Knowledge setup process, and you will have your first knowledge ready!&#x20;

<figure><img src="https://3035252822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FeiBCAl6qTuG0sZpeXLxC%2Fuploads%2FafjnyQZDjWtYzXDktGaQ%2Fimage.png?alt=media&amp;token=58a87543-7d6f-437c-b3c2-778be6d5189b" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
Give the knowledge upload process a few minutes to fully sync up. You can continue to the next step, the sync up process will continue to run in the background.
{% endhint %}

## 2. Create Copilot

Head to the Copilots tab and click Create Copilot

<figure><img src="https://3035252822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FeiBCAl6qTuG0sZpeXLxC%2Fuploads%2FSPs7iXyarTLjqzeRsQQ0%2Fimage.png?alt=media&amp;token=b8b9489d-644b-4f16-9223-77d0459da3ef" alt=""><figcaption></figcaption></figure>

### General Setting and Permissions

Give your copilot a name and a clear description, and configure the access levels of your copilots

<figure><img src="https://3035252822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FeiBCAl6qTuG0sZpeXLxC%2Fuploads%2F4xBH6srvPYT3uwh8InOL%2Fimage.png?alt=media&amp;token=efb250f6-d0cd-48f5-81fa-e0da7dbe13d8" alt=""><figcaption></figcaption></figure>

* **Public:** your copilot will be available to anyone on the internet with the copilot link to use. It might also show up on the Discover page&#x20;
* **Private:** your copilot is only visible to you and the people you invited
* **Unlisted:** your copilot will be available to anyone on the internet with the copilot link to use. It won't show up on the Discover page or search engines &#x20;

### Configure UI & Callable&#x20;

#### Select UI

Choose which type of UI you'd like your copilots to have. Let's choose Chat UI.&#x20;

<figure><img src="https://3035252822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FeiBCAl6qTuG0sZpeXLxC%2Fuploads%2FS2297vVFxiCmKDYh5TFY%2Fimage.png?alt=media&amp;token=e4db32e3-9a2e-4864-b0a3-95d67178cf60" alt=""><figcaption></figcaption></figure>

<figure><img src="https://3035252822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FeiBCAl6qTuG0sZpeXLxC%2Fuploads%2FnhgLI5CgRZhiclVWLlvt%2Fimage.png?alt=media&amp;token=217f6062-993b-49ce-8901-f46e6b561ab5" alt=""><figcaption><p>Chat UI looks like this</p></figcaption></figure>

#### Configure Callable

Callable is what's powering the Copilots UI. We have a list of pre-built Callable for you to choose from. Pick the one that best fits your use case. If you or your organization have built your own Callable, it will also show up here for you to choose.

<figure><img src="https://3035252822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FeiBCAl6qTuG0sZpeXLxC%2Fuploads%2FUyu9ekhbhroQ8XIToYTH%2Fimage.png?alt=media&amp;token=623760bd-be1e-4381-9d32-869aff906fba" alt=""><figcaption></figcaption></figure>

select latest version to receive continuous updates

![](https://3035252822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FeiBCAl6qTuG0sZpeXLxC%2Fuploads%2Fa5tYimVLbBHRggJUq97E%2Fimage.png?alt=media\&token=3857e39a-499a-4da0-81d7-bd1a3f4711c5)

select my-notion-workspace that we've just created earlier.![](https://3035252822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FeiBCAl6qTuG0sZpeXLxC%2Fuploads%2FnZlxvuFh1OWaZMRmcNoR%2Fimage.png?alt=media\&token=cd3b5921-c0db-42ab-bb9c-faa20b19308c)

### Give examples

Give a few examples of how you could use your copilot. This will help your users to understand what your assistants are capable of. For example, for a chat copilot about Notion QA, you can put: "Where is the PRD for the product landing page?"

<figure><img src="https://3035252822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FeiBCAl6qTuG0sZpeXLxC%2Fuploads%2FnluDHnfvLZdQmR8ylvuc%2Fimage.png?alt=media&amp;token=39f7da83-a9e2-4fdc-9ca4-9095ab57aa84" alt=""><figcaption></figcaption></figure>

After clicking + Create Copilot button, your copilot will be available for you to use! You can share this copilot via the URL.&#x20;


# Making your first Callable

{% hint style="info" %}
Callable is currently in private preview, only selected developers and customers have access to Callable Builder. If you'd like to submit a request please contact <cortex@kinesys.ai>!
{% endhint %}

Callable is the serverless function that powers each copilot, or any of your AI workflows. Let's build a Callable today that helps recommend movies to watch!&#x20;

## 1. Create a knowledge

One of the powerful features of Cortex is to let AI interact with your own data. Knowledge is where you store your data.&#x20;

Head to the knowledge tab here and create a knowledge

<figure><img src="https://3035252822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FeiBCAl6qTuG0sZpeXLxC%2Fuploads%2FWmqIxvo1cYYq3RJEBmiB%2Fimage.png?alt=media&amp;token=a4a20526-f2b6-43c9-9ea2-599c251067d6" alt=""><figcaption></figcaption></figure>

Cortex supports multiple upload options. Let's use Web as our options. Enter the Knowledge name and description and go to the the next step

<figure><img src="https://3035252822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FeiBCAl6qTuG0sZpeXLxC%2Fuploads%2Fj0pGNmUtDIcnhXA8tlYi%2Fimage.png?alt=media&amp;token=0cd7e2df-33a1-4e36-94b8-ac5135f3e002" alt=""><figcaption></figcaption></figure>

Enter the url of Rotten Tomateo: <https://editorial.rottentomatoes.com/>. Follow the rest of the set up and your knowledge should be ready to go! &#x20;

<figure><img src="https://3035252822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FeiBCAl6qTuG0sZpeXLxC%2Fuploads%2F7WqhU1MyPrxayQfDosEP%2Fimage.png?alt=media&amp;token=04ac8afb-db33-4c9b-a58b-2c81ebd1073e" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
Give the knowledge upload process a few minutes to fully sync up. You can continue to the next step, the sync up process will continue to run in the background.
{% endhint %}

### 2. Create Callable

Navigate to Callable Builder and create a callable. Enter the name, description, and set the visibility. We will use "Chat" callable template, which is configured to work with Chat copilot.

<figure><img src="https://3035252822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FeiBCAl6qTuG0sZpeXLxC%2Fuploads%2FLESJOuYj7dhnDfmyjOFA%2Fimage.png?alt=media&amp;token=d4c3c8f5-fc18-4b94-a17b-541d03003292" alt=""><figcaption></figcaption></figure>

Go to the RETRIEVALS block, and select rotten-tomateo as your knowledge. You could select multiple knowledge if you have more information.&#x20;

<figure><img src="https://3035252822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FeiBCAl6qTuG0sZpeXLxC%2Fuploads%2F4pc369bXcqCh9Cce0g9f%2Fimage.png?alt=media&amp;token=ffedebb9-4c38-4801-bac2-72990ea01f5f" alt=""><figcaption></figcaption></figure>

You are almost there! Now the last thing to edit would be the prompt that passed into the language model. Let's modify the prompt in the language model block called OUTPUT\_STREAM to this:

```atom
You are an expert of movies. Please answer this following question: {{EXTRACT_QUESTION}}, base on following content:
{{RETRIEVALS_RESULT}}
Please answer the questions with the best of your knowledge. If not, please ask more questions for more information and recommend with some suggestions based on common knowledge.
You can make up an answer if you really cannot answer the question.

let's begin!
```

Let's also set the Max Tokens to around 2000.

<figure><img src="https://3035252822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FeiBCAl6qTuG0sZpeXLxC%2Fuploads%2FCloOvvTz6KHOyqKKgGoq%2Fimage.png?alt=media&amp;token=a096e1ac-ac62-49d2-8f9a-1854f5eb0dff" alt=""><figcaption></figcaption></figure>

### 3. Test your Callable

We've configured our Callable. But how do we know if it will work well? Let's create some test datasets. Go to the Datasets tab and go into ChatDataset.

<figure><img src="https://3035252822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FeiBCAl6qTuG0sZpeXLxC%2Fuploads%2FzLtJpEeJmovYNYJhNNZ8%2Fimage.png?alt=media&amp;token=e546cdc7-32a7-4f69-a480-53eeea1a8498" alt=""><figcaption></figcaption></figure>

You can write a few new test cases like this:

<figure><img src="https://3035252822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FeiBCAl6qTuG0sZpeXLxC%2Fuploads%2FpPsuvZvqi8kfgq3fLRxd%2Fimage.png?alt=media&amp;token=c404d6ea-9894-4c97-8a0e-5b85d9bbe642" alt=""><figcaption></figcaption></figure>

Now you are good to run tests! Go back to Design tab and click Run TestCases.&#x20;

Results from each block will be displayed below each block. We can go to the final OUTPUT block to check if the final results look good.&#x20;

<figure><img src="https://3035252822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FeiBCAl6qTuG0sZpeXLxC%2Fuploads%2FriVu9IuerV25LcgORFXt%2Fimage.png?alt=media&amp;token=3d15afaf-6f91-47f4-aee4-fba969f47535" alt=""><figcaption></figcaption></figure>

### 4. Deploy!

When you feel confident about your Callable's results, hit Deploy on the right top corner. The API for running this callable will be instantly generated, and now can integrate this into your product!

<figure><img src="https://3035252822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FeiBCAl6qTuG0sZpeXLxC%2Fuploads%2FjRPJ5zgI8UBCufnT1bsS%2Fimage.png?alt=media&amp;token=7a9f9bcd-c65d-4493-8245-9b96419620ae" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
Remember to always run TestCases before hitting Deploy. After editing your Callable, If you don't run TestCases, Deploy won't freeze your edits into the next version. If you see that the version number hasn't incremented after Deploy, that means there is no new changes being added in production. Try run TestCases and then Deploy.
{% endhint %}

### 5. Running it with a Copilot (optional)

You could directly consume the Callable API from your project, or you can connect a copilot to this callable and start chatting with it immediately.

Create a new Copilot and configure it as such to connect to the callable.

<figure><img src="https://3035252822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FeiBCAl6qTuG0sZpeXLxC%2Fuploads%2Fg5vjYjZBeJS9j8MSa4Q8%2Fimage.png?alt=media&amp;token=714adb0f-fda7-43b2-872e-918970e30a45" alt=""><figcaption></figcaption></figure>

Congratulations! Now you should be able to directly chat with your movie recommendation assistant.

<figure><img src="https://3035252822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FeiBCAl6qTuG0sZpeXLxC%2Fuploads%2FctK2Y0oMtwQCOzubADge%2Fimage.png?alt=media&amp;token=b2316f4f-e3b8-4883-9049-7824f0493322" alt=""><figcaption></figcaption></figure>


# Copilot

### Chat UI

Chat UI is excellent for general purposed QA. It's a conventional chatbot interface similar to ChatGPT

<figure><img src="https://3035252822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FeiBCAl6qTuG0sZpeXLxC%2Fuploads%2FuFeNQVXoWYzUS3o8qecC%2Fimage.png?alt=media&amp;token=5b014a0e-4105-4a34-bf29-4dc26e5cc607" alt=""><figcaption></figcaption></figure>

#### Examples

By default, Chat will have example questions you can ask the chatbot. Click any example to try it out

<figure><img src="https://3035252822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FeiBCAl6qTuG0sZpeXLxC%2Fuploads%2FFdztQwmRDUG3mGOMbpEZ%2Fimage.png?alt=media&amp;token=74198394-e7fb-4efb-af75-dafb51d03838" alt=""><figcaption></figcaption></figure>

#### Session History

Your chat session will be saved and available for access anytime on the left navigation bar. You can create a new conversation by clicking the + New Conversation button.

Notice that context-aware conversation is only available if the Callable developer incorporates history in the Callable. All Callables created by Cortex Community will have history enabled.&#x20;

### Text Generation UI

Text generation UI is excellent for back-and-forth document editing. It resembles a rich text editor with AI helping you rewrite and generate paragraphs.&#x20;

<figure><img src="https://3035252822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FeiBCAl6qTuG0sZpeXLxC%2Fuploads%2F2I452L7tKM5tsAM5tXJu%2Fimage.png?alt=media&amp;token=0f3a5a6b-0cd6-4a33-9745-a443ed2cdbe4" alt=""><figcaption></figcaption></figure>

#### Editing Field

This is the main editing field. You could manually edit paragraphs inside, or ask AI to write for you, and the generated paragraphs will show up inside as well.

<figure><img src="https://3035252822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FeiBCAl6qTuG0sZpeXLxC%2Fuploads%2FE4YWH69MsO9JlZ34iUq0%2Fimage.png?alt=media&amp;token=652ec93a-8f74-4dd8-9171-4bdaae75fac2" alt=""><figcaption></figcaption></figure>

#### Instruct AI to write

Use the instruction box on the right-hand side to tell AI what to write.&#x20;

You could ask: "write an email to my customer explaining how our pricing plan works." And click generate

![](https://3035252822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FeiBCAl6qTuG0sZpeXLxC%2Fuploads%2FxiYYpnVu8fl3i5f1Rp9T%2Fimage.png?alt=media\&token=c6a78b05-2c81-4568-b863-ca1a1fe1b3cf)

#### Instruct AI to rephrase

To change a specific portion of your paragraphs, highlight the part you'd like to modify, write in the instruction box on how you'd like to modify it, and click Rephrase. This will replace your old highlighted texts with newly generated paragraphs.

<figure><img src="https://3035252822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FeiBCAl6qTuG0sZpeXLxC%2Fuploads%2FyjAY5dljJAmAjjNYOLQG%2Fimage.png?alt=media&amp;token=518316df-9490-449e-8560-ee4d3313db39" alt=""><figcaption></figcaption></figure>

Don't worry about inconsistency, the AI is context-aware, so it knows what're the paragraphs before and after the highlighted texts, and adapts the generated response accordingly.

### Save draft

Click the save button at the second left button corner. Saved edits will show up on the left navigation bar. You could click any saved edits to resume editing a previous version.

<figure><img src="https://3035252822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FeiBCAl6qTuG0sZpeXLxC%2Fuploads%2FvN4oCmQF2GPw7FqK3Ntn%2Fimage.png?alt=media&amp;token=8d32c20a-0d2f-40f6-9a35-1aa13ccab846" alt=""><figcaption></figcaption></figure>

### Search UI (Coming Soon)

Search UI is excellent for finding relevant information from your unstructured documents. It resembles a search engine and includes a short summary of the information you are looking for

<figure><img src="https://3035252822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FeiBCAl6qTuG0sZpeXLxC%2Fuploads%2FkwHMermKVrVOJTmdn6Er%2Fimage.png?alt=media&amp;token=536b1728-e49e-4f78-bad3-734ebcbb8529" alt=""><figcaption></figcaption></figure>


# Knowledge

### Overview

Knowledge is our managed vector database which allows our users and developers to seamlessly interact with their large amount of data.

Our knowledge is designed to be easy to use, with several built-in data integration pipeline that allows users to sync up with their data warehouse dynamically.

### Structure

Each Knowledge is considered to be an independent data source. You would want to create different Knowledges for different types of data sources (Notion vs. SQL DB) or exert separate access control policies.

There is another division within each Knowledge, called Documents. Knowledge consists of a collection of Documents. You could use documents to insert the same type of data but different contents (different pages in the same Notion workspace).

### Self Managed

For the simplest upload options, we allow users to directly upload files from their computers in various formats, such as pdf, docx, and txt.&#x20;

Additionally, developers can also choose to upload and update their knowledge using our [SDK](https://github.com/trycortex-ai).

### Web

We provide a built-in HTTP web crawler that will recursively go through most links from the root URL. Just provide the root URL and we will automatically start the crawl.&#x20;

More on its behavior:

* We will try to get the site map from the root url, and import the first 100 urls. You can remove the ones you don't want.
* we only index first 200k characters of each page.
* it works great if your webpage is server-side rendered, but not so great if it's a SPA, we are working on it.

### Notion

The Notion integration allows users to seamlessly connect their Notion workspace. By signing in through your Notion account, and selecting the workspaces you want to connect, we will automatically sync up your selected Notion pages. This Knowledge is fully-managed, meaning that any changes from Notion will be updated dynamically to the Knowledge

### Slack

Slack integration allows users to connect their Slack message history to Knowledge. It's also a fully managed service like Notion's integration.&#x20;


# Callable

{% hint style="info" %}
Callable is currently in private preview, only selected developers and customers have access to Callable Builder. If you'd like to submit a request please contact <cortex@kinesys.ai>!
{% endhint %}

Seems like you don't have access to this page yet. Please contact <cortex@kinesys.ai>!

<figure><img src="https://3035252822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FeiBCAl6qTuG0sZpeXLxC%2Fuploads%2FDXhHy9ua0GcHbXba1Gf3%2Fimage.png?alt=media&amp;token=e8eff868-511b-44d6-8d95-2155a3636d92" alt=""><figcaption></figcaption></figure>


# Getting set up

Setting up your team account, available to Enterprise plan.

<details>

<summary>Step 1: Creating your organization</summary>

1. "+ Create Team" on the top navigation bar&#x20;
2. Name your organization and confirm

</details>

<details>

<summary>Step 2: Inviting your team</summary>

1. Go to "Team Management" from the profile icon
2. Go to "Members"
3. Enter the emails of your teammates.

By default, all newly joined teammates are User. You can come back later to change their Permission level later.&#x20;

</details>

<details>

<summary>Step 3: Making your first Copilot</summary>

Follow the guide here: [Making your first Copilot](/product-guides/making-your-first-copilot)

</details>


# Setting permissions

## Permission levels

There are 4 types of permission levels in Cortex.

<table><thead><tr><th width="180">Role</th><th>Capabilities</th></tr></thead><tbody><tr><td>User</td><td>Can only use knowledge, and callable</td></tr><tr><td>Builder</td><td>Can view, update, create knowledge, callable</td></tr><tr><td>Admin</td><td>Has all privilages of Builder, and able to set permissions and billing</td></tr><tr><td>Owner</td><td>Has all privilages of Admin, and cannot be removed</td></tr></tbody></table>


# Blocks

{% content-ref url="/pages/2pn1o1NHZvZvFPCC0XrQ" %}
[Models](/callable/blocks/models)
{% endcontent-ref %}

{% content-ref url="/pages/hCuweHimpmK7v9wzXgMd" %}
[Data](/callable/blocks/data)
{% endcontent-ref %}

{% content-ref url="/pages/yJbjhWNJ8VjFA4RKUECE" %}
[Tools](/callable/blocks/tools)
{% endcontent-ref %}

{% content-ref url="/pages/ooQtvWlWsv1l2zzMKs5r" %}
[Control](/callable/blocks/control)
{% endcontent-ref %}


# Models

{% content-ref url="/pages/IeNfanufdCdIGZpRfnmU" %}
[Language Model](/callable/blocks/models/language-model)
{% endcontent-ref %}

{% content-ref url="/pages/qrUDjrGkkFHIqsnxQ8M7" %}
[Language Model With Code](/callable/blocks/models/language-model-with-code)
{% endcontent-ref %}


# Language Model

The Model Block accepts a specified prompt string and returns a Language Model completion as the result.

<figure><img src="https://3035252822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FeiBCAl6qTuG0sZpeXLxC%2Fuploads%2Fa7DIl8JASJawQCyQPFuc%2FScreenshot%202023-07-18%20at%203.37.07%20PM.png?alt=media&amp;token=bb1c74ca-3f0e-4e0b-965a-8be2a249e4b7" alt=""><figcaption></figcaption></figure>

**Parameters:**

* **Prompt:** Enter your prompt to send to the configured model
* **Config:** Provides options for the type of LLM model and the temperature

{% hint style="info" %}
For the final model block in your callable, it must be named OUTPUT\_STREAM to stream the chat results in your copilot.
{% endhint %}

**Using Advanced Model Blocks:**

{% content-ref url="/pages/ky1043l79csEEB89gZPR" %}
[Utilizing Model Examples to Convert Text to JSON](/callable/use-cases/utilizing-model-examples-to-convert-text-to-json)
{% endcontent-ref %}


# Language Model With Code

Sends a prompt and array of functions following the function calling parameter of OpenAI.

<div data-full-width="false"><figure><img src="https://3035252822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FeiBCAl6qTuG0sZpeXLxC%2Fuploads%2FvijK3OW6s0UPZBtmGT6f%2FScreenshot%202023-07-21%20at%204.52.48%20PM.png?alt=media&amp;token=93df437d-db01-4790-b2a5-02d2ad29619d" alt=""><figcaption></figcaption></figure></div>

**Parameters:**

* **Instructions:** Enter prompt to be sent to the model
* **Code for Memory:** Input the message history
* **Code for Functions:** Array of functions to be sent to OpenAI

{% embed url="<https://platform.openai.com/docs/guides/gpt/function-calling>" %}


# Data

{% content-ref url="/pages/xpnWp7w4cQTPSA6neVOy" %}
[Dataset Loader](/callable/blocks/data/dataset-loader)
{% endcontent-ref %}


# Dataset Loader

## Dataset Loader

Loads Data from the Dataset tab.

<div align="center" data-full-width="true"><figure><img src="https://3035252822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FeiBCAl6qTuG0sZpeXLxC%2Fuploads%2FBcVYFDPk73pH4Qk7d1rG%2FScreenshot%202023-07-21%20at%204.55.40%20PM.png?alt=media&amp;token=f1f81da2-68cc-440d-99da-ff80d46866c7" alt=""><figcaption></figcaption></figure></div>

**Parameters**:

* **Select Data:** Choose an existing dataset from your dataset


# Tools

{% content-ref url="/pages/GdsU9JU6yF8qwkmeEUQB" %}
[Knowledge Search](/callable/blocks/tools/knowledge-search)
{% endcontent-ref %}

{% content-ref url="/pages/ymwztqxaQI3wZfD676Us" %}
[Google Search](/callable/blocks/tools/google-search)
{% endcontent-ref %}

{% content-ref url="/pages/jmsXAcw21eo6ro2IZKGQ" %}
[Curl Request](/callable/blocks/tools/curl-request)
{% endcontent-ref %}

{% content-ref url="/pages/HHW1BAtOKqSimIiICNFh" %}
[Web Page Crawler](/callable/blocks/tools/web-page-crawler)
{% endcontent-ref %}


# Knowledge Search

Search blocks allow Callables to make queries to uploaded Knowledges.

<figure><img src="https://3035252822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FeiBCAl6qTuG0sZpeXLxC%2Fuploads%2Fa0j6GXxmiPTranibQ9el%2FScreenshot%202023-07-19%20at%2012.51.46%20PM.png?alt=media&amp;token=c90a8881-5e4f-477b-bc43-af2f919c423b" alt=""><figcaption></figcaption></figure>

Search Blocks consist of the following fields:

* **Query:** Provide the desired prompt to look for inside your knowledges
* **Knowledge:** Add and select as many knowledges that you have created. Allows for specific include or exclude tags to better refine your retrieval.

**Using Knowledge Block for Retrieval:**

{% content-ref url="/pages/6If73mSRMTBP6L5Cnsdg" %}
[Retrievals from Knowledge Search Blocks](/callable/use-cases/retrievals-from-knowledge-search-blocks)
{% endcontent-ref %}


# Google Search

Find the most relevant links based on the Query through a google search

<figure><img src="https://3035252822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FeiBCAl6qTuG0sZpeXLxC%2Fuploads%2FAh8gklL09tLFLjKTUmPi%2FScreenshot%202023-07-21%20at%205.15.25%20PM.png?alt=media&amp;token=5f1f8e08-be04-4037-a482-46cfdc6c75d8" alt=""><figcaption></figcaption></figure>

**Parameters:**

* **Number of Results:** Specifies how many organic results will be returned
* **Query:** Specify the question to search on google.

Return:

{% embed url="<https://serpapi.com/search-api#api-results>" %}


# Curl Request

Send Curl Requests with the Curl Request block

<figure><img src="https://3035252822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FeiBCAl6qTuG0sZpeXLxC%2Fuploads%2FpX5kVTNBG9JZk7BqhfAS%2FScreenshot%202023-07-21%20at%205.37.02%20PM.png?alt=media&amp;token=de13a7f6-d5b2-4ee8-a87a-6834ce8ee87a" alt=""><figcaption><p> </p></figcaption></figure>

**Parameters:**

* **URL:** The url you are sending the curl request to
* **Headers:** Provide the header fields as a javascript object in the return
* **Body:** Provide a JSON string with the body parameters you want send.


# Web Page Crawler

Goes to a specified URL and retrieves the HTML from the page.

<figure><img src="https://3035252822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FeiBCAl6qTuG0sZpeXLxC%2Fuploads%2FctXqtE6uGLmH7VURs8VS%2FScreenshot%202023-07-24%20at%203.05.36%20PM.png?alt=media&amp;token=6acfd87d-fadc-471e-91f2-a62241d335d8" alt=""><figcaption></figcaption></figure>

**Parameters:**

* **URL:** The URL that you want to get HTML data from
* **CSS Selector:** Provide an HTML Element (<https://developer.mozilla.org/en-US/docs/Web/HTML/Element>) to search the contents for on the specified website. Each result will return the html, text, width, height, top, left, and attributes of the each element that matches the selector.


# Control

{% content-ref url="/pages/Otfak2aubqrLI1KHHqyE" %}
[Code](/callable/blocks/control/code)
{% endcontent-ref %}

{% content-ref url="/pages/fbBEu5NFQVdtNpBVwzI6" %}
[Loop Until](/callable/blocks/control/loop-until)
{% endcontent-ref %}

{% content-ref url="/pages/6A89GYMDNj6WBzmLIpkD" %}
[Map Reduce](/callable/blocks/control/map-reduce)
{% endcontent-ref %}


# Code

Code blocks allow for users to execute JavaScript code in a Callable

<figure><img src="https://3035252822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FeiBCAl6qTuG0sZpeXLxC%2Fuploads%2Fh79hGPkMx4o4JCBbrNkP%2FScreenshot%202023-07-24%20at%204.07.04%20PM.png?alt=media&amp;token=b0097b13-d6c9-40c2-b7fc-2edeb2301851" alt=""><figcaption></figcaption></figure>

The env variable passed into the function allows for referencing previous block outputs inside the Code Block. It uses the syntax `env.state.BLOCK_NAME` to reference a block by its name. In the example above, the block name for the code block would be `CODE_1`. User's can name blocks anything as long as it is unique inside the Callable.


# Loop Until

Executes code between the start and end of the loop

<figure><img src="https://3035252822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FeiBCAl6qTuG0sZpeXLxC%2Fuploads%2FdbZrmPhnEvce1GnhG0XW%2FScreenshot%202023-07-24%20at%204.34.40%20PM.png?alt=media&amp;token=23db7736-c32a-48a0-aa5f-f293025d66bc" alt=""><figcaption></figcaption></figure>


# Map Reduce

Map over an array and executes a sequence of blocks in parallel.

<figure><img src="https://3035252822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FeiBCAl6qTuG0sZpeXLxC%2Fuploads%2FodVRYXzNvBAXxgatMePZ%2FScreenshot%202023-07-24%20at%204.40.58%20PM.png?alt=media&amp;token=b84e56f5-f742-4bc3-ab94-2e92183a4642" alt=""><figcaption></figcaption></figure>

**Parameters:**

* **From:** Reference of a block name that outputs an array
* **Repeat:** Integer value that specifies the amount of time to repeat the execution of blocks inside the loop


# Use Cases

{% content-ref url="/pages/v5Lv51Lju9jsk6VcpHWK" %}
[Building a Company Help Desk](/callable/use-cases/building-a-company-help-desk)
{% endcontent-ref %}

{% content-ref url="/pages/DaUjFXIexOEk2BXCQhBg" %}
[Creating a Social Media Manager Chatbot](/callable/use-cases/creating-a-social-media-manager-chatbot)
{% endcontent-ref %}

{% content-ref url="/pages/ky1043l79csEEB89gZPR" %}
[Utilizing Model Examples to Convert Text to JSON](/callable/use-cases/utilizing-model-examples-to-convert-text-to-json)
{% endcontent-ref %}

{% content-ref url="/pages/6If73mSRMTBP6L5Cnsdg" %}
[Retrievals from Knowledge Search Blocks](/callable/use-cases/retrievals-from-knowledge-search-blocks)
{% endcontent-ref %}

{% content-ref url="/pages/rCylswM01ndTsCbMRMq3" %}
[Chatbot with Google Search Assistance](/callable/use-cases/chatbot-with-google-search-assistance)
{% endcontent-ref %}


# Building a Company Help Desk

{% embed url="<https://www.loom.com/share/901950a098de4f0abde3a0bb689d0301?sid=31ffe4bc-2c61-4c68-b221-74b6c8236109>" %}


# Creating a Social Media Manager Chatbot

## Overview

Let's imagine that we are responsible for managing the social media presence of an up and coming startup and would like the help of a language model to help write twitter posts. We want to create a chat bot that can answer questions as if it has the knowledge of an expert social media manager.

Cortex makes the process of building a personalized chat bot fast and simple. Let's look at how this can be done with the power of Callable and Copilot.

## Getting Started

Navigate to the **Callable Builder** tab in the top right of the navigation bar and go ahead and press **Create Callable**. Name your callable **"social-media-call"** and give the following description:

> callable to support creating social media posts

Select **Private** and choose the **Barebone** template callable before pressing **Create**.

Once inside the Callable Builder, you should see two blocks: INPUT, OUTPUT. Since we are creating a Chatbot let's switch the **input type** in the **INPUT** block to **ChatDataset**.

<details>

<summary>Understanding Chat Inputs</summary>

## Chat Inputs

Chat Callable's input is a message object that contains an array of messages.

#### Message Object

The `Message` object is a high-level entity that holds an array of individual message items.

* `messages`: An array of message items. Each item in the array is an object that consists of two properties: 'role' and 'content'.

#### Message Item

Each message item is an individual message with its associated role.

* `'role'` Role related to the message (e.g., 'user', 'assistant').
* `'content'` Text of the message.

### Example

Here is an example of what a `Message` object might look like:

```javascript
{
  "messages": [
    {
      "role": "user",
      "content": "Hello, how can I help you?"
    },
    {
      "role": "assistant",
      "content": "I'm here to assist you. What do you need?"
    },
    {
      "role": "user",
      "content": "I need information on your new products."
    }
  ]
}
  
```

</details>

<details>

<summary>Understanding Callable Blocks</summary>

Blocks are fundamental units that form logical sequences inside a Callable. They operate similarly to server-less functions, running independently yet capable of working in cohesion to create complex features.

Think of each block as an individual piece in a larger puzzle that is your Callable. Every block has its unique role and introduces a new functionality to the Callable. This could be anything from making curl requests, leveraging large language models, extracting specific data, to retrieving knowledge.

A key attribute of these blocks is that they can interact with one another by calling upon each other's results. This ability to collaborate makes them incredibly versatile and adaptable, allowing you to build intricate and sophisticated features by chaining them together in the Callables.

</details>

***

## Callable Code and Model Blocks

For this application, we want to create a callable that takes in chat inputs and outputs a response from a language model in the form of a message item (See [#understanding-chat-inputs](#understanding-chat-inputs "mention")).

We want to start by creating two referable code blocks that return:

1. The question asked by the user
2. The history of the chat

Both of these can be sourced from parsing the input message object with the following blocks.

### EXTRACT\_QUESTION Block

This Code block returns the content of the last element in the message array

<figure><img src="https://3035252822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FeiBCAl6qTuG0sZpeXLxC%2Fuploads%2FZoyD7L5DTuamvF5r9jet%2FScreenshot%202023-07-24%20at%205.21.32%20PM.png?alt=media&amp;token=15601bb9-0b93-4566-a0b3-427059a280e7" alt=""><figcaption></figcaption></figure>

### HISTORY Block

This Code block joins the content of every message in the array except the last message and returns it in a string.

<figure><img src="https://3035252822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FeiBCAl6qTuG0sZpeXLxC%2Fuploads%2FO55fhNkIQ4nYqNiWd3xu%2FScreenshot%202023-07-24%20at%205.21.39%20PM.png?alt=media&amp;token=f7fa2e14-e1df-438c-a149-df9ca02ca807" alt=""><figcaption></figcaption></figure>

Once we have parsed the History and Question from the input, we can references these inside a well designed prompt and send everything to ChatGPT. This can be done inside a Model Block.

### OUTPUT\_STREAM Block

This Model block uses the return of the History block and the Extract Question block and wraps it into prompt that will help specify what kind of answer we want from ChatGPT.

{% hint style="info" %}
Notice that when referencing block variables inside the Model Block prompt section, we must use the syntax`{{BLOCK_NAME}}`.
{% endhint %}

<figure><img src="https://3035252822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FeiBCAl6qTuG0sZpeXLxC%2Fuploads%2F5iMrpriQqTDQ2uyOSZ6F%2FScreenshot%202023-07-24%20at%205.21.45%20PM.png?alt=media&amp;token=e932f4eb-b5b0-48c7-a216-3b1c51eafcdb" alt=""><figcaption></figcaption></figure>

Lastly, we want to return the answer ChatGPT gives into a message item object. This can be done with a Code block again.

### GET\_ANSWER Block

This Code block returns a message item object that contains content from the output of the OUTPUT\_STREAM Block.

<figure><img src="https://3035252822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FeiBCAl6qTuG0sZpeXLxC%2Fuploads%2Fw8QvxnrqIlWcY9BTS9zB%2FScreenshot%202023-07-24%20at%206.09.29%20PM.png?alt=media&amp;token=bd9dff81-5f2a-4998-98df-10eccbb69e0f" alt=""><figcaption></figcaption></figure>

## Test and Deploy

Once you finish creating the necessary blocks for your callable. Go ahead and press **Run TestCases**. If there are no errors, you can deploy your callable by pressing **Deploy**.

## Creating Copilot

After successfully deploying your callable, you can quickly turn your callable into a usable Chat Copilot. Navigate to **My Copilots** and click on **Create Copilot**. Name your Copilot **"Social Media Manager"** and enter the description

> An expert social media content manager to generate tweets and posts for your brand!

Select **Private** and choose **Chat**. Then press **Select Callable** and select **social-media-call**. Select **latest** for the version.

Under **Example Prompts**, paste the following prompts:

1. Write a tweet to launch my new crypto startup: Kr1ptu@
2. Write an Instagram post to announce that my sunglasses brand is now shipping to Europe
3. Write a Facebook post to say I'm offering 30% discount on my online coding courses

Finally, click **Create Copilot.**

## Try it out!

Go ahead and use your new chat copilot and see what tweets you can make!


# Utilizing Model Examples to Convert Text to JSON

## Basic Model Block

The basic Model Block accepts a specified prompt string and returns a Language Model completion as the result.

<figure><img src="https://3035252822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FeiBCAl6qTuG0sZpeXLxC%2Fuploads%2Fa7DIl8JASJawQCyQPFuc%2FScreenshot%202023-07-18%20at%203.37.07%20PM.png?alt=media&amp;token=bb1c74ca-3f0e-4e0b-965a-8be2a249e4b7" alt=""><figcaption></figcaption></figure>

## Advanced Model Block

The advanced Model Block provides parameters for the Introduction and Examples

* **Introduction:** A paragraph that will appear at the beginning of your prompt once. Provides instruction to the model about how it should interpret your examples
* **Examples:** Provide examples of the type of response you want the model to output. This could be a list of examples that are organized as a template question and answer.
* **Prompt:** The final question that will appear at the end of the prompt that the user wants the model to complete.

<figure><img src="https://3035252822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FeiBCAl6qTuG0sZpeXLxC%2Fuploads%2FeHB5tS5FbGqt0PmN88fU%2FScreenshot%202023-07-18%20at%203.18.07%20PM.png?alt=media&amp;token=460bb981-81bd-4c3e-b98b-70d39498678f" alt=""><figcaption></figcaption></figure>

## Converting Text to JSON

In order to create a callable that can change plain text into a JSON, we need to provide examples for our model to reference back to so that the model would know what kind of output we are looking for.

To do this, let's initialize our examples as an array of example objects with a question and an answer field. There are two ways to do this, the first way will use a code block.

<figure><img src="https://3035252822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FeiBCAl6qTuG0sZpeXLxC%2Fuploads%2FWRtiwAYbrWbEqCnHrrNJ%2FScreenshot%202023-07-18%20at%204.09.06%20PM.png?alt=media&amp;token=ac312962-8e4c-479c-b003-17ec37bb5554" alt=""><figcaption></figcaption></figure>

We can also load examples using the Data Block and inputting the examples in the dataset tab.&#x20;

<figure><img src="https://3035252822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FeiBCAl6qTuG0sZpeXLxC%2Fuploads%2FaL14K9LUBnmMXQ8uQFIn%2FScreenshot%202023-07-18%20at%205.18.51%20PM.png?alt=media&amp;token=eb474475-939d-4a3a-b94d-c7eec6f6ee62" alt=""><figcaption></figcaption></figure>

That uses the following example dataset.

<figure><img src="https://3035252822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FeiBCAl6qTuG0sZpeXLxC%2Fuploads%2FLnGmSCkKhhIc5BS7dNVj%2FScreenshot%202023-07-18%20at%205.25.16%20PM.png?alt=media&amp;token=92d16b38-9b95-43aa-9899-a44adb0c0be8" alt=""><figcaption></figcaption></figure>

After initializing the examples, we can now set up an advanced language model block that has an introduction that describes our desired task to our model and then enter in our examples as a question followed by an answer. Finally, we enter our original input question as our prompt.

<figure><img src="https://3035252822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FeiBCAl6qTuG0sZpeXLxC%2Fuploads%2FDE81F8T1ows3z6ieaRTb%2FScreenshot%202023-07-18%20at%204.10.36%20PM.png?alt=media&amp;token=1004082a-3968-4f4b-bc6c-93525511609b" alt=""><figcaption></figcaption></figure>

We can now run some test cases to see if this works. When we try the input:

<figure><img src="https://3035252822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FeiBCAl6qTuG0sZpeXLxC%2Fuploads%2FOAZ7t47xNdUXj7FCc6W4%2FScreenshot%202023-07-18%20at%205.12.57%20PM.png?alt=media&amp;token=8a7765a9-f523-445a-a273-3585510eee2c" alt=""><figcaption></figcaption></figure>

We can see that our callable successful returns the JSON object as:

<figure><img src="https://3035252822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FeiBCAl6qTuG0sZpeXLxC%2Fuploads%2FkV0kESSUeauV9EVkvyu8%2FScreenshot%202023-07-18%20at%205.13.21%20PM.png?alt=media&amp;token=4f9df66d-0708-4d87-9a91-540e0dd3091b" alt=""><figcaption></figcaption></figure>

Once tested, deploy the callable to use in any application.


# Retrievals from Knowledge Search Blocks

## Knowledge Search Block

Search blocks allow Callables to make queries to uploaded Knowledges.

<figure><img src="https://3035252822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FeiBCAl6qTuG0sZpeXLxC%2Fuploads%2Fa0j6GXxmiPTranibQ9el%2FScreenshot%202023-07-19%20at%2012.51.46%20PM.png?alt=media&amp;token=c90a8881-5e4f-477b-bc43-af2f919c423b" alt=""><figcaption></figcaption></figure>

Search Blocks consist of the following fields:

* **Query:** Provide the desired prompt to look for inside your knowledges
* **Knowledge:** Add and select as many knowledges that you have created. Allows for specific include or exclude tags to better refine your retrieval.

<figure><img src="https://3035252822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FeiBCAl6qTuG0sZpeXLxC%2Fuploads%2FvEAa6lTqBdua10VDNOKO%2FScreenshot%202023-07-18%20at%205.30.43%20PM.png?alt=media&amp;token=48cac3c3-840b-401f-980b-c7250aa084a6" alt=""><figcaption></figcaption></figure>


# Chatbot with Google Search Assistance

This guide covers how to build a chat callable that refines user questions with Google Searches to obtain a response from a LLM that references data from websites.

## Getting Started

Navigate to the **Callable Builder** tab in the top right of the navigation bar and go ahead and press **Create Callable**. Name your callable **"llm-with-google-assist"** and give the following description:

> Answer questions with high factual accuracy by searching online and compiling responses based on content downloaded from websites (with references).

Select **Private** and choose the **Barebone** template callable before pressing **Create**.

Once inside the Callable Builder, you should see two blocks: INPUT, OUTPUT. Since we are creating a Chatbot let's switch the **input type** in the **INPUT** block to **ChatDataset**.

<details>

<summary>Understanding Chat Inputs</summary>

## Chat Inputs

Chat Callable's input is a message object that contains an array of messages.

#### Message Object

The `Message` object is a high-level entity that holds an array of individual message items.

* `messages`: An array of message items. Each item in the array is an object that consists of two properties: 'role' and 'content'.

#### Message Item

Each message item is an individual message with its associated role.

* `'role'` Role related to the message (e.g., 'user', 'assistant').
* `'content'` Text of the message.

### Example

Here is an example of what a `Message` object might look like:

```javascript
{
  "messages": [
    {
      "role": "user",
      "content": "Hello, how can I help you?"
    },
    {
      "role": "assistant",
      "content": "I'm here to assist you. What do you need?"
    },
    {
      "role": "user",
      "content": "I need information on your new products."
    }
  ]
}
  
```

</details>

<details>

<summary>Understanding Callable Blocks</summary>

Blocks are fundamental units that form logical sequences inside a Callable. They operate similarly to server-less functions, running independently yet capable of working in cohesion to create complex features.

Think of each block as an individual piece in a larger puzzle that is your Callable. Every block has its unique role and introduces a new functionality to the Callable. This could be anything from making curl requests, leveraging large language models, extracting specific data, to retrieving knowledge.

A key attribute of these blocks is that they can interact with one another by calling upon each other's results. This ability to collaborate makes them incredibly versatile and adaptable, allowing you to build intricate and sophisticated features by chaining them together in the Callables.

</details>

## 1. Formatting Question for Search Query

Message objects contain the entire conversation history as an array with the last message in the array from the user. In order to send a google search query, we first need to extract the relevant context of the conversation to enhance the user’s question and receive correct search results.

To do this, click the plus and create two code blocks: one to extract the question and the second to extract the conversation history.

<figure><img src="https://3035252822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FeiBCAl6qTuG0sZpeXLxC%2Fuploads%2F7BmWWNtd3qwtrqwd8wFU%2FScreenshot%202023-07-17%20at%204.50.44%20PM.png?alt=media&amp;token=37d373da-b3b5-41dc-9e18-010686fb2f76" alt=""><figcaption></figcaption></figure>

<figure><img src="https://3035252822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FeiBCAl6qTuG0sZpeXLxC%2Fuploads%2Fe2fwG5hGUThIO3932pKh%2FScreenshot%202023-07-17%20at%204.50.56%20PM.png?alt=media&amp;token=01c91d1e-1a9b-4b94-a316-eb1516332b22" alt=""><figcaption></figcaption></figure>

Once we extract the question and history with the respected code blocks, we can refine our question with a language model so that it will include the context of the history inside a Model Block.

<figure><img src="https://3035252822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FeiBCAl6qTuG0sZpeXLxC%2Fuploads%2FA5cOs3obNy1C6P9IovOo%2FScreenshot%202023-07-17%20at%205.09.47%20PM.png?alt=media&amp;token=df30c106-b1b7-4e2f-a83c-d3829818ec3c" alt=""><figcaption></figcaption></figure>

For the model configuration, we want a temperature of 0.1 for a more conservative change and so  that our original question is not altered dramatically.

## 2. Google Search and Summarizing Results

After refining our question, we want to create a google search query using the result from the REFINED\_QUESTION block that will provide links to relevant websites.

<figure><img src="https://3035252822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FeiBCAl6qTuG0sZpeXLxC%2Fuploads%2FoCnqdzi50DoryMXDNKjV%2FScreenshot%202023-07-17%20at%205.26.07%20PM.png?alt=media&amp;token=44e7bb1b-9cf0-4dea-86c3-08263a918d18" alt=""><figcaption></figcaption></figure>

Our google search query provides us with a few of the most relevant links related to our query. In order to extract the information from these links, we must utilize a Map Reduce block and call a web crawler block on each link to retrieve the details from the google search results.

In order to extract the relevant links and web crawl over them, we want to simplify our GOOGLE\_SEARCH object into a result object with a field for the title and link before starting our Map Reduce block. This can be done with another Code block.

<figure><img src="https://3035252822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FeiBCAl6qTuG0sZpeXLxC%2Fuploads%2F6nD7tPSjXTuPeeu8jUtJ%2FScreenshot%202023-07-17%20at%205.26.16%20PM.png?alt=media&amp;token=450bc7bc-60ba-4499-a9c6-d0b8727c9609" alt=""><figcaption></figcaption></figure>

Now with a list of relevant links formatted correctly, we can start a Map Reduce loop to collect a summary of each link.

<figure><img src="https://3035252822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FeiBCAl6qTuG0sZpeXLxC%2Fuploads%2FtIx1CbSMdiuTm4vTJeQq%2FScreenshot%202023-07-17%20at%205.26.23%20PM.png?alt=media&amp;token=e4808e05-ddaa-4fa4-ac93-96e1e8b7f532" alt=""><figcaption></figcaption></figure>

This loop begins by calling upon a Web Page Crawler Block with each link to retrieve the HTML body of the page.

<figure><img src="https://3035252822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FeiBCAl6qTuG0sZpeXLxC%2Fuploads%2FHvxtyiLtZjMzNUcuOpAi%2FScreenshot%202023-07-17%20at%205.26.31%20PM.png?alt=media&amp;token=fc8f5d20-129a-44f8-9bf5-51b349dd6a36" alt=""><figcaption></figcaption></figure>

Then, another code block is called upon with the web crawler data to format into content blocks with only the first 2000 bytes of the HTML body.

<figure><img src="https://3035252822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FeiBCAl6qTuG0sZpeXLxC%2Fuploads%2FZwEFTdPsWbQBS6DDHqmD%2FScreenshot%202023-07-17%20at%205.26.38%20PM.png?alt=media&amp;token=fbb16e55-6678-4c0e-be57-526fed72c434" alt=""><figcaption></figcaption></figure>

Once the data is collected, a language model block can help us summarize the raw data from the HTML body into a single paragraph for which we can use in our final prompt.

<figure><img src="https://3035252822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FeiBCAl6qTuG0sZpeXLxC%2Fuploads%2FjeLLmXxEtmCvbM42CVZu%2FScreenshot%202023-07-17%20at%205.26.51%20PM.png?alt=media&amp;token=78029abf-2517-4825-94a6-8317b9088e46" alt=""><figcaption></figcaption></figure>

The last block in the loop is a code block that nicely formats the link summaries into an object for us to reference in our final prompt.

<figure><img src="https://3035252822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FeiBCAl6qTuG0sZpeXLxC%2Fuploads%2FffqP4iuWLdj1DOUbJYWl%2FScreenshot%202023-07-18%20at%201.10.19%20PM.png?alt=media&amp;token=274eb2ba-b654-41d1-967a-de4d71edc041" alt=""><figcaption></figcaption></figure>

## 3. Final Prompt and Returning Result

Lastly, we need to combine the data from all relevant links together along with the original question into a single prompt before sending to our language model. This can be done with a code block that loops through each FORMAT\_SUMMARY object to extract the summary of the links and append it into a single string with the original question.

<figure><img src="https://3035252822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FeiBCAl6qTuG0sZpeXLxC%2Fuploads%2FdB6EQgDuWBsdL2Sp9sRb%2FScreenshot%202023-07-18%20at%201.12.26%20PM.png?alt=media&amp;token=ee6e5c03-15d3-4de5-b66c-df5a3318574d" alt=""><figcaption></figcaption></figure>

Once this is finished, the last step is to run the final prompt in a language model prompt and extract the results.

<figure><img src="https://3035252822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FeiBCAl6qTuG0sZpeXLxC%2Fuploads%2FwbMGTZGvTe75GLJfPzFc%2FScreenshot%202023-07-18%20at%201.17.55%20PM.png?alt=media&amp;token=d8633896-9c3f-4bea-942f-9535b99b3899" alt=""><figcaption></figcaption></figure>

***

Congratulations, you have created a chatbot that uses google search to find relevant information about the question. Create some test cases and deploy your callable to start using it in any application.

## Clone callable


# Getting Started with the SDK

## Installation

{% tabs %}
{% tab title="Typescript" %}

<pre class="language-bash"><code class="lang-bash"><strong>npm install cortex-ts
</strong></code></pre>

{% endtab %}

{% tab title="Python" %}

```bash
pip install trycortex
```

{% endtab %}
{% endtabs %}

## Create a CortexAPI

Create environment variables for your cortex API key.

Use the API key to create a CortexAPI.

{% tabs %}
{% tab title="Typescript" %}

```typescript
import { CortexAPI } from 'cortex-ts';
const {CORTEX_API_KEY} = process.env;

const cortex = new CortexAPI(CORTEX_API_KEY);
```

{% endtab %}

{% tab title="Python" %}

```python
import cortex

CortexAPI = cortex.CortexAPI(API_KEY)
```

{% endtab %}
{% endtabs %}


# Documents

## Retrieving a Document

First, find the name of the knowledge that contains the document you wish to retrieve in the knowledge tab of Cortex.

<figure><img src="https://3035252822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FeiBCAl6qTuG0sZpeXLxC%2Fuploads%2FbonoXJ2eMZh6AOM3e55B%2FScreenshot%202023-06-27%20at%203.09.15%20PM.png?alt=media&amp;token=2c9c5046-17a7-4704-8cb3-796df9bd86d6" alt=""><figcaption></figcaption></figure>

Then, find the name of the documentID you want to retrieve.

<figure><img src="https://3035252822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FeiBCAl6qTuG0sZpeXLxC%2Fuploads%2FkGz4ePNo3wGfWjb5ycOs%2FScreenshot%202023-06-27%20at%203.20.00%20PM.png?alt=media&amp;token=94459212-cf86-4546-aed0-615223539a30" alt=""><figcaption></figcaption></figure>

Use the knowledgeName and documentID with the `.getDocument` function of cortex to retrieve the document. See the Node.js Library for the exact .json return structure.

{% tabs %}
{% tab title="Typescript" %}

```javascript
try {
    const res = await cortex.getDocument('tigers','testing.txt')
    const document = res.data.document
    console.log(document.text);
} catch (error) {
    if (error.response) {
        console.log(error.response.status);
        console.log(error.response.data);
    } else {
        console.log(error.message);
    }
}
```

{% endtab %}

{% tab title="Python" %}

```python
CortexAPI.getDocument('tigers','testing.txt')
```

{% endtab %}
{% endtabs %}

## Uploading a Document

Find the knowledgeName of the desired location of the document.

Create an object that follows the createDocument interface to upload.

{% tabs %}
{% tab title="Typescript" %}

```javascript
interface createDocument {
  timestamp?: number;
  tags?: string[];
  text?: string | null;
  source_url?: string | null;
};
```

{% endtab %}

{% tab title="Python" %}

```python
class CreateDocument:
    def __init__(
        self,
        timestamp: Union[int, None] = None,
        tags:
        List[str] = None,
        text: Union[str, None] = None,
        source_url: Union[str, None] = None
    ):
        self.timestamp = timestamp
        self.tags = tags
        self.text = text
        self.source_url = source_url
```

{% endtab %}
{% endtabs %}

Use the documentID parameter to name the document you want to upload.

{% tabs %}
{% tab title="Typescript" %}

```javascript
const test = {
  "source_url": "https://www.test.com/",
  "text": "test"
  }

try {
  let output = await cortex.uploadDocument('tigers','test1',test);
  console.log(output.data.document);
} catch (error) {
  if (error.response) {
    console.log(error.response.status);
    console.log(error.response.data);
  } else {
    console.log(error.message);
  }
}
```

{% endtab %}

{% tab title="Python" %}

```python
test = cortex.CreateDocument()
test.source_url = "https://www.test.com/"
test.text = "test"

CortexAPI = cortex.CortexAPI("sk-...")
CortexAPI.uploadDocument('tigers','test1',test)
```

{% endtab %}
{% endtabs %}

## Deleting a Document

{% tabs %}
{% tab title="Typescript" %}

```javascript
try {
  let output = await cortex.deleteDocument('tigers','test1');
  console.log(output.data.document);
} catch (error:any) {
  if (error.response) {
    console.log(error.response.status);
    console.log(error.response.data);
  } else {
    console.log(error.message);
  }
}
```

{% endtab %}

{% tab title="Python" %}

```python
CortexAPI.deleteDocument('tigers','test1')
```

{% endtab %}
{% endtabs %}


# Introduction

Interact with our API with HTTP requests or use our Node.js or Python Libraries.

Install our Node.js library with the following command

```bash
npm install cortex-ts
```


# Authentication

Cortex uses an API key to authenticate HTTP requests. Find your API key in the drop down of your profile where it says View API Keys.

<figure><img src="https://3035252822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FeiBCAl6qTuG0sZpeXLxC%2Fuploads%2FQf7qnhi8HvXIu1gJsT3K%2FAPIKey.png?alt=media&amp;token=13da1399-8787-4424-ada5-e86e00fa2314" alt=""><figcaption></figcaption></figure>

API requests should include your API key in the HTTP header.

```http
Authorization: Bearer CORTEX_API_KEY
```


# Making Curl Requests

## Callables

After deploying a Callable, Cortex provides the direct curl request to send inputs to.

```sh
curl -L https://trycortex.ai/api/sdk/p/[pID]/a/[aID]/r \
    -H "Authorization: Bearer $CORTEX_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "version": 1,
      "config": {
        "OUTPUT_STREAM":{
          "provider_id":"openai",
          "model_id":"gpt-3.5-turbo-16k",
          "use_cache":true,
          "use_semantic_cache":false},
        "RETRIEVALS":{
            "knowledge":[{
              "project_id":"$pID",
              "data_source_id":"$DATASOURCE"}],
            "top_k":10,
            "filter":{"tags":null,"timestamp":null},
            "use_cache":false}},
      "blocking": true,
      "inputs": [{ "Key": "Value" }]
    }'
```

By providing a specified key and value pairs into the input, the HTTP response will contain a json with the corresponding output from the callable.

### Request body

| Name                 | Description                                                                   |
| -------------------- | ----------------------------------------------------------------------------- |
| `version (Required)` | (`integer \| 'latest'`) specify which version of the callable you want to run |
| `config (Required)`  | (`object`) configures the callable blocks                                     |
| `inputs (Required)`  | (`array`) array of key and value pairs that will be sent to the callable      |

## Documents

Example curl request

```bash
curl -L https://trycortex.ai/api/sdk/p/[pID]/knowledge/[knowledgeName]/d/[docID] \
    -H "Authorization: Bearer $CORTEX_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      “text”: “value”
    }'
```

### Request body

* text (string)
  * the document text


# Node.js Library

{% embed url="<https://github.com/kinesysai/cortex-ts>" %}

## Documents

#### <mark style="color:purple;">.getDocument(knowledgeName: string, documentID: string)</mark>

The function `.getDocument` takes in two parameters: `knowledgeName` and `documentID`. It retrieves a specific document from a specified knowledge base. The function returns an `AxiosPromise` with the document object.

Example return json:

<pre class="language-javascript"><code class="lang-javascript">{
<strong>    "document": {
</strong>        "created": integer,
        "document_id": string,
        "timestamp": integer,
        "tags": string[],
        "source_url": string,
        "hash": string,
        "text_size": integer,
        "chunk_count": integer,
        "chunks": [],
        "text": string
    } 
}
</code></pre>

#### <mark style="color:purple;">.uploadDocument(knowledgeName: string, documentID: string, document: createDocument)</mark>

The function `.uploadDocument` takes in three parameters: `knowledgeName`, `documentID`, and `document`. It uploads a new document to a specified knowledge base. The function returns an `AxiosPromise` with the newly uploaded document object and the knowledge object that the document was uploaded to.

The Document object has the following interface:

```javascript
interface createDocument {
  timestamp?: number;
  tags?: string[];
  text?: string | null;
  source_url?: string | null;
};
```

Example return json:

```javascript
{
    "document": {
        "created": integer,
        "document_id": string,
        "timestamp": integer,
        "tags": [],
        "source_url": string,
        "hash": string,
        "text_size": integer,
        "chunk_count": integer,
        "chunks": [
            {
                "text": string,
                "hash": string,
                "offset": 0,
                "vector": [],
                "score": null
            }
        ]
    },
    "knowledge": {
        "name": string,
        "description": string,
        "visibility": "private" | "public",
        "config": "{\"provider_id\":\"openai\",\"model_id\":\"text-embedding-ada-002\",\"extras\":null,\"splitter_id\":\"base_v0\",\"max_chunk_size\":365,\"use_cache\":false}",
        "runnerProjectId": string,
        "lastUpdatedAt": string,
        "hub": null
    }
}
```

#### <mark style="color:purple;">.deleteDocument(knowledgeName: string, documentID: string)</mark>

The function `.deleteDocument` takes in two parameters: `knowledgeName` and `documentID`. It deletes a specific document from a specified knowledge base. The function returns an `AxiosPromise` with the deleted document object.

## Callable

#### <mark style="color:purple;">`.runCallable(callableID: string, data: CallableParams): AxiosPromise<{run: RunType}>`</mark>

This function runs a callable identified by `callableID` with the given `data`. The `data` parameter must be an object of type `CallableParams` which includes the `version`, `config`, `inputs`, `blocking`, and `block_filter` properties. The `version` property specifies the version of the callable to run. The `config` property is an object of configuration parameters for the callable. The `inputs` property is an array of input values for the callable. The `blocking` property is a boolean that specifies whether the function should wait for the callable to complete before returning. The `block_filter` property is an array of block status filters for the callable. The function returns a promise that resolves to an object of type `AxiosPromise<{run: RunType}>` which includes the status of the run.

#### <mark style="color:purple;">`.runCallableWithStream(callableID: string, data: CallableParams): AxiosPromise`</mark>

This function runs a callable identified by `callableID` with the given `data` and streams the output. The `data` parameter must be an object of type `CallableParams` which includes the `version`, `config`, `inputs`, `blocking`, and `block_filter` properties. The `version` property specifies the version of the callable to run. The `config` property is an object of configuration parameters for the callable. The `inputs` property is an array of input values for the callable. The `blocking` property is a boolean that specifies whether the function should wait for the callable to complete before returning. The `block_filter` property is an array of block status filters for the callable. The function returns a promise that resolves to an object of type `AxiosPromise` which includes the streamed output of the callable.

#### <mark style="color:purple;">`.runChatCompletion(version: string, messages: Message[], input: string, projectID:string, knowledgeName: string, copilotID: string)`</mark>

| Name            | Description                                                                     |
| --------------- | ------------------------------------------------------------------------------- |
| `version`       | (`string`) `"latest"` \| version number                                         |
| `messages`      | (`Message[]`) array of messages previously sent to the chat callable            |
| `input`         | (`string`) chat message that wants to be answered                               |
| `projectID`     | (`string`) projectID of user who created the knowledge that is being referenced |
| `knowledgeName` | (`string`) name of knowledge being referenced                                   |
| `copilotID`     | (`string`) ID of chat copilot                                                   |


# Python Library

Coming Soon!


