lightnode-sdk 0.8.4 → 0.8.6
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.
- package/dist/add.d.ts +1 -1
- package/dist/add.js +109 -61
- package/package.json +1 -1
package/dist/add.d.ts
CHANGED
|
@@ -119,7 +119,7 @@ export interface LayoutPatch {
|
|
|
119
119
|
* Returns what happened so the CLI can report it; never throws.
|
|
120
120
|
*/
|
|
121
121
|
export declare function patchLayoutWithProviders(cwd?: string): LayoutPatch;
|
|
122
|
-
export declare const SCAFFOLD_GLOBALS_CSS = "@import \"tailwindcss\";\n\n/* let Tailwind v4 see streamdown's classes so markdown answers are styled\n (harmless when streamdown isn't installed - the path just matches nothing) */\n@source \"../node_modules/streamdown/dist
|
|
122
|
+
export declare const SCAFFOLD_GLOBALS_CSS = "@import \"tailwindcss\";\n\n/* let Tailwind v4 see streamdown's classes so markdown answers are styled\n (harmless when streamdown isn't installed - the path just matches nothing) */\n@source \"../node_modules/streamdown/dist\";\n\n/* dark mode via .dark class (we default the app to dark) */\n@custom-variant dark (&:is(.dark, .dark *));\n\n/* design tokens (light) - ported from lcai-chat-v2 */\n:root {\n font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n\n --background: #ffffff;\n --primary: #6767e9;\n --primary-600: #5a4fd8;\n --foreground: #09090b;\n --card: #ffffff;\n --card-foreground: #09090b;\n --popover: #ffffff;\n --popover-foreground: hsl(240 10% 3.9%);\n --primary-foreground: #fafafa;\n --secondary: hsl(240 4.8% 95.9%);\n --secondary-foreground: hsl(240 5.9% 10%);\n --muted: hsl(240 4.8% 95.9%);\n --muted-foreground: hsl(240 3.8% 46.1%);\n --accent: hsl(240 4.8% 95.9%);\n --accent-foreground: hsl(240 5.9% 10%);\n --destructive: #ef4d6a;\n --destructive-foreground: hsl(0 0% 98%);\n --success: #15bd77;\n --warning: #eaa53d;\n --border: hsl(240 5.9% 90%);\n --input: hsl(240 5.9% 90%);\n --ring: hsl(240 10% 3.9%);\n --radius: 0.625rem;\n\n --surface-base-subtle: rgba(34, 35, 42, 0.02);\n --surface-base-faint: rgba(14, 18, 27, 0.04);\n --surface-base-light: rgba(204, 206, 239, 0.16);\n --surface-elevation-light: #ffffff;\n\n --content-primary: #0f0f14;\n --content-default: #373842;\n --content-soft: #656678;\n --content-extraLight: #9798b6;\n\n --border-soft: rgba(14, 18, 27, 0.08);\n --border-light: rgba(14, 18, 27, 0.06);\n}\n\n/* design tokens (dark) */\n.dark {\n --background: #070710;\n --foreground: hsl(0 0% 98%);\n --card: #0f0f14;\n --card-foreground: hsl(0 0% 98%);\n --popover: #0f0f14;\n --popover-foreground: hsl(0 0% 98%);\n --primary: #7064e9;\n --primary-600: #8c71f6;\n --primary-foreground: hsl(0 0% 98%);\n --secondary: hsl(240 3.7% 15.9%);\n --secondary-foreground: hsl(0 0% 98%);\n --muted: hsl(240 3.7% 15.9%);\n --muted-foreground: hsl(240 5% 64.9%);\n --accent: hsl(240 3.7% 15.9%);\n --accent-foreground: hsl(0 0% 98%);\n --destructive: #fb5a76;\n --destructive-foreground: hsl(0 0% 98%);\n --success: #22d68a;\n --warning: #f5be5c;\n --border: hsl(240 3.7% 15.9%);\n --input: hsl(240 3.7% 15.9%);\n --ring: hsl(240 4.9% 83.9%);\n\n --surface-base-subtle: rgba(204, 206, 239, 0.02);\n --surface-base-faint: rgba(204, 206, 239, 0.04);\n --surface-base-light: rgba(204, 206, 239, 0.08);\n --surface-elevation-light: #0f0f14;\n\n --content-primary: #cccef0;\n --content-default: #9798b6;\n --content-soft: rgba(154, 156, 207, 0.8);\n --content-extraLight: #9798b6;\n\n --border-soft: rgba(204, 206, 239, 0.12);\n --border-light: rgba(204, 206, 239, 0.08);\n}\n\n/* theme mapping (Tailwind v4 @theme) */\n@theme inline {\n --radius-md: calc(var(--radius) - 2px);\n --radius-sm: calc(var(--radius) - 4px);\n --radius-lg: var(--radius);\n\n --color-background: var(--background);\n --color-foreground: var(--foreground);\n --color-card: var(--card);\n --color-card-foreground: var(--card-foreground);\n --color-popover: var(--popover);\n --color-popover-foreground: var(--popover-foreground);\n --color-primary: var(--primary);\n --color-primary-600: var(--primary-600);\n --color-primary-foreground: var(--primary-foreground);\n --color-secondary: var(--secondary);\n --color-secondary-foreground: var(--secondary-foreground);\n --color-muted: var(--muted);\n --color-muted-foreground: var(--muted-foreground);\n --color-accent: var(--accent);\n --color-accent-foreground: var(--accent-foreground);\n --color-destructive: var(--destructive);\n --color-destructive-foreground: var(--destructive-foreground);\n --color-success: var(--success);\n --color-warning: var(--warning);\n --color-border: var(--border);\n --color-input: var(--input);\n --color-ring: var(--ring);\n\n --color-surface-base-subtle: var(--surface-base-subtle);\n --color-surface-base-faint: var(--surface-base-faint);\n --color-surface-base-light: var(--surface-base-light);\n --color-surface-elevation-light: var(--surface-elevation-light);\n --color-surface-base-brand-default: #693ee0;\n --color-surface-base-brand-strong: #8c71f6;\n\n --color-content-primary: var(--content-primary);\n --color-content-default: var(--content-default);\n --color-content-soft: var(--content-soft);\n --color-content-extraLight: var(--content-extraLight);\n\n --color-bdr-soft: var(--border-soft);\n --color-bdr-light: var(--border-light);\n\n --color-gradient-primary: linear-gradient(270deg, #7064e9 0%, #dd00ac 100%);\n}\n\n@layer base {\n * {\n border-color: var(--border);\n }\n body {\n background-color: var(--background);\n color: var(--foreground);\n overflow-x: hidden;\n }\n html {\n overflow-x: hidden;\n }\n button {\n cursor: pointer;\n }\n button:disabled {\n cursor: not-allowed;\n }\n /* visible keyboard focus across interactive elements */\n a:focus-visible,\n button:focus-visible,\n input:focus-visible,\n select:focus-visible,\n textarea:focus-visible {\n outline: 2px solid var(--primary);\n outline-offset: 2px;\n border-radius: 6px;\n }\n}\n\n/* respect reduced-motion: kill non-essential animation */\n@media (prefers-reduced-motion: reduce) {\n *,\n ::before,\n ::after {\n animation-duration: 0.001ms !important;\n animation-iteration-count: 1 !important;\n transition-duration: 0.001ms !important;\n scroll-behavior: auto !important;\n }\n}\n\n/* ambient app background (gradient mesh behind everything) */\nbody::before {\n content: \"\";\n position: fixed;\n inset: 0;\n z-index: -1;\n pointer-events: none;\n background:\n radial-gradient(60% 50% at 50% -6%, rgba(221, 0, 172, 0.10), transparent 60%),\n radial-gradient(55% 45% at 12% -8%, rgba(112, 100, 233, 0.14), transparent 60%),\n radial-gradient(50% 40% at 88% -2%, rgba(112, 100, 233, 0.12), transparent 60%),\n radial-gradient(45% 45% at 50% 115%, rgba(112, 100, 233, 0.07), transparent 60%);\n}\n.dark body::before {\n background:\n radial-gradient(60% 50% at 50% -6%, rgba(221, 0, 172, 0.12), transparent 60%),\n radial-gradient(55% 45% at 12% -8%, rgba(112, 100, 233, 0.18), transparent 60%),\n radial-gradient(50% 40% at 88% -2%, rgba(112, 100, 233, 0.14), transparent 60%),\n radial-gradient(45% 45% at 50% 118%, rgba(112, 100, 233, 0.10), transparent 60%);\n}\n\n/* signature lcai gradient (primary buttons / accents) */\n.bg-gradient-primary {\n background-image: var(--color-gradient-primary);\n}\n/* the lcai-chat connect-button gradient (pink -> purple) */\n.bg-gradient-btn {\n background-image: linear-gradient(94deg, #dd00ac 10.66%, #7130c3 53.03%, #410093 96.34%);\n background-size: 200% auto;\n}\n@keyframes pulse-dot {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.4; }\n}\n.animate-pulse-dot {\n animation: pulse-dot 1.6s ease-in-out infinite;\n}\n.text-gradient {\n background: linear-gradient(94deg, #dd00ac 10%, #7130c3 53%, #7064e9 96%);\n -webkit-background-clip: text;\n background-clip: text;\n color: transparent;\n}\n\n/* minimal scrollbar */\n::-webkit-scrollbar {\n width: 6px;\n height: 6px;\n}\n::-webkit-scrollbar-track {\n background: transparent;\n}\n::-webkit-scrollbar-thumb {\n background: var(--border);\n border-radius: 3px;\n}\n* {\n scrollbar-width: thin;\n scrollbar-color: var(--border) transparent;\n}\n";
|
|
123
123
|
export interface ScaffoldWiring {
|
|
124
124
|
written: WrittenFile[];
|
|
125
125
|
/** The route now also served at `/` (e.g. "/chat-web3"), or null if nothing was wired. */
|
package/dist/add.js
CHANGED
|
@@ -970,6 +970,7 @@ import { ConnectButton } from "@/components/connect-button";
|
|
|
970
970
|
type Turn = {
|
|
971
971
|
role: "user" | "assistant";
|
|
972
972
|
text: string;
|
|
973
|
+
streaming?: boolean;
|
|
973
974
|
worker?: string | null;
|
|
974
975
|
jobId?: string | null;
|
|
975
976
|
submitTx?: \`0x\${string}\` | null;
|
|
@@ -978,6 +979,30 @@ type Turn = {
|
|
|
978
979
|
|
|
979
980
|
const MODEL = "llama3-8b";
|
|
980
981
|
|
|
982
|
+
/** The LightChain atom mark (gradient logo). No wordmark - the viewBox frames
|
|
983
|
+
* the atom only. Used as the assistant avatar and the input glyph. */
|
|
984
|
+
function LcaiMark({ className }: { className?: string }) {
|
|
985
|
+
return (
|
|
986
|
+
<svg
|
|
987
|
+
viewBox="854.3951253356933 398.23541259765625 186.60832495117188 198.4013696411746"
|
|
988
|
+
className={className}
|
|
989
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
990
|
+
aria-hidden="true"
|
|
991
|
+
>
|
|
992
|
+
<g transform="translate(856.3148789999999, 398.23539999999997) scale(0.6266964564006055)">
|
|
993
|
+
<linearGradient gradientTransform="matrix(1 0 0 1 0 -244)" gradientUnits="userSpaceOnUse" id="lcai-mark-grad" x1="-0.0000002" x2="298.8796082" y1="401.5" y2="401.5">
|
|
994
|
+
<stop offset="0" stopColor="rgb(48, 5, 250)" />
|
|
995
|
+
<stop offset="1" stopColor="rgb(255, 18, 251)" />
|
|
996
|
+
</linearGradient>
|
|
997
|
+
<path
|
|
998
|
+
fill="url(#lcai-mark-grad)"
|
|
999
|
+
d="M280.0912476,168.2428284c0.0187378-0.036911,0.0380554-0.0726929,0.0562134-0.1096191c16.2681885-32.6010895,17.265564-64.3445282,2.8092651-89.3834915c-12.8778992-22.3064003-36.5042877-36.642292-67.219101-41.070858C196.544342,13.2930756,172.316452,0,146.5589905,0c-22.3245773,0-43.5001221,9.986846-61.2456131,28.5235424C59.731987,30.5614643,38.6132431,40.6585007,24.5028381,57.9581261C6.2308226,80.3639221,2.1413448,111.8585815,12.9886856,146.6407318c0.0119276,0.0391846,0.0255585,0.0778198,0.0380545,0.1170044c-0.0181751,0.0363464-0.0380545,0.0727081-0.0562305,0.1090546c-16.2681713,32.6010895-17.2655487,64.3445282-2.8092442,89.3834991c12.8778811,22.3069611,36.5042725,36.6422882,67.2190933,41.0714264C96.5736389,301.7069092,120.8015289,315,146.5589905,315c22.3296814,0,43.5103455-9.991394,61.2581024-28.5365906c25.5706024-2.0402222,46.6916199-12.125885,60.7980499-29.4215393c18.2720032-22.4057922,22.3614807-53.9004517,11.5141602-88.6826019C280.1173706,168.3206482,280.1037292,168.2814484,280.0912476,168.2428284z M271.8764954,85.1474762c10.6303711,18.4145813,11.1694031,41.5411453,1.7635803,66.0655212c-3.7219849-8.3783264-8.2141418-16.6447449-13.4100647-24.7055588l-4.6642761,17.0429001c4.3473511,7.8126068,7.9301758,15.6831512,10.7121582,23.4855347c-4.3819885,8.0193481-9.6506042,15.8308258-15.7041626,23.3338776c1.5176544-10.6928558,2.3207703-21.6884308,2.3207703-32.8691864c0-29.667511-5.4985657-60.093277-17.7237091-87.3391113c-2.6733246-5.9579468-5.6783905-11.7689896-9.0385132-17.369133C246.8721771,58.2199669,262.7427673,69.3285828,271.8764954,85.1474762z M53.0189972,157.5005646c0-17.7983093,2.0930176-34.8525772,5.9098625-50.615242c11.8929939-11.332962,25.6574974-21.6162949,40.8601341-30.3939056c17.8886261-10.3276367,36.5854874-17.8778381,55.0960617-22.4290848c17.2502136,7.3440208,34.5396118,17.6932373,50.7930145,30.9488297c11.4465637,9.3348007,21.5856323,19.4636459,30.3081512,30.0235825c2.6712189,13.4345093,4.1127625,27.6942902,4.1127625,42.4658203c0,17.79776-2.0930176,34.852005-5.9092865,50.6141052c-11.8930054,11.3329773-25.6575012,21.6163025-40.8607025,30.3939209c-17.8818207,10.3236542-36.5724335,17.8908844-55.0767517,22.4427032c-17.2558975-7.3440094-34.5521164-17.7017517-50.811203-30.9624481h-0.0011368c-11.4465637-9.3348083-21.5856247-19.4636536-30.3081436-30.0235901C54.460537,186.531311,53.0189972,172.27211,53.0189972,157.5005646z M197.5405884,36.2367516c-8.420929-0.1454048-17.0355225,0.3947487-25.7472534,1.5812645l10.6093597,11.7066994c4.158783-0.3368149,8.2834625-0.5191383,12.357605-0.5191383c2.894455,0,5.7661743,0.0851974,8.6072235,0.2578659c1.8720703,0.1141663,3.7151794,0.2686577,5.5338593,0.456089c7.9432373,11.0063782,14.6692963,24.0733986,19.8174896,38.6586342c-4.7466278-4.5887375-9.7346497-9.0269547-14.9538574-13.283989c-5.9595642-4.8602829-12.1525574-9.4351349-18.5579681-13.6909294c-6.3523102-4.2205162-12.9407349-7.9979477-19.6017914-11.7028999c-4.8133698-2.6772537-9.9029083-5.0026283-14.9892578-7.1101379c-1.8141327-0.7520103-3.3374634-1.3887177-4.6540527-1.9288712c-15.6155548-6.2455406-31.4423981-10.2702694-46.9034653-11.8191586c-1.6102371-0.1607399-3.2039948-0.2845592-4.789238-0.3907719c12.707489-10.0067272,27.0797272-15.6558857,42.2897491-15.6558857C165.352417,12.7955227,182.865036,21.4209137,197.5405884,36.2367516z M34.4186859,66.0450745c9.6119766-11.7850838,23.0726089-19.3455086,38.8551559-22.8698425c-0.9178619,1.2932968-1.8266373,2.6036339-2.717804,3.9503212c-7.5609894,11.4329338-13.7923317,24.314785-18.6122322,38.2065163l15.7944679-5.6764221c6.2233963-15.0276947,14.1956024-28.1611671,23.4639511-38.7228127c1.3574829-0.0494118,2.7212067-0.0846291,4.0997009-0.0846291c12.3808975,0,25.5910492,1.9907799,39.0925751,5.8922577c-13.8752594,4.7176666-27.6653214,10.9700241-41.0032654,18.6707382c-9.0180283,5.2061462-17.6032944,11.0505371-25.9167862,17.3136139c-6.0140381,4.5307617-12.0375252,9.2800751-17.314682,14.6695099c-0.9797707,0.965004-1.8680954,1.8391342-2.6734962,2.6308975c-0.0170364,0.0653229-0.0329399,0.1312103-0.0505486,0.1965256c-9.7846451,9.6653671-18.3208618,20.0276489-25.3808918,30.852272C16.8799381,106.224762,20.5229797,83.083992,34.4186859,66.0450745z M21.2414799,229.8525238c-10.630372-18.4140167-11.1693878-41.5405731-1.763588-66.0655212c4.1763802,9.4012604,9.3228741,18.6616516,15.3446293,27.6482849l4.0724411-17.6199799c-4.9550858-8.587326-8.9911728-17.2598572-12.054306-25.851181c4.381422-8.0193481,9.650032-15.8308258,15.7035942-23.3338776c-1.5176506,10.6934204-2.3207779,21.6895752-2.3207779,32.8703156c0,7.742981,0.3608093,15.5649719,1.0776787,23.2746582c2.6225128,28.2041779,11.0045586,56.9674835,25.6845512,81.4324493C46.2463646,256.7800293,30.3752155,245.6719818,21.2414799,229.8525238z M95.5614929,278.7479248c0.9189987,0.0158997,1.8345871,0.0408936,2.7575607,0.0408936c7.9733429,0,16.1102676-0.612854,24.3289871-1.7931213l-10.7837296-11.6033325c-7.5093002,0.662262-14.9044418,0.7838135-22.1138535,0.3441772c-1.8720703-0.1135864-3.7151718-0.2680664-5.5338593-0.4555054c-7.9438095-11.0069427-14.6698608-24.0739594-19.8180618-38.6603394c4.7472,4.5893097,9.7357941,9.0280914,14.9555588,13.2851257h-0.0011292c11.9242325,9.7244415,24.5255051,18.0942383,37.4562073,24.9662781c-0.021019,0.0028381-0.0420303,0.0050964-0.0630493,0.0073547c5.3225708,2.7774658,11.9242401,6.0115356,18.2651978,8.5464478c2.2242279,0.8894653,4.0071259,1.6102295,5.4679718,2.2071838c14.5341187,5.5088806,29.2147827,9.0860291,43.5802155,10.5247192c1.6107941,0.1613159,3.2039948,0.2845764,4.7897949,0.3907776c-12.7080536,10.0067444-27.0802917,15.6558838-42.2903137,15.6558838C127.7593155,302.2044678,110.240448,293.5728455,95.5614929,278.7479248z M258.6993103,248.9549255c-9.6131287,11.7862244-23.0743256,19.3534546-38.8602753,22.8778076c0.9195557-1.2955933,1.8305969-2.6087646,2.7229004-3.9582825c7.3122253-11.0557861,13.3947449-23.4577026,18.1470642-36.8263245l-15.8035583,5.4151459c-6.1529694,14.5613861-13.9542084,27.3091888-22.9919586,37.6073151c-13.5583191,0.4913025-28.2117157-1.4767761-43.229187-5.8201294c13.8883209-4.7193909,27.6931458-10.9535522,41.04245-18.6616669c9.6801453-5.5883789,18.8150177-11.7680359,27.3148804-18.427063c-0.0124969,0.0312347-0.0238647,0.0630493-0.0363464,0.0942841c4.5438538-3.6339569,9.8499603-8.1062622,14.4875336-12.6194458c3.7958374-3.6941681,6.0331268-5.820694,7.3400421-7.0401611c8.474884-8.7463684,15.9393005-18.0238037,22.2302856-27.6698608C276.2380371,208.775238,272.5950012,231.9165802,258.6993103,248.9549255z M151.8601074,99.7067947l2.0352783,43.1479874c0.1197662,2.5387726,2.1956635,4.5453033,4.7370453,4.5787506l30.6875916,0.4037781c3.7883453,0.0498505,6.0318604,4.2594757,3.9608765,7.4320374l-40.7515411,62.4279022c-2.6121979,4.0016479-8.8297119,2.1519318-8.8297119-2.6268463v-42.6512451c0-2.6540527-2.151535-4.8055878-4.805603-4.8055878h-32.7028122c-3.7936096,0-6.0953522-4.18367-4.056221-7.3826447c9.1347427-14.3305359,29.4064636-45.9985199,40.9515228-63.0014496C145.6810608,93.4083862,151.6424866,95.0932236,151.8601074,99.7067947z"
|
|
1000
|
+
/>
|
|
1001
|
+
</g>
|
|
1002
|
+
</svg>
|
|
1003
|
+
);
|
|
1004
|
+
}
|
|
1005
|
+
|
|
981
1006
|
export default function ChatWeb3() {
|
|
982
1007
|
const { address, chain } = useAccount();
|
|
983
1008
|
const network: "mainnet" | "testnet" | null =
|
|
@@ -1021,6 +1046,16 @@ export default function ChatWeb3() {
|
|
|
1021
1046
|
return system ? \`\${system}\\n\\n\${lines.join("\\n\\n")}\` : lines.join("\\n\\n");
|
|
1022
1047
|
}
|
|
1023
1048
|
|
|
1049
|
+
/** Patch the trailing assistant turn (the streaming placeholder) in place. */
|
|
1050
|
+
function patchLastAssistant(patch: Partial<Turn>) {
|
|
1051
|
+
setTurns((prev) => {
|
|
1052
|
+
if (prev.length === 0) return prev;
|
|
1053
|
+
const last = prev[prev.length - 1];
|
|
1054
|
+
if (last.role !== "assistant") return prev;
|
|
1055
|
+
return [...prev.slice(0, -1), { ...last, ...patch }];
|
|
1056
|
+
});
|
|
1057
|
+
}
|
|
1058
|
+
|
|
1024
1059
|
async function send() {
|
|
1025
1060
|
if (!walletClient || !publicClient || !address || !network) {
|
|
1026
1061
|
setErr("Connect a wallet on LightChain mainnet (9200) or testnet (8200) first.");
|
|
@@ -1031,8 +1066,8 @@ export default function ChatWeb3() {
|
|
|
1031
1066
|
setBusy(true);
|
|
1032
1067
|
setErr(null);
|
|
1033
1068
|
const history = [...turns];
|
|
1034
|
-
// Optimistic user bubble
|
|
1035
|
-
setTurns([...history, { role: "user", text: next }]);
|
|
1069
|
+
// Optimistic user bubble + an empty assistant turn we stream tokens into.
|
|
1070
|
+
setTurns([...history, { role: "user", text: next }, { role: "assistant", text: "", streaming: true }]);
|
|
1036
1071
|
setInput("");
|
|
1037
1072
|
try {
|
|
1038
1073
|
const system = "You are a concise assistant. Reply in one or two short sentences.";
|
|
@@ -1052,16 +1087,21 @@ export default function ChatWeb3() {
|
|
|
1052
1087
|
model: MODEL,
|
|
1053
1088
|
jobCompletedTimeoutMs: 120_000,
|
|
1054
1089
|
maxRetries: 1,
|
|
1090
|
+
// Stream each decrypted chunk into the assistant bubble as it arrives.
|
|
1091
|
+
onChunk: (_chunk, totalSoFar) => {
|
|
1092
|
+
setBusyStage("");
|
|
1093
|
+
patchLastAssistant({ text: totalSoFar });
|
|
1094
|
+
},
|
|
1055
1095
|
});
|
|
1056
1096
|
|
|
1057
|
-
|
|
1058
|
-
role: "assistant",
|
|
1097
|
+
patchLastAssistant({
|
|
1059
1098
|
text: result.answer,
|
|
1099
|
+
streaming: false,
|
|
1060
1100
|
worker: result.worker,
|
|
1061
1101
|
jobId: result.jobId?.toString() ?? null,
|
|
1062
1102
|
submitTx: result.txs?.submitJob ?? null,
|
|
1063
1103
|
jobCompletedTx: result.txs?.jobCompleted ?? null,
|
|
1064
|
-
}
|
|
1104
|
+
});
|
|
1065
1105
|
} catch (e) {
|
|
1066
1106
|
// Roll back the optimistic user bubble so the visitor can retry.
|
|
1067
1107
|
setTurns(history);
|
|
@@ -1097,8 +1137,9 @@ export default function ChatWeb3() {
|
|
|
1097
1137
|
</header>
|
|
1098
1138
|
|
|
1099
1139
|
<div className="flex flex-1 flex-col gap-6 overflow-y-auto pb-6">
|
|
1100
|
-
{turns.length === 0
|
|
1101
|
-
<div className="flex flex-1 flex-col items-center justify-center gap-
|
|
1140
|
+
{turns.length === 0 ? (
|
|
1141
|
+
<div className="flex flex-1 flex-col items-center justify-center gap-4 text-center">
|
|
1142
|
+
<LcaiMark className="size-12" />
|
|
1102
1143
|
<h2 className="text-3xl font-medium tracking-tight text-foreground">
|
|
1103
1144
|
Start talking with <span className="text-gradient">AI Chat</span>
|
|
1104
1145
|
</h2>
|
|
@@ -1113,67 +1154,74 @@ export default function ChatWeb3() {
|
|
|
1113
1154
|
)}
|
|
1114
1155
|
</div>
|
|
1115
1156
|
) : (
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
<div
|
|
1120
|
-
|
|
1121
|
-
{t.text}
|
|
1122
|
-
</div>
|
|
1157
|
+
turns.map((t, i) =>
|
|
1158
|
+
t.role === "user" ? (
|
|
1159
|
+
<div key={i} className="flex justify-end">
|
|
1160
|
+
<div className="w-fit max-w-[85%] whitespace-pre-wrap break-words rounded-2xl bg-surface-base-faint px-4 py-2.5 text-sm text-foreground">
|
|
1161
|
+
{t.text}
|
|
1123
1162
|
</div>
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
<
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1163
|
+
</div>
|
|
1164
|
+
) : (
|
|
1165
|
+
<div key={i} className="group flex gap-3">
|
|
1166
|
+
<LcaiMark className="mt-0.5 size-7 shrink-0" />
|
|
1167
|
+
<div className="flex min-w-0 flex-1 flex-col gap-2">
|
|
1168
|
+
{t.text ? (
|
|
1169
|
+
<div className="max-w-none text-sm leading-relaxed text-foreground [&_*:first-child]:mt-0 [&_*:last-child]:mb-0">
|
|
1170
|
+
<Streamdown>{t.text}</Streamdown>
|
|
1171
|
+
</div>
|
|
1172
|
+
) : (
|
|
1173
|
+
<div className="animate-pulse-dot pt-1 text-sm text-muted-foreground">
|
|
1174
|
+
{busyStage || "Writing on chain..."}
|
|
1175
|
+
</div>
|
|
1176
|
+
)}
|
|
1177
|
+
{t.submitTx && (
|
|
1178
|
+
<div className="flex flex-wrap items-center gap-3 text-[11px] text-muted-foreground opacity-0 transition-opacity group-hover:opacity-100">
|
|
1179
|
+
<button
|
|
1180
|
+
type="button"
|
|
1181
|
+
onClick={() => navigator.clipboard?.writeText(t.text)}
|
|
1182
|
+
className="inline-flex items-center gap-1 hover:text-foreground"
|
|
1183
|
+
aria-label="Copy"
|
|
1184
|
+
>
|
|
1185
|
+
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
|
1186
|
+
<rect x="9" y="9" width="13" height="13" rx="2" ry="2" />
|
|
1187
|
+
<path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1" />
|
|
1188
|
+
</svg>
|
|
1189
|
+
Copy
|
|
1190
|
+
</button>
|
|
1191
|
+
{t.worker && (
|
|
1192
|
+
<a className="hover:text-foreground hover:underline" href={\`https://\${network}.lightscan.app/address/\${t.worker}\`} target="_blank" rel="noopener noreferrer">worker</a>
|
|
1193
|
+
)}
|
|
1194
|
+
{t.jobId && <span>job #{t.jobId}</span>}
|
|
1195
|
+
{t.submitTx && (
|
|
1196
|
+
<a className="hover:text-foreground hover:underline" href={\`https://\${network}.lightscan.app/tx/\${t.submitTx}\`} target="_blank" rel="noopener noreferrer">submitJob</a>
|
|
1197
|
+
)}
|
|
1198
|
+
{t.jobCompletedTx && (
|
|
1199
|
+
<a className="hover:text-foreground hover:underline" href={\`https://\${network}.lightscan.app/tx/\${t.jobCompletedTx}\`} target="_blank" rel="noopener noreferrer">completed</a>
|
|
1200
|
+
)}
|
|
1201
|
+
</div>
|
|
1202
|
+
)}
|
|
1153
1203
|
</div>
|
|
1154
|
-
)
|
|
1155
|
-
)}
|
|
1156
|
-
{busy && (
|
|
1157
|
-
<div className="animate-pulse-dot text-sm text-muted-foreground">
|
|
1158
|
-
{busyStage || "Writing on chain..."}
|
|
1159
1204
|
</div>
|
|
1160
|
-
)
|
|
1161
|
-
|
|
1205
|
+
)
|
|
1206
|
+
)
|
|
1162
1207
|
)}
|
|
1163
1208
|
<div ref={endRef} />
|
|
1164
1209
|
</div>
|
|
1165
1210
|
|
|
1166
1211
|
<div className="rounded-2xl border border-border bg-card p-3">
|
|
1167
|
-
<
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1212
|
+
<div className="flex items-start gap-2">
|
|
1213
|
+
<LcaiMark className="mt-2 size-5 shrink-0" />
|
|
1214
|
+
<textarea
|
|
1215
|
+
value={input}
|
|
1216
|
+
onChange={(e) => setInput(e.target.value)}
|
|
1217
|
+
onKeyDown={(e) => {
|
|
1218
|
+
if (e.key === "Enter" && (e.metaKey || e.ctrlKey)) { e.preventDefault(); if (!busy && input.trim()) send(); }
|
|
1219
|
+
}}
|
|
1220
|
+
rows={1}
|
|
1221
|
+
placeholder="Send a message..."
|
|
1222
|
+
className="max-h-40 min-h-[44px] w-full resize-none bg-transparent px-2 py-2 text-sm text-foreground outline-none placeholder:text-muted-foreground"
|
|
1223
|
+
/>
|
|
1224
|
+
</div>
|
|
1177
1225
|
<div className="mt-1 flex items-center justify-between gap-2">
|
|
1178
1226
|
<span className="inline-flex items-center gap-1.5 rounded-lg px-2 py-1 text-xs font-medium text-muted-foreground">
|
|
1179
1227
|
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
|
@@ -2152,7 +2200,7 @@ export const SCAFFOLD_GLOBALS_CSS = `@import "tailwindcss";
|
|
|
2152
2200
|
|
|
2153
2201
|
/* let Tailwind v4 see streamdown's classes so markdown answers are styled
|
|
2154
2202
|
(harmless when streamdown isn't installed - the path just matches nothing) */
|
|
2155
|
-
@source "../node_modules/streamdown/dist
|
|
2203
|
+
@source "../node_modules/streamdown/dist";
|
|
2156
2204
|
|
|
2157
2205
|
/* dark mode via .dark class (we default the app to dark) */
|
|
2158
2206
|
@custom-variant dark (&:is(.dark, .dark *));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lightnode-sdk",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.6",
|
|
4
4
|
"description": "Read-only TypeScript client for LightChain AI: workers, jobs, models, on-chain registration, and per-model network analytics. Independent, community-built (not an official LightChain package).",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|