@copilotkit/react-core 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,19 +1,19 @@
1
1
 
2
- > @copilotkit/react-core@0.1.0 build /Users/ataibarkai/LocalGit/Recursively.ai/CopilotKit2/packages/react-core
3
- > tsup --format cjs --dts
2
+ > @copilotkit/react-core@0.2.0 build /Users/ataibarkai/LocalGit/Recursively.ai/CopilotKit2/packages/react-core
3
+ > tsup src/index.tsx --format esm,cjs --dts --external react
4
4
 
5
- CLI Building entry: src/hook.tsx, src/index.tsx
5
+ CLI Building entry: src/index.tsx
6
6
  CLI Using tsconfig: tsconfig.json
7
7
  CLI tsup v6.5.0
8
8
  CLI Using tsup config: /Users/ataibarkai/LocalGit/Recursively.ai/CopilotKit2/packages/react-core/tsup.config.ts
9
9
  CLI Target: es6
10
10
  CLI Cleaning output folder
11
+ ESM Build start
11
12
  CJS Build start
12
- CJS dist/chunk-KFCOT2YX.js 531.00 B
13
- CJS dist/hook.js 190.00 B
14
- CJS dist/index.js 190.00 B
15
- CJS ⚡️ Build success in 21ms
13
+ ESM dist/index.mjs 5.46 KB
14
+ ESM ⚡️ Build success in 61ms
15
+ CJS dist/index.js 5.50 KB
16
+ CJS ⚡️ Build success in 61ms
16
17
  DTS Build start
17
- DTS ⚡️ Build success in 284ms
18
- DTS dist/hook.d.ts 57.00 B
19
- DTS dist/index.d.ts 38.00 B
18
+ DTS ⚡️ Build success in 484ms
19
+ DTS dist/index.d.ts 2.31 KB
package/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # ui
2
2
 
3
+ ## 0.3.0
4
+
5
+ ### Minor Changes
6
+
7
+ - working version
8
+ - 9d2f3cb: semi compiling
9
+
3
10
  ## 0.2.0
4
11
 
5
12
  ### Minor Changes
package/dist/index.d.ts CHANGED
@@ -1 +1,55 @@
1
- export { useTurbo } from './hook.js';
1
+ import React$1, { ReactNode } from 'react';
2
+ import { ChatCompletionFunctions } from 'openai-edge/types/api';
3
+ import { FunctionCallHandler, UseChatOptions, Message, CreateMessage, ChatRequestOptions } from 'ai';
4
+
5
+ declare function CopilotProvider({ children }: {
6
+ children: ReactNode;
7
+ }): JSX.Element;
8
+
9
+ interface AnnotatedFunctionArgument {
10
+ name: string;
11
+ type: string;
12
+ description: string;
13
+ allowedValues?: any[];
14
+ required: boolean;
15
+ }
16
+ interface AnnotatedFunction<Inputs extends any[]> {
17
+ name: string;
18
+ description: string;
19
+ argumentAnnotations: AnnotatedFunctionArgument[];
20
+ implementation: (...args: Inputs) => Promise<void>;
21
+ }
22
+
23
+ type TreeNodeId = string;
24
+
25
+ interface CopilotContextParams {
26
+ entryPoints: Record<string, AnnotatedFunction<any[]>>;
27
+ getChatCompletionFunctions: () => ChatCompletionFunctions[];
28
+ getFunctionCallHandler: () => FunctionCallHandler;
29
+ setEntryPoint: (id: string, entryPoint: AnnotatedFunction<any[]>) => void;
30
+ removeEntryPoint: (id: string) => void;
31
+ getContextString: () => string;
32
+ addContext: (context: string, parentId?: string) => TreeNodeId;
33
+ removeContext: (id: TreeNodeId) => void;
34
+ }
35
+ declare const CopilotContext: React$1.Context<CopilotContextParams>;
36
+
37
+ interface UseCopilotChatOptions extends UseChatOptions {
38
+ makeSystemMessage?: (contextString: string) => string;
39
+ }
40
+ interface UseCopilotChatReturn {
41
+ visibleMessages: Message[];
42
+ append: (message: Message | CreateMessage, chatRequestOptions?: ChatRequestOptions) => Promise<string | null | undefined>;
43
+ reload: (chatRequestOptions?: ChatRequestOptions) => Promise<string | null | undefined>;
44
+ stop: () => void;
45
+ isLoading: boolean;
46
+ input: string;
47
+ setInput: React.Dispatch<React.SetStateAction<string>>;
48
+ }
49
+ declare function useCopilotChat({ makeSystemMessage, ...options }: UseCopilotChatOptions): UseCopilotChatReturn;
50
+
51
+ declare function useMakeCopilotActionable<ActionInput extends any[]>(annotatedFunction: AnnotatedFunction<ActionInput>, dependencies: any[]): void;
52
+
53
+ declare function useMakeCopilotReadable(information: string, parentId?: string): string | undefined;
54
+
55
+ export { AnnotatedFunction, AnnotatedFunctionArgument, CopilotContext, CopilotContextParams, CopilotProvider, UseCopilotChatOptions, UseCopilotChatReturn, useCopilotChat, useMakeCopilotActionable, useMakeCopilotReadable };
package/dist/index.js CHANGED
@@ -1,10 +1,32 @@
1
1
  'use strict';
2
2
 
3
- var chunkKFCOT2YX_js = require('./chunk-KFCOT2YX.js');
3
+ var V = require('react');
4
+ var nanoid = require('nanoid');
5
+ var jsxRuntime = require('react/jsx-runtime');
6
+ var react = require('ai/react');
4
7
 
8
+ var k=Object.defineProperty,q=Object.defineProperties;var U=Object.getOwnPropertyDescriptors;var x=Object.getOwnPropertySymbols;var P=Object.prototype.hasOwnProperty,A=Object.prototype.propertyIsEnumerable;var N=(e,t,n)=>t in e?k(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,h=(e,t)=>{for(var n in t||(t={}))P.call(t,n)&&N(e,n,t[n]);if(x)for(var n of x(t))A.call(t,n)&&N(e,n,t[n]);return e},T=(e,t)=>q(e,U(t));var E=(e,t)=>{var n={};for(var o in e)P.call(e,o)&&t.indexOf(o)<0&&(n[o]=e[o]);if(e!=null&&x)for(var o of x(e))t.indexOf(o)<0&&A.call(e,o)&&(n[o]=e[o]);return n};var v=(e,t,n)=>new Promise((o,r)=>{var i=u=>{try{a(n.next(u));}catch(c){r(c);}},s=u=>{try{a(n.throw(u));}catch(c){r(c);}},a=u=>u.done?o(u.value):Promise.resolve(u.value).then(i,s);a((n=n.apply(e,t)).next());});var I=(e,t)=>{for(let n of e){if(n.id===t)return n;let o=I(n.children,t);if(o)return o}},M=(e,t)=>e.reduce((n,o)=>{if(o.id!==t){let r=T(h({},o),{children:M(o.children,t)});n.push(r);}return n},[]),b=(e,t)=>{if(t===0)return (e+1).toString();if(t===1)return String.fromCharCode(65+e);if(t===2)return String.fromCharCode(97+e);throw new Error("Indentation level not supported")},O=(e,t="",n=0)=>{let o=" ".repeat(3).repeat(n),r=t.length+o.length,i=" ".repeat(r),s=e.value.split(`
9
+ `),a=`${o}${t}${s[0]}`,u=s.slice(1).map(l=>`${i}${l}`).join(`
10
+ `),c=`${a}
11
+ `;return u&&(c+=`${u}
12
+ `),e.children.forEach((l,g)=>c+=O(l,`${t}${b(g,n+1)}. `,n+1)),c};function j(e,t){switch(t.type){case"ADD_NODE":{let{value:n,parentId:o,id:r}=t,i={id:r,value:n,children:[]};if(o){let s=I(e,o);if(s)i.parentId=o,s.children.push(i);else throw new Error(`Parent with id ${o} not found`)}else return [...e,i];return e}case"REMOVE_NODE":return M(e,t.id);default:return e}}var L=()=>{let[e,t]=V.useReducer(j,[]),n=V.useCallback((i,s)=>{let a=nanoid.nanoid();return t({type:"ADD_NODE",value:i,parentId:s,id:a}),a},[]),o=V.useCallback(i=>{t({type:"REMOVE_NODE",id:i});},[]);return {tree:e,addElement:n,printTree:()=>{let i="";return e.forEach((s,a)=>i+=O(s,`${b(a,0)}. `)),i},removeElement:o}},w=L;var J={entryPoints:{},getChatCompletionFunctions:()=>[],getFunctionCallHandler:()=>()=>v(void 0,null,function*(){}),setEntryPoint:()=>{},removeEntryPoint:()=>{},getContextString:()=>"",addContext:()=>"",removeContext:()=>{}},d=V.createContext(J);function B({children:e}){let[t,n]=V.useState({}),{addElement:o,removeElement:r,printTree:i}=w(),s=V.useCallback((p,m)=>{n(C=>T(h({},C),{[p]:m}));},[]),a=V.useCallback(p=>{n(m=>{let C=h({},m);return delete C[p],C});},[]),u=V.useCallback(()=>i(),[i]),c=V.useCallback((p,m)=>o(p,m),[o]),l=V.useCallback(p=>{r(p);},[r]),g=V.useCallback(()=>X(Object.values(t)),[t]),F=V.useCallback(()=>W(Object.values(t)),[t]);return jsxRuntime.jsx(d.Provider,{value:{entryPoints:t,getChatCompletionFunctions:g,getFunctionCallHandler:F,setEntryPoint:s,removeEntryPoint:a,getContextString:u,addContext:c,removeContext:l},children:e})}function W(e){return (t,n)=>v(this,null,function*(){let o={};for(let i of e)o[i.name]=i;let r=o[n.name||""];if(r){let i=[];n.arguments&&(i=JSON.parse(n.arguments));let s=[];for(let a of r.argumentAnnotations)s.push(i[a.name]);yield r.implementation(...s);}})}function X(e){return e.map(Y)}function Y(e){let t={};for(let r of e.argumentAnnotations)t[r.name]={type:r.type,description:r.description};let n=[];for(let r of e.argumentAnnotations)r.required&&n.push(r.name);return {name:e.name,description:e.description,parameters:{type:"object",properties:t,required:n}}}function Z(n){var o=n,{makeSystemMessage:e}=o,t=E(o,["makeSystemMessage"]);let{getContextString:r,getChatCompletionFunctions:i,getFunctionCallHandler:s}=V.useContext(d),u=[V.useMemo(()=>{let y=e||te,$=r();return {id:"system",content:y($),role:"system"}},[r,e])].concat(t.initialMessages||[]),c=V.useMemo(()=>i(),[i]),{messages:l,append:g,reload:F,stop:p,isLoading:m,input:C,setInput:D}=react.useChat({id:t.id,initialMessages:u,experimental_onFunctionCall:s(),body:{id:t.id,previewToken:ee,functions:c}});return {visibleMessages:l.filter(y=>y.role==="user"||y.role==="assistant"),append:g,reload:F,stop:p,isLoading:m,input:C,setInput:D}}var ee="TODO123";function te(e){return `
13
+ Please act as a efficient, competent, and conscientious professional assistant.
14
+ You help the user achieve their goals, and you do so in a way that is as efficient as possible, without unnecessary fluff, but also without sacrificing professionalism.
15
+ Always be polite and respectful, and prefer brevity over verbosity.
5
16
 
17
+ The user has provided you with the following context:
18
+ \`\`\`
19
+ ${e}
20
+ \`\`\`
6
21
 
7
- Object.defineProperty(exports, 'useTurbo', {
8
- enumerable: true,
9
- get: function () { return chunkKFCOT2YX_js.a; }
10
- });
22
+ They have also provided you with functions you can call to initiate actions on their behalf, or functions you can call to receive more information.
23
+
24
+ Please assist them as best you can.
25
+ If you are not sure how to proceed to best fulfill their requests, please ask them for more information.
26
+ `}function ae(e,t){let n=V.useRef(nanoid.nanoid()),{setEntryPoint:o,removeEntryPoint:r}=V.useContext(d),i=V.useMemo(()=>({name:e.name,description:e.description,argumentAnnotations:e.argumentAnnotations,implementation:e.implementation}),t);V.useEffect(()=>(o(n.current,i),()=>{r(n.current);}),[i,o,r]);}function de(e,t){let{addContext:n,removeContext:o}=V.useContext(d),r=V.useRef();return V.useEffect(()=>{let i=n(e,t);return r.current=i,()=>{o(i);}},[e,t,n,o]),r.current}
27
+
28
+ exports.CopilotContext = d;
29
+ exports.CopilotProvider = B;
30
+ exports.useCopilotChat = Z;
31
+ exports.useMakeCopilotActionable = ae;
32
+ exports.useMakeCopilotReadable = de;
package/dist/index.mjs ADDED
@@ -0,0 +1,26 @@
1
+ import V, { useState, useCallback, useContext, useMemo, useRef, useEffect, useReducer } from 'react';
2
+ import { nanoid } from 'nanoid';
3
+ import { jsx } from 'react/jsx-runtime';
4
+ import { useChat } from 'ai/react';
5
+
6
+ var k=Object.defineProperty,q=Object.defineProperties;var U=Object.getOwnPropertyDescriptors;var x=Object.getOwnPropertySymbols;var P=Object.prototype.hasOwnProperty,A=Object.prototype.propertyIsEnumerable;var N=(e,t,n)=>t in e?k(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,h=(e,t)=>{for(var n in t||(t={}))P.call(t,n)&&N(e,n,t[n]);if(x)for(var n of x(t))A.call(t,n)&&N(e,n,t[n]);return e},T=(e,t)=>q(e,U(t));var E=(e,t)=>{var n={};for(var o in e)P.call(e,o)&&t.indexOf(o)<0&&(n[o]=e[o]);if(e!=null&&x)for(var o of x(e))t.indexOf(o)<0&&A.call(e,o)&&(n[o]=e[o]);return n};var v=(e,t,n)=>new Promise((o,r)=>{var i=u=>{try{a(n.next(u));}catch(c){r(c);}},s=u=>{try{a(n.throw(u));}catch(c){r(c);}},a=u=>u.done?o(u.value):Promise.resolve(u.value).then(i,s);a((n=n.apply(e,t)).next());});var I=(e,t)=>{for(let n of e){if(n.id===t)return n;let o=I(n.children,t);if(o)return o}},M=(e,t)=>e.reduce((n,o)=>{if(o.id!==t){let r=T(h({},o),{children:M(o.children,t)});n.push(r);}return n},[]),b=(e,t)=>{if(t===0)return (e+1).toString();if(t===1)return String.fromCharCode(65+e);if(t===2)return String.fromCharCode(97+e);throw new Error("Indentation level not supported")},O=(e,t="",n=0)=>{let o=" ".repeat(3).repeat(n),r=t.length+o.length,i=" ".repeat(r),s=e.value.split(`
7
+ `),a=`${o}${t}${s[0]}`,u=s.slice(1).map(l=>`${i}${l}`).join(`
8
+ `),c=`${a}
9
+ `;return u&&(c+=`${u}
10
+ `),e.children.forEach((l,g)=>c+=O(l,`${t}${b(g,n+1)}. `,n+1)),c};function j(e,t){switch(t.type){case"ADD_NODE":{let{value:n,parentId:o,id:r}=t,i={id:r,value:n,children:[]};if(o){let s=I(e,o);if(s)i.parentId=o,s.children.push(i);else throw new Error(`Parent with id ${o} not found`)}else return [...e,i];return e}case"REMOVE_NODE":return M(e,t.id);default:return e}}var L=()=>{let[e,t]=useReducer(j,[]),n=useCallback((i,s)=>{let a=nanoid();return t({type:"ADD_NODE",value:i,parentId:s,id:a}),a},[]),o=useCallback(i=>{t({type:"REMOVE_NODE",id:i});},[]);return {tree:e,addElement:n,printTree:()=>{let i="";return e.forEach((s,a)=>i+=O(s,`${b(a,0)}. `)),i},removeElement:o}},w=L;var J={entryPoints:{},getChatCompletionFunctions:()=>[],getFunctionCallHandler:()=>()=>v(void 0,null,function*(){}),setEntryPoint:()=>{},removeEntryPoint:()=>{},getContextString:()=>"",addContext:()=>"",removeContext:()=>{}},d=V.createContext(J);function B({children:e}){let[t,n]=useState({}),{addElement:o,removeElement:r,printTree:i}=w(),s=useCallback((p,m)=>{n(C=>T(h({},C),{[p]:m}));},[]),a=useCallback(p=>{n(m=>{let C=h({},m);return delete C[p],C});},[]),u=useCallback(()=>i(),[i]),c=useCallback((p,m)=>o(p,m),[o]),l=useCallback(p=>{r(p);},[r]),g=useCallback(()=>X(Object.values(t)),[t]),F=useCallback(()=>W(Object.values(t)),[t]);return jsx(d.Provider,{value:{entryPoints:t,getChatCompletionFunctions:g,getFunctionCallHandler:F,setEntryPoint:s,removeEntryPoint:a,getContextString:u,addContext:c,removeContext:l},children:e})}function W(e){return (t,n)=>v(this,null,function*(){let o={};for(let i of e)o[i.name]=i;let r=o[n.name||""];if(r){let i=[];n.arguments&&(i=JSON.parse(n.arguments));let s=[];for(let a of r.argumentAnnotations)s.push(i[a.name]);yield r.implementation(...s);}})}function X(e){return e.map(Y)}function Y(e){let t={};for(let r of e.argumentAnnotations)t[r.name]={type:r.type,description:r.description};let n=[];for(let r of e.argumentAnnotations)r.required&&n.push(r.name);return {name:e.name,description:e.description,parameters:{type:"object",properties:t,required:n}}}function Z(n){var o=n,{makeSystemMessage:e}=o,t=E(o,["makeSystemMessage"]);let{getContextString:r,getChatCompletionFunctions:i,getFunctionCallHandler:s}=useContext(d),u=[useMemo(()=>{let y=e||te,$=r();return {id:"system",content:y($),role:"system"}},[r,e])].concat(t.initialMessages||[]),c=useMemo(()=>i(),[i]),{messages:l,append:g,reload:F,stop:p,isLoading:m,input:C,setInput:D}=useChat({id:t.id,initialMessages:u,experimental_onFunctionCall:s(),body:{id:t.id,previewToken:ee,functions:c}});return {visibleMessages:l.filter(y=>y.role==="user"||y.role==="assistant"),append:g,reload:F,stop:p,isLoading:m,input:C,setInput:D}}var ee="TODO123";function te(e){return `
11
+ Please act as a efficient, competent, and conscientious professional assistant.
12
+ You help the user achieve their goals, and you do so in a way that is as efficient as possible, without unnecessary fluff, but also without sacrificing professionalism.
13
+ Always be polite and respectful, and prefer brevity over verbosity.
14
+
15
+ The user has provided you with the following context:
16
+ \`\`\`
17
+ ${e}
18
+ \`\`\`
19
+
20
+ They have also provided you with functions you can call to initiate actions on their behalf, or functions you can call to receive more information.
21
+
22
+ Please assist them as best you can.
23
+ If you are not sure how to proceed to best fulfill their requests, please ask them for more information.
24
+ `}function ae(e,t){let n=useRef(nanoid()),{setEntryPoint:o,removeEntryPoint:r}=useContext(d),i=useMemo(()=>({name:e.name,description:e.description,argumentAnnotations:e.argumentAnnotations,implementation:e.implementation}),t);useEffect(()=>(o(n.current,i),()=>{r(n.current);}),[i,o,r]);}function de(e,t){let{addContext:n,removeContext:o}=useContext(d),r=useRef();return useEffect(()=>{let i=n(e,t);return r.current=i,()=>{o(i);}},[e,t,n,o]),r.current}
25
+
26
+ export { d as CopilotContext, B as CopilotProvider, Z as useCopilotChat, ae as useMakeCopilotActionable, de as useMakeCopilotReadable };
package/package.json CHANGED
@@ -4,15 +4,12 @@
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
7
- "version": "0.2.0",
8
- "sideEffects": [
9
- "**/*.css"
10
- ],
7
+ "version": "0.3.0",
8
+ "sideEffects": false,
9
+ "main": "./dist/index.mjs",
10
+ "module": "./dist/index.mjs",
11
+ "exports": "./dist/index.mjs",
11
12
  "types": "./dist/index.d.ts",
12
- "exports": {
13
- ".": "./dist",
14
- "./styles.css": "./dist/index.css"
15
- },
16
13
  "license": "MIT",
17
14
  "peerDependencies": {
18
15
  "react": "^18.2.0"
@@ -23,12 +20,18 @@
23
20
  "react": "^18.2.0",
24
21
  "tsup": "^6.1.3",
25
22
  "typescript": "^4.9.4",
26
- "eslint-config-custom": "0.0.0",
27
- "tsconfig": "0.0.0"
23
+ "eslint-config-custom": "0.1.0",
24
+ "tsconfig": "0.1.0"
25
+ },
26
+ "dependencies": {
27
+ "ai": "^2.1.19",
28
+ "nanoid": "^4.0.2",
29
+ "openai-edge": "^1.2.0"
28
30
  },
29
31
  "scripts": {
30
- "build": "tsup --format cjs --dts",
31
- "dev": "tsup --watch",
32
- "check-types": "tsc --noEmit"
32
+ "build": "tsup src/index.tsx --format esm,cjs --dts --external react",
33
+ "dev": "tsup src/index.tsx --format esm,cjs --dts --external react --watch",
34
+ "check-types": "tsc --noEmit",
35
+ "clean": "rm -rf .turbo && rm -rf node_modules && rm -rf dist && rm -rf .next"
33
36
  }
34
37
  }
@@ -0,0 +1,167 @@
1
+ 'use client'
2
+ import React, { useState, ReactNode, useCallback } from 'react'
3
+ import { AnnotatedFunction } from '../types/annotated-function'
4
+ import useTree from '../hooks/use-tree'
5
+ import { CopilotContext } from '../context/copilot-context'
6
+ import { FunctionCallHandler } from 'ai'
7
+ import { ChatCompletionFunctions } from 'openai-edge/types/api'
8
+
9
+ export function CopilotProvider({
10
+ children
11
+ }: {
12
+ children: ReactNode
13
+ }): JSX.Element {
14
+ const [entryPoints, setEntryPoints] = useState<
15
+ Record<string, AnnotatedFunction<any[]>>
16
+ >({})
17
+
18
+ const { addElement, removeElement, printTree } = useTree()
19
+
20
+ const setEntryPoint = useCallback(
21
+ (id: string, entryPoint: AnnotatedFunction<any[]>) => {
22
+ setEntryPoints(prevPoints => {
23
+ return {
24
+ ...prevPoints,
25
+ [id]: entryPoint
26
+ }
27
+ })
28
+ },
29
+ []
30
+ )
31
+
32
+ const removeEntryPoint = useCallback((id: string) => {
33
+ setEntryPoints(prevPoints => {
34
+ const newPoints = { ...prevPoints }
35
+ delete newPoints[id]
36
+ return newPoints
37
+ })
38
+ }, [])
39
+
40
+ const getContextString = useCallback(() => {
41
+ return printTree()
42
+ }, [printTree])
43
+
44
+ const addContext = useCallback(
45
+ (context: string, parentId?: string) => {
46
+ return addElement(context, parentId)
47
+ },
48
+ [addElement]
49
+ )
50
+
51
+ const removeContext = useCallback(
52
+ (id: string) => {
53
+ removeElement(id)
54
+ },
55
+ [removeElement]
56
+ )
57
+
58
+ const getChatCompletionFunctions = useCallback(() => {
59
+ return entryPointsToChatCompletionFunctions(Object.values(entryPoints))
60
+ }, [entryPoints])
61
+
62
+ const getFunctionCallHandler = useCallback(() => {
63
+ return entryPointsToFunctionCallHandler(Object.values(entryPoints))
64
+ }, [entryPoints])
65
+
66
+ return (
67
+ <CopilotContext.Provider
68
+ value={{
69
+ entryPoints,
70
+ getChatCompletionFunctions,
71
+ getFunctionCallHandler,
72
+ setEntryPoint,
73
+ removeEntryPoint,
74
+ getContextString,
75
+ addContext,
76
+ removeContext
77
+ }}
78
+ >
79
+ {children}
80
+ </CopilotContext.Provider>
81
+ )
82
+ }
83
+
84
+ function entryPointsToFunctionCallHandler(
85
+ entryPoints: AnnotatedFunction<any[]>[]
86
+ ): FunctionCallHandler {
87
+ return async (chatMessages, functionCall) => {
88
+ let entrypointsByFunctionName: Record<string, AnnotatedFunction<any[]>> = {}
89
+ for (let entryPoint of entryPoints) {
90
+ entrypointsByFunctionName[entryPoint.name] = entryPoint
91
+ }
92
+
93
+ const entryPointFunction =
94
+ entrypointsByFunctionName[functionCall.name || '']
95
+ if (entryPointFunction) {
96
+ let parsedFunctionCallArguments: Record<string, any>[] = []
97
+ if (functionCall.arguments) {
98
+ parsedFunctionCallArguments = JSON.parse(functionCall.arguments)
99
+ }
100
+
101
+ const paramsInCorrectOrder: any[] = []
102
+ for (let arg of entryPointFunction.argumentAnnotations) {
103
+ paramsInCorrectOrder.push(
104
+ parsedFunctionCallArguments[
105
+ arg.name as keyof typeof parsedFunctionCallArguments
106
+ ]
107
+ )
108
+ }
109
+
110
+ await entryPointFunction.implementation(...paramsInCorrectOrder)
111
+
112
+ // commented out becasue for now we don't want to return anything
113
+ // const result = await entryPointFunction.implementation(
114
+ // ...parsedFunctionCallArguments
115
+ // );
116
+ // const functionResponse: ChatRequest = {
117
+ // messages: [
118
+ // ...chatMessages,
119
+ // {
120
+ // id: nanoid(),
121
+ // name: functionCall.name,
122
+ // role: 'function' as const,
123
+ // content: JSON.stringify(result),
124
+ // },
125
+ // ],
126
+ // };
127
+
128
+ // return functionResponse;
129
+ }
130
+ }
131
+ }
132
+
133
+ function entryPointsToChatCompletionFunctions(
134
+ entryPoints: AnnotatedFunction<any[]>[]
135
+ ): ChatCompletionFunctions[] {
136
+ return entryPoints.map(annotatedFunctionToChatCompletionFunction)
137
+ }
138
+
139
+ function annotatedFunctionToChatCompletionFunction(
140
+ annotatedFunction: AnnotatedFunction<any[]>
141
+ ): ChatCompletionFunctions {
142
+ // Create the parameters object based on the argumentAnnotations
143
+ let parameters: { [key: string]: any } = {}
144
+ for (let arg of annotatedFunction.argumentAnnotations) {
145
+ parameters[arg.name] = { type: arg.type, description: arg.description }
146
+ }
147
+
148
+ let requiredParameterNames: string[] = []
149
+ for (let arg of annotatedFunction.argumentAnnotations) {
150
+ if (arg.required) {
151
+ requiredParameterNames.push(arg.name)
152
+ }
153
+ }
154
+
155
+ // Create the ChatCompletionFunctions object
156
+ let chatCompletionFunction: ChatCompletionFunctions = {
157
+ name: annotatedFunction.name,
158
+ description: annotatedFunction.description,
159
+ parameters: {
160
+ type: 'object',
161
+ properties: parameters,
162
+ required: requiredParameterNames
163
+ }
164
+ }
165
+
166
+ return chatCompletionFunction
167
+ }
@@ -0,0 +1 @@
1
+ export { CopilotProvider } from './copilot-provider'
@@ -0,0 +1,33 @@
1
+ 'use client'
2
+
3
+ import React from 'react'
4
+ import { AnnotatedFunction } from '../types/annotated-function'
5
+ import { TreeNodeId } from '../hooks/use-tree'
6
+ import { ChatCompletionFunctions } from 'openai-edge/types/api'
7
+ import { FunctionCallHandler } from 'ai'
8
+
9
+ export interface CopilotContextParams {
10
+ entryPoints: Record<string, AnnotatedFunction<any[]>>
11
+ getChatCompletionFunctions: () => ChatCompletionFunctions[]
12
+ getFunctionCallHandler: () => FunctionCallHandler
13
+ setEntryPoint: (id: string, entryPoint: AnnotatedFunction<any[]>) => void
14
+ removeEntryPoint: (id: string) => void
15
+
16
+ getContextString: () => string
17
+ addContext: (context: string, parentId?: string) => TreeNodeId
18
+ removeContext: (id: TreeNodeId) => void
19
+ }
20
+
21
+ const emptyCopilotContext: CopilotContextParams = {
22
+ entryPoints: {},
23
+ getChatCompletionFunctions: () => [],
24
+ getFunctionCallHandler: () => async () => {},
25
+ setEntryPoint: () => {},
26
+ removeEntryPoint: () => {},
27
+ getContextString: () => '',
28
+ addContext: () => '',
29
+ removeContext: () => {}
30
+ }
31
+
32
+ export const CopilotContext =
33
+ React.createContext<CopilotContextParams>(emptyCopilotContext)
@@ -0,0 +1,2 @@
1
+ export { CopilotContext } from './copilot-context'
2
+ export type { CopilotContextParams } from './copilot-context'
@@ -0,0 +1,6 @@
1
+ export { useCopilotChat } from './use-copilot-chat'
2
+ export type { UseCopilotChatOptions } from './use-copilot-chat'
3
+ export type { UseCopilotChatReturn } from './use-copilot-chat'
4
+
5
+ export { useMakeCopilotActionable } from './use-make-copilot-actionable'
6
+ export { useMakeCopilotReadable } from './use-make-copilot-readable'
@@ -0,0 +1,103 @@
1
+ import { useMemo, useContext } from 'react'
2
+ import {
3
+ CopilotContext,
4
+ CopilotContextParams
5
+ } from '../context/copilot-context'
6
+ import { useChat } from 'ai/react'
7
+ import { ChatRequestOptions, CreateMessage, Message } from 'ai'
8
+ import { UseChatOptions } from 'ai'
9
+
10
+ export interface UseCopilotChatOptions extends UseChatOptions {
11
+ makeSystemMessage?: (contextString: string) => string
12
+ }
13
+
14
+ export interface UseCopilotChatReturn {
15
+ visibleMessages: Message[]
16
+ append: (
17
+ message: Message | CreateMessage,
18
+ chatRequestOptions?: ChatRequestOptions
19
+ ) => Promise<string | null | undefined>
20
+ reload: (
21
+ chatRequestOptions?: ChatRequestOptions
22
+ ) => Promise<string | null | undefined>
23
+ stop: () => void
24
+ isLoading: boolean
25
+ input: string
26
+ setInput: React.Dispatch<React.SetStateAction<string>>
27
+ }
28
+
29
+ export function useCopilotChat({
30
+ makeSystemMessage,
31
+ ...options
32
+ }: UseCopilotChatOptions): UseCopilotChatReturn {
33
+ const {
34
+ getContextString,
35
+ getChatCompletionFunctions,
36
+ getFunctionCallHandler
37
+ } = useContext(CopilotContext)
38
+
39
+ const systemMessage: Message = useMemo(() => {
40
+ const systemMessageMaker = makeSystemMessage || defaultSystemMessage
41
+ const contextString = getContextString()
42
+
43
+ return {
44
+ id: 'system',
45
+ content: systemMessageMaker(contextString),
46
+ role: 'system'
47
+ }
48
+ }, [getContextString, makeSystemMessage])
49
+
50
+ const initialMessagesWithContext = [systemMessage].concat(
51
+ options.initialMessages || []
52
+ )
53
+
54
+ const functions = useMemo(() => {
55
+ return getChatCompletionFunctions()
56
+ }, [getChatCompletionFunctions])
57
+
58
+ const { messages, append, reload, stop, isLoading, input, setInput } =
59
+ useChat({
60
+ id: options.id,
61
+ initialMessages: initialMessagesWithContext,
62
+ experimental_onFunctionCall: getFunctionCallHandler(),
63
+ body: {
64
+ id: options.id,
65
+ previewToken,
66
+ functions
67
+ }
68
+ })
69
+
70
+ const visibleMessages = messages.filter(
71
+ message => message.role === 'user' || message.role === 'assistant'
72
+ )
73
+
74
+ return {
75
+ visibleMessages,
76
+ append,
77
+ reload,
78
+ stop,
79
+ isLoading,
80
+ input,
81
+ setInput
82
+ }
83
+ }
84
+
85
+ const previewToken = 'TODO123'
86
+
87
+ export function defaultSystemMessage(contextString: string): string {
88
+ return `
89
+ Please act as a efficient, competent, and conscientious professional assistant.
90
+ You help the user achieve their goals, and you do so in a way that is as efficient as possible, without unnecessary fluff, but also without sacrificing professionalism.
91
+ Always be polite and respectful, and prefer brevity over verbosity.
92
+
93
+ The user has provided you with the following context:
94
+ \`\`\`
95
+ ${contextString}
96
+ \`\`\`
97
+
98
+ They have also provided you with functions you can call to initiate actions on their behalf, or functions you can call to receive more information.
99
+
100
+ Please assist them as best you can.
101
+ If you are not sure how to proceed to best fulfill their requests, please ask them for more information.
102
+ `
103
+ }
@@ -0,0 +1,35 @@
1
+ 'use client'
2
+
3
+ import { useRef, useContext, useEffect, useMemo } from 'react'
4
+ import { CopilotContext } from '../context/copilot-context'
5
+ import { AnnotatedFunction } from '../types/annotated-function'
6
+ import { nanoid } from 'nanoid'
7
+
8
+ export function useMakeCopilotActionable<ActionInput extends any[]>(
9
+ annotatedFunction: AnnotatedFunction<ActionInput>,
10
+ dependencies: any[]
11
+ ) {
12
+ const idRef = useRef(nanoid()) // generate a unique id
13
+ const { setEntryPoint, removeEntryPoint } = useContext(CopilotContext)
14
+
15
+ const memoizedAnnotatedFunction: AnnotatedFunction<ActionInput> = useMemo(
16
+ () => ({
17
+ name: annotatedFunction.name,
18
+ description: annotatedFunction.description,
19
+ argumentAnnotations: annotatedFunction.argumentAnnotations,
20
+ implementation: annotatedFunction.implementation
21
+ }),
22
+ dependencies
23
+ )
24
+
25
+ useEffect(() => {
26
+ setEntryPoint(
27
+ idRef.current,
28
+ memoizedAnnotatedFunction as AnnotatedFunction<any[]>
29
+ )
30
+
31
+ return () => {
32
+ removeEntryPoint(idRef.current)
33
+ }
34
+ }, [memoizedAnnotatedFunction, setEntryPoint, removeEntryPoint])
35
+ }
@@ -0,0 +1,23 @@
1
+ 'use client'
2
+
3
+ import { useRef, useContext, useEffect } from 'react'
4
+ import { CopilotContext } from '../context/copilot-context'
5
+
6
+ export function useMakeCopilotReadable(
7
+ information: string,
8
+ parentId?: string
9
+ ): string | undefined {
10
+ const { addContext, removeContext } = useContext(CopilotContext)
11
+ const idRef = useRef<string>()
12
+
13
+ useEffect(() => {
14
+ const id = addContext(information, parentId)
15
+ idRef.current = id
16
+
17
+ return () => {
18
+ removeContext(id)
19
+ }
20
+ }, [information, parentId, addContext, removeContext])
21
+
22
+ return idRef.current
23
+ }
@@ -0,0 +1,159 @@
1
+ import { nanoid } from 'nanoid'
2
+ import { useReducer, useCallback } from 'react'
3
+
4
+ export type TreeNodeId = string
5
+
6
+ export interface TreeNode {
7
+ id: TreeNodeId
8
+ value: string
9
+ children: TreeNode[]
10
+ parentId?: TreeNodeId
11
+ }
12
+
13
+ export type Tree = TreeNode[]
14
+
15
+ export interface UseTreeReturn {
16
+ tree: Tree
17
+ addElement: (value: string, parentId?: TreeNodeId) => TreeNodeId
18
+ printTree: () => string
19
+ removeElement: (id: TreeNodeId) => void
20
+ }
21
+
22
+ const findNode = (nodes: Tree, id: TreeNodeId): TreeNode | undefined => {
23
+ for (const node of nodes) {
24
+ if (node.id === id) {
25
+ return node
26
+ }
27
+ const result = findNode(node.children, id)
28
+ if (result) {
29
+ return result
30
+ }
31
+ }
32
+ return undefined
33
+ }
34
+
35
+ const removeNode = (nodes: Tree, id: TreeNodeId): Tree => {
36
+ return nodes.reduce((result: Tree, node) => {
37
+ if (node.id !== id) {
38
+ const newNode = { ...node, children: removeNode(node.children, id) }
39
+ result.push(newNode)
40
+ }
41
+ return result
42
+ }, [])
43
+ }
44
+
45
+ const treeIndentationRepresentation = (
46
+ index: number,
47
+ indentLevel: number
48
+ ): string => {
49
+ if (indentLevel === 0) {
50
+ return (index + 1).toString()
51
+ } else if (indentLevel === 1) {
52
+ return String.fromCharCode(65 + index) // 65 is the ASCII value for 'A'
53
+ } else if (indentLevel === 2) {
54
+ return String.fromCharCode(97 + index) // 97 is the ASCII value for 'a'
55
+ } else {
56
+ throw new Error('Indentation level not supported')
57
+ }
58
+ }
59
+
60
+ const printNode = (node: TreeNode, prefix = '', indentLevel = 0): string => {
61
+ const indent = ' '.repeat(3).repeat(indentLevel)
62
+
63
+ const prefixPlusIndentLength = prefix.length + indent.length
64
+ const subsequentLinesPrefix = ' '.repeat(prefixPlusIndentLength)
65
+
66
+ const valueLines = node.value.split('\n')
67
+
68
+ const outputFirstLine = `${indent}${prefix}${valueLines[0]}`
69
+ const outputSubsequentLines = valueLines
70
+ .slice(1)
71
+ .map(line => `${subsequentLinesPrefix}${line}`)
72
+ .join('\n')
73
+
74
+ let output = `${outputFirstLine}\n`
75
+ if (outputSubsequentLines) {
76
+ output += `${outputSubsequentLines}\n`
77
+ }
78
+
79
+ node.children.forEach(
80
+ (child, index) =>
81
+ (output += printNode(
82
+ child,
83
+ `${prefix}${treeIndentationRepresentation(index, indentLevel + 1)}. `,
84
+ indentLevel + 1
85
+ ))
86
+ )
87
+ return output
88
+ }
89
+
90
+ // Action types
91
+ type Action =
92
+ | { type: 'ADD_NODE'; value: string; parentId?: string; id: string }
93
+ | { type: 'REMOVE_NODE'; id: string }
94
+
95
+ // Reducer function
96
+ function treeReducer(state: Tree, action: Action): Tree {
97
+ switch (action.type) {
98
+ case 'ADD_NODE': {
99
+ const { value, parentId, id: newNodeId } = action
100
+ const newNode: TreeNode = {
101
+ id: newNodeId,
102
+ value,
103
+ children: []
104
+ }
105
+
106
+ if (parentId) {
107
+ const parent = findNode(state, parentId)
108
+ if (parent) {
109
+ newNode.parentId = parentId
110
+ parent.children.push(newNode)
111
+ } else {
112
+ throw new Error(`Parent with id ${parentId} not found`)
113
+ }
114
+ } else {
115
+ return [...state, newNode]
116
+ }
117
+
118
+ return state
119
+ }
120
+ case 'REMOVE_NODE':
121
+ return removeNode(state, action.id)
122
+ default:
123
+ return state
124
+ }
125
+ }
126
+
127
+ // useTree hook
128
+ const useTree = (): UseTreeReturn => {
129
+ const [tree, dispatch] = useReducer(treeReducer, [])
130
+
131
+ const addElement = useCallback(
132
+ (value: string, parentId?: string): TreeNodeId => {
133
+ const newNodeId = nanoid() // Generate new ID outside of dispatch
134
+ dispatch({ type: 'ADD_NODE', value, parentId, id: newNodeId })
135
+ return newNodeId // Return the new ID
136
+ },
137
+ []
138
+ )
139
+
140
+ const removeElement = useCallback((id: TreeNodeId): void => {
141
+ dispatch({ type: 'REMOVE_NODE', id })
142
+ }, [])
143
+
144
+ const printTree = (): string => {
145
+ let output = ''
146
+ tree.forEach(
147
+ (node, index) =>
148
+ (output += printNode(
149
+ node,
150
+ `${treeIndentationRepresentation(index, 0)}. `
151
+ ))
152
+ )
153
+ return output
154
+ }
155
+
156
+ return { tree, addElement, printTree, removeElement }
157
+ }
158
+
159
+ export default useTree
package/src/index.tsx CHANGED
@@ -1,2 +1,4 @@
1
- // components
2
- export * from "./hook";
1
+ export * from './components'
2
+ export * from './context'
3
+ export * from './hooks'
4
+ export * from './types'
@@ -0,0 +1,14 @@
1
+ export interface AnnotatedFunctionArgument {
2
+ name: string
3
+ type: string
4
+ description: string
5
+ allowedValues?: any[]
6
+ required: boolean
7
+ }
8
+
9
+ export interface AnnotatedFunction<Inputs extends any[]> {
10
+ name: string
11
+ description: string
12
+ argumentAnnotations: AnnotatedFunctionArgument[]
13
+ implementation: (...args: Inputs) => Promise<void>
14
+ }
@@ -0,0 +1,2 @@
1
+ export type { AnnotatedFunctionArgument } from './annotated-function'
2
+ export type { AnnotatedFunction } from './annotated-function'
package/tsup.config.ts CHANGED
@@ -11,3 +11,4 @@ export default defineConfig((options: Options) => ({
11
11
  external: ["react"],
12
12
  ...options,
13
13
  }));
14
+
@@ -1,26 +0,0 @@
1
- 'use strict';
2
-
3
- var t = require('react');
4
-
5
- function _interopNamespaceDefault(e) {
6
- var n = Object.create(null);
7
- if (e) {
8
- Object.keys(e).forEach(function (k) {
9
- if (k !== 'default') {
10
- var d = Object.getOwnPropertyDescriptor(e, k);
11
- Object.defineProperty(n, k, d.get ? d : {
12
- enumerable: true,
13
- get: function () { return e[k]; }
14
- });
15
- }
16
- });
17
- }
18
- n.default = e;
19
- return Object.freeze(n);
20
- }
21
-
22
- var t__namespace = /*#__PURE__*/_interopNamespaceDefault(t);
23
-
24
- function u(){t__namespace.useState(0);}
25
-
26
- exports.a = u;
package/dist/hook.d.ts DELETED
@@ -1,3 +0,0 @@
1
- declare function useTurbo(): void;
2
-
3
- export { useTurbo };
package/dist/hook.js DELETED
@@ -1,10 +0,0 @@
1
- 'use strict';
2
-
3
- var chunkKFCOT2YX_js = require('./chunk-KFCOT2YX.js');
4
-
5
-
6
-
7
- Object.defineProperty(exports, 'useTurbo', {
8
- enumerable: true,
9
- get: function () { return chunkKFCOT2YX_js.a; }
10
- });
package/src/hook.tsx DELETED
@@ -1,5 +0,0 @@
1
- import * as React from "react";
2
-
3
- export function useTurbo() {
4
- const [num, setNum] = React.useState(0);
5
- }