lightnode-sdk 0.8.6 → 0.8.8

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.
Files changed (2) hide show
  1. package/dist/add.js +119 -65
  2. package/package.json +1 -1
package/dist/add.js CHANGED
@@ -966,6 +966,7 @@ import { useAccount, useWalletClient, usePublicClient } from "wagmi";
966
966
  import { siweSignIn, GatewayClient, runInference, estimateJobFee, NETWORKS } from "lightnode-sdk";
967
967
  import { Streamdown } from "streamdown";
968
968
  import { ConnectButton } from "@/components/connect-button";
969
+ import { LcaiMark } from "@/components/lcai-mark";
969
970
 
970
971
  type Turn = {
971
972
  role: "user" | "assistant";
@@ -979,30 +980,6 @@ type Turn = {
979
980
 
980
981
  const MODEL = "llama3-8b";
981
982
 
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
-
1006
983
  export default function ChatWeb3() {
1007
984
  const { address, chain } = useAccount();
1008
985
  const network: "mainnet" | "testnet" | null =
@@ -1030,9 +1007,10 @@ export default function ChatWeb3() {
1030
1007
  return () => { cancelled = true; };
1031
1008
  }, [network]);
1032
1009
 
1033
- // Keep the latest turn (and the "writing on chain" indicator) in view.
1010
+ // Keep the latest turn in view. Instant while streaming (smooth scrolling on
1011
+ // every chunk competes for the main thread); smooth once idle.
1034
1012
  useEffect(() => {
1035
- endRef.current?.scrollIntoView({ behavior: "smooth" });
1013
+ endRef.current?.scrollIntoView({ behavior: busy ? "auto" : "smooth", block: "nearest" });
1036
1014
  }, [turns, busy]);
1037
1015
 
1038
1016
  /** Build a single prompt from history + new user input. */
@@ -1166,9 +1144,15 @@ export default function ChatWeb3() {
1166
1144
  <LcaiMark className="mt-0.5 size-7 shrink-0" />
1167
1145
  <div className="flex min-w-0 flex-1 flex-col gap-2">
1168
1146
  {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>
1147
+ t.streaming ? (
1148
+ // While streaming, render plain text (cheap) - markdown is
1149
+ // parsed once when the turn finalizes, below.
1150
+ <div className="whitespace-pre-wrap break-words text-sm leading-relaxed text-foreground">{t.text}</div>
1151
+ ) : (
1152
+ <div className="max-w-none text-sm leading-relaxed text-foreground [&_*:first-child]:mt-0 [&_*:last-child]:mb-0">
1153
+ <Streamdown>{t.text}</Streamdown>
1154
+ </div>
1155
+ )
1172
1156
  ) : (
1173
1157
  <div className="animate-pulse-dot pt-1 text-sm text-muted-foreground">
1174
1158
  {busyStage || "Writing on chain..."}
@@ -1270,7 +1254,9 @@ const NEXTJS_INFERENCE_WEB3_PAGE = `// app/inference-web3/page.tsx
1270
1254
  import { useEffect, useState } from "react";
1271
1255
  import { useAccount, useWalletClient, usePublicClient } from "wagmi";
1272
1256
  import { siweSignIn, GatewayClient, runInference, estimateJobFee, NETWORKS } from "lightnode-sdk";
1257
+ import { Streamdown } from "streamdown";
1273
1258
  import { ConnectButton } from "@/components/connect-button";
1259
+ import { LcaiMark } from "@/components/lcai-mark";
1274
1260
 
1275
1261
  type Result = {
1276
1262
  answer: string;
@@ -1295,6 +1281,7 @@ export default function InferenceWeb3() {
1295
1281
  const [busy, setBusy] = useState(false);
1296
1282
  const [busyStage, setBusyStage] = useState("");
1297
1283
  const [result, setResult] = useState<Result | null>(null);
1284
+ const [stream, setStream] = useState("");
1298
1285
  const [err, setErr] = useState<string | null>(null);
1299
1286
  const [feeLcai, setFeeLcai] = useState<number | null>(null);
1300
1287
 
@@ -1317,6 +1304,7 @@ export default function InferenceWeb3() {
1317
1304
  setBusy(true);
1318
1305
  setErr(null);
1319
1306
  setResult(null);
1307
+ setStream("");
1320
1308
  const t0 = Date.now();
1321
1309
  try {
1322
1310
  setBusyStage("Sign in with your wallet (SIWE)...");
@@ -1334,6 +1322,8 @@ export default function InferenceWeb3() {
1334
1322
  model: MODEL,
1335
1323
  jobCompletedTimeoutMs: 120_000,
1336
1324
  maxRetries: 1,
1325
+ // Stream the answer live as decrypted chunks arrive.
1326
+ onChunk: (_chunk, totalSoFar) => { setBusyStage(""); setStream(totalSoFar); },
1337
1327
  });
1338
1328
  setResult({
1339
1329
  answer: r.answer,
@@ -1403,18 +1393,35 @@ export default function InferenceWeb3() {
1403
1393
  </p>
1404
1394
  )}
1405
1395
 
1406
- {result && (
1396
+ {(busy || result) && (
1407
1397
  <div className="rounded-2xl border border-border bg-card p-4">
1408
- <div className="mb-2 text-[11px] font-medium uppercase tracking-wide text-muted-foreground">Answer</div>
1409
- <pre className="m-0 whitespace-pre-wrap break-words font-sans text-sm text-foreground">{result.answer}</pre>
1410
- <div className="mt-3 flex flex-wrap gap-3 text-xs text-muted-foreground">
1411
- <span>elapsed {Math.round(result.elapsedMs / 1000)}s</span>
1412
- <span>job #{result.jobId}</span>
1413
- <a className="hover:text-foreground hover:underline" href={\`https://\${network}.lightscan.app/address/\${result.worker}\`} target="_blank" rel="noopener noreferrer">worker</a>
1414
- <a className="hover:text-foreground hover:underline" href={\`https://\${network}.lightscan.app/tx/\${result.submitJob}\`} target="_blank" rel="noopener noreferrer">submitJob</a>
1415
- {result.jobCompleted && (
1416
- <a className="hover:text-foreground hover:underline" href={\`https://\${network}.lightscan.app/tx/\${result.jobCompleted}\`} target="_blank" rel="noopener noreferrer">jobCompleted</a>
1417
- )}
1398
+ <div className="flex gap-3">
1399
+ <LcaiMark className="mt-0.5 size-7 shrink-0" />
1400
+ <div className="flex min-w-0 flex-1 flex-col gap-2">
1401
+ {result ? (
1402
+ <div className="max-w-none text-sm leading-relaxed text-foreground [&_*:first-child]:mt-0 [&_*:last-child]:mb-0">
1403
+ <Streamdown>{result.answer}</Streamdown>
1404
+ </div>
1405
+ ) : stream ? (
1406
+ // Plain text while streaming; markdown is parsed once on completion.
1407
+ <div className="whitespace-pre-wrap break-words text-sm leading-relaxed text-foreground">{stream}</div>
1408
+ ) : (
1409
+ <div className="animate-pulse-dot pt-1 text-sm text-muted-foreground">
1410
+ {busyStage || "Writing on chain..."}
1411
+ </div>
1412
+ )}
1413
+ {result && (
1414
+ <div className="mt-1 flex flex-wrap gap-3 text-xs text-muted-foreground">
1415
+ <span>elapsed {Math.round(result.elapsedMs / 1000)}s</span>
1416
+ <span>job #{result.jobId}</span>
1417
+ <a className="hover:text-foreground hover:underline" href={\`https://\${network}.lightscan.app/address/\${result.worker}\`} target="_blank" rel="noopener noreferrer">worker</a>
1418
+ <a className="hover:text-foreground hover:underline" href={\`https://\${network}.lightscan.app/tx/\${result.submitJob}\`} target="_blank" rel="noopener noreferrer">submitJob</a>
1419
+ {result.jobCompleted && (
1420
+ <a className="hover:text-foreground hover:underline" href={\`https://\${network}.lightscan.app/tx/\${result.jobCompleted}\`} target="_blank" rel="noopener noreferrer">jobCompleted</a>
1421
+ )}
1422
+ </div>
1423
+ )}
1424
+ </div>
1418
1425
  </div>
1419
1426
  </div>
1420
1427
  )}
@@ -1438,7 +1445,9 @@ const NEXTJS_JUDGE_WEB3_PAGE = `// app/judge-web3/page.tsx
1438
1445
  import { useEffect, useState } from "react";
1439
1446
  import { useAccount, useWalletClient, usePublicClient } from "wagmi";
1440
1447
  import { siweSignIn, GatewayClient, runInference, estimateJobFee, NETWORKS } from "lightnode-sdk";
1448
+ import { Streamdown } from "streamdown";
1441
1449
  import { ConnectButton } from "@/components/connect-button";
1450
+ import { LcaiMark } from "@/components/lcai-mark";
1442
1451
 
1443
1452
  type Verdict = {
1444
1453
  passed: boolean;
@@ -1469,6 +1478,7 @@ export default function JudgeWeb3() {
1469
1478
  const [busy, setBusy] = useState(false);
1470
1479
  const [busyStage, setBusyStage] = useState("");
1471
1480
  const [result, setResult] = useState<Result | null>(null);
1481
+ const [stream, setStream] = useState("");
1472
1482
  const [err, setErr] = useState<string | null>(null);
1473
1483
  const [feeLcai, setFeeLcai] = useState<number | null>(null);
1474
1484
 
@@ -1506,6 +1516,7 @@ export default function JudgeWeb3() {
1506
1516
  setBusy(true);
1507
1517
  setErr(null);
1508
1518
  setResult(null);
1519
+ setStream("");
1509
1520
  try {
1510
1521
  setBusyStage("Sign in with your wallet (SIWE)...");
1511
1522
  const session = await siweSignIn(walletClient as unknown as Parameters<typeof siweSignIn>[0], network);
@@ -1527,6 +1538,8 @@ Reply with STRICT JSON only, matching: { "passed": boolean, "confidence": 0-1, "
1527
1538
  model: MODEL,
1528
1539
  jobCompletedTimeoutMs: 120_000,
1529
1540
  maxRetries: 1,
1541
+ // Show the model's raw output streaming in while it generates the verdict.
1542
+ onChunk: (_chunk, totalSoFar) => { setBusyStage(""); setStream(totalSoFar); },
1530
1543
  });
1531
1544
  setResult({
1532
1545
  verdict: parseVerdict(r.answer),
@@ -1596,31 +1609,45 @@ Reply with STRICT JSON only, matching: { "passed": boolean, "confidence": 0-1, "
1596
1609
  </p>
1597
1610
  )}
1598
1611
 
1599
- {result && (
1612
+ {(busy || result) && (
1600
1613
  <div className="rounded-2xl border border-border bg-card p-4">
1601
- <div className="mb-2 text-[11px] font-medium uppercase tracking-wide text-muted-foreground">Verdict</div>
1602
- {result.verdict ? (
1603
- <div>
1604
- <div className={"flex items-baseline gap-3 text-2xl font-semibold " + (result.verdict.passed ? "text-success" : "text-destructive")}>
1605
- {result.verdict.passed ? "PASSED" : "FAILED"}
1606
- <span className="text-sm font-normal text-muted-foreground">
1607
- confidence {Math.round(result.verdict.confidence * 100)}%
1608
- </span>
1609
- </div>
1610
- <p className="mt-2 text-sm text-foreground">{result.verdict.reason}</p>
1614
+ <div className="flex gap-3">
1615
+ <LcaiMark className="mt-0.5 size-7 shrink-0" />
1616
+ <div className="flex min-w-0 flex-1 flex-col gap-2">
1617
+ {result ? (
1618
+ result.verdict ? (
1619
+ <div>
1620
+ <div className={"flex items-baseline gap-3 text-2xl font-semibold " + (result.verdict.passed ? "text-success" : "text-destructive")}>
1621
+ {result.verdict.passed ? "PASSED" : "FAILED"}
1622
+ <span className="text-sm font-normal text-muted-foreground">
1623
+ confidence {Math.round(result.verdict.confidence * 100)}%
1624
+ </span>
1625
+ </div>
1626
+ <div className="mt-2 max-w-none text-sm leading-relaxed text-foreground [&_*:first-child]:mt-0 [&_*:last-child]:mb-0">
1627
+ <Streamdown>{result.verdict.reason}</Streamdown>
1628
+ </div>
1629
+ </div>
1630
+ ) : (
1631
+ <pre className="m-0 whitespace-pre-wrap break-words font-mono text-xs text-muted-foreground">{result.raw}</pre>
1632
+ )
1633
+ ) : stream ? (
1634
+ <pre className="m-0 max-h-40 overflow-y-auto whitespace-pre-wrap break-words font-mono text-xs text-muted-foreground">{stream}</pre>
1635
+ ) : (
1636
+ <div className="animate-pulse-dot pt-1 text-sm text-muted-foreground">
1637
+ {busyStage || "Writing on chain..."}
1638
+ </div>
1639
+ )}
1640
+ {result && (
1641
+ <div className="mt-1 flex flex-wrap gap-3 text-xs text-muted-foreground">
1642
+ <span>job #{result.jobId}</span>
1643
+ <a className="hover:text-foreground hover:underline" href={\`https://\${network}.lightscan.app/address/\${result.worker}\`} target="_blank" rel="noopener noreferrer">worker</a>
1644
+ <a className="hover:text-foreground hover:underline" href={\`https://\${network}.lightscan.app/tx/\${result.submitJob}\`} target="_blank" rel="noopener noreferrer">submitJob</a>
1645
+ {result.jobCompleted && (
1646
+ <a className="hover:text-foreground hover:underline" href={\`https://\${network}.lightscan.app/tx/\${result.jobCompleted}\`} target="_blank" rel="noopener noreferrer">jobCompleted</a>
1647
+ )}
1648
+ </div>
1649
+ )}
1611
1650
  </div>
1612
- ) : (
1613
- <pre className="m-0 whitespace-pre-wrap break-words font-mono text-xs text-muted-foreground">
1614
- {result.raw}
1615
- </pre>
1616
- )}
1617
- <div className="mt-3 flex flex-wrap gap-3 text-xs text-muted-foreground">
1618
- <span>job #{result.jobId}</span>
1619
- <a className="hover:text-foreground hover:underline" href={\`https://\${network}.lightscan.app/address/\${result.worker}\`} target="_blank" rel="noopener noreferrer">worker</a>
1620
- <a className="hover:text-foreground hover:underline" href={\`https://\${network}.lightscan.app/tx/\${result.submitJob}\`} target="_blank" rel="noopener noreferrer">submitJob</a>
1621
- {result.jobCompleted && (
1622
- <a className="hover:text-foreground hover:underline" href={\`https://\${network}.lightscan.app/tx/\${result.jobCompleted}\`} target="_blank" rel="noopener noreferrer">jobCompleted</a>
1623
- )}
1624
1651
  </div>
1625
1652
  </div>
1626
1653
  )}
@@ -1939,7 +1966,7 @@ export function addInferenceWeb3(opts = {}) {
1939
1966
  written.push(writeFile(path.join(cwd, "app/inference-web3/page.tsx"), NEXTJS_INFERENCE_WEB3_PAGE, force));
1940
1967
  return {
1941
1968
  written,
1942
- install: `npm install lightnode-sdk viem` + (hasWagmi ? "" : " wagmi @tanstack/react-query"),
1969
+ install: `npm install lightnode-sdk viem streamdown` + (hasWagmi ? "" : " wagmi @tanstack/react-query"),
1943
1970
  template, network, needsWagmi: !hasWagmi,
1944
1971
  };
1945
1972
  }
@@ -1965,7 +1992,7 @@ export function addJudgeWeb3(opts = {}) {
1965
1992
  written.push(writeFile(path.join(cwd, "app/judge-web3/page.tsx"), NEXTJS_JUDGE_WEB3_PAGE, force));
1966
1993
  return {
1967
1994
  written,
1968
- install: `npm install lightnode-sdk viem` + (hasWagmi ? "" : " wagmi @tanstack/react-query"),
1995
+ install: `npm install lightnode-sdk viem streamdown` + (hasWagmi ? "" : " wagmi @tanstack/react-query"),
1969
1996
  template, network, needsWagmi: !hasWagmi,
1970
1997
  };
1971
1998
  }
@@ -2105,6 +2132,32 @@ export function ConnectButton() {
2105
2132
  );
2106
2133
  }
2107
2134
  `;
2135
+ const LCAI_MARK_FILE = `// components/lcai-mark.tsx
2136
+ // Generated by 'lightnode add wagmi-setup'. The LightChain atom mark (gradient
2137
+ // logo). The viewBox frames the atom only - no wordmark. Used as the assistant
2138
+ // avatar / glyph in the generated chat + inference pages.
2139
+ export function LcaiMark({ className }: { className?: string }) {
2140
+ return (
2141
+ <svg
2142
+ viewBox="854.3951253356933 398.23541259765625 186.60832495117188 198.4013696411746"
2143
+ className={className}
2144
+ xmlns="http://www.w3.org/2000/svg"
2145
+ aria-hidden="true"
2146
+ >
2147
+ <g transform="translate(856.3148789999999, 398.23539999999997) scale(0.6266964564006055)">
2148
+ <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">
2149
+ <stop offset="0" stopColor="rgb(48, 5, 250)" />
2150
+ <stop offset="1" stopColor="rgb(255, 18, 251)" />
2151
+ </linearGradient>
2152
+ <path
2153
+ fill="url(#lcai-mark-grad)"
2154
+ 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"
2155
+ />
2156
+ </g>
2157
+ </svg>
2158
+ );
2159
+ }
2160
+ `;
2108
2161
  export function addWagmiSetup(opts = {}) {
2109
2162
  const cwd = opts.cwd ?? process.cwd();
2110
2163
  const network = opts.network ?? "mainnet";
@@ -2114,6 +2167,7 @@ export function addWagmiSetup(opts = {}) {
2114
2167
  written.push(writeFile(path.join(cwd, "lib/wagmi.ts"), WAGMI_CONFIG_FILE, force));
2115
2168
  written.push(writeFile(path.join(cwd, "app/providers.tsx"), WAGMI_PROVIDERS_FILE, force));
2116
2169
  written.push(writeFile(path.join(cwd, "components/connect-button.tsx"), WAGMI_CONNECT_BUTTON, force));
2170
+ written.push(writeFile(path.join(cwd, "components/lcai-mark.tsx"), LCAI_MARK_FILE, force));
2117
2171
  return {
2118
2172
  written,
2119
2173
  install: `npm install wagmi viem @tanstack/react-query`,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lightnode-sdk",
3
- "version": "0.8.6",
3
+ "version": "0.8.8",
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",