@athenaintel/react 0.10.26 → 0.10.28
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/index.cjs +675 -72
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.js +675 -72
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -14152,14 +14152,20 @@ const useAssetPanelStore = create()(
|
|
|
14152
14152
|
const existing = s.tabs.find((t) => t.id === assetId);
|
|
14153
14153
|
if (existing) {
|
|
14154
14154
|
const tabs = meta ? s.tabs.map(
|
|
14155
|
-
(t) => t.id === assetId ? {
|
|
14155
|
+
(t) => t.id === assetId ? {
|
|
14156
|
+
...t,
|
|
14157
|
+
name: meta.name ?? t.name,
|
|
14158
|
+
type: meta.type ?? t.type,
|
|
14159
|
+
slideNumber: "slideNumber" in meta ? meta.slideNumber : t.slideNumber
|
|
14160
|
+
} : t
|
|
14156
14161
|
) : s.tabs;
|
|
14157
14162
|
return { isOpen: true, tabs, activeTabId: assetId };
|
|
14158
14163
|
}
|
|
14159
14164
|
const newTab = {
|
|
14160
14165
|
id: assetId,
|
|
14161
14166
|
name: (meta == null ? void 0 : meta.name) ?? null,
|
|
14162
|
-
type: (meta == null ? void 0 : meta.type) ?? "unknown"
|
|
14167
|
+
type: (meta == null ? void 0 : meta.type) ?? "unknown",
|
|
14168
|
+
slideNumber: meta == null ? void 0 : meta.slideNumber
|
|
14163
14169
|
};
|
|
14164
14170
|
return { isOpen: true, tabs: [...s.tabs, newTab], activeTabId: assetId };
|
|
14165
14171
|
}),
|
|
@@ -50041,18 +50047,6 @@ function AssetToolCard({
|
|
|
50041
50047
|
const assetId = extractAssetId$1(result);
|
|
50042
50048
|
const title = extractTitle(argsText, result);
|
|
50043
50049
|
const assetType = toolMetaToAssetType(toolName);
|
|
50044
|
-
const wasCompleteAtMount = React.useRef(isComplete);
|
|
50045
|
-
React.useEffect(() => {
|
|
50046
|
-
if (isComplete && !isCancelled && assetId && !wasCompleteAtMount.current) {
|
|
50047
|
-
const store = useAssetPanelStore.getState();
|
|
50048
|
-
if (store.markAutoOpened(assetId)) {
|
|
50049
|
-
store.openAsset(assetId, {
|
|
50050
|
-
name: title ?? void 0,
|
|
50051
|
-
type: assetType
|
|
50052
|
-
});
|
|
50053
|
-
}
|
|
50054
|
-
}
|
|
50055
|
-
}, [isComplete, isCancelled, assetId, title, assetType]);
|
|
50056
50050
|
const success = isComplete && isResultSuccess(result);
|
|
50057
50051
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn(
|
|
50058
50052
|
"aui-tool-fallback-root my-3 w-full rounded-xl border border-border/60 bg-background py-2.5 shadow-sm",
|
|
@@ -50614,6 +50608,32 @@ function normalizeResult(result) {
|
|
|
50614
50608
|
function truncate(text2, max2) {
|
|
50615
50609
|
return text2.length > max2 ? `${text2.slice(0, max2)}...` : text2;
|
|
50616
50610
|
}
|
|
50611
|
+
function isSdkToolDebugEnabled() {
|
|
50612
|
+
var _a2, _b;
|
|
50613
|
+
try {
|
|
50614
|
+
const hostname = (_a2 = globalThis.location) == null ? void 0 : _a2.hostname;
|
|
50615
|
+
if (hostname === "localhost" || hostname === "127.0.0.1" || hostname === "::1") {
|
|
50616
|
+
return true;
|
|
50617
|
+
}
|
|
50618
|
+
return ((_b = globalThis.localStorage) == null ? void 0 : _b.getItem("athena:sdk:debug")) === "1";
|
|
50619
|
+
} catch {
|
|
50620
|
+
return false;
|
|
50621
|
+
}
|
|
50622
|
+
}
|
|
50623
|
+
function stringifyDebugPayload(payload) {
|
|
50624
|
+
return JSON.stringify(payload, (_key, value) => {
|
|
50625
|
+
if (typeof value === "string" && value.length > 800) {
|
|
50626
|
+
return `${value.slice(0, 800)}... [truncated ${value.length - 800} chars]`;
|
|
50627
|
+
}
|
|
50628
|
+
return value;
|
|
50629
|
+
});
|
|
50630
|
+
}
|
|
50631
|
+
function logDebugPayload(label, payload) {
|
|
50632
|
+
if (!isSdkToolDebugEnabled()) {
|
|
50633
|
+
return;
|
|
50634
|
+
}
|
|
50635
|
+
console.info(`${label} ${stringifyDebugPayload(payload)}`);
|
|
50636
|
+
}
|
|
50617
50637
|
function formatToolName(name) {
|
|
50618
50638
|
return name.replace(/_/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
|
|
50619
50639
|
}
|
|
@@ -50904,6 +50924,83 @@ function extractAssetId(result) {
|
|
|
50904
50924
|
function resetAssetAutoOpen() {
|
|
50905
50925
|
useAssetPanelStore.getState().resetAutoOpen();
|
|
50906
50926
|
}
|
|
50927
|
+
function getStringField(source, keys2) {
|
|
50928
|
+
if (!source) return null;
|
|
50929
|
+
for (const key of keys2) {
|
|
50930
|
+
const value = source[key];
|
|
50931
|
+
if (typeof value === "string" && value.trim()) {
|
|
50932
|
+
return value;
|
|
50933
|
+
}
|
|
50934
|
+
}
|
|
50935
|
+
return null;
|
|
50936
|
+
}
|
|
50937
|
+
function getNumberField(source, keys2) {
|
|
50938
|
+
if (!source) return null;
|
|
50939
|
+
for (const key of keys2) {
|
|
50940
|
+
const value = source[key];
|
|
50941
|
+
if (typeof value === "number" && Number.isFinite(value)) {
|
|
50942
|
+
return value;
|
|
50943
|
+
}
|
|
50944
|
+
}
|
|
50945
|
+
return null;
|
|
50946
|
+
}
|
|
50947
|
+
const PRESENTATION_CODE_SLIDE_NUMBER_KEYS = [
|
|
50948
|
+
"slideNumber",
|
|
50949
|
+
"slide_number",
|
|
50950
|
+
"targetSlideNumber",
|
|
50951
|
+
"target_slide_number",
|
|
50952
|
+
"targetSlide",
|
|
50953
|
+
"target_slide"
|
|
50954
|
+
];
|
|
50955
|
+
const PRESENTATION_CODE_SLIDE_INDEX_KEYS = [
|
|
50956
|
+
"slideIndex",
|
|
50957
|
+
"slide_index",
|
|
50958
|
+
"targetSlideIndex",
|
|
50959
|
+
"target_slide_index"
|
|
50960
|
+
];
|
|
50961
|
+
function getStudioAssetId({
|
|
50962
|
+
args,
|
|
50963
|
+
result
|
|
50964
|
+
}) {
|
|
50965
|
+
const id = getStringField(result, ["asset_id", "assetId", "id"]) ?? getStringField(args, ["asset_id", "assetId", "id"]);
|
|
50966
|
+
return (id == null ? void 0 : id.startsWith("asset_")) ? id : null;
|
|
50967
|
+
}
|
|
50968
|
+
function getPresentationCodeDeckId(code2) {
|
|
50969
|
+
const match2 = code2.match(/\bdeck_id\s*=\s*["']([^"']+)["']/);
|
|
50970
|
+
const deckId = match2 == null ? void 0 : match2[1];
|
|
50971
|
+
return (deckId == null ? void 0 : deckId.startsWith("asset_")) ? deckId : null;
|
|
50972
|
+
}
|
|
50973
|
+
function getPresentationCodeSlideNumberFromFields(source) {
|
|
50974
|
+
const explicit = getNumberField(source, PRESENTATION_CODE_SLIDE_NUMBER_KEYS);
|
|
50975
|
+
if (explicit != null && Number.isInteger(explicit) && explicit >= 1) {
|
|
50976
|
+
return explicit;
|
|
50977
|
+
}
|
|
50978
|
+
const zeroBasedIndex = getNumberField(source, PRESENTATION_CODE_SLIDE_INDEX_KEYS);
|
|
50979
|
+
if (zeroBasedIndex != null && Number.isInteger(zeroBasedIndex) && zeroBasedIndex >= 0) {
|
|
50980
|
+
return zeroBasedIndex + 1;
|
|
50981
|
+
}
|
|
50982
|
+
return void 0;
|
|
50983
|
+
}
|
|
50984
|
+
function getPresentationCodeSlideNumberFromText(text2) {
|
|
50985
|
+
const match2 = text2 == null ? void 0 : text2.match(/\bslide\s*(?:#|number\s*)?(\d+)\b/i);
|
|
50986
|
+
if (!match2) {
|
|
50987
|
+
return void 0;
|
|
50988
|
+
}
|
|
50989
|
+
const slideNumber = Number.parseInt(match2[1] ?? "", 10);
|
|
50990
|
+
return Number.isInteger(slideNumber) && slideNumber >= 1 ? slideNumber : void 0;
|
|
50991
|
+
}
|
|
50992
|
+
function getPresentationCodeSlideNumber({
|
|
50993
|
+
args,
|
|
50994
|
+
result
|
|
50995
|
+
}) {
|
|
50996
|
+
return getPresentationCodeSlideNumberFromFields(args) ?? getPresentationCodeSlideNumberFromFields(result) ?? getPresentationCodeSlideNumberFromText(
|
|
50997
|
+
getStringField(args, ["summary", "title", "description"])
|
|
50998
|
+
);
|
|
50999
|
+
}
|
|
51000
|
+
function getAddSlideNumber(args) {
|
|
51001
|
+
const index2 = getNumberField(args, ["index"]);
|
|
51002
|
+
return index2 != null && Number.isInteger(index2) && index2 >= 0 ? index2 + 1 : void 0;
|
|
51003
|
+
}
|
|
50907
51004
|
function CreateAssetToolUIImpl({
|
|
50908
51005
|
icon: Icon2,
|
|
50909
51006
|
assetType,
|
|
@@ -50924,18 +51021,6 @@ function CreateAssetToolUIImpl({
|
|
|
50924
51021
|
const isCancelled = (status == null ? void 0 : status.type) === "incomplete" && status.reason === "cancelled";
|
|
50925
51022
|
const errorMsg = (status == null ? void 0 : status.type) === "incomplete" ? status.error : null;
|
|
50926
51023
|
const openAsset = useAssetPanelStore((s) => s.openAsset);
|
|
50927
|
-
const wasCompleteAtMount = React.useRef(isComplete);
|
|
50928
|
-
React.useEffect(() => {
|
|
50929
|
-
if (isComplete && !isCancelled && assetId && !wasCompleteAtMount.current) {
|
|
50930
|
-
const store = useAssetPanelStore.getState();
|
|
50931
|
-
if (store.markAutoOpened(assetId)) {
|
|
50932
|
-
store.openAsset(assetId, {
|
|
50933
|
-
name: createdName || name || void 0,
|
|
50934
|
-
type: assetType
|
|
50935
|
-
});
|
|
50936
|
-
}
|
|
50937
|
-
}
|
|
50938
|
-
}, [isComplete, isCancelled, assetId, createdName, name, assetType]);
|
|
50939
51024
|
const handleOpen = () => {
|
|
50940
51025
|
if (assetId) {
|
|
50941
51026
|
openAsset(assetId, {
|
|
@@ -51013,6 +51098,258 @@ const CreatePresentationToolUI = React.memo(
|
|
|
51013
51098
|
CreatePresentationToolUIImpl
|
|
51014
51099
|
);
|
|
51015
51100
|
CreatePresentationToolUI.displayName = "CreatePresentationToolUI";
|
|
51101
|
+
function openStudioAsset({
|
|
51102
|
+
assetId,
|
|
51103
|
+
assetType,
|
|
51104
|
+
slideNumber,
|
|
51105
|
+
preserveExistingSlide
|
|
51106
|
+
}) {
|
|
51107
|
+
const store = useAssetPanelStore.getState();
|
|
51108
|
+
const existing = store.tabs.find((tab) => tab.id === assetId);
|
|
51109
|
+
const shouldKeepCurrentSlide = preserveExistingSlide && existing;
|
|
51110
|
+
store.openAsset(assetId, {
|
|
51111
|
+
type: assetType,
|
|
51112
|
+
...!shouldKeepCurrentSlide && slideNumber !== void 0 ? { slideNumber } : {}
|
|
51113
|
+
});
|
|
51114
|
+
}
|
|
51115
|
+
function StudioPtcToolUI({
|
|
51116
|
+
config: config2,
|
|
51117
|
+
toolName,
|
|
51118
|
+
args,
|
|
51119
|
+
result,
|
|
51120
|
+
status
|
|
51121
|
+
}) {
|
|
51122
|
+
var _a2, _b;
|
|
51123
|
+
const typedArgs = args;
|
|
51124
|
+
const data = React.useMemo(() => normalizeResult(result), [result]);
|
|
51125
|
+
const slideNumber = (_a2 = config2.getSlideNumber) == null ? void 0 : _a2.call(config2, typedArgs);
|
|
51126
|
+
const assetId = getStudioAssetId({ args: typedArgs, result: data });
|
|
51127
|
+
const subtitle = (_b = config2.getSubtitle) == null ? void 0 : _b.call(config2, typedArgs, data, slideNumber);
|
|
51128
|
+
const isRunning = (status == null ? void 0 : status.type) === "running";
|
|
51129
|
+
const isComplete = (status == null ? void 0 : status.type) === "complete" || !status;
|
|
51130
|
+
const isCancelled = (status == null ? void 0 : status.type) === "incomplete" && status.reason === "cancelled";
|
|
51131
|
+
const errorMsg = (status == null ? void 0 : status.type) === "incomplete" ? String(status.error ?? status.reason ?? "Tool failed") : null;
|
|
51132
|
+
const handleOpen = React.useCallback(() => {
|
|
51133
|
+
if (!assetId) return;
|
|
51134
|
+
if (toolName === "AddSlide") {
|
|
51135
|
+
logDebugPayload("[Athena SDK AddSlide] manual open", {
|
|
51136
|
+
args: typedArgs,
|
|
51137
|
+
parsedResult: data,
|
|
51138
|
+
rawResult: result,
|
|
51139
|
+
assetId,
|
|
51140
|
+
slideNumber
|
|
51141
|
+
});
|
|
51142
|
+
}
|
|
51143
|
+
openStudioAsset({
|
|
51144
|
+
assetId,
|
|
51145
|
+
assetType: config2.assetType,
|
|
51146
|
+
slideNumber,
|
|
51147
|
+
preserveExistingSlide: config2.preserveExistingSlide
|
|
51148
|
+
});
|
|
51149
|
+
}, [
|
|
51150
|
+
assetId,
|
|
51151
|
+
config2.assetType,
|
|
51152
|
+
config2.preserveExistingSlide,
|
|
51153
|
+
data,
|
|
51154
|
+
result,
|
|
51155
|
+
slideNumber,
|
|
51156
|
+
toolName,
|
|
51157
|
+
typedArgs
|
|
51158
|
+
]);
|
|
51159
|
+
React.useEffect(() => {
|
|
51160
|
+
if (toolName !== "AddSlide") {
|
|
51161
|
+
return;
|
|
51162
|
+
}
|
|
51163
|
+
logDebugPayload("[Athena SDK AddSlide] tool state", {
|
|
51164
|
+
args: typedArgs,
|
|
51165
|
+
parsedResult: data,
|
|
51166
|
+
rawResult: result,
|
|
51167
|
+
status,
|
|
51168
|
+
assetId,
|
|
51169
|
+
slideNumber,
|
|
51170
|
+
isComplete,
|
|
51171
|
+
isCancelled
|
|
51172
|
+
});
|
|
51173
|
+
}, [
|
|
51174
|
+
assetId,
|
|
51175
|
+
data,
|
|
51176
|
+
isCancelled,
|
|
51177
|
+
isComplete,
|
|
51178
|
+
result,
|
|
51179
|
+
slideNumber,
|
|
51180
|
+
status,
|
|
51181
|
+
toolName,
|
|
51182
|
+
typedArgs
|
|
51183
|
+
]);
|
|
51184
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
51185
|
+
ToolCard,
|
|
51186
|
+
{
|
|
51187
|
+
icon: config2.icon,
|
|
51188
|
+
status: (status == null ? void 0 : status.type) ?? "complete",
|
|
51189
|
+
title: isRunning ? config2.runningLabel(typedArgs) : config2.doneLabel(typedArgs, slideNumber),
|
|
51190
|
+
subtitle,
|
|
51191
|
+
badge: config2.badge,
|
|
51192
|
+
toolName,
|
|
51193
|
+
args: typedArgs,
|
|
51194
|
+
result,
|
|
51195
|
+
error: errorMsg,
|
|
51196
|
+
children: assetId && isComplete && !isCancelled && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "border-t border-border/40 px-4 py-2", children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
51197
|
+
"button",
|
|
51198
|
+
{
|
|
51199
|
+
type: "button",
|
|
51200
|
+
onClick: handleOpen,
|
|
51201
|
+
className: "flex items-center gap-1.5 rounded-md border border-border/60 px-3 py-1.5 text-xs font-medium text-muted-foreground transition-colors hover:bg-muted/50 hover:text-foreground",
|
|
51202
|
+
children: [
|
|
51203
|
+
/* @__PURE__ */ jsxRuntime.jsx(ExternalLink, { className: "size-3" }),
|
|
51204
|
+
config2.openLabel(slideNumber)
|
|
51205
|
+
]
|
|
51206
|
+
}
|
|
51207
|
+
) })
|
|
51208
|
+
}
|
|
51209
|
+
);
|
|
51210
|
+
}
|
|
51211
|
+
function createStudioPtcToolUI(displayName, config2) {
|
|
51212
|
+
const Component = (props) => /* @__PURE__ */ jsxRuntime.jsx(StudioPtcToolUI, { config: config2, ...props });
|
|
51213
|
+
const Memoized = React.memo(Component);
|
|
51214
|
+
Memoized.displayName = displayName;
|
|
51215
|
+
return Memoized;
|
|
51216
|
+
}
|
|
51217
|
+
const getNameSubtitle = (args, result) => getStringField(result, ["title", "name", "asset_name"]) ?? getStringField(args, ["title", "name"]) ?? void 0;
|
|
51218
|
+
const getParagraphSubtitle = (args) => {
|
|
51219
|
+
const text2 = getStringField(args, ["text"]);
|
|
51220
|
+
return text2 ? truncate(text2, 80) : void 0;
|
|
51221
|
+
};
|
|
51222
|
+
const getSlideSubtitle = (args, _result, slideNumber) => {
|
|
51223
|
+
const layout = getStringField(args, ["layoutName", "layout_name"]) ?? getStringField(args, ["layoutPath", "layout_path"]);
|
|
51224
|
+
const slideLabel = slideNumber ? `Slide ${slideNumber}` : null;
|
|
51225
|
+
if (slideLabel && layout) return `${slideLabel} - ${truncate(layout, 48)}`;
|
|
51226
|
+
return slideLabel ?? (layout ? truncate(layout, 64) : void 0);
|
|
51227
|
+
};
|
|
51228
|
+
const StudioCreateWorkbookToolUI = createStudioPtcToolUI(
|
|
51229
|
+
"StudioCreateWorkbookToolUI",
|
|
51230
|
+
{
|
|
51231
|
+
icon: ChartColumn,
|
|
51232
|
+
assetType: "spreadsheet",
|
|
51233
|
+
badge: "Sheet",
|
|
51234
|
+
runningLabel: (args) => {
|
|
51235
|
+
const title = getStringField(args, ["title", "name"]);
|
|
51236
|
+
return title ? `Creating workbook "${title}"...` : "Creating workbook...";
|
|
51237
|
+
},
|
|
51238
|
+
doneLabel: () => "Workbook created",
|
|
51239
|
+
getSubtitle: getNameSubtitle,
|
|
51240
|
+
openLabel: () => "Open workbook"
|
|
51241
|
+
}
|
|
51242
|
+
);
|
|
51243
|
+
const StudioAddSheetToolUI = createStudioPtcToolUI(
|
|
51244
|
+
"StudioAddSheetToolUI",
|
|
51245
|
+
{
|
|
51246
|
+
icon: ChartColumn,
|
|
51247
|
+
assetType: "spreadsheet",
|
|
51248
|
+
badge: "Sheet",
|
|
51249
|
+
runningLabel: (args) => {
|
|
51250
|
+
const name = getStringField(args, ["name", "sheetName", "sheet_name"]);
|
|
51251
|
+
return name ? `Adding sheet "${name}"...` : "Adding sheet...";
|
|
51252
|
+
},
|
|
51253
|
+
doneLabel: (args) => {
|
|
51254
|
+
const name = getStringField(args, ["name", "sheetName", "sheet_name"]);
|
|
51255
|
+
return name ? `Sheet added: ${name}` : "Sheet added";
|
|
51256
|
+
},
|
|
51257
|
+
getSubtitle: (args) => getStringField(args, ["name", "sheetName", "sheet_name"]) ?? void 0,
|
|
51258
|
+
openLabel: () => "Open workbook"
|
|
51259
|
+
}
|
|
51260
|
+
);
|
|
51261
|
+
const StudioOpenWorkbookToolUI = createStudioPtcToolUI(
|
|
51262
|
+
"StudioOpenWorkbookToolUI",
|
|
51263
|
+
{
|
|
51264
|
+
icon: ChartColumn,
|
|
51265
|
+
assetType: "spreadsheet",
|
|
51266
|
+
badge: "Sheet",
|
|
51267
|
+
runningLabel: () => "Opening workbook...",
|
|
51268
|
+
doneLabel: () => "Workbook opened",
|
|
51269
|
+
openLabel: () => "Open workbook"
|
|
51270
|
+
}
|
|
51271
|
+
);
|
|
51272
|
+
const StudioCreatePresentationToolUI = createStudioPtcToolUI(
|
|
51273
|
+
"StudioCreatePresentationToolUI",
|
|
51274
|
+
{
|
|
51275
|
+
icon: Presentation,
|
|
51276
|
+
assetType: "presentation",
|
|
51277
|
+
badge: "Deck",
|
|
51278
|
+
runningLabel: (args) => {
|
|
51279
|
+
const title = getStringField(args, ["title", "name"]);
|
|
51280
|
+
return title ? `Creating presentation "${title}"...` : "Creating presentation...";
|
|
51281
|
+
},
|
|
51282
|
+
doneLabel: () => "Presentation created",
|
|
51283
|
+
getSubtitle: getNameSubtitle,
|
|
51284
|
+
getSlideNumber: () => 1,
|
|
51285
|
+
openLabel: () => "Open presentation"
|
|
51286
|
+
}
|
|
51287
|
+
);
|
|
51288
|
+
const StudioOpenPresentationToolUI = createStudioPtcToolUI(
|
|
51289
|
+
"StudioOpenPresentationToolUI",
|
|
51290
|
+
{
|
|
51291
|
+
icon: Presentation,
|
|
51292
|
+
assetType: "presentation",
|
|
51293
|
+
badge: "Deck",
|
|
51294
|
+
runningLabel: () => "Opening presentation...",
|
|
51295
|
+
doneLabel: () => "Presentation opened",
|
|
51296
|
+
getSlideNumber: () => 1,
|
|
51297
|
+
getSubtitle: (_args, _result, slideNumber) => slideNumber ? `Slide ${slideNumber}` : void 0,
|
|
51298
|
+
openLabel: () => "Open presentation",
|
|
51299
|
+
preserveExistingSlide: true
|
|
51300
|
+
}
|
|
51301
|
+
);
|
|
51302
|
+
const StudioAddSlideToolUI = createStudioPtcToolUI(
|
|
51303
|
+
"StudioAddSlideToolUI",
|
|
51304
|
+
{
|
|
51305
|
+
icon: Presentation,
|
|
51306
|
+
assetType: "presentation",
|
|
51307
|
+
badge: "Deck",
|
|
51308
|
+
runningLabel: () => "Adding slide...",
|
|
51309
|
+
doneLabel: (_args, slideNumber) => slideNumber ? `Slide ${slideNumber} added` : "Slide added",
|
|
51310
|
+
getSubtitle: getSlideSubtitle,
|
|
51311
|
+
getSlideNumber: (args) => getAddSlideNumber(args) ?? 1,
|
|
51312
|
+
openLabel: (slideNumber) => slideNumber ? `Open slide ${slideNumber}` : "Open presentation"
|
|
51313
|
+
}
|
|
51314
|
+
);
|
|
51315
|
+
const StudioCreateDocumentToolUI = createStudioPtcToolUI(
|
|
51316
|
+
"StudioCreateDocumentToolUI",
|
|
51317
|
+
{
|
|
51318
|
+
icon: FileText,
|
|
51319
|
+
assetType: "document",
|
|
51320
|
+
badge: "Doc",
|
|
51321
|
+
runningLabel: (args) => {
|
|
51322
|
+
const title = getStringField(args, ["title", "name"]);
|
|
51323
|
+
return title ? `Creating document "${title}"...` : "Creating document...";
|
|
51324
|
+
},
|
|
51325
|
+
doneLabel: () => "Document created",
|
|
51326
|
+
getSubtitle: getNameSubtitle,
|
|
51327
|
+
openLabel: () => "Open document"
|
|
51328
|
+
}
|
|
51329
|
+
);
|
|
51330
|
+
const StudioCreateParagraphToolUI = createStudioPtcToolUI(
|
|
51331
|
+
"StudioCreateParagraphToolUI",
|
|
51332
|
+
{
|
|
51333
|
+
icon: FileText,
|
|
51334
|
+
assetType: "document",
|
|
51335
|
+
badge: "Doc",
|
|
51336
|
+
runningLabel: () => "Adding paragraph...",
|
|
51337
|
+
doneLabel: () => "Paragraph added",
|
|
51338
|
+
getSubtitle: getParagraphSubtitle,
|
|
51339
|
+
openLabel: () => "Open document"
|
|
51340
|
+
}
|
|
51341
|
+
);
|
|
51342
|
+
const StudioOpenDocumentToolUI = createStudioPtcToolUI(
|
|
51343
|
+
"StudioOpenDocumentToolUI",
|
|
51344
|
+
{
|
|
51345
|
+
icon: FileText,
|
|
51346
|
+
assetType: "document",
|
|
51347
|
+
badge: "Doc",
|
|
51348
|
+
runningLabel: () => "Opening document...",
|
|
51349
|
+
doneLabel: () => "Document opened",
|
|
51350
|
+
openLabel: () => "Open document"
|
|
51351
|
+
}
|
|
51352
|
+
);
|
|
51016
51353
|
const CreateEmailDraftToolUIImpl = ({
|
|
51017
51354
|
toolName,
|
|
51018
51355
|
args,
|
|
@@ -51518,7 +51855,7 @@ const ExecutePresentationCodeToolUIImpl = ({
|
|
|
51518
51855
|
const typedArgs = args;
|
|
51519
51856
|
const code2 = (typedArgs == null ? void 0 : typedArgs.code) ?? "";
|
|
51520
51857
|
const summary = (typedArgs == null ? void 0 : typedArgs.summary) ?? null;
|
|
51521
|
-
const deckIdFromArgs =
|
|
51858
|
+
const deckIdFromArgs = getStringField(typedArgs, ["deck_id", "deckId", "asset_id", "assetId"]) ?? getPresentationCodeDeckId(code2);
|
|
51522
51859
|
const isRunning = (status == null ? void 0 : status.type) === "running";
|
|
51523
51860
|
const isComplete = (status == null ? void 0 : status.type) === "complete";
|
|
51524
51861
|
const errorMsg = (status == null ? void 0 : status.type) === "incomplete" ? status.error : null;
|
|
@@ -51526,21 +51863,55 @@ const ExecutePresentationCodeToolUIImpl = ({
|
|
|
51526
51863
|
() => isComplete ? parsePythonResult(result) : null,
|
|
51527
51864
|
[result, isComplete]
|
|
51528
51865
|
);
|
|
51866
|
+
const resultData = React.useMemo(() => normalizeResult(result), [result]);
|
|
51529
51867
|
const outputText = parsed ? getExecutionTextOutput(parsed) : null;
|
|
51530
|
-
const
|
|
51868
|
+
const targetSlideNumber = getPresentationCodeSlideNumber({
|
|
51869
|
+
args: typedArgs,
|
|
51870
|
+
result: resultData
|
|
51871
|
+
});
|
|
51531
51872
|
const deckId = (parsed == null ? void 0 : parsed.deckId) ?? deckIdFromArgs;
|
|
51873
|
+
const assetId = (parsed == null ? void 0 : parsed.assetId) ?? ((deckId == null ? void 0 : deckId.startsWith("asset_")) ? deckId : null);
|
|
51532
51874
|
const hasError = parsed && (parsed.error || parsed.exception);
|
|
51533
51875
|
const openAsset = useAssetPanelStore((s) => s.openAsset);
|
|
51534
|
-
const wasCompleteAtMount = React.useRef(isComplete);
|
|
51535
51876
|
React.useEffect(() => {
|
|
51536
|
-
if (!isComplete
|
|
51877
|
+
if (!isComplete) {
|
|
51537
51878
|
return;
|
|
51538
51879
|
}
|
|
51539
|
-
|
|
51540
|
-
|
|
51541
|
-
|
|
51880
|
+
logDebugPayload("[Athena SDK execute_presentation_code] tool state", {
|
|
51881
|
+
args: typedArgs,
|
|
51882
|
+
parsedResult: resultData,
|
|
51883
|
+
status,
|
|
51884
|
+
assetId,
|
|
51885
|
+
deckId,
|
|
51886
|
+
targetSlideNumber,
|
|
51887
|
+
outputText
|
|
51888
|
+
});
|
|
51889
|
+
}, [
|
|
51890
|
+
assetId,
|
|
51891
|
+
deckId,
|
|
51892
|
+
isComplete,
|
|
51893
|
+
outputText,
|
|
51894
|
+
resultData,
|
|
51895
|
+
status,
|
|
51896
|
+
targetSlideNumber,
|
|
51897
|
+
typedArgs
|
|
51898
|
+
]);
|
|
51899
|
+
const openPresentation = React.useCallback(() => {
|
|
51900
|
+
if (!assetId) {
|
|
51901
|
+
return;
|
|
51542
51902
|
}
|
|
51543
|
-
|
|
51903
|
+
logDebugPayload("[Athena SDK execute_presentation_code] open deck", {
|
|
51904
|
+
args: typedArgs,
|
|
51905
|
+
parsedResult: resultData,
|
|
51906
|
+
assetId,
|
|
51907
|
+
deckId,
|
|
51908
|
+
targetSlideNumber
|
|
51909
|
+
});
|
|
51910
|
+
openAsset(assetId, {
|
|
51911
|
+
type: "presentation",
|
|
51912
|
+
...targetSlideNumber !== void 0 ? { slideNumber: targetSlideNumber } : {}
|
|
51913
|
+
});
|
|
51914
|
+
}, [assetId, deckId, openAsset, resultData, targetSlideNumber, typedArgs]);
|
|
51544
51915
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
51545
51916
|
ToolCard,
|
|
51546
51917
|
{
|
|
@@ -51563,11 +51934,11 @@ const ExecutePresentationCodeToolUIImpl = ({
|
|
|
51563
51934
|
"button",
|
|
51564
51935
|
{
|
|
51565
51936
|
type: "button",
|
|
51566
|
-
onClick:
|
|
51937
|
+
onClick: openPresentation,
|
|
51567
51938
|
className: "flex shrink-0 items-center gap-1.5 rounded-md border border-border/60 px-3 py-1.5 text-xs font-medium text-muted-foreground transition-colors hover:bg-muted/50 hover:text-foreground",
|
|
51568
51939
|
children: [
|
|
51569
51940
|
/* @__PURE__ */ jsxRuntime.jsx(ExternalLink, { className: "size-3" }),
|
|
51570
|
-
"Open deck"
|
|
51941
|
+
targetSlideNumber ? `Open slide ${targetSlideNumber}` : "Open deck"
|
|
51571
51942
|
]
|
|
51572
51943
|
}
|
|
51573
51944
|
)
|
|
@@ -51626,15 +51997,6 @@ const OpenAssetToolUIImpl = ({
|
|
|
51626
51997
|
const isCancelled = (status == null ? void 0 : status.type) === "incomplete" && status.reason === "cancelled";
|
|
51627
51998
|
const errorMsg = (status == null ? void 0 : status.type) === "incomplete" ? status.error : null;
|
|
51628
51999
|
const openAsset = useAssetPanelStore((s) => s.openAsset);
|
|
51629
|
-
const wasCompleteAtMount = React.useRef(isComplete);
|
|
51630
|
-
React.useEffect(() => {
|
|
51631
|
-
if (isComplete && !isCancelled && assetId && !wasCompleteAtMount.current) {
|
|
51632
|
-
const store = useAssetPanelStore.getState();
|
|
51633
|
-
if (store.markAutoOpened(assetId)) {
|
|
51634
|
-
store.openAsset(assetId);
|
|
51635
|
-
}
|
|
51636
|
-
}
|
|
51637
|
-
}, [isComplete, isCancelled, assetId]);
|
|
51638
52000
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
51639
52001
|
ToolCard,
|
|
51640
52002
|
{
|
|
@@ -52373,18 +52735,6 @@ const CaptureMomentToolUIImpl = ({
|
|
|
52373
52735
|
const isComplete = (status == null ? void 0 : status.type) === "complete" || !status;
|
|
52374
52736
|
const isCancelled = (status == null ? void 0 : status.type) === "incomplete" && status.reason === "cancelled";
|
|
52375
52737
|
const openAsset = useAssetPanelStore((s) => s.openAsset);
|
|
52376
|
-
const wasCompleteAtMount = React.useRef(isComplete);
|
|
52377
|
-
React.useEffect(() => {
|
|
52378
|
-
if (isComplete && !isCancelled && createdAssetId && !wasCompleteAtMount.current) {
|
|
52379
|
-
const store = useAssetPanelStore.getState();
|
|
52380
|
-
if (store.markAutoOpened(createdAssetId)) {
|
|
52381
|
-
store.openAsset(createdAssetId, {
|
|
52382
|
-
name: void 0,
|
|
52383
|
-
type: "unknown"
|
|
52384
|
-
});
|
|
52385
|
-
}
|
|
52386
|
-
}
|
|
52387
|
-
}, [isComplete, isCancelled, createdAssetId, resultType]);
|
|
52388
52738
|
const handleOpen = () => {
|
|
52389
52739
|
if (createdAssetId) {
|
|
52390
52740
|
openAsset(createdAssetId, {
|
|
@@ -52444,6 +52794,153 @@ const CaptureMomentToolUI = React.memo(
|
|
|
52444
52794
|
CaptureMomentToolUIImpl
|
|
52445
52795
|
);
|
|
52446
52796
|
CaptureMomentToolUI.displayName = "CaptureMomentToolUI";
|
|
52797
|
+
function normalizeContentResult(result) {
|
|
52798
|
+
if (Array.isArray(result)) {
|
|
52799
|
+
return result;
|
|
52800
|
+
}
|
|
52801
|
+
if (typeof result === "string") {
|
|
52802
|
+
try {
|
|
52803
|
+
const parsed = JSON.parse(result);
|
|
52804
|
+
return normalizeContentResult(parsed);
|
|
52805
|
+
} catch {
|
|
52806
|
+
return [];
|
|
52807
|
+
}
|
|
52808
|
+
}
|
|
52809
|
+
if (result && typeof result === "object") {
|
|
52810
|
+
const obj = result;
|
|
52811
|
+
if (Array.isArray(obj.result)) {
|
|
52812
|
+
return obj.result;
|
|
52813
|
+
}
|
|
52814
|
+
if (typeof obj.result === "string") {
|
|
52815
|
+
return normalizeContentResult(obj.result);
|
|
52816
|
+
}
|
|
52817
|
+
if (Array.isArray(obj.content)) {
|
|
52818
|
+
return obj.content;
|
|
52819
|
+
}
|
|
52820
|
+
}
|
|
52821
|
+
return [];
|
|
52822
|
+
}
|
|
52823
|
+
function getSlideScreenshotResult(result) {
|
|
52824
|
+
let text2 = null;
|
|
52825
|
+
let imageUrl = null;
|
|
52826
|
+
let mediaType = null;
|
|
52827
|
+
let s3Key = null;
|
|
52828
|
+
for (const item of normalizeContentResult(result)) {
|
|
52829
|
+
if (!item || typeof item !== "object") {
|
|
52830
|
+
continue;
|
|
52831
|
+
}
|
|
52832
|
+
const part = item;
|
|
52833
|
+
if (!text2 && part.type === "text" && typeof part.text === "string") {
|
|
52834
|
+
text2 = part.text;
|
|
52835
|
+
continue;
|
|
52836
|
+
}
|
|
52837
|
+
if (part.type !== "image") {
|
|
52838
|
+
continue;
|
|
52839
|
+
}
|
|
52840
|
+
const source = part.source && typeof part.source === "object" ? part.source : {};
|
|
52841
|
+
if (!imageUrl) {
|
|
52842
|
+
imageUrl = getStringField(source, ["presigned_url", "url"]) ?? getStringField(part, ["url", "image_url"]);
|
|
52843
|
+
}
|
|
52844
|
+
if (!mediaType) {
|
|
52845
|
+
mediaType = getStringField(source, ["media_type", "mime_type"]) ?? getStringField(part, ["media_type", "mime_type"]);
|
|
52846
|
+
}
|
|
52847
|
+
if (!s3Key) {
|
|
52848
|
+
s3Key = getStringField(source, ["data", "s3_key"]);
|
|
52849
|
+
}
|
|
52850
|
+
}
|
|
52851
|
+
return { text: text2, imageUrl, mediaType, s3Key };
|
|
52852
|
+
}
|
|
52853
|
+
const CaptureSlideScreenshotToolUIImpl = ({
|
|
52854
|
+
toolName,
|
|
52855
|
+
args,
|
|
52856
|
+
result,
|
|
52857
|
+
status
|
|
52858
|
+
}) => {
|
|
52859
|
+
const typedArgs = args;
|
|
52860
|
+
const assetId = getStringField(typedArgs, ["asset_id", "assetId"]);
|
|
52861
|
+
const slideNumber = getNumberField(typedArgs, ["slide_number", "slideNumber"]) ?? void 0;
|
|
52862
|
+
const { text: text2, imageUrl, mediaType } = React.useMemo(
|
|
52863
|
+
() => getSlideScreenshotResult(result),
|
|
52864
|
+
[result]
|
|
52865
|
+
);
|
|
52866
|
+
const isRunning = (status == null ? void 0 : status.type) === "running";
|
|
52867
|
+
const isComplete = (status == null ? void 0 : status.type) === "complete" || !status;
|
|
52868
|
+
const isCancelled = (status == null ? void 0 : status.type) === "incomplete" && status.reason === "cancelled";
|
|
52869
|
+
const errorMsg = (status == null ? void 0 : status.type) === "incomplete" ? String(status.error ?? status.reason ?? "Capture failed") : null;
|
|
52870
|
+
const openAsset = useAssetPanelStore((s) => s.openAsset);
|
|
52871
|
+
const handleOpenSlide = React.useCallback(() => {
|
|
52872
|
+
if (!assetId) {
|
|
52873
|
+
return;
|
|
52874
|
+
}
|
|
52875
|
+
openAsset(assetId, {
|
|
52876
|
+
type: "presentation",
|
|
52877
|
+
...slideNumber ? { slideNumber } : {}
|
|
52878
|
+
});
|
|
52879
|
+
}, [assetId, openAsset, slideNumber]);
|
|
52880
|
+
const subtitle = [
|
|
52881
|
+
slideNumber ? `Slide ${slideNumber}` : null,
|
|
52882
|
+
assetId ? truncate(assetId, 34) : null
|
|
52883
|
+
].filter((value) => Boolean(value)).join(" · ");
|
|
52884
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
52885
|
+
ToolCard,
|
|
52886
|
+
{
|
|
52887
|
+
icon: Camera,
|
|
52888
|
+
status: (status == null ? void 0 : status.type) ?? "complete",
|
|
52889
|
+
title: isRunning ? "Capturing slide screenshot..." : errorMsg ? "Slide screenshot failed" : "Slide screenshot captured",
|
|
52890
|
+
subtitle: subtitle || void 0,
|
|
52891
|
+
badge: slideNumber ? `Slide ${slideNumber}` : mediaType ?? void 0,
|
|
52892
|
+
toolName,
|
|
52893
|
+
args: typedArgs,
|
|
52894
|
+
result,
|
|
52895
|
+
error: errorMsg,
|
|
52896
|
+
children: [
|
|
52897
|
+
isComplete && !isCancelled && imageUrl && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "border-t border-border/40 p-3", children: [
|
|
52898
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "overflow-hidden rounded-lg border border-border/50 bg-muted/20", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
52899
|
+
"img",
|
|
52900
|
+
{
|
|
52901
|
+
src: imageUrl,
|
|
52902
|
+
alt: slideNumber ? `Slide ${slideNumber} screenshot` : "Slide screenshot",
|
|
52903
|
+
className: "aspect-video w-full object-contain",
|
|
52904
|
+
loading: "lazy"
|
|
52905
|
+
}
|
|
52906
|
+
) }),
|
|
52907
|
+
text2 && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-2 text-[11px] leading-relaxed text-muted-foreground", children: truncate(text2, 160) })
|
|
52908
|
+
] }),
|
|
52909
|
+
isComplete && !isCancelled && assetId && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap gap-2 border-t border-border/40 px-4 py-2", children: [
|
|
52910
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
52911
|
+
"button",
|
|
52912
|
+
{
|
|
52913
|
+
type: "button",
|
|
52914
|
+
onClick: handleOpenSlide,
|
|
52915
|
+
className: "flex items-center gap-1.5 rounded-md border border-border/60 px-3 py-1.5 text-xs font-medium text-muted-foreground transition-colors hover:bg-muted/50 hover:text-foreground",
|
|
52916
|
+
children: [
|
|
52917
|
+
/* @__PURE__ */ jsxRuntime.jsx(ExternalLink, { className: "size-3" }),
|
|
52918
|
+
slideNumber ? `Open slide ${slideNumber}` : "Open presentation"
|
|
52919
|
+
]
|
|
52920
|
+
}
|
|
52921
|
+
),
|
|
52922
|
+
imageUrl && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
52923
|
+
"a",
|
|
52924
|
+
{
|
|
52925
|
+
href: imageUrl,
|
|
52926
|
+
target: "_blank",
|
|
52927
|
+
rel: "noreferrer",
|
|
52928
|
+
className: "flex items-center gap-1.5 rounded-md border border-border/60 px-3 py-1.5 text-xs font-medium text-muted-foreground transition-colors hover:bg-muted/50 hover:text-foreground",
|
|
52929
|
+
children: [
|
|
52930
|
+
/* @__PURE__ */ jsxRuntime.jsx(Image, { className: "size-3" }),
|
|
52931
|
+
"Open image"
|
|
52932
|
+
]
|
|
52933
|
+
}
|
|
52934
|
+
)
|
|
52935
|
+
] })
|
|
52936
|
+
]
|
|
52937
|
+
}
|
|
52938
|
+
);
|
|
52939
|
+
};
|
|
52940
|
+
const CaptureSlideScreenshotToolUI = React.memo(
|
|
52941
|
+
CaptureSlideScreenshotToolUIImpl
|
|
52942
|
+
);
|
|
52943
|
+
CaptureSlideScreenshotToolUI.displayName = "CaptureSlideScreenshotToolUI";
|
|
52447
52944
|
const TOOL_UI_REGISTRY = {
|
|
52448
52945
|
search: WebSearchToolUI,
|
|
52449
52946
|
browse: BrowseToolUI,
|
|
@@ -52456,11 +52953,22 @@ const TOOL_UI_REGISTRY = {
|
|
|
52456
52953
|
create_new_sheet: CreateSheetToolUI,
|
|
52457
52954
|
create_powerpoint_deck: CreatePresentationToolUI,
|
|
52458
52955
|
create_new_notebook: CreateNotebookToolUI,
|
|
52956
|
+
// Studio SDK nested PTC tools
|
|
52957
|
+
CreateWorkbook: StudioCreateWorkbookToolUI,
|
|
52958
|
+
AddSheet: StudioAddSheetToolUI,
|
|
52959
|
+
OpenWorkbook: StudioOpenWorkbookToolUI,
|
|
52960
|
+
CreatePresentation: StudioCreatePresentationToolUI,
|
|
52961
|
+
OpenPresentation: StudioOpenPresentationToolUI,
|
|
52962
|
+
AddSlide: StudioAddSlideToolUI,
|
|
52963
|
+
CreateDocument: StudioCreateDocumentToolUI,
|
|
52964
|
+
OpenDocument: StudioOpenDocumentToolUI,
|
|
52965
|
+
CreateParagraph: StudioCreateParagraphToolUI,
|
|
52459
52966
|
execute_presentation_code: ExecutePresentationCodeToolUI,
|
|
52460
52967
|
run_python_code: RunPythonCodeToolUI,
|
|
52461
52968
|
open_asset_in_workspace: OpenAssetToolUI,
|
|
52462
52969
|
// Media capture
|
|
52463
52970
|
capture_moment: CaptureMomentToolUI,
|
|
52971
|
+
capture_slide_screenshot: CaptureSlideScreenshotToolUI,
|
|
52464
52972
|
// Spreadsheet toolkit
|
|
52465
52973
|
update_sheet_range: UpdateSheetRangeToolUI,
|
|
52466
52974
|
// Database toolkit
|
|
@@ -53570,10 +54078,37 @@ const AthenaUserMessage = ({
|
|
|
53570
54078
|
}
|
|
53571
54079
|
);
|
|
53572
54080
|
const embedCache = /* @__PURE__ */ new Map();
|
|
54081
|
+
function resolveAssetEmbedUrl({
|
|
54082
|
+
embedUrl,
|
|
54083
|
+
appUrl
|
|
54084
|
+
}) {
|
|
54085
|
+
if (!appUrl) {
|
|
54086
|
+
return embedUrl;
|
|
54087
|
+
}
|
|
54088
|
+
try {
|
|
54089
|
+
const resolvedEmbedUrl = new URL(embedUrl);
|
|
54090
|
+
const resolvedAppUrl = new URL(appUrl);
|
|
54091
|
+
if (!resolvedEmbedUrl.pathname.startsWith("/embed/")) {
|
|
54092
|
+
return embedUrl;
|
|
54093
|
+
}
|
|
54094
|
+
resolvedEmbedUrl.protocol = resolvedAppUrl.protocol;
|
|
54095
|
+
resolvedEmbedUrl.host = resolvedAppUrl.host;
|
|
54096
|
+
return resolvedEmbedUrl.toString();
|
|
54097
|
+
} catch {
|
|
54098
|
+
return embedUrl;
|
|
54099
|
+
}
|
|
54100
|
+
}
|
|
53573
54101
|
function useAssetEmbed(assetId, options = {
|
|
53574
54102
|
backendUrl: ""
|
|
53575
54103
|
}) {
|
|
53576
|
-
const {
|
|
54104
|
+
const {
|
|
54105
|
+
readOnly = false,
|
|
54106
|
+
expiresInSeconds = 60 * 60 * 24 * 30,
|
|
54107
|
+
backendUrl,
|
|
54108
|
+
appUrl,
|
|
54109
|
+
apiKey,
|
|
54110
|
+
token
|
|
54111
|
+
} = options;
|
|
53577
54112
|
const [embedUrl, setEmbedUrl] = React.useState(null);
|
|
53578
54113
|
const [isLoading, setIsLoading] = React.useState(false);
|
|
53579
54114
|
const [error2, setError] = React.useState(null);
|
|
@@ -53590,7 +54125,7 @@ function useAssetEmbed(assetId, options = {
|
|
|
53590
54125
|
return;
|
|
53591
54126
|
}
|
|
53592
54127
|
const authContext = hasToken ? "token" : apiKey ?? "anon";
|
|
53593
|
-
const cacheKey = `${assetId}:${readOnly}:${authContext}`;
|
|
54128
|
+
const cacheKey = `${assetId}:${readOnly}:${authContext}:${appUrl ?? ""}`;
|
|
53594
54129
|
const cached2 = embedCache.get(cacheKey);
|
|
53595
54130
|
if (cached2 && cached2.expiresAt > Date.now() / 1e3) {
|
|
53596
54131
|
setEmbedUrl(cached2.url);
|
|
@@ -53628,8 +54163,12 @@ function useAssetEmbed(assetId, options = {
|
|
|
53628
54163
|
}
|
|
53629
54164
|
return res.json();
|
|
53630
54165
|
}).then((data) => {
|
|
53631
|
-
|
|
53632
|
-
|
|
54166
|
+
const resolvedEmbedUrl = resolveAssetEmbedUrl({
|
|
54167
|
+
embedUrl: data.embed_url,
|
|
54168
|
+
appUrl
|
|
54169
|
+
});
|
|
54170
|
+
embedCache.set(cacheKey, { url: resolvedEmbedUrl, expiresAt: data.expires_at });
|
|
54171
|
+
setEmbedUrl(resolvedEmbedUrl);
|
|
53633
54172
|
setIsLoading(false);
|
|
53634
54173
|
}).catch((err) => {
|
|
53635
54174
|
if (err.name === "AbortError") return;
|
|
@@ -53637,9 +54176,44 @@ function useAssetEmbed(assetId, options = {
|
|
|
53637
54176
|
setIsLoading(false);
|
|
53638
54177
|
});
|
|
53639
54178
|
return () => controller.abort();
|
|
53640
|
-
}, [assetId, readOnly, expiresInSeconds, backendUrl, apiKey, hasToken]);
|
|
54179
|
+
}, [assetId, readOnly, expiresInSeconds, backendUrl, appUrl, apiKey, hasToken]);
|
|
53641
54180
|
return { embedUrl, isLoading, error: error2 };
|
|
53642
54181
|
}
|
|
54182
|
+
const ABSOLUTE_URL_PATTERN = /^[a-zA-Z][a-zA-Z\d+\-.]*:/;
|
|
54183
|
+
function buildAssetIframeSrc({
|
|
54184
|
+
embedUrl,
|
|
54185
|
+
assetType,
|
|
54186
|
+
slideNumber
|
|
54187
|
+
}) {
|
|
54188
|
+
const targetSlide = slideNumber;
|
|
54189
|
+
if (assetType !== "presentation" || typeof targetSlide !== "number" || !Number.isInteger(targetSlide) || targetSlide < 1) {
|
|
54190
|
+
return embedUrl;
|
|
54191
|
+
}
|
|
54192
|
+
try {
|
|
54193
|
+
const isAbsolute = ABSOLUTE_URL_PATTERN.test(embedUrl);
|
|
54194
|
+
const url = new URL(embedUrl, "https://athena.local");
|
|
54195
|
+
url.searchParams.set("slide", String(targetSlide));
|
|
54196
|
+
return isAbsolute ? url.toString() : `${url.pathname}${url.search}${url.hash}`;
|
|
54197
|
+
} catch {
|
|
54198
|
+
const separator = embedUrl.includes("?") ? "&" : "?";
|
|
54199
|
+
return `${embedUrl}${separator}slide=${targetSlide}`;
|
|
54200
|
+
}
|
|
54201
|
+
}
|
|
54202
|
+
function buildPresentationNavigationMessage({
|
|
54203
|
+
assetId,
|
|
54204
|
+
assetType,
|
|
54205
|
+
slideNumber
|
|
54206
|
+
}) {
|
|
54207
|
+
if (assetType !== "presentation" || typeof slideNumber !== "number" || !Number.isInteger(slideNumber) || slideNumber < 1) {
|
|
54208
|
+
return null;
|
|
54209
|
+
}
|
|
54210
|
+
return {
|
|
54211
|
+
type: "NAVIGATE_TO_SLIDE",
|
|
54212
|
+
assetId,
|
|
54213
|
+
deckId: assetId,
|
|
54214
|
+
slideNumber
|
|
54215
|
+
};
|
|
54216
|
+
}
|
|
53643
54217
|
const ASSET_TYPE_CONFIG = {
|
|
53644
54218
|
presentation: { icon: Presentation, label: "Presentation" },
|
|
53645
54219
|
spreadsheet: { icon: FileSpreadsheet, label: "Spreadsheet" },
|
|
@@ -53648,13 +54222,39 @@ const ASSET_TYPE_CONFIG = {
|
|
|
53648
54222
|
unknown: { icon: File$1, label: "Asset" }
|
|
53649
54223
|
};
|
|
53650
54224
|
const AssetIframe = React.memo(
|
|
53651
|
-
({
|
|
53652
|
-
const
|
|
53653
|
-
const {
|
|
54225
|
+
({ tab }) => {
|
|
54226
|
+
const iframeRef = React.useRef(null);
|
|
54227
|
+
const { backendUrl, appUrl, apiKey, token } = useAthenaConfig();
|
|
54228
|
+
const { embedUrl, isLoading, error: error2 } = useAssetEmbed(tab.id, {
|
|
53654
54229
|
backendUrl,
|
|
54230
|
+
appUrl,
|
|
53655
54231
|
apiKey,
|
|
53656
54232
|
token
|
|
53657
54233
|
});
|
|
54234
|
+
const iframeSrc = React.useMemo(
|
|
54235
|
+
() => embedUrl ? buildAssetIframeSrc({
|
|
54236
|
+
embedUrl,
|
|
54237
|
+
assetType: tab.type,
|
|
54238
|
+
slideNumber: tab.slideNumber
|
|
54239
|
+
}) : null,
|
|
54240
|
+
[embedUrl, tab.slideNumber, tab.type]
|
|
54241
|
+
);
|
|
54242
|
+
const navigationMessage = React.useMemo(
|
|
54243
|
+
() => buildPresentationNavigationMessage({
|
|
54244
|
+
assetId: tab.id,
|
|
54245
|
+
assetType: tab.type,
|
|
54246
|
+
slideNumber: tab.slideNumber
|
|
54247
|
+
}),
|
|
54248
|
+
[tab.id, tab.slideNumber, tab.type]
|
|
54249
|
+
);
|
|
54250
|
+
const postNavigationMessage = React.useCallback(() => {
|
|
54251
|
+
var _a2, _b;
|
|
54252
|
+
if (!navigationMessage) return;
|
|
54253
|
+
(_b = (_a2 = iframeRef.current) == null ? void 0 : _a2.contentWindow) == null ? void 0 : _b.postMessage(navigationMessage, "*");
|
|
54254
|
+
}, [navigationMessage]);
|
|
54255
|
+
React.useEffect(() => {
|
|
54256
|
+
postNavigationMessage();
|
|
54257
|
+
}, [postNavigationMessage]);
|
|
53658
54258
|
if (isLoading) {
|
|
53659
54259
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex h-full items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-center", children: [
|
|
53660
54260
|
/* @__PURE__ */ jsxRuntime.jsx(LoaderCircle, { className: "mx-auto size-6 animate-spin text-muted-foreground" }),
|
|
@@ -53668,20 +54268,23 @@ const AssetIframe = React.memo(
|
|
|
53668
54268
|
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-0.5 line-clamp-2 break-words text-[10px] text-muted-foreground", children: error2 })
|
|
53669
54269
|
] }) });
|
|
53670
54270
|
}
|
|
53671
|
-
if (!
|
|
54271
|
+
if (!iframeSrc) return null;
|
|
53672
54272
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
53673
54273
|
"iframe",
|
|
53674
54274
|
{
|
|
53675
|
-
|
|
54275
|
+
ref: iframeRef,
|
|
54276
|
+
src: iframeSrc,
|
|
53676
54277
|
width: "100%",
|
|
53677
54278
|
height: "100%",
|
|
53678
54279
|
frameBorder: "0",
|
|
53679
54280
|
allow: "fullscreen",
|
|
53680
|
-
title:
|
|
53681
|
-
className: "h-full w-full"
|
|
54281
|
+
title: tab.name ?? `Asset ${tab.id}`,
|
|
54282
|
+
className: "h-full w-full",
|
|
54283
|
+
onLoad: postNavigationMessage
|
|
53682
54284
|
}
|
|
53683
54285
|
);
|
|
53684
|
-
}
|
|
54286
|
+
},
|
|
54287
|
+
(prev, next) => prev.tab.id === next.tab.id && prev.tab.name === next.tab.name && prev.tab.type === next.tab.type && prev.tab.slideNumber === next.tab.slideNumber
|
|
53685
54288
|
);
|
|
53686
54289
|
AssetIframe.displayName = "AssetIframe";
|
|
53687
54290
|
const PanelContent = ({
|
|
@@ -53739,7 +54342,7 @@ const PanelContent = ({
|
|
|
53739
54342
|
}
|
|
53740
54343
|
)
|
|
53741
54344
|
] }),
|
|
53742
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx(AssetIframe, {
|
|
54345
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx(AssetIframe, { tab }) })
|
|
53743
54346
|
]
|
|
53744
54347
|
},
|
|
53745
54348
|
tab.id
|
|
@@ -53749,7 +54352,7 @@ const PanelContent = ({
|
|
|
53749
54352
|
"div",
|
|
53750
54353
|
{
|
|
53751
54354
|
className: isActive2 ? "h-full w-full" : "hidden",
|
|
53752
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(AssetIframe, {
|
|
54355
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(AssetIframe, { tab })
|
|
53753
54356
|
},
|
|
53754
54357
|
tab.id
|
|
53755
54358
|
);
|