Merge pull request #861 from ManishMadan2882/main

DocsGPT Widget
pull/880/head
Alex 3 months ago committed by GitHub
commit 229f62d071
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

14216
docs/package-lock.json generated

File diff suppressed because it is too large Load Diff

@ -7,7 +7,7 @@
"license": "MIT",
"dependencies": {
"@vercel/analytics": "^1.1.1",
"docsgpt": "^0.2.4",
"docsgpt": "^0.3.0",
"next": "^14.0.4",
"nextra": "^2.13.2",
"nextra-theme-docs": "^2.13.2",

@ -1,5 +1,4 @@
import { DocsGPTWidget } from "docsgpt";
import "docsgpt/dist/style.css";
export default function MyApp({ Component, pageProps }) {
return (

@ -0,0 +1,3 @@
node_modules
dist
.parcel-cache

@ -0,0 +1,10 @@
{
"extends": "@parcel/config-default",
"resolvers": ["@parcel/resolver-glob","..."],
"transformers": {
"*.svg": ["...", "@parcel/transformer-svg-react", "@parcel/transformer-typescript-tsc"]
},
"validators": {
"*.{ts,tsx}": ["@parcel/validator-typescript"]
}
}

@ -13,7 +13,6 @@ npm install docsgpt
```javascript
import { DocsGPTWidget } from "docsgpt";
import "docsgpt/dist/style.css";
const App = () => {
return <DocsGPTWidget />;
@ -24,10 +23,18 @@ To link the widget to your api and your documents you can pass parameters to the
```javascript
import { DocsGPTWidget } from "docsgpt";
import "docsgpt/dist/style.css";
const App = () => {
return <DocsGPTWidget apiHost="http://localhost:7001" selectDocs='default' apiKey=''/>;
return <DocsGPTWidget
apiHost = 'http://localhost:7001',
selectDocs = 'default',
apiKey = '',
avatar = 'https://d3dg1063dc54p9.cloudfront.net/cute-docsgpt.png',
title = 'Get AI assistance',
description = 'DocsGPT\'s AI Chatbot is here to help',
heroTitle = 'Welcome to DocsGPT !',
heroDescription='This chatbot is built with DocsGPT and utilises GenAI, please review important information using sources.'
/>;
};
```

@ -0,0 +1,9 @@
declare module "*.svg" {
import * as React from "react";
const ReactComponent: React.FunctionComponent<
React.SVGProps<SVGSVGElement> & { title?: string }
>;
export default ReactComponent;
}

@ -1 +0,0 @@
export { DocsGPTWidget } from "./src/components/DocsGPTWidget";

@ -1,832 +0,0 @@
import Ne, { useState as ke, useRef as ur, useEffect as Pe } from "react";
var ne = { exports: {} }, Y = {};
/**
* @license React
* react-jsx-runtime.development.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
var Ce;
function cr() {
return Ce || (Ce = 1, process.env.NODE_ENV !== "production" && function() {
var N = Ne, w = Symbol.for("react.element"), C = Symbol.for("react.portal"), u = Symbol.for("react.fragment"), E = Symbol.for("react.strict_mode"), S = Symbol.for("react.profiler"), T = Symbol.for("react.provider"), b = Symbol.for("react.context"), d = Symbol.for("react.forward_ref"), v = Symbol.for("react.suspense"), m = Symbol.for("react.suspense_list"), h = Symbol.for("react.memo"), x = Symbol.for("react.lazy"), p = Symbol.for("react.offscreen"), R = Symbol.iterator, j = "@@iterator";
function J(e) {
if (e === null || typeof e != "object")
return null;
var r = R && e[R] || e[j];
return typeof r == "function" ? r : null;
}
var O = N.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
function g(e) {
{
for (var r = arguments.length, t = new Array(r > 1 ? r - 1 : 0), n = 1; n < r; n++)
t[n - 1] = arguments[n];
B("error", e, t);
}
}
function B(e, r, t) {
{
var n = O.ReactDebugCurrentFrame, o = n.getStackAddendum();
o !== "" && (r += "%s", t = t.concat([o]));
var s = t.map(function(i) {
return String(i);
});
s.unshift("Warning: " + r), Function.prototype.apply.call(console[e], console, s);
}
}
var D = !1, z = !1, De = !1, Ae = !1, Fe = !1, ae;
ae = Symbol.for("react.module.reference");
function Ie(e) {
return !!(typeof e == "string" || typeof e == "function" || e === u || e === S || Fe || e === E || e === v || e === m || Ae || e === p || D || z || De || typeof e == "object" && e !== null && (e.$$typeof === x || e.$$typeof === h || e.$$typeof === T || e.$$typeof === b || e.$$typeof === d || // This needs to include all possible module reference object
// types supported by any Flight configuration anywhere since
// we don't know which Flight build this will end up being used
// with.
e.$$typeof === ae || e.getModuleId !== void 0));
}
function $e(e, r, t) {
var n = e.displayName;
if (n)
return n;
var o = r.displayName || r.name || "";
return o !== "" ? t + "(" + o + ")" : t;
}
function ie(e) {
return e.displayName || "Context";
}
function k(e) {
if (e == null)
return null;
if (typeof e.tag == "number" && g("Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."), typeof e == "function")
return e.displayName || e.name || null;
if (typeof e == "string")
return e;
switch (e) {
case u:
return "Fragment";
case C:
return "Portal";
case S:
return "Profiler";
case E:
return "StrictMode";
case v:
return "Suspense";
case m:
return "SuspenseList";
}
if (typeof e == "object")
switch (e.$$typeof) {
case b:
var r = e;
return ie(r) + ".Consumer";
case T:
var t = e;
return ie(t._context) + ".Provider";
case d:
return $e(e, e.render, "ForwardRef");
case h:
var n = e.displayName || null;
return n !== null ? n : k(e.type) || "Memo";
case x: {
var o = e, s = o._payload, i = o._init;
try {
return k(i(s));
} catch {
return null;
}
}
}
return null;
}
var A = Object.assign, $ = 0, oe, se, le, ue, ce, fe, de;
function ve() {
}
ve.__reactDisabledLog = !0;
function We() {
{
if ($ === 0) {
oe = console.log, se = console.info, le = console.warn, ue = console.error, ce = console.group, fe = console.groupCollapsed, de = console.groupEnd;
var e = {
configurable: !0,
enumerable: !0,
value: ve,
writable: !0
};
Object.defineProperties(console, {
info: e,
log: e,
warn: e,
error: e,
group: e,
groupCollapsed: e,
groupEnd: e
});
}
$++;
}
}
function Ye() {
{
if ($--, $ === 0) {
var e = {
configurable: !0,
enumerable: !0,
writable: !0
};
Object.defineProperties(console, {
log: A({}, e, {
value: oe
}),
info: A({}, e, {
value: se
}),
warn: A({}, e, {
value: le
}),
error: A({}, e, {
value: ue
}),
group: A({}, e, {
value: ce
}),
groupCollapsed: A({}, e, {
value: fe
}),
groupEnd: A({}, e, {
value: de
})
});
}
$ < 0 && g("disabledDepth fell below zero. This is a bug in React. Please file an issue.");
}
}
var H = O.ReactCurrentDispatcher, K;
function V(e, r, t) {
{
if (K === void 0)
try {
throw Error();
} catch (o) {
var n = o.stack.trim().match(/\n( *(at )?)/);
K = n && n[1] || "";
}
return `
` + K + e;
}
}
var X = !1, M;
{
var Le = typeof WeakMap == "function" ? WeakMap : Map;
M = new Le();
}
function pe(e, r) {
if (!e || X)
return "";
{
var t = M.get(e);
if (t !== void 0)
return t;
}
var n;
X = !0;
var o = Error.prepareStackTrace;
Error.prepareStackTrace = void 0;
var s;
s = H.current, H.current = null, We();
try {
if (r) {
var i = function() {
throw Error();
};
if (Object.defineProperty(i.prototype, "props", {
set: function() {
throw Error();
}
}), typeof Reflect == "object" && Reflect.construct) {
try {
Reflect.construct(i, []);
} catch (P) {
n = P;
}
Reflect.construct(e, [], i);
} else {
try {
i.call();
} catch (P) {
n = P;
}
e.call(i.prototype);
}
} else {
try {
throw Error();
} catch (P) {
n = P;
}
e();
}
} catch (P) {
if (P && n && typeof P.stack == "string") {
for (var a = P.stack.split(`
`), y = n.stack.split(`
`), c = a.length - 1, f = y.length - 1; c >= 1 && f >= 0 && a[c] !== y[f]; )
f--;
for (; c >= 1 && f >= 0; c--, f--)
if (a[c] !== y[f]) {
if (c !== 1 || f !== 1)
do
if (c--, f--, f < 0 || a[c] !== y[f]) {
var _ = `
` + a[c].replace(" at new ", " at ");
return e.displayName && _.includes("<anonymous>") && (_ = _.replace("<anonymous>", e.displayName)), typeof e == "function" && M.set(e, _), _;
}
while (c >= 1 && f >= 0);
break;
}
}
} finally {
X = !1, H.current = s, Ye(), Error.prepareStackTrace = o;
}
var I = e ? e.displayName || e.name : "", je = I ? V(I) : "";
return typeof e == "function" && M.set(e, je), je;
}
function Ve(e, r, t) {
return pe(e, !1);
}
function Me(e) {
var r = e.prototype;
return !!(r && r.isReactComponent);
}
function U(e, r, t) {
if (e == null)
return "";
if (typeof e == "function")
return pe(e, Me(e));
if (typeof e == "string")
return V(e);
switch (e) {
case v:
return V("Suspense");
case m:
return V("SuspenseList");
}
if (typeof e == "object")
switch (e.$$typeof) {
case d:
return Ve(e.render);
case h:
return U(e.type, r, t);
case x: {
var n = e, o = n._payload, s = n._init;
try {
return U(s(o), r, t);
} catch {
}
}
}
return "";
}
var G = Object.prototype.hasOwnProperty, he = {}, me = O.ReactDebugCurrentFrame;
function q(e) {
if (e) {
var r = e._owner, t = U(e.type, e._source, r ? r.type : null);
me.setExtraStackFrame(t);
} else
me.setExtraStackFrame(null);
}
function Ue(e, r, t, n, o) {
{
var s = Function.call.bind(G);
for (var i in e)
if (s(e, i)) {
var a = void 0;
try {
if (typeof e[i] != "function") {
var y = Error((n || "React class") + ": " + t + " type `" + i + "` is invalid; it must be a function, usually from the `prop-types` package, but received `" + typeof e[i] + "`.This often happens because of typos such as `PropTypes.function` instead of `PropTypes.func`.");
throw y.name = "Invariant Violation", y;
}
a = e[i](r, i, n, t, null, "SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED");
} catch (c) {
a = c;
}
a && !(a instanceof Error) && (q(o), g("%s: type specification of %s `%s` is invalid; the type checker function must return `null` or an `Error` but returned a %s. You may have forgotten to pass an argument to the type checker creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and shape all require an argument).", n || "React class", t, i, typeof a), q(null)), a instanceof Error && !(a.message in he) && (he[a.message] = !0, q(o), g("Failed %s type: %s", t, a.message), q(null));
}
}
}
var Ge = Array.isArray;
function Z(e) {
return Ge(e);
}
function qe(e) {
{
var r = typeof Symbol == "function" && Symbol.toStringTag, t = r && e[Symbol.toStringTag] || e.constructor.name || "Object";
return t;
}
}
function Je(e) {
try {
return ge(e), !1;
} catch {
return !0;
}
}
function ge(e) {
return "" + e;
}
function ye(e) {
if (Je(e))
return g("The provided key is an unsupported type %s. This value must be coerced to a string before before using it here.", qe(e)), ge(e);
}
var W = O.ReactCurrentOwner, Be = {
key: !0,
ref: !0,
__self: !0,
__source: !0
}, be, Ee, Q;
Q = {};
function ze(e) {
if (G.call(e, "ref")) {
var r = Object.getOwnPropertyDescriptor(e, "ref").get;
if (r && r.isReactWarning)
return !1;
}
return e.ref !== void 0;
}
function He(e) {
if (G.call(e, "key")) {
var r = Object.getOwnPropertyDescriptor(e, "key").get;
if (r && r.isReactWarning)
return !1;
}
return e.key !== void 0;
}
function Ke(e, r) {
if (typeof e.ref == "string" && W.current && r && W.current.stateNode !== r) {
var t = k(W.current.type);
Q[t] || (g('Component "%s" contains the string ref "%s". Support for string refs will be removed in a future major release. This case cannot be automatically converted to an arrow function. We ask you to manually fix this case by using useRef() or createRef() instead. Learn more about using refs safely here: https://reactjs.org/link/strict-mode-string-ref', k(W.current.type), e.ref), Q[t] = !0);
}
}
function Xe(e, r) {
{
var t = function() {
be || (be = !0, g("%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://reactjs.org/link/special-props)", r));
};
t.isReactWarning = !0, Object.defineProperty(e, "key", {
get: t,
configurable: !0
});
}
}
function Ze(e, r) {
{
var t = function() {
Ee || (Ee = !0, g("%s: `ref` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://reactjs.org/link/special-props)", r));
};
t.isReactWarning = !0, Object.defineProperty(e, "ref", {
get: t,
configurable: !0
});
}
}
var Qe = function(e, r, t, n, o, s, i) {
var a = {
// This tag allows us to uniquely identify this as a React Element
$$typeof: w,
// Built-in properties that belong on the element
type: e,
key: r,
ref: t,
props: i,
// Record the component responsible for creating this element.
_owner: s
};
return a._store = {}, Object.defineProperty(a._store, "validated", {
configurable: !1,
enumerable: !1,
writable: !0,
value: !1
}), Object.defineProperty(a, "_self", {
configurable: !1,
enumerable: !1,
writable: !1,
value: n
}), Object.defineProperty(a, "_source", {
configurable: !1,
enumerable: !1,
writable: !1,
value: o
}), Object.freeze && (Object.freeze(a.props), Object.freeze(a)), a;
};
function er(e, r, t, n, o) {
{
var s, i = {}, a = null, y = null;
t !== void 0 && (ye(t), a = "" + t), He(r) && (ye(r.key), a = "" + r.key), ze(r) && (y = r.ref, Ke(r, o));
for (s in r)
G.call(r, s) && !Be.hasOwnProperty(s) && (i[s] = r[s]);
if (e && e.defaultProps) {
var c = e.defaultProps;
for (s in c)
i[s] === void 0 && (i[s] = c[s]);
}
if (a || y) {
var f = typeof e == "function" ? e.displayName || e.name || "Unknown" : e;
a && Xe(i, f), y && Ze(i, f);
}
return Qe(e, a, y, o, n, W.current, i);
}
}
var ee = O.ReactCurrentOwner, xe = O.ReactDebugCurrentFrame;
function F(e) {
if (e) {
var r = e._owner, t = U(e.type, e._source, r ? r.type : null);
xe.setExtraStackFrame(t);
} else
xe.setExtraStackFrame(null);
}
var re;
re = !1;
function te(e) {
return typeof e == "object" && e !== null && e.$$typeof === w;
}
function _e() {
{
if (ee.current) {
var e = k(ee.current.type);
if (e)
return `
Check the render method of \`` + e + "`.";
}
return "";
}
}
function rr(e) {
{
if (e !== void 0) {
var r = e.fileName.replace(/^.*[\\\/]/, ""), t = e.lineNumber;
return `
Check your code at ` + r + ":" + t + ".";
}
return "";
}
}
var Re = {};
function tr(e) {
{
var r = _e();
if (!r) {
var t = typeof e == "string" ? e : e.displayName || e.name;
t && (r = `
Check the top-level render call using <` + t + ">.");
}
return r;
}
}
function we(e, r) {
{
if (!e._store || e._store.validated || e.key != null)
return;
e._store.validated = !0;
var t = tr(r);
if (Re[t])
return;
Re[t] = !0;
var n = "";
e && e._owner && e._owner !== ee.current && (n = " It was passed a child from " + k(e._owner.type) + "."), F(e), g('Each child in a list should have a unique "key" prop.%s%s See https://reactjs.org/link/warning-keys for more information.', t, n), F(null);
}
}
function Te(e, r) {
{
if (typeof e != "object")
return;
if (Z(e))
for (var t = 0; t < e.length; t++) {
var n = e[t];
te(n) && we(n, r);
}
else if (te(e))
e._store && (e._store.validated = !0);
else if (e) {
var o = J(e);
if (typeof o == "function" && o !== e.entries)
for (var s = o.call(e), i; !(i = s.next()).done; )
te(i.value) && we(i.value, r);
}
}
}
function nr(e) {
{
var r = e.type;
if (r == null || typeof r == "string")
return;
var t;
if (typeof r == "function")
t = r.propTypes;
else if (typeof r == "object" && (r.$$typeof === d || // Note: Memo only checks outer props here.
// Inner props are checked in the reconciler.
r.$$typeof === h))
t = r.propTypes;
else
return;
if (t) {
var n = k(r);
Ue(t, e.props, "prop", n, e);
} else if (r.PropTypes !== void 0 && !re) {
re = !0;
var o = k(r);
g("Component %s declared `PropTypes` instead of `propTypes`. Did you misspell the property assignment?", o || "Unknown");
}
typeof r.getDefaultProps == "function" && !r.getDefaultProps.isReactClassApproved && g("getDefaultProps is only used on classic React.createClass definitions. Use a static property named `defaultProps` instead.");
}
}
function ar(e) {
{
for (var r = Object.keys(e.props), t = 0; t < r.length; t++) {
var n = r[t];
if (n !== "children" && n !== "key") {
F(e), g("Invalid prop `%s` supplied to `React.Fragment`. React.Fragment can only have `key` and `children` props.", n), F(null);
break;
}
}
e.ref !== null && (F(e), g("Invalid attribute `ref` supplied to `React.Fragment`."), F(null));
}
}
function Se(e, r, t, n, o, s) {
{
var i = Ie(e);
if (!i) {
var a = "";
(e === void 0 || typeof e == "object" && e !== null && Object.keys(e).length === 0) && (a += " You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.");
var y = rr(o);
y ? a += y : a += _e();
var c;
e === null ? c = "null" : Z(e) ? c = "array" : e !== void 0 && e.$$typeof === w ? (c = "<" + (k(e.type) || "Unknown") + " />", a = " Did you accidentally export a JSX literal instead of a component?") : c = typeof e, g("React.jsx: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: %s.%s", c, a);
}
var f = er(e, r, t, o, s);
if (f == null)
return f;
if (i) {
var _ = r.children;
if (_ !== void 0)
if (n)
if (Z(_)) {
for (var I = 0; I < _.length; I++)
Te(_[I], e);
Object.freeze && Object.freeze(_);
} else
g("React.jsx: Static children should always be an array. You are likely explicitly calling React.jsxs or React.jsxDEV. Use the Babel transform instead.");
else
Te(_, e);
}
return e === u ? ar(f) : nr(f), f;
}
}
function ir(e, r, t) {
return Se(e, r, t, !0);
}
function or(e, r, t) {
return Se(e, r, t, !1);
}
var sr = or, lr = ir;
Y.Fragment = u, Y.jsx = sr, Y.jsxs = lr;
}()), Y;
}
var L = {};
/**
* @license React
* react-jsx-runtime.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
var Oe;
function fr() {
if (Oe)
return L;
Oe = 1;
var N = Ne, w = Symbol.for("react.element"), C = Symbol.for("react.fragment"), u = Object.prototype.hasOwnProperty, E = N.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner, S = { key: !0, ref: !0, __self: !0, __source: !0 };
function T(b, d, v) {
var m, h = {}, x = null, p = null;
v !== void 0 && (x = "" + v), d.key !== void 0 && (x = "" + d.key), d.ref !== void 0 && (p = d.ref);
for (m in d)
u.call(d, m) && !S.hasOwnProperty(m) && (h[m] = d[m]);
if (b && b.defaultProps)
for (m in d = b.defaultProps, d)
h[m] === void 0 && (h[m] = d[m]);
return { $$typeof: w, type: b, key: x, ref: p, props: h, _owner: E.current };
}
return L.Fragment = C, L.jsx = T, L.jsxs = T, L;
}
process.env.NODE_ENV === "production" ? ne.exports = fr() : ne.exports = cr();
var l = ne.exports;
function dr({
question: N = "",
apiKey: w = "",
selectedDocs: C = "",
history: u = [],
conversationId: E = null,
apiHost: S = "",
onEvent: T = () => {
console.log("Event triggered, but no handler provided.");
}
}) {
let b = "default";
return C && (b = C), new Promise((d, v) => {
const m = {
question: N,
api_key: w,
embeddings_key: w,
active_docs: b,
history: JSON.stringify(u),
conversation_id: E,
model: "default"
};
fetch(S + "/stream", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(m)
}).then((h) => {
if (!h.body)
throw Error("No response body");
const x = h.body.getReader(), p = new TextDecoder("utf-8");
let R = 0;
const j = ({
done: J,
value: O
}) => {
if (J) {
console.log(R), d();
return;
}
R += 1;
const B = p.decode(O).split(`
`);
for (let D of B) {
if (D.trim() == "")
continue;
D.startsWith("data:") && (D = D.substring(5));
const z = new MessageEvent("message", {
data: D
});
T(z);
}
x.read().then(j).catch(v);
};
x.read().then(j).catch(v);
}).catch((h) => {
console.error("Connection failed:", h), v(h);
});
});
}
const pr = ({ apiHost: N = "https://gptcloud.arc53.com", selectDocs: w = "default", apiKey: C = "docsgpt-public" }) => {
const [u, E] = ke(() => typeof window < "u" && localStorage.getItem("docsGPTChatState") || "init"), [S, T] = ke(""), b = ur(null);
Pe(() => {
if (b.current) {
const v = b.current;
v.scrollTop = v.scrollHeight;
}
}, [S]), Pe(() => {
localStorage.setItem("docsGPTChatState", u);
}, [u]);
const d = (v) => {
T(""), v.preventDefault(), E(
"processing"
/* Processing */
), setTimeout(() => {
E(
"answer"
/* Answer */
);
}, 800);
const h = v.currentTarget[0].value;
dr({
question: h,
apiKey: C,
selectedDocs: w,
history: [],
conversationId: null,
apiHost: N,
onEvent: (x) => {
const p = JSON.parse(x.data);
if (p.type === "end")
E(
"answer"
/* Answer */
);
else if (p.type === "source") {
let R;
if (p.metadata && p.metadata.title) {
const j = p.metadata.title.split("/");
R = {
title: j[j.length - 1],
text: p.doc
};
} else
R = { title: p.doc, text: p.doc };
console.log(R);
} else if (p.type === "id")
console.log(p.id);
else {
const R = p.answer;
T((j) => j + R);
}
}
});
};
return /* @__PURE__ */ l.jsx(l.Fragment, { children: /* @__PURE__ */ l.jsxs("div", { className: "dark widget-container", children: [
/* @__PURE__ */ l.jsx(
"div",
{
onClick: () => E(
"init"
/* Init */
),
className: `${u !== "minimized" ? "hidden" : ""} cursor-pointer`,
children: /* @__PURE__ */ l.jsx("div", { className: "mr-2 mb-2 w-20 h-20 rounded-full overflow-hidden dark:divide-gray-700 border dark:border-gray-700 bg-gradient-to-br from-gray-100/80 via-white to-white dark:from-gray-900/80 dark:via-gray-900 dark:to-gray-900 font-sans shadow backdrop-blur-sm flex items-center justify-center", children: /* @__PURE__ */ l.jsx(
"img",
{
src: "https://d3dg1063dc54p9.cloudfront.net/cute-docsgpt.png",
alt: "DocsGPT",
className: "cursor-pointer hover:opacity-50 h-14"
}
) })
}
),
/* @__PURE__ */ l.jsxs("div", { className: ` ${u !== "minimized" ? "" : "hidden"} divide-y dark:divide-gray-700 rounded-md border dark:border-gray-700 bg-gradient-to-br from-gray-100/80 via-white to-white dark:from-gray-900/80 dark:via-gray-900 dark:to-gray-900 font-sans shadow backdrop-blur-sm`, style: { width: "18rem", transform: "translateY(0%) translateZ(0px)" }, children: [
/* @__PURE__ */ l.jsxs("div", { children: [
/* @__PURE__ */ l.jsx(
"img",
{
src: "https://d3dg1063dc54p9.cloudfront.net/exit.svg",
alt: "Exit",
className: "cursor-pointer hover:opacity-50 h-2 absolute top-0 right-0 m-2 white-filter",
onClick: (v) => {
v.stopPropagation(), E(
"minimized"
/* Minimized */
);
}
}
),
/* @__PURE__ */ l.jsxs("div", { className: "flex items-center gap-2 p-3", children: [
/* @__PURE__ */ l.jsxs("div", { className: `${u === "init" || u === "processing" || u === "typing" ? "" : "hidden"} flex-1`, children: [
/* @__PURE__ */ l.jsx("h3", { className: "text-sm font-bold text-gray-700 dark:text-gray-200", children: "Need help with documentation?" }),
/* @__PURE__ */ l.jsx("p", { className: "mt-1 text-xs text-gray-400 dark:text-gray-500", children: "DocsGPT AI assistant will help you with docs" })
] }),
/* @__PURE__ */ l.jsx("div", { id: "docsgpt-answer", ref: b, className: `${u !== "answer" ? "hidden" : ""}`, children: /* @__PURE__ */ l.jsx("p", { className: "mt-1 text-sm text-gray-600 dark:text-white text-left", children: S }) })
] })
] }),
/* @__PURE__ */ l.jsxs("div", { className: "w-full", children: [
/* @__PURE__ */ l.jsx(
"button",
{
onClick: () => E(
"typing"
/* Typing */
),
className: `flex w-full justify-center px-5 py-3 text-sm text-gray-800 font-bold dark:text-white transition duration-300 hover:bg-gray-100 rounded-b dark:hover:bg-gray-800/70 ${u !== "init" ? "hidden" : ""}`,
children: "Ask DocsGPT"
}
),
(u === "typing" || u === "answer") && /* @__PURE__ */ l.jsxs(
"form",
{
onSubmit: d,
className: "relative w-full m-0",
style: { opacity: 1 },
children: [
/* @__PURE__ */ l.jsx(
"input",
{
type: "text",
className: "w-full bg-transparent px-5 py-3 pr-8 text-sm text-gray-700 dark:text-white focus:outline-none",
placeholder: "What do you want to do?"
}
),
/* @__PURE__ */ l.jsx("button", { className: "absolute text-gray-400 dark:text-gray-500 text-sm inset-y-0 right-2 -mx-2 px-2", type: "submit", children: "Submit" })
]
}
),
/* @__PURE__ */ l.jsxs("p", { className: `${u !== "processing" ? "hidden" : ""} flex w-full justify-center px-5 py-3 text-sm text-gray-800 font-bold dark:text-white transition duration-300 rounded-b`, children: [
"Processing",
/* @__PURE__ */ l.jsx("span", { className: "dot-animation", children: "." }),
/* @__PURE__ */ l.jsx("span", { className: "dot-animation delay-200", children: "." }),
/* @__PURE__ */ l.jsx("span", { className: "dot-animation delay-400", children: "." })
] })
] })
] })
] }) });
};
export {
pr as DocsGPTWidget
};
//# sourceMappingURL=index.es.js.map

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -1,3 +0,0 @@
/// <reference types="react" />
declare function App(): JSX.Element;
export default App;

@ -1,5 +0,0 @@
export declare const DocsGPTWidget: ({ apiHost, selectDocs, apiKey }: {
apiHost?: string | undefined;
selectDocs?: string | undefined;
apiKey?: string | undefined;
}) => JSX.Element;

@ -1 +0,0 @@
export { DocsGPTWidget } from "./DocsGPTWidget";

@ -1,762 +0,0 @@
/*
! tailwindcss v3.2.4 | MIT License | https://tailwindcss.com
*//*
1. Prevent padding and border from affecting element width. (https://github.com/mozdevs/cssremedy/issues/4)
2. Allow adding a border to an element by just adding a border-width. (https://github.com/tailwindcss/tailwindcss/pull/116)
*/
*,
::before,
::after {
box-sizing: border-box; /* 1 */
border-width: 0; /* 2 */
border-style: solid; /* 2 */
border-color: #e5e7eb; /* 2 */
}
::before,
::after {
--tw-content: '';
}
/*
1. Use a consistent sensible line-height in all browsers.
2. Prevent adjustments of font size after orientation changes in iOS.
3. Use a more readable tab size.
4. Use the user's configured `sans` font-family by default.
5. Use the user's configured `sans` font-feature-settings by default.
*/
html {
line-height: 1.5; /* 1 */
-webkit-text-size-adjust: 100%; /* 2 */
-moz-tab-size: 4; /* 3 */
-o-tab-size: 4;
tab-size: 4; /* 3 */
font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; /* 4 */
font-feature-settings: normal; /* 5 */
}
/*
1. Remove the margin in all browsers.
2. Inherit line-height from `html` so users can set them as a class directly on the `html` element.
*/
body {
margin: 0; /* 1 */
line-height: inherit; /* 2 */
}
/*
1. Add the correct height in Firefox.
2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655)
3. Ensure horizontal rules are visible by default.
*/
hr {
height: 0; /* 1 */
color: inherit; /* 2 */
border-top-width: 1px; /* 3 */
}
/*
Add the correct text decoration in Chrome, Edge, and Safari.
*/
abbr:where([title]) {
-webkit-text-decoration: underline dotted;
text-decoration: underline dotted;
}
/*
Remove the default font size and weight for headings.
*/
h1,
h2,
h3,
h4,
h5,
h6 {
font-size: inherit;
font-weight: inherit;
}
/*
Reset links to optimize for opt-in styling instead of opt-out.
*/
a {
color: inherit;
text-decoration: inherit;
}
/*
Add the correct font weight in Edge and Safari.
*/
b,
strong {
font-weight: bolder;
}
/*
1. Use the user's configured `mono` font family by default.
2. Correct the odd `em` font sizing in all browsers.
*/
code,
kbd,
samp,
pre {
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; /* 1 */
font-size: 1em; /* 2 */
}
/*
Add the correct font size in all browsers.
*/
small {
font-size: 80%;
}
/*
Prevent `sub` and `sup` elements from affecting the line height in all browsers.
*/
sub,
sup {
font-size: 75%;
line-height: 0;
position: relative;
vertical-align: baseline;
}
sub {
bottom: -0.25em;
}
sup {
top: -0.5em;
}
/*
1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297)
2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016)
3. Remove gaps between table borders by default.
*/
table {
text-indent: 0; /* 1 */
border-color: inherit; /* 2 */
border-collapse: collapse; /* 3 */
}
/*
1. Change the font styles in all browsers.
2. Remove the margin in Firefox and Safari.
3. Remove default padding in all browsers.
*/
button,
input,
optgroup,
select,
textarea {
font-family: inherit; /* 1 */
font-size: 100%; /* 1 */
font-weight: inherit; /* 1 */
line-height: inherit; /* 1 */
color: inherit; /* 1 */
margin: 0; /* 2 */
padding: 0; /* 3 */
}
/*
Remove the inheritance of text transform in Edge and Firefox.
*/
button,
select {
text-transform: none;
}
/*
1. Correct the inability to style clickable types in iOS and Safari.
2. Remove default button styles.
*/
button,
[type='button'],
[type='reset'],
[type='submit'] {
-webkit-appearance: button; /* 1 */
background-color: transparent; /* 2 */
background-image: none; /* 2 */
}
/*
Use the modern Firefox focus style for all focusable elements.
*/
:-moz-focusring {
outline: auto;
}
/*
Remove the additional `:invalid` styles in Firefox. (https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737)
*/
:-moz-ui-invalid {
box-shadow: none;
}
/*
Add the correct vertical alignment in Chrome and Firefox.
*/
progress {
vertical-align: baseline;
}
/*
Correct the cursor style of increment and decrement buttons in Safari.
*/
::-webkit-inner-spin-button,
::-webkit-outer-spin-button {
height: auto;
}
/*
1. Correct the odd appearance in Chrome and Safari.
2. Correct the outline style in Safari.
*/
[type='search'] {
-webkit-appearance: textfield; /* 1 */
outline-offset: -2px; /* 2 */
}
/*
Remove the inner padding in Chrome and Safari on macOS.
*/
::-webkit-search-decoration {
-webkit-appearance: none;
}
/*
1. Correct the inability to style clickable types in iOS and Safari.
2. Change font properties to `inherit` in Safari.
*/
::-webkit-file-upload-button {
-webkit-appearance: button; /* 1 */
font: inherit; /* 2 */
}
/*
Add the correct display in Chrome and Safari.
*/
summary {
display: list-item;
}
/*
Removes the default spacing and border for appropriate elements.
*/
blockquote,
dl,
dd,
h1,
h2,
h3,
h4,
h5,
h6,
hr,
figure,
p,
pre {
margin: 0;
}
fieldset {
margin: 0;
padding: 0;
}
legend {
padding: 0;
}
ol,
ul,
menu {
list-style: none;
margin: 0;
padding: 0;
}
/*
Prevent resizing textareas horizontally by default.
*/
textarea {
resize: vertical;
}
/*
1. Reset the default placeholder opacity in Firefox. (https://github.com/tailwindlabs/tailwindcss/issues/3300)
2. Set the default placeholder color to the user's configured gray 400 color.
*/
input::-moz-placeholder, textarea::-moz-placeholder {
opacity: 1; /* 1 */
color: #9ca3af; /* 2 */
}
input::placeholder,
textarea::placeholder {
opacity: 1; /* 1 */
color: #9ca3af; /* 2 */
}
/*
Set the default cursor for buttons.
*/
button,
[role="button"] {
cursor: pointer;
}
/*
Make sure disabled buttons don't get the pointer cursor.
*/
:disabled {
cursor: default;
}
/*
1. Make replaced elements `display: block` by default. (https://github.com/mozdevs/cssremedy/issues/14)
2. Add `vertical-align: middle` to align replaced elements more sensibly by default. (https://github.com/jensimmons/cssremedy/issues/14#issuecomment-634934210)
This can trigger a poorly considered lint error in some tools but is included by design.
*/
img,
svg,
video,
canvas,
audio,
iframe,
embed,
object {
display: block; /* 1 */
vertical-align: middle; /* 2 */
}
/*
Constrain images and videos to the parent width and preserve their intrinsic aspect ratio. (https://github.com/mozdevs/cssremedy/issues/14)
*/
img,
video {
max-width: 100%;
height: auto;
}
/* Make elements with the HTML hidden attribute stay hidden by default */
[hidden] {
display: none;
}
*, ::before, ::after {
--tw-border-spacing-x: 0;
--tw-border-spacing-y: 0;
--tw-translate-x: 0;
--tw-translate-y: 0;
--tw-rotate: 0;
--tw-skew-x: 0;
--tw-skew-y: 0;
--tw-scale-x: 1;
--tw-scale-y: 1;
--tw-pan-x: ;
--tw-pan-y: ;
--tw-pinch-zoom: ;
--tw-scroll-snap-strictness: proximity;
--tw-ordinal: ;
--tw-slashed-zero: ;
--tw-numeric-figure: ;
--tw-numeric-spacing: ;
--tw-numeric-fraction: ;
--tw-ring-inset: ;
--tw-ring-offset-width: 0px;
--tw-ring-offset-color: #fff;
--tw-ring-color: rgb(59 130 246 / 0.5);
--tw-ring-offset-shadow: 0 0 #0000;
--tw-ring-shadow: 0 0 #0000;
--tw-shadow: 0 0 #0000;
--tw-shadow-colored: 0 0 #0000;
--tw-blur: ;
--tw-brightness: ;
--tw-contrast: ;
--tw-grayscale: ;
--tw-hue-rotate: ;
--tw-invert: ;
--tw-saturate: ;
--tw-sepia: ;
--tw-drop-shadow: ;
--tw-backdrop-blur: ;
--tw-backdrop-brightness: ;
--tw-backdrop-contrast: ;
--tw-backdrop-grayscale: ;
--tw-backdrop-hue-rotate: ;
--tw-backdrop-invert: ;
--tw-backdrop-opacity: ;
--tw-backdrop-saturate: ;
--tw-backdrop-sepia: ;
}
::backdrop {
--tw-border-spacing-x: 0;
--tw-border-spacing-y: 0;
--tw-translate-x: 0;
--tw-translate-y: 0;
--tw-rotate: 0;
--tw-skew-x: 0;
--tw-skew-y: 0;
--tw-scale-x: 1;
--tw-scale-y: 1;
--tw-pan-x: ;
--tw-pan-y: ;
--tw-pinch-zoom: ;
--tw-scroll-snap-strictness: proximity;
--tw-ordinal: ;
--tw-slashed-zero: ;
--tw-numeric-figure: ;
--tw-numeric-spacing: ;
--tw-numeric-fraction: ;
--tw-ring-inset: ;
--tw-ring-offset-width: 0px;
--tw-ring-offset-color: #fff;
--tw-ring-color: rgb(59 130 246 / 0.5);
--tw-ring-offset-shadow: 0 0 #0000;
--tw-ring-shadow: 0 0 #0000;
--tw-shadow: 0 0 #0000;
--tw-shadow-colored: 0 0 #0000;
--tw-blur: ;
--tw-brightness: ;
--tw-contrast: ;
--tw-grayscale: ;
--tw-hue-rotate: ;
--tw-invert: ;
--tw-saturate: ;
--tw-sepia: ;
--tw-drop-shadow: ;
--tw-backdrop-blur: ;
--tw-backdrop-brightness: ;
--tw-backdrop-contrast: ;
--tw-backdrop-grayscale: ;
--tw-backdrop-hue-rotate: ;
--tw-backdrop-invert: ;
--tw-backdrop-opacity: ;
--tw-backdrop-saturate: ;
--tw-backdrop-sepia: ;
}
.absolute {
position: absolute;
}
.relative {
position: relative;
}
.inset-y-0 {
top: 0px;
bottom: 0px;
}
.top-0 {
top: 0px;
}
.right-0 {
right: 0px;
}
.right-2 {
right: 0.5rem;
}
.m-2 {
margin: 0.5rem;
}
.m-0 {
margin: 0px;
}
.-mx-2 {
margin-left: -0.5rem;
margin-right: -0.5rem;
}
.mr-2 {
margin-right: 0.5rem;
}
.mb-2 {
margin-bottom: 0.5rem;
}
.mt-1 {
margin-top: 0.25rem;
}
.flex {
display: flex;
}
.hidden {
display: none;
}
.h-20 {
height: 5rem;
}
.h-14 {
height: 3.5rem;
}
.h-2 {
height: 0.5rem;
}
.w-20 {
width: 5rem;
}
.w-full {
width: 100%;
}
.flex-1 {
flex: 1 1 0%;
}
.transform {
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
.cursor-pointer {
cursor: pointer;
}
.items-center {
align-items: center;
}
.justify-center {
justify-content: center;
}
.gap-2 {
gap: 0.5rem;
}
.divide-y > :not([hidden]) ~ :not([hidden]) {
--tw-divide-y-reverse: 0;
border-top-width: calc(1px * calc(1 - var(--tw-divide-y-reverse)));
border-bottom-width: calc(1px * var(--tw-divide-y-reverse));
}
.overflow-hidden {
overflow: hidden;
}
.rounded-full {
border-radius: 9999px;
}
.rounded-md {
border-radius: 0.375rem;
}
.rounded-b {
border-bottom-right-radius: 0.25rem;
border-bottom-left-radius: 0.25rem;
}
.border {
border-width: 1px;
}
.bg-transparent {
background-color: transparent;
}
.bg-gradient-to-br {
background-image: linear-gradient(to bottom right, var(--tw-gradient-stops));
}
.from-gray-100\/80 {
--tw-gradient-from: rgb(243 244 246 / 0.8);
--tw-gradient-to: rgb(243 244 246 / 0);
--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to);
}
.via-white {
--tw-gradient-to: rgb(255 255 255 / 0);
--tw-gradient-stops: var(--tw-gradient-from), #fff, var(--tw-gradient-to);
}
.to-white {
--tw-gradient-to: #fff;
}
.p-3 {
padding: 0.75rem;
}
.px-5 {
padding-left: 1.25rem;
padding-right: 1.25rem;
}
.py-3 {
padding-top: 0.75rem;
padding-bottom: 0.75rem;
}
.px-2 {
padding-left: 0.5rem;
padding-right: 0.5rem;
}
.pr-8 {
padding-right: 2rem;
}
.text-left {
text-align: left;
}
.font-sans {
font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
}
.text-sm {
font-size: 0.875rem;
line-height: 1.25rem;
}
.text-xs {
font-size: 0.75rem;
line-height: 1rem;
}
.font-bold {
font-weight: 700;
}
.text-gray-700 {
--tw-text-opacity: 1;
color: rgb(55 65 81 / var(--tw-text-opacity));
}
.text-gray-400 {
--tw-text-opacity: 1;
color: rgb(156 163 175 / var(--tw-text-opacity));
}
.text-gray-600 {
--tw-text-opacity: 1;
color: rgb(75 85 99 / var(--tw-text-opacity));
}
.text-gray-800 {
--tw-text-opacity: 1;
color: rgb(31 41 55 / var(--tw-text-opacity));
}
.shadow {
--tw-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);
--tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color);
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
}
.backdrop-blur-sm {
--tw-backdrop-blur: blur(4px);
-webkit-backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);
backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);
}
.transition {
transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, -webkit-backdrop-filter;
transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter;
transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter, -webkit-backdrop-filter;
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
transition-duration: 150ms;
}
.delay-200 {
transition-delay: 200ms;
}
.duration-300 {
transition-duration: 300ms;
}
#docsgpt-answer {
max-height: 50vh; /* 50% of the viewport height */
overflow-y: auto; /* Adds a vertical scrollbar if the content exceeds the container height */
}
.widget-container {
position: fixed; /* fixed positioning */
right: 10px; /* from the right edge */
bottom: 10px; /* from the bottom edge */
z-index: 1000; /* to ensure it appears on top of other content, if any */
display: flex;
flex-direction: column;
align-items: center;
}
@keyframes dotBounce {
0%, 80%, 100% {
transform: translateY(0);
}
40% {
transform: translateY(-5px);
}
}
.dot-animation {
display: inline-block;
animation: dotBounce 1s infinite ease-in-out;
}
.delay-200 {
animation-delay: 200ms;
}
.delay-400 {
animation-delay: 400ms;
}
.white-filter {
filter: invert(1) brightness(2);
}
.hover\:bg-gray-100:hover {
--tw-bg-opacity: 1;
background-color: rgb(243 244 246 / var(--tw-bg-opacity));
}
.hover\:opacity-50:hover {
opacity: 0.5;
}
.focus\:outline-none:focus {
outline: 2px solid transparent;
outline-offset: 2px;
}
@media (prefers-color-scheme: dark) {
.dark\:divide-gray-700 > :not([hidden]) ~ :not([hidden]) {
--tw-divide-opacity: 1;
border-color: rgb(55 65 81 / var(--tw-divide-opacity));
}
.dark\:border-gray-700 {
--tw-border-opacity: 1;
border-color: rgb(55 65 81 / var(--tw-border-opacity));
}
.dark\:from-gray-900\/80 {
--tw-gradient-from: rgb(17 24 39 / 0.8);
--tw-gradient-to: rgb(17 24 39 / 0);
--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to);
}
.dark\:via-gray-900 {
--tw-gradient-to: rgb(17 24 39 / 0);
--tw-gradient-stops: var(--tw-gradient-from), #111827, var(--tw-gradient-to);
}
.dark\:to-gray-900 {
--tw-gradient-to: #111827;
}
.dark\:text-gray-200 {
--tw-text-opacity: 1;
color: rgb(229 231 235 / var(--tw-text-opacity));
}
.dark\:text-gray-500 {
--tw-text-opacity: 1;
color: rgb(107 114 128 / var(--tw-text-opacity));
}
.dark\:text-white {
--tw-text-opacity: 1;
color: rgb(255 255 255 / var(--tw-text-opacity));
}
.dark\:hover\:bg-gray-800\/70:hover {
background-color: rgb(31 41 55 / 0.7);
}
}

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>

Before

Width:  |  Height:  |  Size: 1.5 KiB

@ -1 +0,0 @@
export { DocsGPTWidget } from "./src/components/DocsGPTWidget";

File diff suppressed because it is too large Load Diff

@ -1,47 +1,62 @@
{
"name": "docsgpt",
"version": "0.3.0",
"private": false,
"version": "0.2.4",
"type": "module",
"main": "dist/index.umd.js",
"module": "dist/index.es.js",
"types": "dist/index.d.ts",
"exports": {
".": {
"import": "./dist/index.es.js",
"require": "./dist/index.umd.js",
"types": "./dist/index.d.ts"
},
"./dist/style.css": "./dist/style.css"
},
"description": "docsgpt ai assistant",
"source": "./src/index.html",
"main": "dist/main.js",
"module": "dist/module.js",
"types": "dist/types.d.ts",
"files": [
"/dist"
"dist",
"package.json"
],
"publishConfig": {
"access": "public"
"@parcel/resolver-default": {
"packageExports": true
},
"resolution":{
"styled-components": "^5"
},
"scripts": {
"dev": "vite",
"build": "tsc && vite build",
"prepare": "npm run build && npm run build-css",
"build-css": "postcss src/index.css -o dist/style.css",
"preview": "vite preview"
"build": "parcel build src/index.ts",
"dev": "parcel",
"test": "jest",
"lint": "eslint",
"check": "tsc --noEmit",
"ci": "yarn build && yarn test && yarn lint && yarn check"
},
"dependencies": {
"postcss-cli": "^10.1.0",
"@babel/plugin-transform-flow-strip-types": "^7.23.3",
"@parcel/resolver-glob": "^2.12.0",
"@parcel/transformer-svg-react": "^2.12.0",
"@parcel/transformer-typescript-tsc": "^2.12.0",
"@parcel/validator-typescript": "^2.12.0",
"@radix-ui/react-icons": "^1.3.0",
"@types/react": "^18.2.61",
"@types/react-dom": "^18.2.19",
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.0",
"flow-bin": "^0.229.2",
"i": "^0.3.7",
"install": "^0.13.0",
"npm": "^10.5.0",
"parcel": "^2.12.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"tailwindcss": "^3.2.4"
"styled-components": "^6.1.8"
},
"devDependencies": {
"@types/react": "^18.0.26",
"@types/react-dom": "^18.0.9",
"@vitejs/plugin-react-swc": "^3.5.0",
"autoprefixer": "^10.4.13",
"postcss": "^8.4.31",
"typescript": "^4.9.3",
"vite": "^5.0.12",
"vite-plugin-dts": "^3.7.0"
"@babel/core": "^7.24.0",
"@babel/preset-env": "^7.24.0",
"@babel/preset-react": "^7.23.3",
"@parcel/packager-ts": "^2.12.0",
"@parcel/transformer-typescript-types": "^2.12.0",
"babel-loader": "^8.0.4",
"process": "^0.11.10",
"typescript": "^5.3.3"
},
"publishConfig": {
"access": "public"
},
"repository": {
"type": "git",

@ -1,6 +0,0 @@
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>

Before

Width:  |  Height:  |  Size: 1.5 KiB

@ -1,15 +1,11 @@
import { useState } from "react";
//import "./App.css";
import {DocsGPTWidget} from "./components/DocsGPTWidget";
function App() {
const [count, setCount] = useState(0);
import React from "react"
import {DocsGPTWidget} from "./components/DocsGPTWidget"
const App = () => {
return (
<div className="App">
<DocsGPTWidget />
<div>
<DocsGPTWidget/>
</div>
);
)
}
export default App;
export default App

@ -0,0 +1,7 @@
<svg width="36" height="36" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M4.37891 9.44824H7.75821" stroke="white" stroke-width="1.68965" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M11.1377 9.44824H12.8273" stroke="white" stroke-width="1.68965" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M4.37891 6.06934H6.06856" stroke="white" stroke-width="1.68965" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M9.44824 6.06934H12.8276" stroke="white" stroke-width="1.68965" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M16.2069 11.1379C16.2069 11.5861 16.0289 12.0158 15.712 12.3327C15.3951 12.6496 14.9654 12.8276 14.5172 12.8276H4.37931L1 16.2069V2.68965C1 2.24153 1.17802 1.81176 1.49489 1.49489C1.81176 1.17802 2.24153 1 2.68965 1H14.5172C14.9654 1 15.3951 1.17802 15.712 1.49489C16.0289 1.81176 16.2069 2.24153 16.2069 2.68965V11.1379Z" stroke="white" stroke-width="1.68965" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 1009 B

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="35.93" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 228"><path fill="#00D8FF" d="M210.483 73.824a171.49 171.49 0 0 0-8.24-2.597c.465-1.9.893-3.777 1.273-5.621c6.238-30.281 2.16-54.676-11.769-62.708c-13.355-7.7-35.196.329-57.254 19.526a171.23 171.23 0 0 0-6.375 5.848a155.866 155.866 0 0 0-4.241-3.917C100.759 3.829 77.587-4.822 63.673 3.233C50.33 10.957 46.379 33.89 51.995 62.588a170.974 170.974 0 0 0 1.892 8.48c-3.28.932-6.445 1.924-9.474 2.98C17.309 83.498 0 98.307 0 113.668c0 15.865 18.582 31.778 46.812 41.427a145.52 145.52 0 0 0 6.921 2.165a167.467 167.467 0 0 0-2.01 9.138c-5.354 28.2-1.173 50.591 12.134 58.266c13.744 7.926 36.812-.22 59.273-19.855a145.567 145.567 0 0 0 5.342-4.923a168.064 168.064 0 0 0 6.92 6.314c21.758 18.722 43.246 26.282 56.54 18.586c13.731-7.949 18.194-32.003 12.4-61.268a145.016 145.016 0 0 0-1.535-6.842c1.62-.48 3.21-.974 4.76-1.488c29.348-9.723 48.443-25.443 48.443-41.52c0-15.417-17.868-30.326-45.517-39.844Zm-6.365 70.984c-1.4.463-2.836.91-4.3 1.345c-3.24-10.257-7.612-21.163-12.963-32.432c5.106-11 9.31-21.767 12.459-31.957c2.619.758 5.16 1.557 7.61 2.4c23.69 8.156 38.14 20.213 38.14 29.504c0 9.896-15.606 22.743-40.946 31.14Zm-10.514 20.834c2.562 12.94 2.927 24.64 1.23 33.787c-1.524 8.219-4.59 13.698-8.382 15.893c-8.067 4.67-25.32-1.4-43.927-17.412a156.726 156.726 0 0 1-6.437-5.87c7.214-7.889 14.423-17.06 21.459-27.246c12.376-1.098 24.068-2.894 34.671-5.345a134.17 134.17 0 0 1 1.386 6.193ZM87.276 214.515c-7.882 2.783-14.16 2.863-17.955.675c-8.075-4.657-11.432-22.636-6.853-46.752a156.923 156.923 0 0 1 1.869-8.499c10.486 2.32 22.093 3.988 34.498 4.994c7.084 9.967 14.501 19.128 21.976 27.15a134.668 134.668 0 0 1-4.877 4.492c-9.933 8.682-19.886 14.842-28.658 17.94ZM50.35 144.747c-12.483-4.267-22.792-9.812-29.858-15.863c-6.35-5.437-9.555-10.836-9.555-15.216c0-9.322 13.897-21.212 37.076-29.293c2.813-.98 5.757-1.905 8.812-2.773c3.204 10.42 7.406 21.315 12.477 32.332c-5.137 11.18-9.399 22.249-12.634 32.792a134.718 134.718 0 0 1-6.318-1.979Zm12.378-84.26c-4.811-24.587-1.616-43.134 6.425-47.789c8.564-4.958 27.502 2.111 47.463 19.835a144.318 144.318 0 0 1 3.841 3.545c-7.438 7.987-14.787 17.08-21.808 26.988c-12.04 1.116-23.565 2.908-34.161 5.309a160.342 160.342 0 0 1-1.76-7.887Zm110.427 27.268a347.8 347.8 0 0 0-7.785-12.803c8.168 1.033 15.994 2.404 23.343 4.08c-2.206 7.072-4.956 14.465-8.193 22.045a381.151 381.151 0 0 0-7.365-13.322Zm-45.032-43.861c5.044 5.465 10.096 11.566 15.065 18.186a322.04 322.04 0 0 0-30.257-.006c4.974-6.559 10.069-12.652 15.192-18.18ZM82.802 87.83a323.167 323.167 0 0 0-7.227 13.238c-3.184-7.553-5.909-14.98-8.134-22.152c7.304-1.634 15.093-2.97 23.209-3.984a321.524 321.524 0 0 0-7.848 12.897Zm8.081 65.352c-8.385-.936-16.291-2.203-23.593-3.793c2.26-7.3 5.045-14.885 8.298-22.6a321.187 321.187 0 0 0 7.257 13.246c2.594 4.48 5.28 8.868 8.038 13.147Zm37.542 31.03c-5.184-5.592-10.354-11.779-15.403-18.433c4.902.192 9.899.29 14.978.29c5.218 0 10.376-.117 15.453-.343c-4.985 6.774-10.018 12.97-15.028 18.486Zm52.198-57.817c3.422 7.8 6.306 15.345 8.596 22.52c-7.422 1.694-15.436 3.058-23.88 4.071a382.417 382.417 0 0 0 7.859-13.026a347.403 347.403 0 0 0 7.425-13.565Zm-16.898 8.101a358.557 358.557 0 0 1-12.281 19.815a329.4 329.4 0 0 1-23.444.823c-7.967 0-15.716-.248-23.178-.732a310.202 310.202 0 0 1-12.513-19.846h.001a307.41 307.41 0 0 1-10.923-20.627a310.278 310.278 0 0 1 10.89-20.637l-.001.001a307.318 307.318 0 0 1 12.413-19.761c7.613-.576 15.42-.876 23.31-.876H128c7.926 0 15.743.303 23.354.883a329.357 329.357 0 0 1 12.335 19.695a358.489 358.489 0 0 1 11.036 20.54a329.472 329.472 0 0 1-11 20.722Zm22.56-122.124c8.572 4.944 11.906 24.881 6.52 51.026c-.344 1.668-.73 3.367-1.15 5.09c-10.622-2.452-22.155-4.275-34.23-5.408c-7.034-10.017-14.323-19.124-21.64-27.008a160.789 160.789 0 0 1 5.888-5.4c18.9-16.447 36.564-22.941 44.612-18.3ZM128 90.808c12.625 0 22.86 10.235 22.86 22.86s-10.235 22.86-22.86 22.86s-22.86-10.235-22.86-22.86s10.235-22.86 22.86-22.86Z"></path></svg>

Before

Width:  |  Height:  |  Size: 4.0 KiB

@ -1,247 +1,426 @@
"use client";
import {useEffect, useRef, useState} from 'react'
//import './style.css'
interface HistoryItem {
prompt: string;
response: string;
}
interface FetchAnswerStreamingProps {
question?: string;
apiKey?: string;
selectedDocs?: string;
history?: HistoryItem[];
conversationId?: string | null;
apiHost?: string;
onEvent?: (event: MessageEvent) => void;
}
enum ChatStates {
Init = 'init',
Processing = 'processing',
Typing = 'typing',
Answer = 'answer',
Minimized = 'minimized',
}
function fetchAnswerStreaming({
question = '',
apiKey = '',
selectedDocs = '',
history = [],
conversationId = null,
apiHost = '',
onEvent = () => {console.log("Event triggered, but no handler provided.");}
}: FetchAnswerStreamingProps): Promise<void> {
let docPath = 'default';
if (selectedDocs) {
docPath = selectedDocs;
}
return new Promise<void>((resolve, reject) => {
const body = {
question: question,
api_key: apiKey,
embeddings_key: apiKey,
active_docs: docPath,
history: JSON.stringify(history),
conversation_id: conversationId,
model: 'default'
};
fetch(apiHost + '/stream', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(body),
})
.then((response) => {
if (!response.body) throw Error('No response body');
const reader = response.body.getReader();
const decoder = new TextDecoder('utf-8');
let counterrr = 0;
const processStream = ({
done,
value,
}: ReadableStreamReadResult<Uint8Array>) => {
if (done) {
console.log(counterrr);
resolve();
return;
}
counterrr += 1;
import { Fragment, useEffect, useRef, useState } from 'react'
import { PaperPlaneIcon, RocketIcon, ExclamationTriangleIcon, Cross1Icon } from '@radix-ui/react-icons';
import { MESSAGE_TYPE } from '../models/types';
import { Query, Status } from '../models/types';
import MessageIcon from '../assets/message.svg'
import { fetchAnswerStreaming } from '../requests/streamingApi';
import styled, { keyframes } from 'styled-components';
const WidgetContainer = styled.div`
position: fixed;
right: 10px;
bottom: 10px;
z-index: 1000;
display: flex;
flex-direction: column;
align-items: center;
text-align: left;
width: 356px;
height: 405px;
`;
const StyledContainer = styled.div`
position: absolute;
bottom: 0;
left: 0;
width: 100%;
border-radius: 0.375rem;
background-color: rgb(34, 35, 39);
border: 1px solid gray;
font-family: sans-serif;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05), 0 2px 4px rgba(0, 0, 0, 0.1);
transition: visibility 0.3s, opacity 0.3s;
`;
const FloatingButton = styled.div`
position: absolute;
display: flex;
justify-content: center;
bottom: 1rem;
right: 1rem;
width: 5rem;
height: 5rem;
border-radius: 9999px;
overflow: hidden;
background-image: linear-gradient(to bottom right, #5AF0EC, #E80D9D);
background-color: #5AF0EC;
background-color: rgba(0, 0, 0, 0.8);
font-family: sans-serif;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
align-items: center;
justify-content: center;
cursor: pointer;
&:hover {
transform: scale(1.1);
transition: transform 0.2s ease-in-out;
}
`;
const CancelButton = styled.button`
cursor: pointer;
position: absolute;
top: 0;
right: 0;
margin: 0.5rem;
padding: 0;
background-color: transparent;
border: none;
outline: none;
color: inherit;
transition: opacity 0.3s ease;
&:hover {
opacity: 0.5;
}
.white-filter {
filter: invert(100%);
}
`;
const chunk = decoder.decode(value);
const Header = styled.div`
display: flex;
align-items: center;
padding: 0.75rem;
`;
const lines = chunk.split('\n');
const IconWrapper = styled.div`
padding: 0.5rem;
`;
for (let line of lines) {
if (line.trim() == '') {
continue;
}
if (line.startsWith('data:')) {
line = line.substring(5);
}
const ContentWrapper = styled.div`
flex: 1;
margin-left: 0.5rem;
`;
const messageEvent = new MessageEvent('message', {
data: line,
});
const Title = styled.h3`
font-size: 0.875rem;
font-weight: normal;
color: #FAFAFA;
margin-top: 0;
margin-bottom: 0.25rem;
`;
onEvent(messageEvent); // handle each message
}
const Description = styled.p`
font-size: 0.75rem;
color: #A1A1AA;
margin-top: 0;
`;
const Conversation = styled.div`
height: 18rem;
padding: 0.5rem;
border-radius: 0.375rem;
text-align: left;
overflow-y: auto;
scrollbar-width: thin;
scrollbar-color: #4a4a4a transparent; /* thumb color track color */
`;
reader.read().then(processStream).catch(reject);
};
const MessageBubble = styled.div<{ type: MESSAGE_TYPE }>`
display: flex;
justify-content: ${props => props.type === 'QUESTION' ? 'flex-end' : 'flex-start'};
margin: 0.5rem;
`;
const Message = styled.p<{ type: MESSAGE_TYPE }>`
background: ${props => props.type === 'QUESTION' ?
'linear-gradient(to bottom right, #8860DB, #6D42C5)' :
props => props.type === 'ANSWER' ?
'#38383b' :
''};
reader.read().then(processStream).catch(reject);
})
.catch((error) => {
console.error('Connection failed:', error);
reject(error);
});
});
}
export const DocsGPTWidget = ({ apiHost = 'https://gptcloud.arc53.com', selectDocs = 'default', apiKey = 'docsgpt-public'}) => {
// processing states
const [chatState, setChatState] = useState<ChatStates>(() => {
if (typeof window !== 'undefined') {
return localStorage.getItem('docsGPTChatState') as ChatStates || ChatStates.Init;
}
return ChatStates.Init;
});
const [answer, setAnswer] = useState<string>('');
color: ${props => props.type != 'ERROR' ? '#ffff' : '#b91c1c'};
border:${props => props.type !== 'ERROR' ? 'none' : '1px solid #b91c1c'};
max-width: 80%;
display: block;
padding: 0.75rem;
border-radius: 0.375rem;
`;
const ErrorAlert = styled.div`
color: #b91c1c;
border:0.1px solid #b91c1c;
display: flex;
padding:4px;
opacity: 90%;
max-width: 70%;
font-weight: 400;
border-radius: 0.375rem;
justify-content: space-evenly;
`
//dot loading animation
const dotBounce = keyframes`
0%, 80%, 100% {
transform: translateY(0);
}
40% {
transform: translateY(-5px);
}
`;
//const selectDocs = 'local/1706.03762.pdf/'
const answerRef = useRef<HTMLDivElement | null>(null);
const DotAnimation = styled.div`
display: inline-block;
animation: ${dotBounce} 1s infinite ease-in-out;
`;
useEffect(() => {
if (answerRef.current) {
const element = answerRef.current;
element.scrollTop = element.scrollHeight;
}
}, [answer]);
// delay classes as styled components
const Delay = styled(DotAnimation) <{ delay: number }>`
animation-delay: ${props => props.delay + 'ms'};
`;
const PromptContainer = styled.form`
background-color: transparent;
padding: 12px 8px;
opacity: 1;
width: 340px;
display: flex;
justify-content: space-between;
`;
const StyledInput = styled.input`
width: 80%;
border: 1px solid #686877;
height: 36px;
background-color: transparent;
font-size: 14px;
border-radius: 6px;
color: #ffff;
outline: none;
padding: 6px;
`;
const StyledButton = styled.button`
color: #ccc;
background-image: linear-gradient(to bottom right, #5AF0EC, #E80D9D);
font-size: 14px;
padding: 0 8px;
border-radius: 6px;
margin: 2px;
width: 36px;
border: none;
cursor: pointer;
outline: none;
&:hover{
opacity: 80%;
}
&:disabled {
opacity: 60%;
}`
const HeroContainer = styled.div`
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 80%;
background-image: linear-gradient(to bottom right, #5AF0EC, #ff1bf4);
border-radius: 10px;
margin: 0 auto;
padding: 1px;
`;
const HeroWrapper = styled.div`
background-color: #222327;
border-radius: 10px;
font-weight: normal;
padding: 6px;
display: flex;
justify-content: space-between;
`
const HeroTitle = styled.h3`
color: #fff;
font-size: 15px;
margin-bottom: 5px;
padding: 3px;
`;
useEffect(() => {
localStorage.setItem('docsGPTChatState', chatState);
}, [chatState]);
const HeroDescription = styled.p`
color: #fff;
font-size: 13px;
`;
const Avatar = styled.img<{width:number,height:number}>`
max-width: ${props => props.width};
`
const Hero = ({title,description}:{title:string,description:string}) => {
return (
<>
<HeroContainer>
<HeroWrapper>
<IconWrapper style={{ marginTop: '8px' }}>
<RocketIcon color='white' width={20} height={20} />
</IconWrapper>
<div>
<HeroTitle>{title}</HeroTitle>
<HeroDescription>
{description}
</HeroDescription>
</div>
</HeroWrapper>
</HeroContainer>
</>
);
};
export const DocsGPTWidget = ({
apiHost = 'https://gptcloud.arc53.com',
selectDocs = 'default',
apiKey = 'docsgpt-public',
avatar = 'https://d3dg1063dc54p9.cloudfront.net/cute-docsgpt.png',
title = 'Get AI assistance',
description = 'DocsGPT\'s AI Chatbot is here to help',
heroTitle = 'Welcome to DocsGPT !',
heroDescription='This chatbot is built with DocsGPT and utilises GenAI, please review important information using sources.'
}) => {
const [prompt, setPrompt] = useState('');
const [status, setStatus] = useState<Status>('idle');
const [queries, setQueries] = useState<Query[]>([])
const [conversationId, setConversationId] = useState<string | null>(null)
const [open, setOpen] = useState<boolean>(false)
const scrollRef = useRef<HTMLDivElement | null>(null);
const scrollToBottom = (element: Element | null) => {
//recursive function to scroll to the last child of the last child ...
// to get to the bottom most element
if (!element) return;
if (element?.children.length === 0) {
element?.scrollIntoView({
behavior: 'smooth',
block: 'start',
});
}
const lastChild = element?.children?.[element.children.length - 1]
lastChild && scrollToBottom(lastChild)
};
// submit handler
const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
setAnswer('')
e.preventDefault()
// get question
setChatState(ChatStates.Processing)
setTimeout(() => {
setChatState(ChatStates.Answer)
}, 800)
const inputElement = e.currentTarget[0] as HTMLInputElement;
const questionValue = inputElement.value;
useEffect(() => {
scrollToBottom(scrollRef.current);
}, [queries.length, queries[queries.length - 1]?.response]);
fetchAnswerStreaming({
question: questionValue,
async function stream(question: string) {
setStatus('loading');
try {
await fetchAnswerStreaming(
{
question: question,
apiKey: apiKey,
selectedDocs: selectDocs,
history: [],
conversationId: null,
apiHost: apiHost,
onEvent: (event) => {
selectedDocs: selectDocs,
history: queries,
conversationId: conversationId,
onEvent: (event: MessageEvent) => {
const data = JSON.parse(event.data);
// check if the 'end' event has been received
if (data.type === 'end') {
setChatState(ChatStates.Answer)
} else if (data.type === 'source') {
// check if data.metadata exists
let result;
if (data.metadata && data.metadata.title) {
const titleParts = data.metadata.title.split('/');
result = {
title: titleParts[titleParts.length - 1],
text: data.doc,
};
} else {
result = { title: data.doc, text: data.doc };
}
console.log(result)
// set status to 'idle'
setStatus('idle');
} else if (data.type === 'id') {
console.log(data.id);
setConversationId(data.id)
} else {
const result = data.answer;
// set answer by appending answer
setAnswer(prevAnswer => prevAnswer + result);
const streamingResponse = queries[queries.length - 1].response ? queries[queries.length - 1].response : '';
const updatedQueries = [...queries];
updatedQueries[updatedQueries.length - 1].response = streamingResponse + result;
setQueries(updatedQueries);
}
},
});
}
}
);
} catch (error) {
console.log(error);
const updatedQueries = [...queries];
updatedQueries[updatedQueries.length - 1].error = 'error'
setQueries(updatedQueries);
setStatus('idle')
}
}
// submit handler
const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault()
queries.push({ prompt })
setPrompt('')
await stream(prompt)
}
const handleImageError = (event: React.SyntheticEvent<HTMLImageElement, Event>) => {
event.currentTarget.src = "https://d3dg1063dc54p9.cloudfront.net/cute-docsgpt.png";
};
return (
<>
<div className="dark widget-container">
<div onClick={() => setChatState(ChatStates.Init)}
className={`${chatState !== 'minimized' ? 'hidden' : ''} cursor-pointer`}>
<div className="mr-2 mb-2 w-20 h-20 rounded-full overflow-hidden dark:divide-gray-700 border dark:border-gray-700 bg-gradient-to-br from-gray-100/80 via-white to-white dark:from-gray-900/80 dark:via-gray-900 dark:to-gray-900 font-sans shadow backdrop-blur-sm flex items-center justify-center">
<img
src="https://d3dg1063dc54p9.cloudfront.net/cute-docsgpt.png"
alt="DocsGPT"
className="cursor-pointer hover:opacity-50 h-14"
/>
</div>
</div>
<div className={` ${chatState !== 'minimized' ? '' : 'hidden'} divide-y dark:divide-gray-700 rounded-md border dark:border-gray-700 bg-gradient-to-br from-gray-100/80 via-white to-white dark:from-gray-900/80 dark:via-gray-900 dark:to-gray-900 font-sans shadow backdrop-blur-sm`} style={{ width: '18rem', transform: 'translateY(0%) translateZ(0px)' }}>
<div>
<img
src="https://d3dg1063dc54p9.cloudfront.net/exit.svg"
alt="Exit"
className="cursor-pointer hover:opacity-50 h-2 absolute top-0 right-0 m-2 white-filter"
onClick={(event) => {
event.stopPropagation();
setChatState(ChatStates.Minimized);
}}
/>
<div className="flex items-center gap-2 p-3">
<div className={`${chatState === 'init' ? '' :
chatState === 'processing' ? '' :
chatState === 'typing' ? '' :
'hidden'} flex-1`}>
<h3 className="text-sm font-bold text-gray-700 dark:text-gray-200">Need help with documentation?</h3>
<p className="mt-1 text-xs text-gray-400 dark:text-gray-500">DocsGPT AI assistant will help you with docs</p>
</div>
<div id="docsgpt-answer" ref={answerRef} className={`${chatState !== 'answer' ? 'hidden' : ''}`}>
<p className="mt-1 text-sm text-gray-600 dark:text-white text-left">{answer}</p>
</div>
<WidgetContainer>
<FloatingButton onClick={() => setOpen(true)} hidden={open}>
<MessageIcon />
</FloatingButton>
{open && <StyledContainer>
<div>
<CancelButton onClick={() => setOpen(false)}>
<Cross1Icon style={{ color: 'white' }} />
</CancelButton>
<Header>
<IconWrapper>
<img style={{maxWidth:"42px",maxHeight:"42px"}} onError={handleImageError} src={avatar} alt='docs-gpt' />
</IconWrapper>
<ContentWrapper>
<Title>{title}</Title>
<Description>{description}</Description>
</ContentWrapper>
</Header>
</div>
</div>
<div className="w-full">
<button onClick={() => setChatState(ChatStates.Typing)}
className={`flex w-full justify-center px-5 py-3 text-sm text-gray-800 font-bold dark:text-white transition duration-300 hover:bg-gray-100 rounded-b dark:hover:bg-gray-800/70 ${chatState !== 'init' ? 'hidden' : ''}`}>
Ask DocsGPT
</button>
{ (chatState === 'typing' || chatState === 'answer') && (
<form
onSubmit={handleSubmit}
className="relative w-full m-0" style={{ opacity: 1 }}>
<input type="text"
className="w-full bg-transparent px-5 py-3 pr-8 text-sm text-gray-700 dark:text-white focus:outline-none" placeholder="What do you want to do?" />
<button className="absolute text-gray-400 dark:text-gray-500 text-sm inset-y-0 right-2 -mx-2 px-2" type="submit" >Submit</button>
</form>
)}
<p className={`${chatState !== 'processing' ? 'hidden' : ''} flex w-full justify-center px-5 py-3 text-sm text-gray-800 font-bold dark:text-white transition duration-300 rounded-b`}>
Processing<span className="dot-animation">.</span><span className="dot-animation delay-200">.</span><span className="dot-animation delay-400">.</span>
</p>
</div>
</div>
</div>
<div style={{ width: '100%' }}>
<Conversation>
{
queries.length > 0 ? queries?.map((query, index) => {
return (
<Fragment key={index}>
{
query.prompt && <MessageBubble type='QUESTION'>
<Message
type='QUESTION'
ref={(!(query.response || query.error) && index === queries.length - 1) ? scrollRef : null}>
{query.prompt}
</Message>
</MessageBubble>
}
{
query.response ? <MessageBubble type='ANSWER'>
<Message
type='ANSWER'
ref={(index === queries.length - 1) ? scrollRef : null}
>
{query.response}
</Message>
</MessageBubble>
: <div>
{
query.error ? <ErrorAlert>
<IconWrapper>
<ExclamationTriangleIcon style={{ marginTop: '4px' }} width={22} height={22} color='#b91c1c' />
</IconWrapper>
<div>
<h5 style={{ margin: 2 }}>Network Error</h5>
<span style={{ margin: 2, fontSize: '13px' }}>Something went wrong !</span>
</div>
</ErrorAlert>
: <MessageBubble type='ANSWER'>
<Message type='ANSWER' style={{ fontWeight: 600 }}>
<DotAnimation>.</DotAnimation>
<Delay delay={200}>.</Delay>
<Delay delay={400}>.</Delay>
</Message>
</MessageBubble>
}
</div>
}
</Fragment>)
})
: <Hero title={heroTitle} description={heroDescription}/>
}
</Conversation>
<PromptContainer
onSubmit={handleSubmit}>
<StyledInput
value={prompt} onChange={(event) => setPrompt(event.target.value)}
type='text' placeholder="What do you want to do?" />
<StyledButton
disabled={prompt.length == 0 || status !== 'idle'}>
<PaperPlaneIcon color='white' />
</StyledButton>
</PromptContainer>
</div>
</StyledContainer>}
</WidgetContainer>
</>
)
}
}

@ -1 +0,0 @@
export { DocsGPTWidget } from "./DocsGPTWidget";

@ -1,44 +0,0 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
#docsgpt-answer {
max-height: 50vh; /* 50% of the viewport height */
overflow-y: auto; /* Adds a vertical scrollbar if the content exceeds the container height */
}
.widget-container {
position: fixed; /* fixed positioning */
right: 10px; /* from the right edge */
bottom: 10px; /* from the bottom edge */
z-index: 1000; /* to ensure it appears on top of other content, if any */
display: flex;
flex-direction: column;
align-items: center;
}
@keyframes dotBounce {
0%, 80%, 100% {
transform: translateY(0);
}
40% {
transform: translateY(-5px);
}
}
.dot-animation {
display: inline-block;
animation: dotBounce 1s infinite ease-in-out;
}
.delay-200 {
animation-delay: 200ms;
}
.delay-400 {
animation-delay: 400ms;
}
.white-filter {
filter: invert(1) brightness(2);
}

@ -2,12 +2,12 @@
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + React + TS</title>
<title>React (Parcel + TypeScript)</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
<div id="app"></div>
<script type="module" src="main.tsx"></script>
</body>
</html>

@ -0,0 +1 @@
export { DocsGPTWidget } from "./components/DocsGPTWidget";

@ -1,10 +1,6 @@
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App'
import './index.css'
import { createRoot } from 'react-dom/client';
import App from './App.tsx';
import React from 'react';
const root = createRoot(document.getElementById('app') as HTMLElement);
ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
<React.StrictMode>
<App />
</React.StrictMode>,
)
root.render(<App />);

@ -0,0 +1,93 @@
interface HistoryItem {
prompt: string;
response?: string;
}
interface FetchAnswerStreamingProps {
question?: string;
apiKey?: string;
selectedDocs?: string;
history?: HistoryItem[];
conversationId?: string | null;
apiHost?: string;
onEvent?: (event: MessageEvent) => void;
}
export function fetchAnswerStreaming({
question = '',
apiKey = '',
selectedDocs = '',
history = [],
conversationId = null,
apiHost = '',
onEvent = () => {console.log("Event triggered, but no handler provided.");}
}: FetchAnswerStreamingProps): Promise<void> {
let docPath = 'default';
if (selectedDocs) {
docPath = selectedDocs;
}
return new Promise<void>((resolve, reject) => {
const body = {
question: question,
api_key: apiKey,
embeddings_key: apiKey,
active_docs: docPath,
history: JSON.stringify(history),
conversation_id: conversationId,
model: 'default'
};
fetch(apiHost + '/stream', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(body),
})
.then((response) => {
if (!response.body) throw Error('No response body');
const reader = response.body.getReader();
const decoder = new TextDecoder('utf-8');
let counterrr = 0;
const processStream = ({
done,
value,
}: ReadableStreamReadResult<Uint8Array>) => {
if (done) {
console.log(counterrr);
resolve();
return;
}
counterrr += 1;
const chunk = decoder.decode(value);
const lines = chunk.split('\n');
for (let line of lines) {
if (line.trim() == '') {
continue;
}
if (line.startsWith('data:')) {
line = line.substring(5);
}
const messageEvent = new MessageEvent('message', {
data: line,
});
onEvent(messageEvent); // handle each message
}
reader.read().then(processStream).catch(reject);
};
reader.read().then(processStream).catch(reject);
})
.catch((error) => {
console.error('Connection failed:', error);
reject(error);
});
});
}

@ -1 +0,0 @@
/// <reference types="vite/client" />

@ -1,8 +0,0 @@
/** @type {import('tailwindcss').Config} */
module.exports = {
content: ["./index.html", "./src/**/*.{js,ts,jsx,tsx}"],
theme: {
extend: {},
},
plugins: [],
};

@ -1,23 +1,34 @@
{
"compilerOptions": {
"target": "ESNext",
"useDefineForClassFields": true,
"lib": ["DOM", "DOM.Iterable", "ESNext"],
"allowJs": false,
"skipLibCheck": true,
"esModuleInterop": false,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"module": "ESNext",
"moduleResolution": "Node",
"resolveJsonModule": true,
"isolatedModules": true,
"declaration": true,
"typeRoots": ["./dist/index.d.ts", "node_modules/@types"],
"noEmit": true,
"jsx": "react-jsx"
},
"include": ["src", "./index.ts"],
"references": [{ "path": "./tsconfig.node.json" }]
}
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["src/*", "@/*"]
},
"target": "ES2020",
"useDefineForClassFields": true,
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"module": "ESNext",
"skipLibCheck": true,
/* Bundler mode */
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx",
/* Linting */
"strict": true,
"noUnusedLocals": false,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true,
/* The "typeRoots" configuration specifies the locations where
TypeScript looks for type definitions (.d.ts files) to
include in the compilation process.*/
"typeRoots": ["./dist/index.d.ts", "node_modules/@types"]
},
/* include /index.ts*/
"include": ["src/index.ts","custom.d.ts"],
"exclude": ["node_modules"],
}

@ -1,9 +0,0 @@
{
"compilerOptions": {
"composite": true,
"module": "ESNext",
"moduleResolution": "Node",
"allowSyntheticDefaultImports": true
},
"include": ["vite.config.ts"]
}

@ -1,26 +0,0 @@
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react-swc";
import dts from "vite-plugin-dts";
import path from "path";
export default defineConfig({
build: {
lib: {
entry: path.resolve(__dirname, "index.ts"),
name: "ViteButton",
fileName: (format) => `index.${format}.js`,
},
rollupOptions: {
external: ["react", "react-dom"],
output: {
globals: {
react: "React",
"react-dom": "ReactDOM",
},
},
},
sourcemap: true,
emptyOutDir: true,
},
plugins: [react(), dts()],
});
Loading…
Cancel
Save