@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.js
CHANGED
|
@@ -14112,14 +14112,20 @@ const useAssetPanelStore = create()(
|
|
|
14112
14112
|
const existing = s.tabs.find((t) => t.id === assetId);
|
|
14113
14113
|
if (existing) {
|
|
14114
14114
|
const tabs = meta ? s.tabs.map(
|
|
14115
|
-
(t) => t.id === assetId ? {
|
|
14115
|
+
(t) => t.id === assetId ? {
|
|
14116
|
+
...t,
|
|
14117
|
+
name: meta.name ?? t.name,
|
|
14118
|
+
type: meta.type ?? t.type,
|
|
14119
|
+
slideNumber: "slideNumber" in meta ? meta.slideNumber : t.slideNumber
|
|
14120
|
+
} : t
|
|
14116
14121
|
) : s.tabs;
|
|
14117
14122
|
return { isOpen: true, tabs, activeTabId: assetId };
|
|
14118
14123
|
}
|
|
14119
14124
|
const newTab = {
|
|
14120
14125
|
id: assetId,
|
|
14121
14126
|
name: (meta == null ? void 0 : meta.name) ?? null,
|
|
14122
|
-
type: (meta == null ? void 0 : meta.type) ?? "unknown"
|
|
14127
|
+
type: (meta == null ? void 0 : meta.type) ?? "unknown",
|
|
14128
|
+
slideNumber: meta == null ? void 0 : meta.slideNumber
|
|
14123
14129
|
};
|
|
14124
14130
|
return { isOpen: true, tabs: [...s.tabs, newTab], activeTabId: assetId };
|
|
14125
14131
|
}),
|
|
@@ -50001,18 +50007,6 @@ function AssetToolCard({
|
|
|
50001
50007
|
const assetId = extractAssetId$1(result);
|
|
50002
50008
|
const title = extractTitle(argsText, result);
|
|
50003
50009
|
const assetType = toolMetaToAssetType(toolName);
|
|
50004
|
-
const wasCompleteAtMount = useRef(isComplete);
|
|
50005
|
-
useEffect(() => {
|
|
50006
|
-
if (isComplete && !isCancelled && assetId && !wasCompleteAtMount.current) {
|
|
50007
|
-
const store = useAssetPanelStore.getState();
|
|
50008
|
-
if (store.markAutoOpened(assetId)) {
|
|
50009
|
-
store.openAsset(assetId, {
|
|
50010
|
-
name: title ?? void 0,
|
|
50011
|
-
type: assetType
|
|
50012
|
-
});
|
|
50013
|
-
}
|
|
50014
|
-
}
|
|
50015
|
-
}, [isComplete, isCancelled, assetId, title, assetType]);
|
|
50016
50010
|
const success = isComplete && isResultSuccess(result);
|
|
50017
50011
|
return /* @__PURE__ */ jsxs("div", { className: cn(
|
|
50018
50012
|
"aui-tool-fallback-root my-3 w-full rounded-xl border border-border/60 bg-background py-2.5 shadow-sm",
|
|
@@ -50574,6 +50568,32 @@ function normalizeResult(result) {
|
|
|
50574
50568
|
function truncate(text2, max2) {
|
|
50575
50569
|
return text2.length > max2 ? `${text2.slice(0, max2)}...` : text2;
|
|
50576
50570
|
}
|
|
50571
|
+
function isSdkToolDebugEnabled() {
|
|
50572
|
+
var _a2, _b;
|
|
50573
|
+
try {
|
|
50574
|
+
const hostname = (_a2 = globalThis.location) == null ? void 0 : _a2.hostname;
|
|
50575
|
+
if (hostname === "localhost" || hostname === "127.0.0.1" || hostname === "::1") {
|
|
50576
|
+
return true;
|
|
50577
|
+
}
|
|
50578
|
+
return ((_b = globalThis.localStorage) == null ? void 0 : _b.getItem("athena:sdk:debug")) === "1";
|
|
50579
|
+
} catch {
|
|
50580
|
+
return false;
|
|
50581
|
+
}
|
|
50582
|
+
}
|
|
50583
|
+
function stringifyDebugPayload(payload) {
|
|
50584
|
+
return JSON.stringify(payload, (_key, value) => {
|
|
50585
|
+
if (typeof value === "string" && value.length > 800) {
|
|
50586
|
+
return `${value.slice(0, 800)}... [truncated ${value.length - 800} chars]`;
|
|
50587
|
+
}
|
|
50588
|
+
return value;
|
|
50589
|
+
});
|
|
50590
|
+
}
|
|
50591
|
+
function logDebugPayload(label, payload) {
|
|
50592
|
+
if (!isSdkToolDebugEnabled()) {
|
|
50593
|
+
return;
|
|
50594
|
+
}
|
|
50595
|
+
console.info(`${label} ${stringifyDebugPayload(payload)}`);
|
|
50596
|
+
}
|
|
50577
50597
|
function formatToolName(name) {
|
|
50578
50598
|
return name.replace(/_/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
|
|
50579
50599
|
}
|
|
@@ -50864,6 +50884,83 @@ function extractAssetId(result) {
|
|
|
50864
50884
|
function resetAssetAutoOpen() {
|
|
50865
50885
|
useAssetPanelStore.getState().resetAutoOpen();
|
|
50866
50886
|
}
|
|
50887
|
+
function getStringField(source, keys2) {
|
|
50888
|
+
if (!source) return null;
|
|
50889
|
+
for (const key of keys2) {
|
|
50890
|
+
const value = source[key];
|
|
50891
|
+
if (typeof value === "string" && value.trim()) {
|
|
50892
|
+
return value;
|
|
50893
|
+
}
|
|
50894
|
+
}
|
|
50895
|
+
return null;
|
|
50896
|
+
}
|
|
50897
|
+
function getNumberField(source, keys2) {
|
|
50898
|
+
if (!source) return null;
|
|
50899
|
+
for (const key of keys2) {
|
|
50900
|
+
const value = source[key];
|
|
50901
|
+
if (typeof value === "number" && Number.isFinite(value)) {
|
|
50902
|
+
return value;
|
|
50903
|
+
}
|
|
50904
|
+
}
|
|
50905
|
+
return null;
|
|
50906
|
+
}
|
|
50907
|
+
const PRESENTATION_CODE_SLIDE_NUMBER_KEYS = [
|
|
50908
|
+
"slideNumber",
|
|
50909
|
+
"slide_number",
|
|
50910
|
+
"targetSlideNumber",
|
|
50911
|
+
"target_slide_number",
|
|
50912
|
+
"targetSlide",
|
|
50913
|
+
"target_slide"
|
|
50914
|
+
];
|
|
50915
|
+
const PRESENTATION_CODE_SLIDE_INDEX_KEYS = [
|
|
50916
|
+
"slideIndex",
|
|
50917
|
+
"slide_index",
|
|
50918
|
+
"targetSlideIndex",
|
|
50919
|
+
"target_slide_index"
|
|
50920
|
+
];
|
|
50921
|
+
function getStudioAssetId({
|
|
50922
|
+
args,
|
|
50923
|
+
result
|
|
50924
|
+
}) {
|
|
50925
|
+
const id = getStringField(result, ["asset_id", "assetId", "id"]) ?? getStringField(args, ["asset_id", "assetId", "id"]);
|
|
50926
|
+
return (id == null ? void 0 : id.startsWith("asset_")) ? id : null;
|
|
50927
|
+
}
|
|
50928
|
+
function getPresentationCodeDeckId(code2) {
|
|
50929
|
+
const match2 = code2.match(/\bdeck_id\s*=\s*["']([^"']+)["']/);
|
|
50930
|
+
const deckId = match2 == null ? void 0 : match2[1];
|
|
50931
|
+
return (deckId == null ? void 0 : deckId.startsWith("asset_")) ? deckId : null;
|
|
50932
|
+
}
|
|
50933
|
+
function getPresentationCodeSlideNumberFromFields(source) {
|
|
50934
|
+
const explicit = getNumberField(source, PRESENTATION_CODE_SLIDE_NUMBER_KEYS);
|
|
50935
|
+
if (explicit != null && Number.isInteger(explicit) && explicit >= 1) {
|
|
50936
|
+
return explicit;
|
|
50937
|
+
}
|
|
50938
|
+
const zeroBasedIndex = getNumberField(source, PRESENTATION_CODE_SLIDE_INDEX_KEYS);
|
|
50939
|
+
if (zeroBasedIndex != null && Number.isInteger(zeroBasedIndex) && zeroBasedIndex >= 0) {
|
|
50940
|
+
return zeroBasedIndex + 1;
|
|
50941
|
+
}
|
|
50942
|
+
return void 0;
|
|
50943
|
+
}
|
|
50944
|
+
function getPresentationCodeSlideNumberFromText(text2) {
|
|
50945
|
+
const match2 = text2 == null ? void 0 : text2.match(/\bslide\s*(?:#|number\s*)?(\d+)\b/i);
|
|
50946
|
+
if (!match2) {
|
|
50947
|
+
return void 0;
|
|
50948
|
+
}
|
|
50949
|
+
const slideNumber = Number.parseInt(match2[1] ?? "", 10);
|
|
50950
|
+
return Number.isInteger(slideNumber) && slideNumber >= 1 ? slideNumber : void 0;
|
|
50951
|
+
}
|
|
50952
|
+
function getPresentationCodeSlideNumber({
|
|
50953
|
+
args,
|
|
50954
|
+
result
|
|
50955
|
+
}) {
|
|
50956
|
+
return getPresentationCodeSlideNumberFromFields(args) ?? getPresentationCodeSlideNumberFromFields(result) ?? getPresentationCodeSlideNumberFromText(
|
|
50957
|
+
getStringField(args, ["summary", "title", "description"])
|
|
50958
|
+
);
|
|
50959
|
+
}
|
|
50960
|
+
function getAddSlideNumber(args) {
|
|
50961
|
+
const index2 = getNumberField(args, ["index"]);
|
|
50962
|
+
return index2 != null && Number.isInteger(index2) && index2 >= 0 ? index2 + 1 : void 0;
|
|
50963
|
+
}
|
|
50867
50964
|
function CreateAssetToolUIImpl({
|
|
50868
50965
|
icon: Icon2,
|
|
50869
50966
|
assetType,
|
|
@@ -50884,18 +50981,6 @@ function CreateAssetToolUIImpl({
|
|
|
50884
50981
|
const isCancelled = (status == null ? void 0 : status.type) === "incomplete" && status.reason === "cancelled";
|
|
50885
50982
|
const errorMsg = (status == null ? void 0 : status.type) === "incomplete" ? status.error : null;
|
|
50886
50983
|
const openAsset = useAssetPanelStore((s) => s.openAsset);
|
|
50887
|
-
const wasCompleteAtMount = useRef(isComplete);
|
|
50888
|
-
useEffect(() => {
|
|
50889
|
-
if (isComplete && !isCancelled && assetId && !wasCompleteAtMount.current) {
|
|
50890
|
-
const store = useAssetPanelStore.getState();
|
|
50891
|
-
if (store.markAutoOpened(assetId)) {
|
|
50892
|
-
store.openAsset(assetId, {
|
|
50893
|
-
name: createdName || name || void 0,
|
|
50894
|
-
type: assetType
|
|
50895
|
-
});
|
|
50896
|
-
}
|
|
50897
|
-
}
|
|
50898
|
-
}, [isComplete, isCancelled, assetId, createdName, name, assetType]);
|
|
50899
50984
|
const handleOpen = () => {
|
|
50900
50985
|
if (assetId) {
|
|
50901
50986
|
openAsset(assetId, {
|
|
@@ -50973,6 +51058,258 @@ const CreatePresentationToolUI = memo(
|
|
|
50973
51058
|
CreatePresentationToolUIImpl
|
|
50974
51059
|
);
|
|
50975
51060
|
CreatePresentationToolUI.displayName = "CreatePresentationToolUI";
|
|
51061
|
+
function openStudioAsset({
|
|
51062
|
+
assetId,
|
|
51063
|
+
assetType,
|
|
51064
|
+
slideNumber,
|
|
51065
|
+
preserveExistingSlide
|
|
51066
|
+
}) {
|
|
51067
|
+
const store = useAssetPanelStore.getState();
|
|
51068
|
+
const existing = store.tabs.find((tab) => tab.id === assetId);
|
|
51069
|
+
const shouldKeepCurrentSlide = preserveExistingSlide && existing;
|
|
51070
|
+
store.openAsset(assetId, {
|
|
51071
|
+
type: assetType,
|
|
51072
|
+
...!shouldKeepCurrentSlide && slideNumber !== void 0 ? { slideNumber } : {}
|
|
51073
|
+
});
|
|
51074
|
+
}
|
|
51075
|
+
function StudioPtcToolUI({
|
|
51076
|
+
config: config2,
|
|
51077
|
+
toolName,
|
|
51078
|
+
args,
|
|
51079
|
+
result,
|
|
51080
|
+
status
|
|
51081
|
+
}) {
|
|
51082
|
+
var _a2, _b;
|
|
51083
|
+
const typedArgs = args;
|
|
51084
|
+
const data = useMemo(() => normalizeResult(result), [result]);
|
|
51085
|
+
const slideNumber = (_a2 = config2.getSlideNumber) == null ? void 0 : _a2.call(config2, typedArgs);
|
|
51086
|
+
const assetId = getStudioAssetId({ args: typedArgs, result: data });
|
|
51087
|
+
const subtitle = (_b = config2.getSubtitle) == null ? void 0 : _b.call(config2, typedArgs, data, slideNumber);
|
|
51088
|
+
const isRunning = (status == null ? void 0 : status.type) === "running";
|
|
51089
|
+
const isComplete = (status == null ? void 0 : status.type) === "complete" || !status;
|
|
51090
|
+
const isCancelled = (status == null ? void 0 : status.type) === "incomplete" && status.reason === "cancelled";
|
|
51091
|
+
const errorMsg = (status == null ? void 0 : status.type) === "incomplete" ? String(status.error ?? status.reason ?? "Tool failed") : null;
|
|
51092
|
+
const handleOpen = useCallback(() => {
|
|
51093
|
+
if (!assetId) return;
|
|
51094
|
+
if (toolName === "AddSlide") {
|
|
51095
|
+
logDebugPayload("[Athena SDK AddSlide] manual open", {
|
|
51096
|
+
args: typedArgs,
|
|
51097
|
+
parsedResult: data,
|
|
51098
|
+
rawResult: result,
|
|
51099
|
+
assetId,
|
|
51100
|
+
slideNumber
|
|
51101
|
+
});
|
|
51102
|
+
}
|
|
51103
|
+
openStudioAsset({
|
|
51104
|
+
assetId,
|
|
51105
|
+
assetType: config2.assetType,
|
|
51106
|
+
slideNumber,
|
|
51107
|
+
preserveExistingSlide: config2.preserveExistingSlide
|
|
51108
|
+
});
|
|
51109
|
+
}, [
|
|
51110
|
+
assetId,
|
|
51111
|
+
config2.assetType,
|
|
51112
|
+
config2.preserveExistingSlide,
|
|
51113
|
+
data,
|
|
51114
|
+
result,
|
|
51115
|
+
slideNumber,
|
|
51116
|
+
toolName,
|
|
51117
|
+
typedArgs
|
|
51118
|
+
]);
|
|
51119
|
+
useEffect(() => {
|
|
51120
|
+
if (toolName !== "AddSlide") {
|
|
51121
|
+
return;
|
|
51122
|
+
}
|
|
51123
|
+
logDebugPayload("[Athena SDK AddSlide] tool state", {
|
|
51124
|
+
args: typedArgs,
|
|
51125
|
+
parsedResult: data,
|
|
51126
|
+
rawResult: result,
|
|
51127
|
+
status,
|
|
51128
|
+
assetId,
|
|
51129
|
+
slideNumber,
|
|
51130
|
+
isComplete,
|
|
51131
|
+
isCancelled
|
|
51132
|
+
});
|
|
51133
|
+
}, [
|
|
51134
|
+
assetId,
|
|
51135
|
+
data,
|
|
51136
|
+
isCancelled,
|
|
51137
|
+
isComplete,
|
|
51138
|
+
result,
|
|
51139
|
+
slideNumber,
|
|
51140
|
+
status,
|
|
51141
|
+
toolName,
|
|
51142
|
+
typedArgs
|
|
51143
|
+
]);
|
|
51144
|
+
return /* @__PURE__ */ jsx(
|
|
51145
|
+
ToolCard,
|
|
51146
|
+
{
|
|
51147
|
+
icon: config2.icon,
|
|
51148
|
+
status: (status == null ? void 0 : status.type) ?? "complete",
|
|
51149
|
+
title: isRunning ? config2.runningLabel(typedArgs) : config2.doneLabel(typedArgs, slideNumber),
|
|
51150
|
+
subtitle,
|
|
51151
|
+
badge: config2.badge,
|
|
51152
|
+
toolName,
|
|
51153
|
+
args: typedArgs,
|
|
51154
|
+
result,
|
|
51155
|
+
error: errorMsg,
|
|
51156
|
+
children: assetId && isComplete && !isCancelled && /* @__PURE__ */ jsx("div", { className: "border-t border-border/40 px-4 py-2", children: /* @__PURE__ */ jsxs(
|
|
51157
|
+
"button",
|
|
51158
|
+
{
|
|
51159
|
+
type: "button",
|
|
51160
|
+
onClick: handleOpen,
|
|
51161
|
+
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",
|
|
51162
|
+
children: [
|
|
51163
|
+
/* @__PURE__ */ jsx(ExternalLink, { className: "size-3" }),
|
|
51164
|
+
config2.openLabel(slideNumber)
|
|
51165
|
+
]
|
|
51166
|
+
}
|
|
51167
|
+
) })
|
|
51168
|
+
}
|
|
51169
|
+
);
|
|
51170
|
+
}
|
|
51171
|
+
function createStudioPtcToolUI(displayName, config2) {
|
|
51172
|
+
const Component = (props) => /* @__PURE__ */ jsx(StudioPtcToolUI, { config: config2, ...props });
|
|
51173
|
+
const Memoized = memo(Component);
|
|
51174
|
+
Memoized.displayName = displayName;
|
|
51175
|
+
return Memoized;
|
|
51176
|
+
}
|
|
51177
|
+
const getNameSubtitle = (args, result) => getStringField(result, ["title", "name", "asset_name"]) ?? getStringField(args, ["title", "name"]) ?? void 0;
|
|
51178
|
+
const getParagraphSubtitle = (args) => {
|
|
51179
|
+
const text2 = getStringField(args, ["text"]);
|
|
51180
|
+
return text2 ? truncate(text2, 80) : void 0;
|
|
51181
|
+
};
|
|
51182
|
+
const getSlideSubtitle = (args, _result, slideNumber) => {
|
|
51183
|
+
const layout = getStringField(args, ["layoutName", "layout_name"]) ?? getStringField(args, ["layoutPath", "layout_path"]);
|
|
51184
|
+
const slideLabel = slideNumber ? `Slide ${slideNumber}` : null;
|
|
51185
|
+
if (slideLabel && layout) return `${slideLabel} - ${truncate(layout, 48)}`;
|
|
51186
|
+
return slideLabel ?? (layout ? truncate(layout, 64) : void 0);
|
|
51187
|
+
};
|
|
51188
|
+
const StudioCreateWorkbookToolUI = createStudioPtcToolUI(
|
|
51189
|
+
"StudioCreateWorkbookToolUI",
|
|
51190
|
+
{
|
|
51191
|
+
icon: ChartColumn,
|
|
51192
|
+
assetType: "spreadsheet",
|
|
51193
|
+
badge: "Sheet",
|
|
51194
|
+
runningLabel: (args) => {
|
|
51195
|
+
const title = getStringField(args, ["title", "name"]);
|
|
51196
|
+
return title ? `Creating workbook "${title}"...` : "Creating workbook...";
|
|
51197
|
+
},
|
|
51198
|
+
doneLabel: () => "Workbook created",
|
|
51199
|
+
getSubtitle: getNameSubtitle,
|
|
51200
|
+
openLabel: () => "Open workbook"
|
|
51201
|
+
}
|
|
51202
|
+
);
|
|
51203
|
+
const StudioAddSheetToolUI = createStudioPtcToolUI(
|
|
51204
|
+
"StudioAddSheetToolUI",
|
|
51205
|
+
{
|
|
51206
|
+
icon: ChartColumn,
|
|
51207
|
+
assetType: "spreadsheet",
|
|
51208
|
+
badge: "Sheet",
|
|
51209
|
+
runningLabel: (args) => {
|
|
51210
|
+
const name = getStringField(args, ["name", "sheetName", "sheet_name"]);
|
|
51211
|
+
return name ? `Adding sheet "${name}"...` : "Adding sheet...";
|
|
51212
|
+
},
|
|
51213
|
+
doneLabel: (args) => {
|
|
51214
|
+
const name = getStringField(args, ["name", "sheetName", "sheet_name"]);
|
|
51215
|
+
return name ? `Sheet added: ${name}` : "Sheet added";
|
|
51216
|
+
},
|
|
51217
|
+
getSubtitle: (args) => getStringField(args, ["name", "sheetName", "sheet_name"]) ?? void 0,
|
|
51218
|
+
openLabel: () => "Open workbook"
|
|
51219
|
+
}
|
|
51220
|
+
);
|
|
51221
|
+
const StudioOpenWorkbookToolUI = createStudioPtcToolUI(
|
|
51222
|
+
"StudioOpenWorkbookToolUI",
|
|
51223
|
+
{
|
|
51224
|
+
icon: ChartColumn,
|
|
51225
|
+
assetType: "spreadsheet",
|
|
51226
|
+
badge: "Sheet",
|
|
51227
|
+
runningLabel: () => "Opening workbook...",
|
|
51228
|
+
doneLabel: () => "Workbook opened",
|
|
51229
|
+
openLabel: () => "Open workbook"
|
|
51230
|
+
}
|
|
51231
|
+
);
|
|
51232
|
+
const StudioCreatePresentationToolUI = createStudioPtcToolUI(
|
|
51233
|
+
"StudioCreatePresentationToolUI",
|
|
51234
|
+
{
|
|
51235
|
+
icon: Presentation,
|
|
51236
|
+
assetType: "presentation",
|
|
51237
|
+
badge: "Deck",
|
|
51238
|
+
runningLabel: (args) => {
|
|
51239
|
+
const title = getStringField(args, ["title", "name"]);
|
|
51240
|
+
return title ? `Creating presentation "${title}"...` : "Creating presentation...";
|
|
51241
|
+
},
|
|
51242
|
+
doneLabel: () => "Presentation created",
|
|
51243
|
+
getSubtitle: getNameSubtitle,
|
|
51244
|
+
getSlideNumber: () => 1,
|
|
51245
|
+
openLabel: () => "Open presentation"
|
|
51246
|
+
}
|
|
51247
|
+
);
|
|
51248
|
+
const StudioOpenPresentationToolUI = createStudioPtcToolUI(
|
|
51249
|
+
"StudioOpenPresentationToolUI",
|
|
51250
|
+
{
|
|
51251
|
+
icon: Presentation,
|
|
51252
|
+
assetType: "presentation",
|
|
51253
|
+
badge: "Deck",
|
|
51254
|
+
runningLabel: () => "Opening presentation...",
|
|
51255
|
+
doneLabel: () => "Presentation opened",
|
|
51256
|
+
getSlideNumber: () => 1,
|
|
51257
|
+
getSubtitle: (_args, _result, slideNumber) => slideNumber ? `Slide ${slideNumber}` : void 0,
|
|
51258
|
+
openLabel: () => "Open presentation",
|
|
51259
|
+
preserveExistingSlide: true
|
|
51260
|
+
}
|
|
51261
|
+
);
|
|
51262
|
+
const StudioAddSlideToolUI = createStudioPtcToolUI(
|
|
51263
|
+
"StudioAddSlideToolUI",
|
|
51264
|
+
{
|
|
51265
|
+
icon: Presentation,
|
|
51266
|
+
assetType: "presentation",
|
|
51267
|
+
badge: "Deck",
|
|
51268
|
+
runningLabel: () => "Adding slide...",
|
|
51269
|
+
doneLabel: (_args, slideNumber) => slideNumber ? `Slide ${slideNumber} added` : "Slide added",
|
|
51270
|
+
getSubtitle: getSlideSubtitle,
|
|
51271
|
+
getSlideNumber: (args) => getAddSlideNumber(args) ?? 1,
|
|
51272
|
+
openLabel: (slideNumber) => slideNumber ? `Open slide ${slideNumber}` : "Open presentation"
|
|
51273
|
+
}
|
|
51274
|
+
);
|
|
51275
|
+
const StudioCreateDocumentToolUI = createStudioPtcToolUI(
|
|
51276
|
+
"StudioCreateDocumentToolUI",
|
|
51277
|
+
{
|
|
51278
|
+
icon: FileText,
|
|
51279
|
+
assetType: "document",
|
|
51280
|
+
badge: "Doc",
|
|
51281
|
+
runningLabel: (args) => {
|
|
51282
|
+
const title = getStringField(args, ["title", "name"]);
|
|
51283
|
+
return title ? `Creating document "${title}"...` : "Creating document...";
|
|
51284
|
+
},
|
|
51285
|
+
doneLabel: () => "Document created",
|
|
51286
|
+
getSubtitle: getNameSubtitle,
|
|
51287
|
+
openLabel: () => "Open document"
|
|
51288
|
+
}
|
|
51289
|
+
);
|
|
51290
|
+
const StudioCreateParagraphToolUI = createStudioPtcToolUI(
|
|
51291
|
+
"StudioCreateParagraphToolUI",
|
|
51292
|
+
{
|
|
51293
|
+
icon: FileText,
|
|
51294
|
+
assetType: "document",
|
|
51295
|
+
badge: "Doc",
|
|
51296
|
+
runningLabel: () => "Adding paragraph...",
|
|
51297
|
+
doneLabel: () => "Paragraph added",
|
|
51298
|
+
getSubtitle: getParagraphSubtitle,
|
|
51299
|
+
openLabel: () => "Open document"
|
|
51300
|
+
}
|
|
51301
|
+
);
|
|
51302
|
+
const StudioOpenDocumentToolUI = createStudioPtcToolUI(
|
|
51303
|
+
"StudioOpenDocumentToolUI",
|
|
51304
|
+
{
|
|
51305
|
+
icon: FileText,
|
|
51306
|
+
assetType: "document",
|
|
51307
|
+
badge: "Doc",
|
|
51308
|
+
runningLabel: () => "Opening document...",
|
|
51309
|
+
doneLabel: () => "Document opened",
|
|
51310
|
+
openLabel: () => "Open document"
|
|
51311
|
+
}
|
|
51312
|
+
);
|
|
50976
51313
|
const CreateEmailDraftToolUIImpl = ({
|
|
50977
51314
|
toolName,
|
|
50978
51315
|
args,
|
|
@@ -51478,7 +51815,7 @@ const ExecutePresentationCodeToolUIImpl = ({
|
|
|
51478
51815
|
const typedArgs = args;
|
|
51479
51816
|
const code2 = (typedArgs == null ? void 0 : typedArgs.code) ?? "";
|
|
51480
51817
|
const summary = (typedArgs == null ? void 0 : typedArgs.summary) ?? null;
|
|
51481
|
-
const deckIdFromArgs =
|
|
51818
|
+
const deckIdFromArgs = getStringField(typedArgs, ["deck_id", "deckId", "asset_id", "assetId"]) ?? getPresentationCodeDeckId(code2);
|
|
51482
51819
|
const isRunning = (status == null ? void 0 : status.type) === "running";
|
|
51483
51820
|
const isComplete = (status == null ? void 0 : status.type) === "complete";
|
|
51484
51821
|
const errorMsg = (status == null ? void 0 : status.type) === "incomplete" ? status.error : null;
|
|
@@ -51486,21 +51823,55 @@ const ExecutePresentationCodeToolUIImpl = ({
|
|
|
51486
51823
|
() => isComplete ? parsePythonResult(result) : null,
|
|
51487
51824
|
[result, isComplete]
|
|
51488
51825
|
);
|
|
51826
|
+
const resultData = useMemo(() => normalizeResult(result), [result]);
|
|
51489
51827
|
const outputText = parsed ? getExecutionTextOutput(parsed) : null;
|
|
51490
|
-
const
|
|
51828
|
+
const targetSlideNumber = getPresentationCodeSlideNumber({
|
|
51829
|
+
args: typedArgs,
|
|
51830
|
+
result: resultData
|
|
51831
|
+
});
|
|
51491
51832
|
const deckId = (parsed == null ? void 0 : parsed.deckId) ?? deckIdFromArgs;
|
|
51833
|
+
const assetId = (parsed == null ? void 0 : parsed.assetId) ?? ((deckId == null ? void 0 : deckId.startsWith("asset_")) ? deckId : null);
|
|
51492
51834
|
const hasError = parsed && (parsed.error || parsed.exception);
|
|
51493
51835
|
const openAsset = useAssetPanelStore((s) => s.openAsset);
|
|
51494
|
-
const wasCompleteAtMount = useRef(isComplete);
|
|
51495
51836
|
useEffect(() => {
|
|
51496
|
-
if (!isComplete
|
|
51837
|
+
if (!isComplete) {
|
|
51497
51838
|
return;
|
|
51498
51839
|
}
|
|
51499
|
-
|
|
51500
|
-
|
|
51501
|
-
|
|
51840
|
+
logDebugPayload("[Athena SDK execute_presentation_code] tool state", {
|
|
51841
|
+
args: typedArgs,
|
|
51842
|
+
parsedResult: resultData,
|
|
51843
|
+
status,
|
|
51844
|
+
assetId,
|
|
51845
|
+
deckId,
|
|
51846
|
+
targetSlideNumber,
|
|
51847
|
+
outputText
|
|
51848
|
+
});
|
|
51849
|
+
}, [
|
|
51850
|
+
assetId,
|
|
51851
|
+
deckId,
|
|
51852
|
+
isComplete,
|
|
51853
|
+
outputText,
|
|
51854
|
+
resultData,
|
|
51855
|
+
status,
|
|
51856
|
+
targetSlideNumber,
|
|
51857
|
+
typedArgs
|
|
51858
|
+
]);
|
|
51859
|
+
const openPresentation = useCallback(() => {
|
|
51860
|
+
if (!assetId) {
|
|
51861
|
+
return;
|
|
51502
51862
|
}
|
|
51503
|
-
|
|
51863
|
+
logDebugPayload("[Athena SDK execute_presentation_code] open deck", {
|
|
51864
|
+
args: typedArgs,
|
|
51865
|
+
parsedResult: resultData,
|
|
51866
|
+
assetId,
|
|
51867
|
+
deckId,
|
|
51868
|
+
targetSlideNumber
|
|
51869
|
+
});
|
|
51870
|
+
openAsset(assetId, {
|
|
51871
|
+
type: "presentation",
|
|
51872
|
+
...targetSlideNumber !== void 0 ? { slideNumber: targetSlideNumber } : {}
|
|
51873
|
+
});
|
|
51874
|
+
}, [assetId, deckId, openAsset, resultData, targetSlideNumber, typedArgs]);
|
|
51504
51875
|
return /* @__PURE__ */ jsxs(
|
|
51505
51876
|
ToolCard,
|
|
51506
51877
|
{
|
|
@@ -51523,11 +51894,11 @@ const ExecutePresentationCodeToolUIImpl = ({
|
|
|
51523
51894
|
"button",
|
|
51524
51895
|
{
|
|
51525
51896
|
type: "button",
|
|
51526
|
-
onClick:
|
|
51897
|
+
onClick: openPresentation,
|
|
51527
51898
|
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",
|
|
51528
51899
|
children: [
|
|
51529
51900
|
/* @__PURE__ */ jsx(ExternalLink, { className: "size-3" }),
|
|
51530
|
-
"Open deck"
|
|
51901
|
+
targetSlideNumber ? `Open slide ${targetSlideNumber}` : "Open deck"
|
|
51531
51902
|
]
|
|
51532
51903
|
}
|
|
51533
51904
|
)
|
|
@@ -51586,15 +51957,6 @@ const OpenAssetToolUIImpl = ({
|
|
|
51586
51957
|
const isCancelled = (status == null ? void 0 : status.type) === "incomplete" && status.reason === "cancelled";
|
|
51587
51958
|
const errorMsg = (status == null ? void 0 : status.type) === "incomplete" ? status.error : null;
|
|
51588
51959
|
const openAsset = useAssetPanelStore((s) => s.openAsset);
|
|
51589
|
-
const wasCompleteAtMount = useRef(isComplete);
|
|
51590
|
-
useEffect(() => {
|
|
51591
|
-
if (isComplete && !isCancelled && assetId && !wasCompleteAtMount.current) {
|
|
51592
|
-
const store = useAssetPanelStore.getState();
|
|
51593
|
-
if (store.markAutoOpened(assetId)) {
|
|
51594
|
-
store.openAsset(assetId);
|
|
51595
|
-
}
|
|
51596
|
-
}
|
|
51597
|
-
}, [isComplete, isCancelled, assetId]);
|
|
51598
51960
|
return /* @__PURE__ */ jsx(
|
|
51599
51961
|
ToolCard,
|
|
51600
51962
|
{
|
|
@@ -52333,18 +52695,6 @@ const CaptureMomentToolUIImpl = ({
|
|
|
52333
52695
|
const isComplete = (status == null ? void 0 : status.type) === "complete" || !status;
|
|
52334
52696
|
const isCancelled = (status == null ? void 0 : status.type) === "incomplete" && status.reason === "cancelled";
|
|
52335
52697
|
const openAsset = useAssetPanelStore((s) => s.openAsset);
|
|
52336
|
-
const wasCompleteAtMount = useRef(isComplete);
|
|
52337
|
-
useEffect(() => {
|
|
52338
|
-
if (isComplete && !isCancelled && createdAssetId && !wasCompleteAtMount.current) {
|
|
52339
|
-
const store = useAssetPanelStore.getState();
|
|
52340
|
-
if (store.markAutoOpened(createdAssetId)) {
|
|
52341
|
-
store.openAsset(createdAssetId, {
|
|
52342
|
-
name: void 0,
|
|
52343
|
-
type: "unknown"
|
|
52344
|
-
});
|
|
52345
|
-
}
|
|
52346
|
-
}
|
|
52347
|
-
}, [isComplete, isCancelled, createdAssetId, resultType]);
|
|
52348
52698
|
const handleOpen = () => {
|
|
52349
52699
|
if (createdAssetId) {
|
|
52350
52700
|
openAsset(createdAssetId, {
|
|
@@ -52404,6 +52754,153 @@ const CaptureMomentToolUI = memo(
|
|
|
52404
52754
|
CaptureMomentToolUIImpl
|
|
52405
52755
|
);
|
|
52406
52756
|
CaptureMomentToolUI.displayName = "CaptureMomentToolUI";
|
|
52757
|
+
function normalizeContentResult(result) {
|
|
52758
|
+
if (Array.isArray(result)) {
|
|
52759
|
+
return result;
|
|
52760
|
+
}
|
|
52761
|
+
if (typeof result === "string") {
|
|
52762
|
+
try {
|
|
52763
|
+
const parsed = JSON.parse(result);
|
|
52764
|
+
return normalizeContentResult(parsed);
|
|
52765
|
+
} catch {
|
|
52766
|
+
return [];
|
|
52767
|
+
}
|
|
52768
|
+
}
|
|
52769
|
+
if (result && typeof result === "object") {
|
|
52770
|
+
const obj = result;
|
|
52771
|
+
if (Array.isArray(obj.result)) {
|
|
52772
|
+
return obj.result;
|
|
52773
|
+
}
|
|
52774
|
+
if (typeof obj.result === "string") {
|
|
52775
|
+
return normalizeContentResult(obj.result);
|
|
52776
|
+
}
|
|
52777
|
+
if (Array.isArray(obj.content)) {
|
|
52778
|
+
return obj.content;
|
|
52779
|
+
}
|
|
52780
|
+
}
|
|
52781
|
+
return [];
|
|
52782
|
+
}
|
|
52783
|
+
function getSlideScreenshotResult(result) {
|
|
52784
|
+
let text2 = null;
|
|
52785
|
+
let imageUrl = null;
|
|
52786
|
+
let mediaType = null;
|
|
52787
|
+
let s3Key = null;
|
|
52788
|
+
for (const item of normalizeContentResult(result)) {
|
|
52789
|
+
if (!item || typeof item !== "object") {
|
|
52790
|
+
continue;
|
|
52791
|
+
}
|
|
52792
|
+
const part = item;
|
|
52793
|
+
if (!text2 && part.type === "text" && typeof part.text === "string") {
|
|
52794
|
+
text2 = part.text;
|
|
52795
|
+
continue;
|
|
52796
|
+
}
|
|
52797
|
+
if (part.type !== "image") {
|
|
52798
|
+
continue;
|
|
52799
|
+
}
|
|
52800
|
+
const source = part.source && typeof part.source === "object" ? part.source : {};
|
|
52801
|
+
if (!imageUrl) {
|
|
52802
|
+
imageUrl = getStringField(source, ["presigned_url", "url"]) ?? getStringField(part, ["url", "image_url"]);
|
|
52803
|
+
}
|
|
52804
|
+
if (!mediaType) {
|
|
52805
|
+
mediaType = getStringField(source, ["media_type", "mime_type"]) ?? getStringField(part, ["media_type", "mime_type"]);
|
|
52806
|
+
}
|
|
52807
|
+
if (!s3Key) {
|
|
52808
|
+
s3Key = getStringField(source, ["data", "s3_key"]);
|
|
52809
|
+
}
|
|
52810
|
+
}
|
|
52811
|
+
return { text: text2, imageUrl, mediaType, s3Key };
|
|
52812
|
+
}
|
|
52813
|
+
const CaptureSlideScreenshotToolUIImpl = ({
|
|
52814
|
+
toolName,
|
|
52815
|
+
args,
|
|
52816
|
+
result,
|
|
52817
|
+
status
|
|
52818
|
+
}) => {
|
|
52819
|
+
const typedArgs = args;
|
|
52820
|
+
const assetId = getStringField(typedArgs, ["asset_id", "assetId"]);
|
|
52821
|
+
const slideNumber = getNumberField(typedArgs, ["slide_number", "slideNumber"]) ?? void 0;
|
|
52822
|
+
const { text: text2, imageUrl, mediaType } = useMemo(
|
|
52823
|
+
() => getSlideScreenshotResult(result),
|
|
52824
|
+
[result]
|
|
52825
|
+
);
|
|
52826
|
+
const isRunning = (status == null ? void 0 : status.type) === "running";
|
|
52827
|
+
const isComplete = (status == null ? void 0 : status.type) === "complete" || !status;
|
|
52828
|
+
const isCancelled = (status == null ? void 0 : status.type) === "incomplete" && status.reason === "cancelled";
|
|
52829
|
+
const errorMsg = (status == null ? void 0 : status.type) === "incomplete" ? String(status.error ?? status.reason ?? "Capture failed") : null;
|
|
52830
|
+
const openAsset = useAssetPanelStore((s) => s.openAsset);
|
|
52831
|
+
const handleOpenSlide = useCallback(() => {
|
|
52832
|
+
if (!assetId) {
|
|
52833
|
+
return;
|
|
52834
|
+
}
|
|
52835
|
+
openAsset(assetId, {
|
|
52836
|
+
type: "presentation",
|
|
52837
|
+
...slideNumber ? { slideNumber } : {}
|
|
52838
|
+
});
|
|
52839
|
+
}, [assetId, openAsset, slideNumber]);
|
|
52840
|
+
const subtitle = [
|
|
52841
|
+
slideNumber ? `Slide ${slideNumber}` : null,
|
|
52842
|
+
assetId ? truncate(assetId, 34) : null
|
|
52843
|
+
].filter((value) => Boolean(value)).join(" · ");
|
|
52844
|
+
return /* @__PURE__ */ jsxs(
|
|
52845
|
+
ToolCard,
|
|
52846
|
+
{
|
|
52847
|
+
icon: Camera,
|
|
52848
|
+
status: (status == null ? void 0 : status.type) ?? "complete",
|
|
52849
|
+
title: isRunning ? "Capturing slide screenshot..." : errorMsg ? "Slide screenshot failed" : "Slide screenshot captured",
|
|
52850
|
+
subtitle: subtitle || void 0,
|
|
52851
|
+
badge: slideNumber ? `Slide ${slideNumber}` : mediaType ?? void 0,
|
|
52852
|
+
toolName,
|
|
52853
|
+
args: typedArgs,
|
|
52854
|
+
result,
|
|
52855
|
+
error: errorMsg,
|
|
52856
|
+
children: [
|
|
52857
|
+
isComplete && !isCancelled && imageUrl && /* @__PURE__ */ jsxs("div", { className: "border-t border-border/40 p-3", children: [
|
|
52858
|
+
/* @__PURE__ */ jsx("div", { className: "overflow-hidden rounded-lg border border-border/50 bg-muted/20", children: /* @__PURE__ */ jsx(
|
|
52859
|
+
"img",
|
|
52860
|
+
{
|
|
52861
|
+
src: imageUrl,
|
|
52862
|
+
alt: slideNumber ? `Slide ${slideNumber} screenshot` : "Slide screenshot",
|
|
52863
|
+
className: "aspect-video w-full object-contain",
|
|
52864
|
+
loading: "lazy"
|
|
52865
|
+
}
|
|
52866
|
+
) }),
|
|
52867
|
+
text2 && /* @__PURE__ */ jsx("p", { className: "mt-2 text-[11px] leading-relaxed text-muted-foreground", children: truncate(text2, 160) })
|
|
52868
|
+
] }),
|
|
52869
|
+
isComplete && !isCancelled && assetId && /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap gap-2 border-t border-border/40 px-4 py-2", children: [
|
|
52870
|
+
/* @__PURE__ */ jsxs(
|
|
52871
|
+
"button",
|
|
52872
|
+
{
|
|
52873
|
+
type: "button",
|
|
52874
|
+
onClick: handleOpenSlide,
|
|
52875
|
+
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",
|
|
52876
|
+
children: [
|
|
52877
|
+
/* @__PURE__ */ jsx(ExternalLink, { className: "size-3" }),
|
|
52878
|
+
slideNumber ? `Open slide ${slideNumber}` : "Open presentation"
|
|
52879
|
+
]
|
|
52880
|
+
}
|
|
52881
|
+
),
|
|
52882
|
+
imageUrl && /* @__PURE__ */ jsxs(
|
|
52883
|
+
"a",
|
|
52884
|
+
{
|
|
52885
|
+
href: imageUrl,
|
|
52886
|
+
target: "_blank",
|
|
52887
|
+
rel: "noreferrer",
|
|
52888
|
+
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",
|
|
52889
|
+
children: [
|
|
52890
|
+
/* @__PURE__ */ jsx(Image, { className: "size-3" }),
|
|
52891
|
+
"Open image"
|
|
52892
|
+
]
|
|
52893
|
+
}
|
|
52894
|
+
)
|
|
52895
|
+
] })
|
|
52896
|
+
]
|
|
52897
|
+
}
|
|
52898
|
+
);
|
|
52899
|
+
};
|
|
52900
|
+
const CaptureSlideScreenshotToolUI = memo(
|
|
52901
|
+
CaptureSlideScreenshotToolUIImpl
|
|
52902
|
+
);
|
|
52903
|
+
CaptureSlideScreenshotToolUI.displayName = "CaptureSlideScreenshotToolUI";
|
|
52407
52904
|
const TOOL_UI_REGISTRY = {
|
|
52408
52905
|
search: WebSearchToolUI,
|
|
52409
52906
|
browse: BrowseToolUI,
|
|
@@ -52416,11 +52913,22 @@ const TOOL_UI_REGISTRY = {
|
|
|
52416
52913
|
create_new_sheet: CreateSheetToolUI,
|
|
52417
52914
|
create_powerpoint_deck: CreatePresentationToolUI,
|
|
52418
52915
|
create_new_notebook: CreateNotebookToolUI,
|
|
52916
|
+
// Studio SDK nested PTC tools
|
|
52917
|
+
CreateWorkbook: StudioCreateWorkbookToolUI,
|
|
52918
|
+
AddSheet: StudioAddSheetToolUI,
|
|
52919
|
+
OpenWorkbook: StudioOpenWorkbookToolUI,
|
|
52920
|
+
CreatePresentation: StudioCreatePresentationToolUI,
|
|
52921
|
+
OpenPresentation: StudioOpenPresentationToolUI,
|
|
52922
|
+
AddSlide: StudioAddSlideToolUI,
|
|
52923
|
+
CreateDocument: StudioCreateDocumentToolUI,
|
|
52924
|
+
OpenDocument: StudioOpenDocumentToolUI,
|
|
52925
|
+
CreateParagraph: StudioCreateParagraphToolUI,
|
|
52419
52926
|
execute_presentation_code: ExecutePresentationCodeToolUI,
|
|
52420
52927
|
run_python_code: RunPythonCodeToolUI,
|
|
52421
52928
|
open_asset_in_workspace: OpenAssetToolUI,
|
|
52422
52929
|
// Media capture
|
|
52423
52930
|
capture_moment: CaptureMomentToolUI,
|
|
52931
|
+
capture_slide_screenshot: CaptureSlideScreenshotToolUI,
|
|
52424
52932
|
// Spreadsheet toolkit
|
|
52425
52933
|
update_sheet_range: UpdateSheetRangeToolUI,
|
|
52426
52934
|
// Database toolkit
|
|
@@ -53530,10 +54038,37 @@ const AthenaUserMessage = ({
|
|
|
53530
54038
|
}
|
|
53531
54039
|
);
|
|
53532
54040
|
const embedCache = /* @__PURE__ */ new Map();
|
|
54041
|
+
function resolveAssetEmbedUrl({
|
|
54042
|
+
embedUrl,
|
|
54043
|
+
appUrl
|
|
54044
|
+
}) {
|
|
54045
|
+
if (!appUrl) {
|
|
54046
|
+
return embedUrl;
|
|
54047
|
+
}
|
|
54048
|
+
try {
|
|
54049
|
+
const resolvedEmbedUrl = new URL(embedUrl);
|
|
54050
|
+
const resolvedAppUrl = new URL(appUrl);
|
|
54051
|
+
if (!resolvedEmbedUrl.pathname.startsWith("/embed/")) {
|
|
54052
|
+
return embedUrl;
|
|
54053
|
+
}
|
|
54054
|
+
resolvedEmbedUrl.protocol = resolvedAppUrl.protocol;
|
|
54055
|
+
resolvedEmbedUrl.host = resolvedAppUrl.host;
|
|
54056
|
+
return resolvedEmbedUrl.toString();
|
|
54057
|
+
} catch {
|
|
54058
|
+
return embedUrl;
|
|
54059
|
+
}
|
|
54060
|
+
}
|
|
53533
54061
|
function useAssetEmbed(assetId, options = {
|
|
53534
54062
|
backendUrl: ""
|
|
53535
54063
|
}) {
|
|
53536
|
-
const {
|
|
54064
|
+
const {
|
|
54065
|
+
readOnly = false,
|
|
54066
|
+
expiresInSeconds = 60 * 60 * 24 * 30,
|
|
54067
|
+
backendUrl,
|
|
54068
|
+
appUrl,
|
|
54069
|
+
apiKey,
|
|
54070
|
+
token
|
|
54071
|
+
} = options;
|
|
53537
54072
|
const [embedUrl, setEmbedUrl] = useState(null);
|
|
53538
54073
|
const [isLoading, setIsLoading] = useState(false);
|
|
53539
54074
|
const [error2, setError] = useState(null);
|
|
@@ -53550,7 +54085,7 @@ function useAssetEmbed(assetId, options = {
|
|
|
53550
54085
|
return;
|
|
53551
54086
|
}
|
|
53552
54087
|
const authContext = hasToken ? "token" : apiKey ?? "anon";
|
|
53553
|
-
const cacheKey = `${assetId}:${readOnly}:${authContext}`;
|
|
54088
|
+
const cacheKey = `${assetId}:${readOnly}:${authContext}:${appUrl ?? ""}`;
|
|
53554
54089
|
const cached2 = embedCache.get(cacheKey);
|
|
53555
54090
|
if (cached2 && cached2.expiresAt > Date.now() / 1e3) {
|
|
53556
54091
|
setEmbedUrl(cached2.url);
|
|
@@ -53588,8 +54123,12 @@ function useAssetEmbed(assetId, options = {
|
|
|
53588
54123
|
}
|
|
53589
54124
|
return res.json();
|
|
53590
54125
|
}).then((data) => {
|
|
53591
|
-
|
|
53592
|
-
|
|
54126
|
+
const resolvedEmbedUrl = resolveAssetEmbedUrl({
|
|
54127
|
+
embedUrl: data.embed_url,
|
|
54128
|
+
appUrl
|
|
54129
|
+
});
|
|
54130
|
+
embedCache.set(cacheKey, { url: resolvedEmbedUrl, expiresAt: data.expires_at });
|
|
54131
|
+
setEmbedUrl(resolvedEmbedUrl);
|
|
53593
54132
|
setIsLoading(false);
|
|
53594
54133
|
}).catch((err) => {
|
|
53595
54134
|
if (err.name === "AbortError") return;
|
|
@@ -53597,9 +54136,44 @@ function useAssetEmbed(assetId, options = {
|
|
|
53597
54136
|
setIsLoading(false);
|
|
53598
54137
|
});
|
|
53599
54138
|
return () => controller.abort();
|
|
53600
|
-
}, [assetId, readOnly, expiresInSeconds, backendUrl, apiKey, hasToken]);
|
|
54139
|
+
}, [assetId, readOnly, expiresInSeconds, backendUrl, appUrl, apiKey, hasToken]);
|
|
53601
54140
|
return { embedUrl, isLoading, error: error2 };
|
|
53602
54141
|
}
|
|
54142
|
+
const ABSOLUTE_URL_PATTERN = /^[a-zA-Z][a-zA-Z\d+\-.]*:/;
|
|
54143
|
+
function buildAssetIframeSrc({
|
|
54144
|
+
embedUrl,
|
|
54145
|
+
assetType,
|
|
54146
|
+
slideNumber
|
|
54147
|
+
}) {
|
|
54148
|
+
const targetSlide = slideNumber;
|
|
54149
|
+
if (assetType !== "presentation" || typeof targetSlide !== "number" || !Number.isInteger(targetSlide) || targetSlide < 1) {
|
|
54150
|
+
return embedUrl;
|
|
54151
|
+
}
|
|
54152
|
+
try {
|
|
54153
|
+
const isAbsolute = ABSOLUTE_URL_PATTERN.test(embedUrl);
|
|
54154
|
+
const url = new URL(embedUrl, "https://athena.local");
|
|
54155
|
+
url.searchParams.set("slide", String(targetSlide));
|
|
54156
|
+
return isAbsolute ? url.toString() : `${url.pathname}${url.search}${url.hash}`;
|
|
54157
|
+
} catch {
|
|
54158
|
+
const separator = embedUrl.includes("?") ? "&" : "?";
|
|
54159
|
+
return `${embedUrl}${separator}slide=${targetSlide}`;
|
|
54160
|
+
}
|
|
54161
|
+
}
|
|
54162
|
+
function buildPresentationNavigationMessage({
|
|
54163
|
+
assetId,
|
|
54164
|
+
assetType,
|
|
54165
|
+
slideNumber
|
|
54166
|
+
}) {
|
|
54167
|
+
if (assetType !== "presentation" || typeof slideNumber !== "number" || !Number.isInteger(slideNumber) || slideNumber < 1) {
|
|
54168
|
+
return null;
|
|
54169
|
+
}
|
|
54170
|
+
return {
|
|
54171
|
+
type: "NAVIGATE_TO_SLIDE",
|
|
54172
|
+
assetId,
|
|
54173
|
+
deckId: assetId,
|
|
54174
|
+
slideNumber
|
|
54175
|
+
};
|
|
54176
|
+
}
|
|
53603
54177
|
const ASSET_TYPE_CONFIG = {
|
|
53604
54178
|
presentation: { icon: Presentation, label: "Presentation" },
|
|
53605
54179
|
spreadsheet: { icon: FileSpreadsheet, label: "Spreadsheet" },
|
|
@@ -53608,13 +54182,39 @@ const ASSET_TYPE_CONFIG = {
|
|
|
53608
54182
|
unknown: { icon: File$1, label: "Asset" }
|
|
53609
54183
|
};
|
|
53610
54184
|
const AssetIframe = memo(
|
|
53611
|
-
({
|
|
53612
|
-
const
|
|
53613
|
-
const {
|
|
54185
|
+
({ tab }) => {
|
|
54186
|
+
const iframeRef = useRef(null);
|
|
54187
|
+
const { backendUrl, appUrl, apiKey, token } = useAthenaConfig();
|
|
54188
|
+
const { embedUrl, isLoading, error: error2 } = useAssetEmbed(tab.id, {
|
|
53614
54189
|
backendUrl,
|
|
54190
|
+
appUrl,
|
|
53615
54191
|
apiKey,
|
|
53616
54192
|
token
|
|
53617
54193
|
});
|
|
54194
|
+
const iframeSrc = useMemo(
|
|
54195
|
+
() => embedUrl ? buildAssetIframeSrc({
|
|
54196
|
+
embedUrl,
|
|
54197
|
+
assetType: tab.type,
|
|
54198
|
+
slideNumber: tab.slideNumber
|
|
54199
|
+
}) : null,
|
|
54200
|
+
[embedUrl, tab.slideNumber, tab.type]
|
|
54201
|
+
);
|
|
54202
|
+
const navigationMessage = useMemo(
|
|
54203
|
+
() => buildPresentationNavigationMessage({
|
|
54204
|
+
assetId: tab.id,
|
|
54205
|
+
assetType: tab.type,
|
|
54206
|
+
slideNumber: tab.slideNumber
|
|
54207
|
+
}),
|
|
54208
|
+
[tab.id, tab.slideNumber, tab.type]
|
|
54209
|
+
);
|
|
54210
|
+
const postNavigationMessage = useCallback(() => {
|
|
54211
|
+
var _a2, _b;
|
|
54212
|
+
if (!navigationMessage) return;
|
|
54213
|
+
(_b = (_a2 = iframeRef.current) == null ? void 0 : _a2.contentWindow) == null ? void 0 : _b.postMessage(navigationMessage, "*");
|
|
54214
|
+
}, [navigationMessage]);
|
|
54215
|
+
useEffect(() => {
|
|
54216
|
+
postNavigationMessage();
|
|
54217
|
+
}, [postNavigationMessage]);
|
|
53618
54218
|
if (isLoading) {
|
|
53619
54219
|
return /* @__PURE__ */ jsx("div", { className: "flex h-full items-center justify-center", children: /* @__PURE__ */ jsxs("div", { className: "text-center", children: [
|
|
53620
54220
|
/* @__PURE__ */ jsx(LoaderCircle, { className: "mx-auto size-6 animate-spin text-muted-foreground" }),
|
|
@@ -53628,20 +54228,23 @@ const AssetIframe = memo(
|
|
|
53628
54228
|
/* @__PURE__ */ jsx("p", { className: "mt-0.5 line-clamp-2 break-words text-[10px] text-muted-foreground", children: error2 })
|
|
53629
54229
|
] }) });
|
|
53630
54230
|
}
|
|
53631
|
-
if (!
|
|
54231
|
+
if (!iframeSrc) return null;
|
|
53632
54232
|
return /* @__PURE__ */ jsx(
|
|
53633
54233
|
"iframe",
|
|
53634
54234
|
{
|
|
53635
|
-
|
|
54235
|
+
ref: iframeRef,
|
|
54236
|
+
src: iframeSrc,
|
|
53636
54237
|
width: "100%",
|
|
53637
54238
|
height: "100%",
|
|
53638
54239
|
frameBorder: "0",
|
|
53639
54240
|
allow: "fullscreen",
|
|
53640
|
-
title:
|
|
53641
|
-
className: "h-full w-full"
|
|
54241
|
+
title: tab.name ?? `Asset ${tab.id}`,
|
|
54242
|
+
className: "h-full w-full",
|
|
54243
|
+
onLoad: postNavigationMessage
|
|
53642
54244
|
}
|
|
53643
54245
|
);
|
|
53644
|
-
}
|
|
54246
|
+
},
|
|
54247
|
+
(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
|
|
53645
54248
|
);
|
|
53646
54249
|
AssetIframe.displayName = "AssetIframe";
|
|
53647
54250
|
const PanelContent = ({
|
|
@@ -53699,7 +54302,7 @@ const PanelContent = ({
|
|
|
53699
54302
|
}
|
|
53700
54303
|
)
|
|
53701
54304
|
] }),
|
|
53702
|
-
/* @__PURE__ */ jsx("div", { className: "flex-1 overflow-hidden", children: /* @__PURE__ */ jsx(AssetIframe, {
|
|
54305
|
+
/* @__PURE__ */ jsx("div", { className: "flex-1 overflow-hidden", children: /* @__PURE__ */ jsx(AssetIframe, { tab }) })
|
|
53703
54306
|
]
|
|
53704
54307
|
},
|
|
53705
54308
|
tab.id
|
|
@@ -53709,7 +54312,7 @@ const PanelContent = ({
|
|
|
53709
54312
|
"div",
|
|
53710
54313
|
{
|
|
53711
54314
|
className: isActive2 ? "h-full w-full" : "hidden",
|
|
53712
|
-
children: /* @__PURE__ */ jsx(AssetIframe, {
|
|
54315
|
+
children: /* @__PURE__ */ jsx(AssetIframe, { tab })
|
|
53713
54316
|
},
|
|
53714
54317
|
tab.id
|
|
53715
54318
|
);
|