Security News
JSR Working Group Kicks Off with Ambitious Roadmap and Plans for Open Governance
At its inaugural meeting, the JSR Working Group outlined plans for an open governance model and a roadmap to enhance JavaScript package management.
@cognite/copilot-core
Advanced tools
This is the core library for the Copilot. It contains the UI for the chatbot, and acts as a thin wrapper above the Chains from `@cognite/llm-hub`.
This is the core library for the Copilot. It contains the UI for the chatbot, and acts as a thin wrapper above the Chains from @cognite/llm-hub
.
yarn add @cognite/copilot-core
# if your in `fusion` repo already, you can skip this,
# '@fusion/copilot-core' is already avaialble to you
Copilot
component from the library and mount it. It expects a valid sdk
(CogniteClient).import { Copilot } from '@cognite/copilot-core';
// or
// import { Copilot } from '@fusion/copilot-core'
// somewhere in your app
<Copilot sdk={sdk}>{/* children */}</Copilot>;
You can mount the copilot anywhere in your app, but we recommend the root. With this wrapper, useCopilotContext
will be available to you anywhere in your app. You can use this to customize the copilot chat interface, such as (or "for example"/"e.g."):
We call these features "Flows", more on this in next section.
Flows are features you can run to help a user do a task end to end. They are wrapped around a Chain from @cognite/llm-hub
usually, but they can be anything.
For example, we have PythonAppBuilderFlow
which is a flow that helps a user build a python app. This flow is a wrapper around the PythonAppBuilderChain
from @cognite/llm-hub
. In the Flow, we add the ability for apps to pass in the current code, and also decide how the response should be rendered as a UI for the user.
A Flow is defined as the following:
import { CogniteClient } from '@cognite/sdk';
import { Flow, CopilotBotTextResponse } from '@cognite/copilot-core'; // or '@fusion/copilot-core' from within the fusion repo
type Input = { prompt: string; sdk: CogniteClient }; // must at least have SDK
type Output = CopilotBotTextResponse; // must be one of CopilotBotResponse
export class MyAwesomeFlow extends Flow<Input, Output> {
label = 'Inquire about CDF';
description = 'Answer questions about CDF';
// must be implemented
// takes the input, does magic, and gives a Response
run: Flow<Input, Output>['run'] = async ({ prompt, sdk }) => {
// some magic...
// here you should also run Chains from @cognite/llm-hub
return {
type: 'text',
content: 'some new content',
};
};
// implement chatRun to allow for it to run from Copilot
chatRun: Flow<Input, Output>['chatRun'] = async (sendMessage, sendStatus) => {
// loop through required Inputs that hasnt been completed yet
if (this.fields?.prompt === undefined) {
// return only valid "UserAction" (those supported by the chatbot)
return {
text: 'What would like you like to know about CDF?',
type: 'text',
onNext: ({ content }) => {
this.fields.prompt = content;
},
};
}
// update status
sendStatus({ status: 'Finding answer...' });
// send a Response to the copilot coming back by the default run
// and send to the user as a Message
sendMessage(await this.run(this.fields as Input));
// reset the state after a response is finished
this.fields.prompt = undefined;
// return undefined to stop the chatbot from asking for more input
return undefined;
};
}
After declaring the flow, there are 2 ways to run the flow.
const { runFlow } = useCopilotContext();
const flow = useMemo(() => new MyAwesomeFlow({ sdk }), [sdk]);
const response = await runFlow(flow, { prompt: 'What is CDF' });
// if you want to have the response in the chatbot with a message indicating some context, you can do
const response = await runFlow(flow, { prompt: 'What is CDF' }, true, { type: 'text', content: 'Running this now', source: 'user' });
const { registerFlow } = useCopilotContext();
const flow = useMemo(() => new MyAwesomeFlow({ sdk }), [sdk]);
useEffect(() => {
const unregister = await registerFlow({
flow,
});
// dont forget to unregister the flow
return () => unregister();
}, []);
Sometimes you need to pass in additional input to the flow that needs to be passed in at time of request (i.e. the current code when user runs the Flow).
const unregister = await registerFlow({
flow,
input: {
somethingFromTheApp: () => someRef.current.value,
},
});
Sometimes the message from Copilot (Responses from Flows) needs additional actions for users to be able to interact with. For example, the PythonAppBuilderFlow
has a "Use code" button that allows users to use the code.
const unregister = await registerFlow({
flow,
undefined,
messageActions: {
text: (message) => [
{
content: 'Use code',
onClick: () => {
// do something with message.content
},
},
],
},
});
AI states
loadingStatus
- the current loading status of the copilotUI states
messages
- all the current messagescreateNewChat
- creates a new chatshowChatButton
/setShowChatButton
- the current visibility of the chat buttonExplaining more of how it works, here's some diagrams
monaco
Make sure to create a file like the following
/* eslint-disable import/no-webpack-loader-syntax */
/** This is the built in way how to load the web workers using webpack is with worker-loader */
import { loader } from '@monaco-editor/react';
import * as monaco from 'monaco-editor';
/** This is the built in way how to load the web workers using webpack is with worker-loader */
import { Environment as MonacoEditorEnvironment } from 'monaco-editor';
import MonacoEditorWorker from 'worker-loader?esModule=true&inline=fallback!monaco-editor/esm/vs/editor/editor.worker?worker';
// point here so the context can be used
declare const self: any;
(self as any).MonacoEnvironment = {
getWorker(_: string, _label: string) {
// otherwise, load the default web worker from monaco
return new MonacoEditorWorker();
},
} as MonacoEditorEnvironment;
loader.config({ monaco });
styles
Additionally, make sure to load in the styles!
import 'highlight.js/styles/dracula.css';
import 'monaco-editor/dev/vs/editor/editor.main.css';
import 'react-resizable/css/styles.css';
import '@cognite/cogs.js/dist/cogs.css';
import '@cognite/cogs.js-v10/dist/cogs.css';
In fusion monorepo if you want to use this library in any subapp, just load it in via @fusion/copilot-core
. Then any updates are picked up immediately from the app you are running local dev mode or build.
We have also a thin wrapper for the homepage's copilot, which is in apps/copilot
. For that to develop locally read the README there.
To host build the library by itself, you can just run yarn nx build copilot-core --with-deps --watch
. The --watch
will allow NX to watch for changes and rebuild the library.
For debugging add
--skip-nx-cache
if you want to make sure it is always building, and not loading from cache.
The output of the library will be at dist/libs/@fusion/copilot-core
(NOT dist/libs/copilot-core
). This is good to know as you can run yarn link
from the library, and then yarn link @cognite/copilot-core
from the app you want to use it in. This will allow you to use the locally built library from the app. To see how yarn link works, check here.
@cognite/llm-hub
There's a special caveat to just the normal yarn link
method, as the `@cognite/sdk`` will cause issues, thus
fusion
cd node_modules/@cognite/sdk
yarn link
(set up SDK linking)cd ../../../
)llm-hub
yarn link @cognite/sdk
(link up to @cognite/sdk from fusion)yarn build --watch
yarn link
(set up llm-hub linking)fusion
yarn link @cognite/llm-hub
(link up to @cognite/llm-hub from cognite-llm-hub)Voila!
Copilot is built in fusion, which is linked and imported from other apps (link from fusion, used in app), in these cases you may see errors for common libraries, like
error: react hooks invalid
or core-js not found
.
In these cases, the app you are running takes priority, and fusion
side needs to respect the packages of your app.
You then would link @cognite/sdk
and monaco-editor
and react
the opposite way - from your app to fusion. To do this, go to node_modules/<package>
like node_modules/@cognite/sdk
and run yarn link from the other repo (the app you are running copilot in), then in the fusion side (from the root folder /fusion
NOT /fusion/lib/copilot-core
), do yarn link <package>
.
yarn nx build copilot-core --watch
again
Note:
Intel chips There is a potential issue with core-js, in which case, install core-js in the root of this repo / in the
libs/copilot-core
.
Run yarn nx test copilot-core
to execute the unit tests via Jest.
Run yarn nx storybook copilot-core
FAQs
This is the core library for the Copilot. It contains the UI for the chatbot, and acts as a thin wrapper above the Chains from `@cognite/llm-hub`.
We found that @cognite/copilot-core demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
At its inaugural meeting, the JSR Working Group outlined plans for an open governance model and a roadmap to enhance JavaScript package management.
Security News
Research
An advanced npm supply chain attack is leveraging Ethereum smart contracts for decentralized, persistent malware control, evading traditional defenses.
Security News
Research
Attackers are impersonating Sindre Sorhus on npm with a fake 'chalk-node' package containing a malicious backdoor to compromise developers' projects.