@markus-global/cli 0.9.7-rc.0 → 0.9.7-rc.1
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/markus.mjs +223 -14
- package/dist/web-ui/assets/{CommentInput-Dvlq2svZ.js → CommentInput-CIxUL6dU.js} +1 -1
- package/dist/web-ui/assets/{ContentRenderer-BfnvpFM7.js → ContentRenderer-Bb_drUpO.js} +2 -2
- package/dist/web-ui/assets/{DeliverableShareModal-DkGpQmZ8.js → DeliverableShareModal-BEeIlXig.js} +1 -1
- package/dist/web-ui/assets/{Deliverables-CtPvquKO.js → Deliverables-CJFzxbLw.js} +1 -1
- package/dist/web-ui/assets/{Notifications-C_e9_V74.js → Notifications-Cz2LKhGE.js} +1 -1
- package/dist/web-ui/assets/{Search-DZBGpN3c.js → Search-dq45wHQN.js} +1 -1
- package/dist/web-ui/assets/Settings-WAXEtxMR.js +8 -0
- package/dist/web-ui/assets/{Store-dbJSFCFw.js → Store-DOGCOxTK.js} +1 -1
- package/dist/web-ui/assets/{Team-vmqHkmh8.js → Team-NM2SsmjN.js} +4 -4
- package/dist/web-ui/assets/{Work-Ds7q6pZg.js → Work-ornw-1Zh.js} +1 -1
- package/dist/web-ui/assets/{arc-BLoofCdL.js → arc-D4xcu8MX.js} +1 -1
- package/dist/web-ui/assets/{architectureDiagram-3BPJPVTR-BGO4nFRN.js → architectureDiagram-3BPJPVTR-DP3EZPSb.js} +1 -1
- package/dist/web-ui/assets/{blockDiagram-GPEHLZMM-Cn1E0037.js → blockDiagram-GPEHLZMM-BnSHtwXa.js} +1 -1
- package/dist/web-ui/assets/{c4Diagram-AAUBKEIU-DXFAnq3E.js → c4Diagram-AAUBKEIU-DpPSihlY.js} +1 -1
- package/dist/web-ui/assets/channel-DSB2MBEK.js +1 -0
- package/dist/web-ui/assets/{chunk-2J33WTMH-BXCSmrWD.js → chunk-2J33WTMH-DD5lZIGF.js} +1 -1
- package/dist/web-ui/assets/{chunk-4BX2VUAB-CIWJeena.js → chunk-4BX2VUAB-D9wu9GG0.js} +1 -1
- package/dist/web-ui/assets/{chunk-55IACEB6-BuQ5-tdz.js → chunk-55IACEB6-p_n2ARjh.js} +1 -1
- package/dist/web-ui/assets/{chunk-727SXJPM-q9Yx_12l.js → chunk-727SXJPM-BiTqi43c.js} +1 -1
- package/dist/web-ui/assets/{chunk-AQP2D5EJ-DqaehwKB.js → chunk-AQP2D5EJ-DVPMedje.js} +1 -1
- package/dist/web-ui/assets/{chunk-FMBD7UC4-BFs2IYjK.js → chunk-FMBD7UC4-B53AqN8D.js} +1 -1
- package/dist/web-ui/assets/{chunk-ND2GUHAM-DyYGWpbj.js → chunk-ND2GUHAM-sACe_lkd.js} +1 -1
- package/dist/web-ui/assets/{chunk-QZHKN3VN-DmbA4AU_.js → chunk-QZHKN3VN-B0qDAQUW.js} +1 -1
- package/dist/web-ui/assets/classDiagram-4FO5ZUOK-D5cDjaiz.js +1 -0
- package/dist/web-ui/assets/classDiagram-v2-Q7XG4LA2-D5cDjaiz.js +1 -0
- package/dist/web-ui/assets/{cose-bilkent-S5V4N54A-BLWm27gv.js → cose-bilkent-S5V4N54A-BzZayQQf.js} +1 -1
- package/dist/web-ui/assets/{dagre-BM42HDAG-Cb2YgHjF.js → dagre-BM42HDAG-DjcfWzm_.js} +1 -1
- package/dist/web-ui/assets/{diagram-2AECGRRQ-hMyyF4SK.js → diagram-2AECGRRQ-CEK9T3rW.js} +1 -1
- package/dist/web-ui/assets/{diagram-5GNKFQAL-DQvYRI_z.js → diagram-5GNKFQAL-BJsJPwEI.js} +1 -1
- package/dist/web-ui/assets/{diagram-KO2AKTUF-CPOv2Kga.js → diagram-KO2AKTUF-BZlki2qo.js} +1 -1
- package/dist/web-ui/assets/{diagram-LMA3HP47-DvgOU39M.js → diagram-LMA3HP47-Bkmh3WcY.js} +1 -1
- package/dist/web-ui/assets/{diagram-OG6HWLK6-DhLJ9Bog.js → diagram-OG6HWLK6-4THSXHiA.js} +1 -1
- package/dist/web-ui/assets/{erDiagram-TEJ5UH35-C4MKvJYc.js → erDiagram-TEJ5UH35-CPj2HGe-.js} +1 -1
- package/dist/web-ui/assets/{flowDiagram-I6XJVG4X-C4KiUPBX.js → flowDiagram-I6XJVG4X-Bu8HgFqR.js} +1 -1
- package/dist/web-ui/assets/{ganttDiagram-6RSMTGT7-CFiAe8nx.js → ganttDiagram-6RSMTGT7-C5gs9b9P.js} +1 -1
- package/dist/web-ui/assets/{gitGraphDiagram-PVQCEYII-y6rZo1sT.js → gitGraphDiagram-PVQCEYII-DxnBgR_T.js} +1 -1
- package/dist/web-ui/assets/{index-CcppNtga.js → index-CiAGgfZx.js} +6 -6
- package/dist/web-ui/assets/{infoDiagram-5YYISTIA-LLlnmiVb.js → infoDiagram-5YYISTIA-D4M-cR8I.js} +1 -1
- package/dist/web-ui/assets/{ishikawaDiagram-YF4QCWOH-Brs-NT84.js → ishikawaDiagram-YF4QCWOH-Oiq6jknk.js} +1 -1
- package/dist/web-ui/assets/{journeyDiagram-JHISSGLW-um06-20P.js → journeyDiagram-JHISSGLW-D2gmyCKv.js} +1 -1
- package/dist/web-ui/assets/{kanban-definition-UN3LZRKU-yws0Rgw8.js → kanban-definition-UN3LZRKU-DqjzkO8l.js} +1 -1
- package/dist/web-ui/assets/{mermaid.core-C0Q8mcc_.js → mermaid.core-N5tL3hIv.js} +5 -5
- package/dist/web-ui/assets/{mindmap-definition-RKZ34NQL-xCtHajk4.js → mindmap-definition-RKZ34NQL-ATHsVy0v.js} +1 -1
- package/dist/web-ui/assets/{pieDiagram-4H26LBE5-BhKiwY7r.js → pieDiagram-4H26LBE5-CprLr2Gv.js} +1 -1
- package/dist/web-ui/assets/{quadrantDiagram-W4KKPZXB-CGmxw13s.js → quadrantDiagram-W4KKPZXB-0uN86dlU.js} +1 -1
- package/dist/web-ui/assets/{requirementDiagram-4Y6WPE33-CYJRHrZE.js → requirementDiagram-4Y6WPE33-CQmWbZXW.js} +1 -1
- package/dist/web-ui/assets/{sankeyDiagram-5OEKKPKP-CgkdSCTc.js → sankeyDiagram-5OEKKPKP-D6kdJsQI.js} +1 -1
- package/dist/web-ui/assets/{sequenceDiagram-3UESZ5HK-BD2dXCDe.js → sequenceDiagram-3UESZ5HK-1Y79snKt.js} +1 -1
- package/dist/web-ui/assets/{stateDiagram-AJRCARHV-DdEvCrm2.js → stateDiagram-AJRCARHV-BqmCPSIN.js} +1 -1
- package/dist/web-ui/assets/stateDiagram-v2-BHNVJYJU-DRaoGsBn.js +1 -0
- package/dist/web-ui/assets/{timeline-definition-PNZ67QCA-CWfdKPN1.js → timeline-definition-PNZ67QCA-OG71KAzb.js} +1 -1
- package/dist/web-ui/assets/{vennDiagram-CIIHVFJN-BTiDdRt6.js → vennDiagram-CIIHVFJN-V9c-71bn.js} +1 -1
- package/dist/web-ui/assets/{wardley-L42UT6IY-eDkltTBC.js → wardley-L42UT6IY-C3A6_LpL.js} +1 -1
- package/dist/web-ui/assets/{wardleyDiagram-YWT4CUSO-DLOZOKTX.js → wardleyDiagram-YWT4CUSO-B54ZiT7U.js} +1 -1
- package/dist/web-ui/assets/{xychartDiagram-2RQKCTM6-RU8GlPu6.js → xychartDiagram-2RQKCTM6-DpWlpUfV.js} +1 -1
- package/dist/web-ui/index.html +1 -1
- package/package.json +1 -1
- package/dist/web-ui/assets/Settings-6xm2sHhm.js +0 -8
- package/dist/web-ui/assets/channel-Cw25sYRm.js +0 -1
- package/dist/web-ui/assets/classDiagram-4FO5ZUOK-CDWjvgnK.js +0 -1
- package/dist/web-ui/assets/classDiagram-v2-Q7XG4LA2-CDWjvgnK.js +0 -1
- package/dist/web-ui/assets/stateDiagram-v2-BHNVJYJU-DKPteYMC.js +0 -1
package/dist/markus.mjs
CHANGED
|
@@ -72159,7 +72159,7 @@ var init_ollama = __esm({
|
|
|
72159
72159
|
async chat(request) {
|
|
72160
72160
|
const messages2 = this.convertMessages(request.messages);
|
|
72161
72161
|
const body = {
|
|
72162
|
-
model: this.model,
|
|
72162
|
+
model: request.model ?? this.model,
|
|
72163
72163
|
messages: messages2,
|
|
72164
72164
|
stream: false,
|
|
72165
72165
|
options: {
|
|
@@ -72194,7 +72194,7 @@ var init_ollama = __esm({
|
|
|
72194
72194
|
async chatStream(request, onEvent, signal) {
|
|
72195
72195
|
const messages2 = this.convertMessages(request.messages);
|
|
72196
72196
|
const body = {
|
|
72197
|
-
model: this.model,
|
|
72197
|
+
model: request.model ?? this.model,
|
|
72198
72198
|
messages: messages2,
|
|
72199
72199
|
stream: true,
|
|
72200
72200
|
options: {
|
|
@@ -75095,12 +75095,13 @@ function costTierFromPrice(inputPer1M) {
|
|
|
75095
75095
|
return "$$$";
|
|
75096
75096
|
return "$$$$";
|
|
75097
75097
|
}
|
|
75098
|
-
var log57, CAPABILITY_KEY_MAP, MINIMAX_NAMES, DASHSCOPE_NAMES, FIREWORKS_NAMES, REGIONAL_PROVIDER_ALIASES, ALL_COMPLEXITY, LLMRouter, PROVIDER_DISPLAY_NAMES, BUILTIN_MODEL_CATALOG;
|
|
75098
|
+
var log57, OLLAMA_DEFAULT_CONTEXT_WINDOW, OLLAMA_DEFAULT_MAX_OUTPUT, DEFAULT_CONTEXT_WINDOW_FALLBACK, DEFAULT_MAX_OUTPUT_FALLBACK, CAPABILITY_KEY_MAP, MINIMAX_NAMES, DASHSCOPE_NAMES, FIREWORKS_NAMES, REGIONAL_PROVIDER_ALIASES, ALL_COMPLEXITY, LLMRouter, PROVIDER_DISPLAY_NAMES, BUILTIN_MODEL_CATALOG;
|
|
75099
75099
|
var init_router2 = __esm({
|
|
75100
75100
|
"../core/dist/llm/router.js"() {
|
|
75101
75101
|
"use strict";
|
|
75102
75102
|
init_dist();
|
|
75103
75103
|
init_tracing();
|
|
75104
|
+
init_provider();
|
|
75104
75105
|
init_anthropic();
|
|
75105
75106
|
init_openai();
|
|
75106
75107
|
init_minimax();
|
|
@@ -75115,6 +75116,10 @@ var init_router2 = __esm({
|
|
|
75115
75116
|
init_auth_profiles();
|
|
75116
75117
|
init_oauth_manager();
|
|
75117
75118
|
log57 = createLogger("llm-router");
|
|
75119
|
+
OLLAMA_DEFAULT_CONTEXT_WINDOW = 8192;
|
|
75120
|
+
OLLAMA_DEFAULT_MAX_OUTPUT = 4096;
|
|
75121
|
+
DEFAULT_CONTEXT_WINDOW_FALLBACK = 128e3;
|
|
75122
|
+
DEFAULT_MAX_OUTPUT_FALLBACK = DEFAULT_REQUEST_MAX_TOKENS;
|
|
75118
75123
|
CAPABILITY_KEY_MAP = {
|
|
75119
75124
|
image_generation: "imageGeneration",
|
|
75120
75125
|
image_recognition: "vision",
|
|
@@ -75419,6 +75424,12 @@ var init_router2 = __esm({
|
|
|
75419
75424
|
return hubModels.map((m) => this.enrichModelFromCatalog(m));
|
|
75420
75425
|
}
|
|
75421
75426
|
}
|
|
75427
|
+
if (providerName === "ollama") {
|
|
75428
|
+
const localModels = this.customModelCatalog.get("ollama");
|
|
75429
|
+
if (localModels && localModels.length > 0) {
|
|
75430
|
+
return localModels.map((m) => this.enrichModelFromCatalog(m));
|
|
75431
|
+
}
|
|
75432
|
+
}
|
|
75422
75433
|
let builtinModels = BUILTIN_MODEL_CATALOG.filter((m) => m.provider === providerName);
|
|
75423
75434
|
if (builtinModels.length === 0 && REGIONAL_PROVIDER_ALIASES[providerName]) {
|
|
75424
75435
|
const parent = REGIONAL_PROVIDER_ALIASES[providerName];
|
|
@@ -75477,6 +75488,133 @@ var init_router2 = __esm({
|
|
|
75477
75488
|
}
|
|
75478
75489
|
return defs.length;
|
|
75479
75490
|
}
|
|
75491
|
+
/**
|
|
75492
|
+
* Probe a local Ollama server (/api/tags) and record the actually-pulled
|
|
75493
|
+
* models into the provider's custom catalog. This makes local models appear
|
|
75494
|
+
* in both the Settings panel and the chat model picker (which both read
|
|
75495
|
+
* getEnhancedSettings / getProviderModels). On success the local list
|
|
75496
|
+
* REPLACES the static catalog for Ollama (only real models are usable).
|
|
75497
|
+
* On failure we keep any previously-cached local models (last-good), so a
|
|
75498
|
+
* transient Ollama stop does not wipe the picker.
|
|
75499
|
+
*/
|
|
75500
|
+
async refreshOllamaLocalModels(baseUrl) {
|
|
75501
|
+
const provider = this.providers.get("ollama");
|
|
75502
|
+
const effectiveBase = baseUrl ?? provider?.baseUrl ?? process.env["OLLAMA_BASE_URL"] ?? "http://localhost:11434";
|
|
75503
|
+
const base = String(effectiveBase).replace(/\/+$/, "");
|
|
75504
|
+
try {
|
|
75505
|
+
const ctrl = new AbortController();
|
|
75506
|
+
const tmr = setTimeout(() => ctrl.abort(), 5e3);
|
|
75507
|
+
const res = await fetch(`${base}/api/tags`, {
|
|
75508
|
+
signal: ctrl.signal
|
|
75509
|
+
});
|
|
75510
|
+
clearTimeout(tmr);
|
|
75511
|
+
if (!res.ok) {
|
|
75512
|
+
log57.warn("Ollama /api/tags HTTP error", { baseUrl: base, status: res.status });
|
|
75513
|
+
return this.customModelCatalog.get("ollama")?.length ?? 0;
|
|
75514
|
+
}
|
|
75515
|
+
const data = await res.json();
|
|
75516
|
+
const models = await Promise.all((data.models ?? []).map(async (m) => {
|
|
75517
|
+
const d = m.details;
|
|
75518
|
+
const tag = d?.parameter_size || d?.quantization_level;
|
|
75519
|
+
const contextWindow = await this.probeOllamaContext(base, m.name);
|
|
75520
|
+
return {
|
|
75521
|
+
id: m.name,
|
|
75522
|
+
name: m.name,
|
|
75523
|
+
provider: "ollama",
|
|
75524
|
+
contextWindow,
|
|
75525
|
+
maxOutputTokens: OLLAMA_DEFAULT_MAX_OUTPUT,
|
|
75526
|
+
cost: { input: 0, output: 0 },
|
|
75527
|
+
inputTypes: ["text"],
|
|
75528
|
+
description: tag ? tag : void 0
|
|
75529
|
+
};
|
|
75530
|
+
}));
|
|
75531
|
+
this.customModelCatalog.set("ollama", models);
|
|
75532
|
+
log57.info(`Synced ${models.length} local Ollama models`, { baseUrl: base });
|
|
75533
|
+
return models.length;
|
|
75534
|
+
} catch (err) {
|
|
75535
|
+
log57.warn("Ollama local model sync failed", { error: String(err), baseUrl: base });
|
|
75536
|
+
return this.customModelCatalog.get("ollama")?.length ?? 0;
|
|
75537
|
+
}
|
|
75538
|
+
}
|
|
75539
|
+
/**
|
|
75540
|
+
* Probe a local Ollama model's real context length via `/api/show`.
|
|
75541
|
+
* Reads `model_info["*.context_length"]` (key name varies by model family,
|
|
75542
|
+
* e.g. `llama.context_length`, `qwen3_5.context_length`) and returns the
|
|
75543
|
+
* largest positive value found. Falls back to a sane default so a probe
|
|
75544
|
+
* failure never blocks agent budget planning.
|
|
75545
|
+
*/
|
|
75546
|
+
async probeOllamaContext(base, modelId) {
|
|
75547
|
+
try {
|
|
75548
|
+
const ctrl = new AbortController();
|
|
75549
|
+
const tmr = setTimeout(() => ctrl.abort(), 4e3);
|
|
75550
|
+
const res = await fetch(`${base}/api/show`, {
|
|
75551
|
+
method: "POST",
|
|
75552
|
+
headers: { "Content-Type": "application/json" },
|
|
75553
|
+
body: JSON.stringify({ model: modelId }),
|
|
75554
|
+
signal: ctrl.signal
|
|
75555
|
+
});
|
|
75556
|
+
clearTimeout(tmr);
|
|
75557
|
+
if (!res.ok)
|
|
75558
|
+
return OLLAMA_DEFAULT_CONTEXT_WINDOW;
|
|
75559
|
+
const data = await res.json();
|
|
75560
|
+
const vals = Object.entries(data.model_info ?? {}).filter(([k]) => k.toLowerCase().includes("context_length")).map(([, v]) => Number(v)).filter((n2) => Number.isFinite(n2) && n2 > 0);
|
|
75561
|
+
const ctx = vals.length ? Math.max(...vals) : 0;
|
|
75562
|
+
if (ctx <= 0)
|
|
75563
|
+
return OLLAMA_DEFAULT_CONTEXT_WINDOW;
|
|
75564
|
+
log57.info(`Ollama local model ${modelId}: context_window=${ctx}`);
|
|
75565
|
+
return ctx;
|
|
75566
|
+
} catch {
|
|
75567
|
+
return OLLAMA_DEFAULT_CONTEXT_WINDOW;
|
|
75568
|
+
}
|
|
75569
|
+
}
|
|
75570
|
+
/**
|
|
75571
|
+
* Pull a live /v1/models list for an OpenAI-compatible provider into its
|
|
75572
|
+
* custom catalog. Used for newly-added providers that have no builtin entry
|
|
75573
|
+
* (and therefore would otherwise show zero models in pickers). If the
|
|
75574
|
+
* provider already has a usable catalog (builtin/custom) we skip the call.
|
|
75575
|
+
*/
|
|
75576
|
+
async refreshProviderLiveModels(providerName, baseUrl, apiKey) {
|
|
75577
|
+
if (this.getProviderModels(providerName).length > 0)
|
|
75578
|
+
return 0;
|
|
75579
|
+
const provider = this.providers.get(providerName);
|
|
75580
|
+
const effectiveBase = baseUrl ?? provider?.baseUrl;
|
|
75581
|
+
if (!effectiveBase)
|
|
75582
|
+
return 0;
|
|
75583
|
+
const effectiveKey = apiKey ?? provider?.apiKey;
|
|
75584
|
+
try {
|
|
75585
|
+
const headers = {};
|
|
75586
|
+
if (effectiveKey)
|
|
75587
|
+
headers["Authorization"] = `Bearer ${effectiveKey}`;
|
|
75588
|
+
const ctrl = new AbortController();
|
|
75589
|
+
const tmr = setTimeout(() => ctrl.abort(), 8e3);
|
|
75590
|
+
const res = await fetch(`${String(effectiveBase).replace(/\/+$/, "")}/v1/models`, {
|
|
75591
|
+
headers,
|
|
75592
|
+
signal: ctrl.signal
|
|
75593
|
+
});
|
|
75594
|
+
clearTimeout(tmr);
|
|
75595
|
+
if (!res.ok)
|
|
75596
|
+
return 0;
|
|
75597
|
+
const data = await res.json();
|
|
75598
|
+
const ids = (data.data ?? []).map((m) => m.id).filter((x) => !!x);
|
|
75599
|
+
if (ids.length === 0)
|
|
75600
|
+
return 0;
|
|
75601
|
+
const defs = ids.map((id) => ({
|
|
75602
|
+
id,
|
|
75603
|
+
name: id,
|
|
75604
|
+
provider: providerName,
|
|
75605
|
+
contextWindow: 0,
|
|
75606
|
+
maxOutputTokens: 0,
|
|
75607
|
+
cost: { input: 0, output: 0 },
|
|
75608
|
+
inputTypes: ["text"]
|
|
75609
|
+
}));
|
|
75610
|
+
this.customModelCatalog.set(providerName, defs);
|
|
75611
|
+
log57.info(`Synced ${defs.length} live models for provider ${providerName}`, { baseUrl: effectiveBase });
|
|
75612
|
+
return defs.length;
|
|
75613
|
+
} catch (err) {
|
|
75614
|
+
log57.warn(`Live model sync failed for provider ${providerName}`, { error: String(err), baseUrl: effectiveBase });
|
|
75615
|
+
return 0;
|
|
75616
|
+
}
|
|
75617
|
+
}
|
|
75480
75618
|
/**
|
|
75481
75619
|
* Drop sticky Markus defaults that are no longer in the Hub catalog
|
|
75482
75620
|
* (e.g. CN geo-filter removes anthropic/claude-opus-5 while chip still shows it).
|
|
@@ -76161,7 +76299,7 @@ var init_router2 = __esm({
|
|
|
76161
76299
|
* Used by the test endpoint to verify a single provider's connectivity.
|
|
76162
76300
|
* Also returns the baseUrl used for diagnostics.
|
|
76163
76301
|
*/
|
|
76164
|
-
async chatDirect(request, providerName) {
|
|
76302
|
+
async chatDirect(request, providerName, altModel) {
|
|
76165
76303
|
const provider = this.providers.get(providerName);
|
|
76166
76304
|
if (!provider) {
|
|
76167
76305
|
throw new Error(`Provider "${providerName}" not registered`);
|
|
@@ -76170,9 +76308,24 @@ var init_router2 = __esm({
|
|
|
76170
76308
|
throw new Error(`Provider "${providerName}" is disabled`);
|
|
76171
76309
|
}
|
|
76172
76310
|
request = this.resolveMaxTokens(request, providerName);
|
|
76173
|
-
const
|
|
76174
|
-
const
|
|
76175
|
-
|
|
76311
|
+
const originalModel = provider.model;
|
|
76312
|
+
const useRequestModelOnly = providerName === "markus" || provider instanceof MarkusProvider;
|
|
76313
|
+
const activeModel = altModel ?? originalModel;
|
|
76314
|
+
let switched = false;
|
|
76315
|
+
if (!useRequestModelOnly && altModel && altModel !== originalModel) {
|
|
76316
|
+
provider.configure({ provider: providerName, model: altModel });
|
|
76317
|
+
switched = true;
|
|
76318
|
+
}
|
|
76319
|
+
const directRequest = useRequestModelOnly && altModel ? { ...request, model: altModel } : request;
|
|
76320
|
+
try {
|
|
76321
|
+
const response = await provider.chat(directRequest);
|
|
76322
|
+
const baseUrl = provider.baseUrl ?? provider.config?.baseUrl;
|
|
76323
|
+
return Object.assign(response, { _providerBaseUrl: baseUrl, _model: activeModel });
|
|
76324
|
+
} finally {
|
|
76325
|
+
if (switched) {
|
|
76326
|
+
provider.configure({ provider: providerName, model: originalModel });
|
|
76327
|
+
}
|
|
76328
|
+
}
|
|
76176
76329
|
}
|
|
76177
76330
|
/**
|
|
76178
76331
|
* Try a streaming chat on a specific provider, optionally with an alternate model.
|
|
@@ -76522,7 +76675,8 @@ var init_router2 = __esm({
|
|
|
76522
76675
|
});
|
|
76523
76676
|
const ctx = catalogEntry?.contextWindow;
|
|
76524
76677
|
if (!ctx || ctx <= 0) {
|
|
76525
|
-
|
|
76678
|
+
log57.warn(`No context_window for provider "${name}" model "${provider.model || "(unset)"}" \u2014 using fallback ${DEFAULT_CONTEXT_WINDOW_FALLBACK}. Configure the model for accurate budgeting.`);
|
|
76679
|
+
return DEFAULT_CONTEXT_WINDOW_FALLBACK;
|
|
76526
76680
|
}
|
|
76527
76681
|
return ctx;
|
|
76528
76682
|
}
|
|
@@ -76544,7 +76698,8 @@ var init_router2 = __esm({
|
|
|
76544
76698
|
});
|
|
76545
76699
|
const out = catalogEntry?.maxOutputTokens;
|
|
76546
76700
|
if (!out || out <= 0) {
|
|
76547
|
-
|
|
76701
|
+
log57.warn(`No max_output_tokens for provider "${name}" model "${provider.model || "(unset)"}" \u2014 using fallback ${DEFAULT_MAX_OUTPUT_FALLBACK}.`);
|
|
76702
|
+
return DEFAULT_MAX_OUTPUT_FALLBACK;
|
|
76548
76703
|
}
|
|
76549
76704
|
return out;
|
|
76550
76705
|
}
|
|
@@ -215631,6 +215786,42 @@ EXPLANATION_END`;
|
|
|
215631
215786
|
}
|
|
215632
215787
|
return;
|
|
215633
215788
|
}
|
|
215789
|
+
if (providerName === "ollama") {
|
|
215790
|
+
const ollamaUrl = process.env["OLLAMA_BASE_URL"] || "http://localhost:11434";
|
|
215791
|
+
const providerInstance = this.llmRouter?.getProvider("ollama");
|
|
215792
|
+
const configuredBaseUrl = providerInstance?.baseUrl;
|
|
215793
|
+
const baseUrl = configuredBaseUrl ?? ollamaUrl;
|
|
215794
|
+
try {
|
|
215795
|
+
const ctrl = new AbortController();
|
|
215796
|
+
const tmr = setTimeout(() => ctrl.abort(), 5e3);
|
|
215797
|
+
const ollamaRes = await fetch(`${String(baseUrl).replace(/\/+$/, "")}/api/tags`, { signal: ctrl.signal });
|
|
215798
|
+
clearTimeout(tmr);
|
|
215799
|
+
if (!ollamaRes.ok) {
|
|
215800
|
+
this.json(res, 200, { provider: "ollama", models: [], source: "error", error: `Ollama returned HTTP ${ollamaRes.status}` });
|
|
215801
|
+
return;
|
|
215802
|
+
}
|
|
215803
|
+
const data = await ollamaRes.json();
|
|
215804
|
+
const models = (data.models ?? []).map((m) => ({
|
|
215805
|
+
id: m.name,
|
|
215806
|
+
provider: "ollama",
|
|
215807
|
+
mode: "chat",
|
|
215808
|
+
maxInputTokens: 0,
|
|
215809
|
+
maxOutputTokens: 0,
|
|
215810
|
+
inputCostPer1MTokens: 0,
|
|
215811
|
+
outputCostPer1MTokens: 0,
|
|
215812
|
+
capabilities: { vision: false, functionCalling: false, reasoning: false, promptCaching: false, webSearch: false, audioInput: false, audioOutput: false },
|
|
215813
|
+
size: m.size,
|
|
215814
|
+
modifiedAt: m.modified_at,
|
|
215815
|
+
parameterSize: m.details?.parameter_size,
|
|
215816
|
+
family: m.details?.family,
|
|
215817
|
+
quantization: m.details?.quantization_level
|
|
215818
|
+
}));
|
|
215819
|
+
this.json(res, 200, { provider: "ollama", models, source: "live", count: models.length });
|
|
215820
|
+
} catch (err) {
|
|
215821
|
+
this.json(res, 200, { provider: "ollama", models: [], source: "error", error: err instanceof Error ? err.message : String(err) });
|
|
215822
|
+
}
|
|
215823
|
+
return;
|
|
215824
|
+
}
|
|
215634
215825
|
try {
|
|
215635
215826
|
const providerInstance = this.llmRouter?.getProvider(providerName);
|
|
215636
215827
|
const apiKey = providerInstance?.apiKey ?? "";
|
|
@@ -215677,6 +215868,10 @@ EXPLANATION_END`;
|
|
|
215677
215868
|
}
|
|
215678
215869
|
} catch {
|
|
215679
215870
|
}
|
|
215871
|
+
try {
|
|
215872
|
+
await this.llmRouter.refreshOllamaLocalModels?.();
|
|
215873
|
+
} catch {
|
|
215874
|
+
}
|
|
215680
215875
|
this.json(res, 200, this.llmRouter.getEnhancedSettings());
|
|
215681
215876
|
return;
|
|
215682
215877
|
}
|
|
@@ -216883,6 +217078,11 @@ data: ${JSON.stringify({ error: msg })}
|
|
|
216883
217078
|
apiKey,
|
|
216884
217079
|
baseUrl
|
|
216885
217080
|
});
|
|
217081
|
+
if (name === "ollama") {
|
|
217082
|
+
await this.llmRouter.refreshOllamaLocalModels?.(baseUrl);
|
|
217083
|
+
} else {
|
|
217084
|
+
await this.llmRouter.refreshProviderLiveModels?.(name, baseUrl, apiKey);
|
|
217085
|
+
}
|
|
216886
217086
|
if (enabled === false) {
|
|
216887
217087
|
this.llmRouter.setProviderEnabled(name, false);
|
|
216888
217088
|
}
|
|
@@ -216965,6 +217165,11 @@ data: ${JSON.stringify({ error: msg })}
|
|
|
216965
217165
|
if (typeof enabled === "boolean") {
|
|
216966
217166
|
this.llmRouter.setProviderEnabled(providerName, enabled);
|
|
216967
217167
|
}
|
|
217168
|
+
if (providerName === "ollama") {
|
|
217169
|
+
await this.llmRouter.refreshOllamaLocalModels?.(baseUrl ?? void 0);
|
|
217170
|
+
} else {
|
|
217171
|
+
await this.llmRouter.refreshProviderLiveModels?.(providerName, baseUrl ?? void 0, apiKey);
|
|
217172
|
+
}
|
|
216968
217173
|
if (contextWindow || maxOutputTokens || cost) {
|
|
216969
217174
|
this.llmRouter.updateProviderModelConfig(providerName, {
|
|
216970
217175
|
...contextWindow ? { contextWindow } : {},
|
|
@@ -217245,26 +217450,30 @@ data: ${JSON.stringify({ error: msg })}
|
|
|
217245
217450
|
this.json(res, 404, { ok: false, error: `Provider "${providerName}" not found or not configured` });
|
|
217246
217451
|
return;
|
|
217247
217452
|
}
|
|
217453
|
+
const body = await this.readBody(req);
|
|
217454
|
+
const requestedModel = typeof body?.model === "string" && body.model.trim() ? body.model.trim() : void 0;
|
|
217248
217455
|
const requestBody = {
|
|
217249
217456
|
messages: [{ role: "user", content: "Reply with exactly one word: hello" }],
|
|
217250
217457
|
// No maxTokens cap: a reasoning model spends the whole budget on hidden
|
|
217251
217458
|
// reasoning under a tight cap, returning empty content and producing a
|
|
217252
217459
|
// false "empty response / misconfigured" result. Let the router fill in
|
|
217253
217460
|
// the model's real limit; the model stops after the one-word reply.
|
|
217254
|
-
temperature: 0
|
|
217461
|
+
temperature: 0,
|
|
217462
|
+
...requestedModel ? { model: requestedModel } : {}
|
|
217255
217463
|
};
|
|
217256
217464
|
const baseUrl = provider.baseUrl ?? provider.config?.baseUrl ?? "";
|
|
217257
217465
|
try {
|
|
217258
217466
|
const startMs = Date.now();
|
|
217259
|
-
const response = await this.llmRouter.chatDirect(requestBody, providerName);
|
|
217467
|
+
const response = await this.llmRouter.chatDirect(requestBody, providerName, requestedModel);
|
|
217260
217468
|
const durationMs = Date.now() - startMs;
|
|
217261
217469
|
const reply = (response.content ?? "").trim();
|
|
217262
217470
|
const requestUrl = response._providerBaseUrl ?? baseUrl;
|
|
217471
|
+
const resultModel = response._model ?? requestedModel ?? provider.model;
|
|
217263
217472
|
if (!reply) {
|
|
217264
217473
|
this.json(res, 200, {
|
|
217265
217474
|
ok: false,
|
|
217266
217475
|
error: "Model returned empty response \u2014 API key or model may be misconfigured",
|
|
217267
|
-
model:
|
|
217476
|
+
model: resultModel,
|
|
217268
217477
|
durationMs,
|
|
217269
217478
|
requestUrl,
|
|
217270
217479
|
requestBody
|
|
@@ -217273,7 +217482,7 @@ data: ${JSON.stringify({ error: msg })}
|
|
|
217273
217482
|
this.json(res, 200, {
|
|
217274
217483
|
ok: true,
|
|
217275
217484
|
durationMs,
|
|
217276
|
-
model:
|
|
217485
|
+
model: resultModel,
|
|
217277
217486
|
reply: reply.slice(0, 100),
|
|
217278
217487
|
usage: response.usage,
|
|
217279
217488
|
requestUrl,
|
|
@@ -217300,7 +217509,7 @@ data: ${JSON.stringify({ error: msg })}
|
|
|
217300
217509
|
ok: false,
|
|
217301
217510
|
error: errorMsg.slice(0, 500),
|
|
217302
217511
|
errorCode,
|
|
217303
|
-
model: provider.model,
|
|
217512
|
+
model: requestedModel ?? provider.model,
|
|
217304
217513
|
requestUrl: baseUrl,
|
|
217305
217514
|
requestBody
|
|
217306
217515
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{j as t,u as T,r as a,k as ee}from"./index-CcppNtga.js";const te=1920,ne=10*1024*1024,W=5,re=.8;function se(l,u,i){return new Promise((g,f)=>{const y=new Image;y.onload=()=>{let{width:s,height:r}=y;if(s<=u&&r<=u){g(l);return}s>r?(r=Math.round(r*(u/s)),s=u):(s=Math.round(s*(u/r)),r=u);const x=document.createElement("canvas");x.width=s,x.height=r;const b=x.getContext("2d");if(!b){f(new Error("Failed to get canvas context"));return}b.drawImage(y,0,0,s,r),g(x.toDataURL("image/jpeg",i))},y.onerror=()=>f(new Error("Failed to load image")),y.src=l})}function ae({candidates:l,filter:u,anchorRef:i,onSelect:g,selectedIndex:f,onIndexChange:y}){const{t:s}=T("common"),[r,x]=a.useState(null),b=a.useRef(null),w=l.filter(d=>d.name.toLowerCase().includes(u));return a.useEffect(()=>{const d=i.current;if(!d)return;const h=d.getBoundingClientRect();x({top:h.top+window.scrollY-4,left:h.left+window.scrollX+8})},[i,u]),a.useEffect(()=>{if(!b.current||!r)return;if(b.current.getBoundingClientRect().top<8){const h=i.current;if(!h)return;const c=h.getBoundingClientRect();x({top:c.bottom+window.scrollY+4,left:r.left})}},[r,i]),a.useEffect(()=>{f>=w.length&&y(Math.max(0,w.length-1))},[w.length,f,y]),a.useEffect(()=>{if(!b.current)return;b.current.querySelector('[data-selected="true"]')?.scrollIntoView({block:"nearest"})},[f]),!r||w.length===0?null:ee.createPortal(t.jsxs("div",{ref:b,style:{position:"absolute",top:r.top,left:r.left,transform:"translateY(-100%)"},className:"w-60 bg-surface-overlay border border-border-default rounded-lg shadow-xl z-[9999] max-h-48 overflow-y-auto",children:[t.jsx("div",{className:"px-2.5 py-1.5 text-[10px] text-fg-tertiary font-medium uppercase tracking-wider border-b border-border-default",children:s("commentInput.mentionHeading")}),w.map((d,h)=>t.jsxs("button",{"data-selected":h===f,onMouseDown:c=>{c.preventDefault(),g(d)},onMouseEnter:()=>y(h),className:`w-full text-left px-3 py-2 text-xs flex items-center gap-2 transition-colors ${h===f?"bg-brand-500/15 text-brand-500":"hover:bg-surface-elevated"}`,children:[t.jsx("span",{className:`w-6 h-6 rounded-full flex items-center justify-center text-[10px] font-bold shrink-0 ${d.type==="human"?"bg-green-500/20 text-green-500":"bg-brand-500/20 text-brand-500"}`,children:d.name.slice(0,2).toUpperCase()}),t.jsxs("div",{className:"flex-1 min-w-0",children:[t.jsx("span",{className:"text-fg-primary font-medium",children:d.name}),t.jsx("span",{className:"text-fg-tertiary text-[10px] ml-1.5",children:d.subtitle??d.type})]}),d.type==="agent"&&t.jsx("span",{className:`w-1.5 h-1.5 rounded-full shrink-0 ${d.online?"bg-green-400":"bg-gray-500"}`})]},d.id))]}),document.body)}function oe(l){return/^\w+$/.test(l)?`@${l}`:`@[${l}]`}const K=/@\[([^\]]+)\]|@([\w\p{L}\p{N}]+)/gu;function ie(l){const u=[];let i;for(K.lastIndex=0;(i=K.exec(l))!==null;)u.push(i[1]??i[2]);return u}function ce(l,u,i){const g=[];let f=0;const y=u.map(r=>r.name).sort((r,x)=>x.length-r.length);let s=0;for(;s<l.length;){const r=l.indexOf("@",s);if(r<0){g.push(t.jsx("span",{children:l.slice(s)},f++));break}if(r>s&&g.push(t.jsx("span",{children:l.slice(s,r)},f++)),l[r+1]==="["){const c=l.indexOf("]",r+2);if(c>r+2){const m=l.slice(r+2,c),j=u.find(k=>k.name.toLowerCase()===m.toLowerCase());g.push(t.jsxs("span",{className:`text-brand-500 font-medium ${i&&j?"cursor-pointer hover:underline":""}`,onClick:i&&j?k=>i(j,k):void 0,title:j?`${j.name} (${j.role})`:void 0,children:["@",m]},f++)),s=c+1;continue}}const x=l.slice(r+1),b=x.toLowerCase(),w=y.find(c=>b.startsWith(c.toLowerCase()));if(w){const c=u.find(m=>m.name.toLowerCase()===w.toLowerCase());g.push(t.jsxs("span",{className:`text-brand-500 font-medium ${i&&c?"cursor-pointer hover:underline":""}`,onClick:i&&c?m=>i(c,m):void 0,title:c?`${c.name} (${c.role})`:void 0,children:["@",w]},f++)),s=r+1+w.length;continue}const d=/^([\w\p{L}\p{N}]+)/u,h=x.match(d);if(h){const c=h[1],m=u.find(j=>j.name.toLowerCase()===c.toLowerCase());g.push(t.jsxs("span",{className:`text-brand-500 font-medium ${i&&m?"cursor-pointer hover:underline":""}`,onClick:i&&m?j=>i(m,j):void 0,title:m?`${m.name} (${m.role})`:void 0,children:["@",c]},f++)),s=r+1+c.length;continue}g.push(t.jsx("span",{children:"@"},f++)),s=r+1}return g.length>0?g:[t.jsx("span",{children:l},0)]}function de({agents:l,humans:u,onSubmit:i,placeholder:g,replyTo:f,onCancelReply:y}){const{t:s}=T("common"),[r,x]=a.useState(""),[b,w]=a.useState(!1),[d,h]=a.useState(null),[c,m]=a.useState(!1),[j,k]=a.useState(""),[C,S]=a.useState([]),[B,I]=a.useState(0),[N,M]=a.useState([]),[z,A]=a.useState(!1),F=a.useRef(null),U=a.useRef(null),L=a.useRef(null),$=a.useMemo(()=>{const e=(u??[]).map(n=>({id:n.id,name:n.name,type:"human",subtitle:n.role}));for(const n of l)e.push({id:n.id,name:n.name,type:"agent",subtitle:n.role,online:n.status==="idle"||n.status==="working"});return e},[l,u]),D=$.filter(e=>e.name.toLowerCase().includes(j)),E=a.useCallback(e=>{const n=Array.from(e).filter(o=>o.type.startsWith("image/"));if(n.length!==0)for(const o of n){if(o.size>ne)continue;const p=new FileReader;p.onload=()=>{const R=p.result;se(R,te,re).then(v=>{M(_=>_.length>=W?_:[..._,{id:`img_${Date.now()}_${Math.random().toString(36).slice(2,6)}`,dataUrl:v,name:o.name}])})},p.readAsDataURL(o)}},[]),X=a.useCallback(e=>{M(n=>n.filter(o=>o.id!==e))},[]),Y=a.useCallback(e=>{const n=e.clipboardData?.files;if(n&&n.length>0){const o=Array.from(n).filter(p=>p.type.startsWith("image/"));o.length>0&&(e.preventDefault(),E(o))}},[E]),q=a.useCallback(e=>{e.preventDefault(),A(!1);const n=e.dataTransfer?.files;n&&n.length>0&&E(Array.from(n).filter(o=>o.type.startsWith("image/")))},[E]),G=a.useCallback(e=>{e.preventDefault(),A(!0)},[]),H=a.useCallback(()=>{A(!1)},[]),O=async()=>{if(!(!r.trim()&&N.length===0)){w(!0),h(null),L.current={content:r,mentions:[...C],images:[...N]};try{await i(r,C,[...N],f?.id),x(""),S([]),M([]),L.current=null,y?.()}catch(e){h(String(e instanceof Error?e.message:e)||s("commentInput.sendFailed"))}w(!1)}},Q=async()=>{if(!L.current)return;const{content:e,mentions:n,images:o}=L.current;w(!0),h(null);try{await i(e,n,o),x(""),S([]),M([]),L.current=null}catch(p){h(String(p instanceof Error?p.message:p)||s("commentInput.sendFailed"))}w(!1)},P=a.useCallback(e=>{x(n=>{const o=n.lastIndexOf("@"),p=oe(e.name);return o>=0?n.slice(0,o)+p+" ":n+p+" "}),C.includes(e.id)||S(n=>[...n,e.id]),m(!1),k(""),I(0),F.current?.focus()},[C]),V=e=>{x(e),h(null);const n=e.lastIndexOf("@");if(n>=0&&(n===0||e[n-1]===" ")){const p=e.slice(n+1).toLowerCase();if($.some(v=>v.name.toLowerCase().includes(p))){k(p),m(!0),I(0);return}}m(!1)},Z=e=>{if(c&&D.length>0){const n=e.key==="ArrowUp"||e.ctrlKey&&e.key==="p",o=e.key==="ArrowDown"||e.ctrlKey&&e.key==="n",p=e.key==="Enter"||e.key==="Tab",R=e.key==="Escape";if(n){e.preventDefault(),I(v=>(v-1+D.length)%D.length);return}if(o){e.preventDefault(),I(v=>(v+1)%D.length);return}if(p){e.preventDefault();const v=D[B];v&&P(v);return}if(R){e.preventDefault(),m(!1);return}}e.key==="Enter"&&!e.shiftKey&&(e.preventDefault(),O())},J=a.useCallback(()=>{setTimeout(()=>m(!1),200)},[]);return t.jsxs("div",{className:"relative",onDragOver:G,onDragLeave:H,onDrop:q,children:[z&&t.jsx("div",{className:"absolute inset-0 z-50 flex items-center justify-center bg-brand-500/10 rounded-lg border-2 border-dashed border-brand-500",children:t.jsx("span",{className:"text-sm text-brand-500 font-medium",children:s("commentInput.dragDropHint")})}),c&&t.jsx(ae,{candidates:$,filter:j,anchorRef:F,onSelect:P,selectedIndex:B,onIndexChange:I}),t.jsxs("div",{className:"border border-border-default rounded-lg bg-surface-elevated",children:[f&&t.jsxs("div",{className:"flex items-center gap-2 px-2.5 pt-2 pb-1 border-b border-border-default/50",children:[t.jsxs("div",{className:"flex-1 min-w-0 pl-2 border-l-2 border-brand-500/50",children:[t.jsx("span",{className:"text-[10px] font-medium text-brand-500",children:f.authorName}),t.jsx("p",{className:"text-[10px] text-fg-tertiary truncate",children:f.content})]}),t.jsx("button",{onClick:y,className:"text-fg-tertiary hover:text-fg-secondary shrink-0 p-0.5",children:t.jsxs("svg",{width:"12",height:"12",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[t.jsx("line",{x1:"18",y1:"6",x2:"6",y2:"18"}),t.jsx("line",{x1:"6",y1:"6",x2:"18",y2:"18"})]})})]}),C.length>0&&t.jsx("div",{className:"flex gap-1 px-2.5 pt-2 flex-wrap",children:C.map(e=>{const n=$.find(o=>o.id===e);return t.jsxs("span",{className:`inline-flex items-center gap-1 px-1.5 py-0.5 text-[10px] rounded-full ${n?.type==="human"?"bg-green-500/15 text-green-500":"bg-brand-500/15 text-brand-500"}`,children:["@",n?.name??e,t.jsx("button",{onClick:()=>S(o=>o.filter(p=>p!==e)),className:"hover:text-red-400",children:"×"})]},e)})}),t.jsx("textarea",{ref:F,value:r,onChange:e=>V(e.target.value),onKeyDown:Z,onBlur:J,onPaste:Y,placeholder:g??s("commentInput.placeholder"),rows:2,className:"w-full px-2.5 py-2 text-xs bg-transparent text-fg-primary placeholder-fg-tertiary outline-none resize-none"}),N.length>0&&t.jsx("div",{className:"flex items-center gap-1.5 px-2.5 pb-1.5 overflow-x-auto",children:N.map(e=>t.jsxs("div",{className:"relative group/img shrink-0",children:[t.jsx("img",{src:e.dataUrl,alt:e.name,className:"w-12 h-12 rounded-lg object-cover border border-border-default"}),t.jsx("button",{onClick:()=>X(e.id),className:"absolute -top-1.5 -right-1.5 w-4 h-4 bg-surface-secondary border border-gray-600 rounded-full flex items-center justify-center text-fg-secondary hover:text-red-500 hover:border-red-500 text-[10px] opacity-0 group-hover/img:opacity-100 transition-opacity",title:s("commentInput.removeImage"),children:"×"})]},e.id))}),d&&t.jsxs("div",{className:"flex items-center gap-2 px-2.5 pb-1.5",children:[t.jsx("span",{className:"text-[11px] text-red-400 flex-1 truncate",children:d}),t.jsxs("button",{onClick:Q,disabled:b,className:"text-[11px] text-amber-500 hover:text-amber-400 font-medium transition-colors flex items-center gap-1",children:[t.jsxs("svg",{className:"w-3 h-3",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",children:[t.jsx("polyline",{points:"23 4 23 10 17 10"}),t.jsx("path",{d:"M20.49 15a9 9 0 11-2.12-9.36L23 10"})]}),s("commentInput.retry")]})]}),t.jsxs("div",{className:"flex items-center justify-between px-2.5 pb-2",children:[t.jsx("button",{type:"button",onClick:()=>U.current?.click(),disabled:b||N.length>=W,className:"p-1 text-fg-tertiary hover:text-brand-500 disabled:opacity-30 disabled:cursor-not-allowed transition-colors",title:s("commentInput.attachImage"),children:t.jsxs("svg",{className:"w-4 h-4",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[t.jsx("rect",{x:"3",y:"3",width:"18",height:"18",rx:"2",ry:"2"}),t.jsx("circle",{cx:"8.5",cy:"8.5",r:"1.5"}),t.jsx("polyline",{points:"21 15 16 10 5 21"})]})}),t.jsx("input",{ref:U,type:"file",accept:"image/*",multiple:!0,className:"hidden",onChange:e=>{e.target.files&&E(e.target.files),e.target.value=""}}),t.jsx("button",{onClick:O,disabled:!r.trim()&&N.length===0||b,className:"px-3 py-1 text-[11px] font-medium bg-brand-500 text-white rounded-md hover:bg-brand-600 disabled:opacity-40 disabled:cursor-not-allowed transition-colors",children:s(b?"commentInput.sending":"commentInput.submit")})]})]}),t.jsx("p",{className:"mt-1 text-center text-[10px] text-fg-tertiary/80 select-none",children:s("aiDisclaimer")})]})}export{de as C,ie as p,ce as r};
|
|
1
|
+
import{j as t,u as T,r as a,k as ee}from"./index-CiAGgfZx.js";const te=1920,ne=10*1024*1024,W=5,re=.8;function se(l,u,i){return new Promise((g,f)=>{const y=new Image;y.onload=()=>{let{width:s,height:r}=y;if(s<=u&&r<=u){g(l);return}s>r?(r=Math.round(r*(u/s)),s=u):(s=Math.round(s*(u/r)),r=u);const x=document.createElement("canvas");x.width=s,x.height=r;const b=x.getContext("2d");if(!b){f(new Error("Failed to get canvas context"));return}b.drawImage(y,0,0,s,r),g(x.toDataURL("image/jpeg",i))},y.onerror=()=>f(new Error("Failed to load image")),y.src=l})}function ae({candidates:l,filter:u,anchorRef:i,onSelect:g,selectedIndex:f,onIndexChange:y}){const{t:s}=T("common"),[r,x]=a.useState(null),b=a.useRef(null),w=l.filter(d=>d.name.toLowerCase().includes(u));return a.useEffect(()=>{const d=i.current;if(!d)return;const h=d.getBoundingClientRect();x({top:h.top+window.scrollY-4,left:h.left+window.scrollX+8})},[i,u]),a.useEffect(()=>{if(!b.current||!r)return;if(b.current.getBoundingClientRect().top<8){const h=i.current;if(!h)return;const c=h.getBoundingClientRect();x({top:c.bottom+window.scrollY+4,left:r.left})}},[r,i]),a.useEffect(()=>{f>=w.length&&y(Math.max(0,w.length-1))},[w.length,f,y]),a.useEffect(()=>{if(!b.current)return;b.current.querySelector('[data-selected="true"]')?.scrollIntoView({block:"nearest"})},[f]),!r||w.length===0?null:ee.createPortal(t.jsxs("div",{ref:b,style:{position:"absolute",top:r.top,left:r.left,transform:"translateY(-100%)"},className:"w-60 bg-surface-overlay border border-border-default rounded-lg shadow-xl z-[9999] max-h-48 overflow-y-auto",children:[t.jsx("div",{className:"px-2.5 py-1.5 text-[10px] text-fg-tertiary font-medium uppercase tracking-wider border-b border-border-default",children:s("commentInput.mentionHeading")}),w.map((d,h)=>t.jsxs("button",{"data-selected":h===f,onMouseDown:c=>{c.preventDefault(),g(d)},onMouseEnter:()=>y(h),className:`w-full text-left px-3 py-2 text-xs flex items-center gap-2 transition-colors ${h===f?"bg-brand-500/15 text-brand-500":"hover:bg-surface-elevated"}`,children:[t.jsx("span",{className:`w-6 h-6 rounded-full flex items-center justify-center text-[10px] font-bold shrink-0 ${d.type==="human"?"bg-green-500/20 text-green-500":"bg-brand-500/20 text-brand-500"}`,children:d.name.slice(0,2).toUpperCase()}),t.jsxs("div",{className:"flex-1 min-w-0",children:[t.jsx("span",{className:"text-fg-primary font-medium",children:d.name}),t.jsx("span",{className:"text-fg-tertiary text-[10px] ml-1.5",children:d.subtitle??d.type})]}),d.type==="agent"&&t.jsx("span",{className:`w-1.5 h-1.5 rounded-full shrink-0 ${d.online?"bg-green-400":"bg-gray-500"}`})]},d.id))]}),document.body)}function oe(l){return/^\w+$/.test(l)?`@${l}`:`@[${l}]`}const K=/@\[([^\]]+)\]|@([\w\p{L}\p{N}]+)/gu;function ie(l){const u=[];let i;for(K.lastIndex=0;(i=K.exec(l))!==null;)u.push(i[1]??i[2]);return u}function ce(l,u,i){const g=[];let f=0;const y=u.map(r=>r.name).sort((r,x)=>x.length-r.length);let s=0;for(;s<l.length;){const r=l.indexOf("@",s);if(r<0){g.push(t.jsx("span",{children:l.slice(s)},f++));break}if(r>s&&g.push(t.jsx("span",{children:l.slice(s,r)},f++)),l[r+1]==="["){const c=l.indexOf("]",r+2);if(c>r+2){const m=l.slice(r+2,c),j=u.find(k=>k.name.toLowerCase()===m.toLowerCase());g.push(t.jsxs("span",{className:`text-brand-500 font-medium ${i&&j?"cursor-pointer hover:underline":""}`,onClick:i&&j?k=>i(j,k):void 0,title:j?`${j.name} (${j.role})`:void 0,children:["@",m]},f++)),s=c+1;continue}}const x=l.slice(r+1),b=x.toLowerCase(),w=y.find(c=>b.startsWith(c.toLowerCase()));if(w){const c=u.find(m=>m.name.toLowerCase()===w.toLowerCase());g.push(t.jsxs("span",{className:`text-brand-500 font-medium ${i&&c?"cursor-pointer hover:underline":""}`,onClick:i&&c?m=>i(c,m):void 0,title:c?`${c.name} (${c.role})`:void 0,children:["@",w]},f++)),s=r+1+w.length;continue}const d=/^([\w\p{L}\p{N}]+)/u,h=x.match(d);if(h){const c=h[1],m=u.find(j=>j.name.toLowerCase()===c.toLowerCase());g.push(t.jsxs("span",{className:`text-brand-500 font-medium ${i&&m?"cursor-pointer hover:underline":""}`,onClick:i&&m?j=>i(m,j):void 0,title:m?`${m.name} (${m.role})`:void 0,children:["@",c]},f++)),s=r+1+c.length;continue}g.push(t.jsx("span",{children:"@"},f++)),s=r+1}return g.length>0?g:[t.jsx("span",{children:l},0)]}function de({agents:l,humans:u,onSubmit:i,placeholder:g,replyTo:f,onCancelReply:y}){const{t:s}=T("common"),[r,x]=a.useState(""),[b,w]=a.useState(!1),[d,h]=a.useState(null),[c,m]=a.useState(!1),[j,k]=a.useState(""),[C,S]=a.useState([]),[B,I]=a.useState(0),[N,M]=a.useState([]),[z,A]=a.useState(!1),F=a.useRef(null),U=a.useRef(null),L=a.useRef(null),$=a.useMemo(()=>{const e=(u??[]).map(n=>({id:n.id,name:n.name,type:"human",subtitle:n.role}));for(const n of l)e.push({id:n.id,name:n.name,type:"agent",subtitle:n.role,online:n.status==="idle"||n.status==="working"});return e},[l,u]),D=$.filter(e=>e.name.toLowerCase().includes(j)),E=a.useCallback(e=>{const n=Array.from(e).filter(o=>o.type.startsWith("image/"));if(n.length!==0)for(const o of n){if(o.size>ne)continue;const p=new FileReader;p.onload=()=>{const R=p.result;se(R,te,re).then(v=>{M(_=>_.length>=W?_:[..._,{id:`img_${Date.now()}_${Math.random().toString(36).slice(2,6)}`,dataUrl:v,name:o.name}])})},p.readAsDataURL(o)}},[]),X=a.useCallback(e=>{M(n=>n.filter(o=>o.id!==e))},[]),Y=a.useCallback(e=>{const n=e.clipboardData?.files;if(n&&n.length>0){const o=Array.from(n).filter(p=>p.type.startsWith("image/"));o.length>0&&(e.preventDefault(),E(o))}},[E]),q=a.useCallback(e=>{e.preventDefault(),A(!1);const n=e.dataTransfer?.files;n&&n.length>0&&E(Array.from(n).filter(o=>o.type.startsWith("image/")))},[E]),G=a.useCallback(e=>{e.preventDefault(),A(!0)},[]),H=a.useCallback(()=>{A(!1)},[]),O=async()=>{if(!(!r.trim()&&N.length===0)){w(!0),h(null),L.current={content:r,mentions:[...C],images:[...N]};try{await i(r,C,[...N],f?.id),x(""),S([]),M([]),L.current=null,y?.()}catch(e){h(String(e instanceof Error?e.message:e)||s("commentInput.sendFailed"))}w(!1)}},Q=async()=>{if(!L.current)return;const{content:e,mentions:n,images:o}=L.current;w(!0),h(null);try{await i(e,n,o),x(""),S([]),M([]),L.current=null}catch(p){h(String(p instanceof Error?p.message:p)||s("commentInput.sendFailed"))}w(!1)},P=a.useCallback(e=>{x(n=>{const o=n.lastIndexOf("@"),p=oe(e.name);return o>=0?n.slice(0,o)+p+" ":n+p+" "}),C.includes(e.id)||S(n=>[...n,e.id]),m(!1),k(""),I(0),F.current?.focus()},[C]),V=e=>{x(e),h(null);const n=e.lastIndexOf("@");if(n>=0&&(n===0||e[n-1]===" ")){const p=e.slice(n+1).toLowerCase();if($.some(v=>v.name.toLowerCase().includes(p))){k(p),m(!0),I(0);return}}m(!1)},Z=e=>{if(c&&D.length>0){const n=e.key==="ArrowUp"||e.ctrlKey&&e.key==="p",o=e.key==="ArrowDown"||e.ctrlKey&&e.key==="n",p=e.key==="Enter"||e.key==="Tab",R=e.key==="Escape";if(n){e.preventDefault(),I(v=>(v-1+D.length)%D.length);return}if(o){e.preventDefault(),I(v=>(v+1)%D.length);return}if(p){e.preventDefault();const v=D[B];v&&P(v);return}if(R){e.preventDefault(),m(!1);return}}e.key==="Enter"&&!e.shiftKey&&(e.preventDefault(),O())},J=a.useCallback(()=>{setTimeout(()=>m(!1),200)},[]);return t.jsxs("div",{className:"relative",onDragOver:G,onDragLeave:H,onDrop:q,children:[z&&t.jsx("div",{className:"absolute inset-0 z-50 flex items-center justify-center bg-brand-500/10 rounded-lg border-2 border-dashed border-brand-500",children:t.jsx("span",{className:"text-sm text-brand-500 font-medium",children:s("commentInput.dragDropHint")})}),c&&t.jsx(ae,{candidates:$,filter:j,anchorRef:F,onSelect:P,selectedIndex:B,onIndexChange:I}),t.jsxs("div",{className:"border border-border-default rounded-lg bg-surface-elevated",children:[f&&t.jsxs("div",{className:"flex items-center gap-2 px-2.5 pt-2 pb-1 border-b border-border-default/50",children:[t.jsxs("div",{className:"flex-1 min-w-0 pl-2 border-l-2 border-brand-500/50",children:[t.jsx("span",{className:"text-[10px] font-medium text-brand-500",children:f.authorName}),t.jsx("p",{className:"text-[10px] text-fg-tertiary truncate",children:f.content})]}),t.jsx("button",{onClick:y,className:"text-fg-tertiary hover:text-fg-secondary shrink-0 p-0.5",children:t.jsxs("svg",{width:"12",height:"12",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[t.jsx("line",{x1:"18",y1:"6",x2:"6",y2:"18"}),t.jsx("line",{x1:"6",y1:"6",x2:"18",y2:"18"})]})})]}),C.length>0&&t.jsx("div",{className:"flex gap-1 px-2.5 pt-2 flex-wrap",children:C.map(e=>{const n=$.find(o=>o.id===e);return t.jsxs("span",{className:`inline-flex items-center gap-1 px-1.5 py-0.5 text-[10px] rounded-full ${n?.type==="human"?"bg-green-500/15 text-green-500":"bg-brand-500/15 text-brand-500"}`,children:["@",n?.name??e,t.jsx("button",{onClick:()=>S(o=>o.filter(p=>p!==e)),className:"hover:text-red-400",children:"×"})]},e)})}),t.jsx("textarea",{ref:F,value:r,onChange:e=>V(e.target.value),onKeyDown:Z,onBlur:J,onPaste:Y,placeholder:g??s("commentInput.placeholder"),rows:2,className:"w-full px-2.5 py-2 text-xs bg-transparent text-fg-primary placeholder-fg-tertiary outline-none resize-none"}),N.length>0&&t.jsx("div",{className:"flex items-center gap-1.5 px-2.5 pb-1.5 overflow-x-auto",children:N.map(e=>t.jsxs("div",{className:"relative group/img shrink-0",children:[t.jsx("img",{src:e.dataUrl,alt:e.name,className:"w-12 h-12 rounded-lg object-cover border border-border-default"}),t.jsx("button",{onClick:()=>X(e.id),className:"absolute -top-1.5 -right-1.5 w-4 h-4 bg-surface-secondary border border-gray-600 rounded-full flex items-center justify-center text-fg-secondary hover:text-red-500 hover:border-red-500 text-[10px] opacity-0 group-hover/img:opacity-100 transition-opacity",title:s("commentInput.removeImage"),children:"×"})]},e.id))}),d&&t.jsxs("div",{className:"flex items-center gap-2 px-2.5 pb-1.5",children:[t.jsx("span",{className:"text-[11px] text-red-400 flex-1 truncate",children:d}),t.jsxs("button",{onClick:Q,disabled:b,className:"text-[11px] text-amber-500 hover:text-amber-400 font-medium transition-colors flex items-center gap-1",children:[t.jsxs("svg",{className:"w-3 h-3",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",children:[t.jsx("polyline",{points:"23 4 23 10 17 10"}),t.jsx("path",{d:"M20.49 15a9 9 0 11-2.12-9.36L23 10"})]}),s("commentInput.retry")]})]}),t.jsxs("div",{className:"flex items-center justify-between px-2.5 pb-2",children:[t.jsx("button",{type:"button",onClick:()=>U.current?.click(),disabled:b||N.length>=W,className:"p-1 text-fg-tertiary hover:text-brand-500 disabled:opacity-30 disabled:cursor-not-allowed transition-colors",title:s("commentInput.attachImage"),children:t.jsxs("svg",{className:"w-4 h-4",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[t.jsx("rect",{x:"3",y:"3",width:"18",height:"18",rx:"2",ry:"2"}),t.jsx("circle",{cx:"8.5",cy:"8.5",r:"1.5"}),t.jsx("polyline",{points:"21 15 16 10 5 21"})]})}),t.jsx("input",{ref:U,type:"file",accept:"image/*",multiple:!0,className:"hidden",onChange:e=>{e.target.files&&E(e.target.files),e.target.value=""}}),t.jsx("button",{onClick:O,disabled:!r.trim()&&N.length===0||b,className:"px-3 py-1 text-[11px] font-medium bg-brand-500 text-white rounded-md hover:bg-brand-600 disabled:opacity-40 disabled:cursor-not-allowed transition-colors",children:s(b?"commentInput.sending":"commentInput.submit")})]})]}),t.jsx("p",{className:"mt-1 text-center text-[10px] text-fg-tertiary/80 select-none",children:s("aiDisclaimer")})]})}export{de as C,ie as p,ce as r};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/index-
|
|
2
|
-
import{j as a,r as i,_ as f}from"./index-
|
|
1
|
+
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/index-CiAGgfZx.js","assets/index-BbQpGkiM.css"])))=>i.map(i=>d[i]);
|
|
2
|
+
import{j as a,r as i,_ as f}from"./index-CiAGgfZx.js";const x=i.lazy(()=>f(()=>import("./index-CiAGgfZx.js").then(e=>e.aE),__vite__mapDeps([0,1])).then(e=>({default:e.MarkdownMessage}))),b=new Set(["ts","tsx","js","jsx","mjs","cjs","py","go","rs","java","kt","kts","c","cc","cpp","cxx","h","hpp","hxx","cs","rb","php","swift","scala","sh","bash","zsh","fish","ps1","sql","yaml","yml","toml","xml","css","scss","less","vue","svelte","graphql","gql","proto","dockerfile","makefile","cmake","rsx","r","lua","pl","pm","ex","exs","erl","hs","clj","zig","nim","dart","gradle","tf","hcl"]);function v(e){const t=e.split(/[/\\]/).pop()?.toLowerCase()||"";if(t==="dockerfile"||t==="makefile")return"code";const r=t.includes(".")?t.split(".").pop():"";switch(r){case"md":case"markdown":return"markdown";case"html":case"htm":return"html";case"json":case"jsonc":return"json";case"csv":case"tsv":return"csv";default:return r&&b.has(r)?"code":r?"text":void 0}}function w(e){const t=e.trimStart();if(/^<!doctype\s+html/i.test(t)||/^<html[\s>]/i.test(t))return"html";if(t.startsWith("{")||t.startsWith("["))try{return JSON.parse(e),"json"}catch{}}function S(e){if(e.format)return e.format;if(e.reference){const t=v(e.reference);if(t)return t}if(e.content){const t=w(e.content);if(t)return t}return e.reference?"text":"markdown"}function y({content:e,className:t,onSelection:r}){const c=i.useRef(null),[l,p]=i.useState(null);i.useEffect(()=>{const o=d=>{d.data?.type==="__htmlpreview_height"&&typeof d.data.height=="number"&&p(d.data.height),d.data?.type==="__htmlpreview_selection"&&r&&r(d.data)};return window.addEventListener("message",o),()=>window.removeEventListener("message",o)},[r]);const h=`<script>
|
|
3
3
|
(function(){
|
|
4
4
|
function getXPath(el){
|
|
5
5
|
if(!el||el.nodeType!==1)return'';
|
package/dist/web-ui/assets/{DeliverableShareModal-DkGpQmZ8.js → DeliverableShareModal-BEeIlXig.js}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{u as ce,r as u,h as A,o as de,t as ue,l as N,j as r}from"./index-CcppNtga.js";const O=50*1024*1024;class H extends Error{constructor(e){super(e),this.name="DeliverableShareError"}}class Z extends H{constructor(){super("需要登录 Markus Hub 账号后才能分享产出物。"),this.name="NotLoggedIntoHubError"}}class fe extends H{bytes;limit;constructor(e,a){super(`产出物文件大小 ${e} 字节超过上限 ${a} 字节(50MB),请压缩或拒绝分享。`),this.name="DeliverableTooLargeError",this.bytes=e,this.limit=a}}class he extends H{status;constructor(e,a){super(`Hub 请求失败 (HTTP ${e}): ${a}`),this.name="HubApiError",this.status=e}}function be(t){const e=t.replace(/\s+/g,"");if(!e)return 0;let a=0;return e.endsWith("==")?a=2:e.endsWith("=")&&(a=1),Math.floor(e.length*3/4)-a}function V(t,e){const a=t&&typeof t=="object"?t:{},l=a.share??a.deliverable??{},s=m=>a[m]??l[m],i=s("id")??s("shareId")??"",c=s("slug"),o=c!=null?String(c):void 0,d=s("url")??s("shareUrl");let h=null;d!=null?h=String(d):o&&e&&(h=`${e.replace(/\/+$/,"")}/deliverable/${encodeURIComponent(o)}`);const f=s("reason")??s("rejectNote"),p=s("localDeliverableId")??s("localId");return{id:String(i),slug:o,visibility:s("visibility")??"public",status:s("status")??"pending_review",url:h,reason:f!=null?String(f):null,localId:p!=null?String(p):null}}class pe{basePath;fetchImpl;hubOrigin;constructor(e){this.getHubToken=e.getHubToken,this.hubOrigin=e.hubUrl,this.basePath=(e.proxyBasePath??"/api/hub").replace(/\/+$/,""),this.fetchImpl=e.fetch??(globalThis.fetch?globalThis.fetch.bind(globalThis):(()=>{throw new Error("fetch unavailable")}))}getHubToken;isHubLoggedIn(){return!!this.getHubToken()}assertHubLoggedIn(){if(!this.getHubToken())throw new Z}async doFetch(e,a){const l=this.getHubToken(),s={"Content-Type":"application/json",...a.headers};l&&(s.Authorization=`Bearer ${l}`);const i=await this.fetchImpl(`${this.basePath}${e}`,{...a,headers:s,credentials:"include"});let c=null;try{c=await i.json()}catch{c=null}if(!i.ok){const o=c&&typeof c=="object"&&"error"in c?String(c.error):i.statusText||`HTTP ${i.status}`;throw new he(i.status,o)}return{status:i.status,data:c}}async publish(e){this.assertHubLoggedIn();const a=e.fileSizeBytes??(e.fileBase64?be(e.fileBase64):0);if(a>O)throw new fe(a,O);const l={localDeliverableId:e.localId,visibility:e.visibility,title:e.title,summary:e.summary,tags:e.tags,filename:e.filename,format:e.format,producerAgent:{id:e.producerAgent.id,name:e.producerAgent.name,source:e.producerAgent.source}};e.content&&(l.content=e.content),e.fileBase64&&(l.fileBase64=e.fileBase64);const{data:s}=await this.doFetch("/deliverables/publish",{method:"POST",body:JSON.stringify(l)});return V(s,this.hubOrigin)}async pollStatus(e){this.assertHubLoggedIn();const{data:a}=await this.doFetch(`/deliverables/status?localId=${encodeURIComponent(e)}`,{method:"GET"});return V(a,this.hubOrigin)}async listMine(){this.assertHubLoggedIn();const{data:e}=await this.doFetch("/deliverables/mine",{method:"GET"}),a=e&&typeof e=="object"?e:{};return(Array.isArray(a.shares)?a.shares:[]).map(s=>V(s,this.hubOrigin))}async revoke(e){this.assertHubLoggedIn();const{data:a}=await this.doFetch("/deliverables/revoke",{method:"POST",body:JSON.stringify({localId:e})});return{...V(a,this.hubOrigin),status:"revoked",url:null}}}function me(t,e){return new pe({getHubToken:t,hubUrl:e,proxyBasePath:"/api/hub"})}const ge=/\.(png|jpe?g|gif|webp|svg|bmp|avif|ico)$/i,xe=/\.(mp4|webm|mp3|wav|ogg|m4a|mov|avi|mkv|flac)$/i;function K(t){return ge.test(t)?"image":xe.test(t)?"media":"other"}function ye(t){return t.replace(/^file:\/\//i,"").replace(/^file:/i,"")}function G(t){const e=t.match(/!?\[[^\]]*\]\(([^)]+)\)/);if(e)return e[1].trim().split(/\s+(?="|')/)[0].trim()||null;const a=t.match(/(?:src|href|poster)\s*=\s*["']([^"']+)["']/i);return a?a[1]:null}function X(t){return!t||/^(https?:|data:|mailto:|tel:|#)/i.test(t)||t.startsWith("//")?!1:(t.startsWith("/api/files/"),!0)}function J(t,e){if(!t)return null;const a=t.trim(),l=a.match(/^\/api\/files\/(?:image|stream|preview)\?path=([^&]+)/i);if(l)try{return decodeURIComponent(l[1])||null}catch{return l[1]||null}return/^file:\/\//i.test(a)?ye(a).replace(/\\/g,"/"):/^[a-zA-Z]:[\\/]/.test(a)?a.replace(/\\/g,"/"):a.startsWith("/")?a:e&&(a.startsWith("./")||a.startsWith("../")||!a.includes("://"))?`${e.replace(/\\/g,"/").replace(/\/+$/,"")}/${a.replace(/^\.\//,"").replace(/\\/g,"/")}`:null}function ve(t,e){const a=[],l=new Set,s=/!?\[[^\]]*\]\(([^)\s]+(?:\s+["'][^"']*["'])?)\)/g;for(const c of t.matchAll(s)){const o=c[0],d=G(o);if(!d||!X(d))continue;const h=J(d,e);!h||l.has(o)||(l.add(o),a.push({raw:o,localPath:h,kind:K(h.split("?")[0])}))}const i=/<[a-zA-Z][^>]*(?:src|href|poster)\s*=\s*["'][^"']+["'][^>]*>/gi;for(const c of t.matchAll(i)){const o=c[0],d=G(o);if(!d||!X(d))continue;const h=J(d,e);!h||l.has(o)||(l.add(o),a.push({raw:o,localPath:h,kind:K(h.split("?")[0])}))}return{refs:a,baseDir:e??""}}function ke(t,e){let a=t;for(const[l,s]of e){const i=we(l,s);a=a.split(l).join(i)}return a}function we(t,e){const a=t.match(/^(!?\[[^\]]*\])\([^)]*\)$/);if(a)return`${a[1]}(${e})`;const l=t.match(/(src|href|poster)(\s*=\s*)(["'])[^"']*\3/i);return l?t.replace(/(src|href|poster)(\s*=\s*)(["'])[^"']*\3/i,`${l[1]}${l[2]}${l[3]}${e}${l[3]}`):e}function je(t,e){return/^https?:\/\//i.test(t)?t:`${e.replace(/\/+$/,"")}${t.startsWith("/")?"":"/"}${t}`}function Ne(t,e,a){const l=new Map,s=new Map(t.map(i=>[i.localPath,i]));for(const i of e){if(!i.key)continue;const c=s.get(i.key);!c||!i.url||l.set(c.raw,je(i.url,a))}return l}async function He(t){try{const e=N.files.streamUrl(t),a=await fetch(e).then(d=>d.ok?d.blob():null);if(!a)return null;const l=await a.arrayBuffer(),s=new Uint8Array(l);let i="";const c=32768;for(let d=0;d<s.length;d+=c)i+=String.fromCharCode.apply(null,Array.from(s.subarray(d,d+c)));const o=t.split("/").pop()||"media";return{base64:btoa(i),filename:o}}catch{return null}}async function Ie(t,e){const a=new Map;if(t.length===0)return a;const l=[];for(const c of t){const o=await He(c.localPath);o&&l.push({key:c.localPath,filename:o.filename,base64:o.base64})}if(l.length===0)return a;const{files:s,errors:i}=await A.uploadMediaBatch(l);return i.length>0&&console.warn("[deliverable-share] media upload errors:",i),Ne(t,s,e)}async function Se(t,e,a){if(!t||e==="directory"||t.startsWith("http://")||t.startsWith("https://"))return{};try{const l=await N.files.preview(t);if((l.type==="text"||l.type==="markdown"||l.type==="html"||l.type==="json"||l.type==="csv")&&typeof l.content=="string"){if(!(l.type==="markdown"||l.type==="html"))return{content:l.content};const i=t.replace(/[/\\]/g,"/").split("/").slice(0,-1).join("/"),{refs:c}=ve(l.content,i);if(c.length===0)return{content:l.content};const o=await Ie(c,a);return o.size===0?{content:l.content}:{content:ke(l.content,o),uploadedMedia:o.size}}if(l.type==="image"||l.type==="audio"||l.type==="video"||l.type==="binary"){const s=l.streamUrl||(l.path?N.files.streamUrl(l.path):N.files.streamUrl(t)),c=await(await fetch(s).then(f=>f.blob())).arrayBuffer(),o=new Uint8Array(c);let d="";const h=32768;for(let f=0;f<o.length;f+=h)d+=String.fromCharCode.apply(null,Array.from(o.subarray(f,f+h)));return{fileBase64:btoa(d)}}return{}}catch{return{}}}function Ve({item:t,onClose:e,onShared:a,service:l}){const{t:s}=ce(["deliverables","common"]),i=u.useMemo(()=>l??me(de,A.getUrl()),[l]),[c,o]=u.useState(()=>i?i.isHubLoggedIn():null),[d,h]=u.useState(!1),[f,p]=u.useState(()=>{const n=t.shareStatus;return n==="published"?"published":n==="pending_review"?"pending_review":n==="rejected"?"rejected":"form"}),[m,B]=u.useState("public"),[I,Y]=u.useState(t.title||""),[C,q]=u.useState(t.summary||""),[g,$]=u.useState(Array.isArray(t.tags)?[...t.tags]:[]),[k,M]=u.useState(""),[L,Q]=u.useState(null),[R,P]=u.useState(!1),[S,x]=u.useState(null),U=u.useRef(a);U.current=a;const y=u.useCallback(n=>{Q(n);const b=n.status;p(b==="published"?"published":b==="rejected"?"rejected":b==="revoked"?"revoked":b==="pending_review"?"pending_review":"form"),U.current?.(n)},[]);u.useEffect(()=>{o(i.isHubLoggedIn())},[i]);const ee=u.useCallback(async()=>{h(!0),x(null);try{await ue({force:!0}),o(i.isHubLoggedIn())}catch{o(i.isHubLoggedIn())}finally{h(!1)}},[i]),E=u.useCallback(()=>{const n=k.trim().replace(/^#/,"");n&&!g.includes(n)&&$(b=>[...b,n]),M("")},[k,g]),te=u.useCallback(n=>{$(b=>b.filter(v=>v!==n))},[]),re=u.useCallback(n=>{n.key==="Enter"||n.key===","?(n.preventDefault(),E()):n.key==="Backspace"&&!k&&g.length&&$(b=>b.slice(0,-1))},[E,k,g.length]),se=u.useCallback(()=>{const n=L?.url??t.shareUrl;n&&navigator.clipboard?.writeText(n).then(()=>{P(!0),setTimeout(()=>P(!1),1500)}).catch(()=>{})},[L,t.shareUrl]),ae=u.useCallback(async()=>{x(null),p("busy");try{const n=t.reference.replace(/[/\\]/g,"/").split("/").pop()||"deliverable",b=A.getUrl(),{content:v,fileBase64:ne,uploadedMedia:W}=await Se(t.reference,t.type,b);W&&console.info(`[deliverable-share] uploaded ${W} local media reference(s) to Hub`);const w=t.agentId??"";let _=w;if(w)try{const{agents:ie}=await N.agents.list(),z=ie.find(oe=>oe.id===w);z&&(_=z.name||w)}catch{}const j=await i.publish({localId:t.id,title:I.trim()||t.title,summary:C.trim(),tags:g,visibility:m,filename:n,format:t.format||"markdown",content:v,fileBase64:ne,producerAgent:{id:w,name:_,source:"local"}});y(j),j.status==="rejected"?x(typeof j.reason=="string"&&j.reason?j.reason:"分享被拒绝"):e()}catch(n){if(p("form"),n instanceof Z){o(!1);return}x(n instanceof H||n instanceof Error?n.message:String(n))}},[i,t,I,C,g,m,y]),le=u.useCallback(async()=>{x(null);try{const n=await i.revoke(t.id);y({...n,status:"revoked",url:null})}catch(n){x(n instanceof H?n.message:String(n))}},[i,t.id,y]),D=u.useCallback(()=>{p("form"),x(null)},[]);u.useEffect(()=>{if(f!=="pending_review")return;let n=!1;const b=setInterval(async()=>{try{const v=await i.pollStatus(t.id);if(n)return;v.status!=="pending_review"&&y(v)}catch{}},8e3);return()=>{n=!0,clearInterval(b)}},[f,i,t.id,y]),u.useEffect(()=>{const n=b=>{b.key==="Escape"&&e()};return window.addEventListener("keydown",n),()=>window.removeEventListener("keydown",n)},[e]);const T=m==="link",F=L?.url??t.shareUrl;return r.jsxs("div",{className:"fixed inset-0 z-50 flex items-center justify-center p-4",onClick:e,children:[r.jsx("div",{className:"absolute inset-0 bg-black/50 backdrop-blur-sm"}),r.jsxs("div",{className:"relative bg-surface-primary rounded-2xl shadow-2xl border border-border-default w-full max-w-md max-h-[85vh] overflow-y-auto",onClick:n=>n.stopPropagation(),children:[r.jsxs("div",{className:"sticky top-0 bg-surface-primary/95 backdrop-blur-sm border-b border-border-default px-5 py-4 flex items-center justify-between rounded-t-2xl z-10",children:[r.jsx("h3",{className:"text-base font-semibold text-fg-primary",children:s("deliverables:share.title",{defaultValue:"分享到 Markus Hub"})}),r.jsx("button",{onClick:e,className:"p-1.5 rounded-lg hover:bg-surface-overlay transition-colors text-fg-tertiary hover:text-fg-primary",children:r.jsxs("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[r.jsx("line",{x1:"18",y1:"6",x2:"6",y2:"18"}),r.jsx("line",{x1:"6",y1:"6",x2:"18",y2:"18"})]})})]}),r.jsx("div",{className:"px-5 py-4 space-y-4",children:c===!1?r.jsxs("div",{className:"space-y-4 py-2",children:[r.jsxs("div",{className:"flex items-start gap-3 rounded-xl bg-amber-500/10 border border-amber-500/25 p-3",children:[r.jsx("span",{className:"text-lg",children:"🔑"}),r.jsx("p",{className:"text-sm text-fg-secondary",children:s("deliverables:share.needHubLogin",{defaultValue:"需登录 Markus Hub 账号后才能分享产出物。"})})]}),r.jsx("button",{onClick:()=>{ee()},disabled:d,className:"w-full px-3 py-2 text-sm font-medium rounded-lg bg-brand-600 text-white hover:bg-brand-500 transition-colors disabled:opacity-60",children:d?s("deliverables:share.loggingIn",{defaultValue:"正在打开登录…"}):s("deliverables:share.loginHub",{defaultValue:"登录 Markus Hub 账号"})}),r.jsx("p",{className:"text-[11px] text-fg-tertiary",children:s("deliverables:share.loginHint",{defaultValue:"解锁后将支持一键公开/链接分享产出物。"})})]}):r.jsx(r.Fragment,{children:f==="published"?r.jsxs("div",{className:"space-y-3",children:[r.jsxs("div",{className:"flex items-center gap-2",children:[r.jsx("span",{className:"px-2 py-0.5 text-[11px] rounded-full bg-green-500/15 text-green-500 font-medium",children:s("deliverables:share.published",{defaultValue:"已发布"})}),r.jsx("span",{className:"text-[11px] text-fg-tertiary",children:m==="link"?s("deliverables:share.linkVisibility",{defaultValue:"有链接可见"}):s("deliverables:share.publicVisibility",{defaultValue:"公开"})})]}),F?r.jsxs("div",{className:"flex items-center gap-2 bg-surface-elevated rounded-lg px-3 py-2",children:[r.jsx("span",{className:"text-xs text-fg-secondary font-mono break-all flex-1 select-all",children:F}),r.jsx("button",{onClick:se,className:`px-2 py-1 text-[10px] rounded transition-colors shrink-0 ${R?"bg-green-500/20 text-green-500":"bg-brand-600/20 text-brand-500 hover:bg-brand-600/30"}`,children:R?s("common:copied",{defaultValue:"已复制"}):s("common:copy",{defaultValue:"复制链接"})})]}):r.jsx("p",{className:"text-xs text-fg-tertiary",children:s("deliverables:share.urlPending",{defaultValue:"链接生成中,稍后刷新查看…"})}),r.jsx("button",{onClick:()=>{le()},className:"w-full px-3 py-2 text-xs font-medium rounded-lg text-red-500 border border-red-500/30 hover:bg-red-500/10 transition-colors",children:s("deliverables:share.revoke",{defaultValue:"取消分享"})})]}):f==="pending_review"?r.jsxs("div",{className:"space-y-3",children:[r.jsxs("div",{className:"flex items-center gap-2",children:[r.jsx("span",{className:"w-2.5 h-2.5 rounded-full bg-amber-500 animate-pulse"}),r.jsx("span",{className:"px-2 py-0.5 text-[11px] rounded-full bg-amber-500/15 text-amber-500 font-medium",children:s("deliverables:share.pendingReview",{defaultValue:"审核中"})})]}),r.jsx("p",{className:"text-sm text-fg-secondary",children:s("deliverables:share.pendingHint",{defaultValue:"你的产出物已提交审核,通过后将生成可分享链接。"})})]}):f==="rejected"?r.jsxs("div",{className:"space-y-3",children:[r.jsx("div",{className:"flex items-center gap-2",children:r.jsx("span",{className:"px-2 py-0.5 text-[11px] rounded-full bg-red-500/15 text-red-500 font-medium",children:s("deliverables:share.rejected",{defaultValue:"已拒绝"})})}),S&&r.jsx("div",{className:"rounded-lg bg-red-500/10 border border-red-500/25 px-3 py-2 text-xs text-red-500",children:S}),r.jsx("button",{onClick:D,className:"w-full px-3 py-2 text-sm font-medium rounded-lg bg-brand-600 text-white hover:bg-brand-500 transition-colors",children:s("deliverables:share.resubmit",{defaultValue:"重新提交"})})]}):f==="revoked"?r.jsxs("div",{className:"space-y-3",children:[r.jsx("p",{className:"text-sm text-fg-secondary",children:s("deliverables:share.revoked",{defaultValue:"已取消分享,该产出物不再公开可访问。"})}),r.jsx("button",{onClick:D,className:"w-full px-3 py-2 text-sm font-medium rounded-lg bg-brand-600 text-white hover:bg-brand-500 transition-colors",children:s("deliverables:share.shareAgain",{defaultValue:"重新分享"})})]}):r.jsxs(r.Fragment,{children:[r.jsxs("div",{className:"space-y-2",children:[r.jsx("div",{className:"text-[10px] text-fg-tertiary uppercase tracking-wider font-medium",children:s("deliverables:share.visibility",{defaultValue:"可见性"})}),r.jsxs("label",{className:`flex items-start gap-3 rounded-xl border p-3 cursor-pointer transition-colors ${T?"border-border-default hover:bg-surface-elevated":"border-brand-500/50 bg-brand-500/5"}`,children:[r.jsx("input",{type:"radio",name:"visibility",checked:!T,onChange:()=>B("public"),className:"mt-0.5 accent-brand-500"}),r.jsxs("span",{className:"space-y-0.5",children:[r.jsx("span",{className:"block text-sm font-medium text-fg-primary",children:s("deliverables:share.public",{defaultValue:"公开(所有人可见 + 搜索引擎)"})}),r.jsx("span",{className:"block text-[11px] text-fg-tertiary",children:s("deliverables:share.publicHint",{defaultValue:"公开产出物需经 Hub 审核后发布,发布后所有人可见并参与搜索"})})]})]}),r.jsxs("label",{className:`flex items-start gap-3 rounded-xl border p-3 cursor-pointer transition-colors ${T?"border-brand-500/50 bg-brand-500/5":"border-border-default hover:bg-surface-elevated"}`,children:[r.jsx("input",{type:"radio",name:"visibility",checked:T,onChange:()=>B("link"),className:"mt-0.5 accent-brand-500"}),r.jsxs("span",{className:"space-y-0.5",children:[r.jsx("span",{className:"block text-sm font-medium text-fg-primary",children:s("deliverables:share.link",{defaultValue:"有链接可见"})}),r.jsx("span",{className:"block text-[11px] text-fg-tertiary",children:s("deliverables:share.linkHint",{defaultValue:"仅获得链接的人可查看,不参与搜索引擎;同样需经 Hub 审核"})})]})]})]}),r.jsxs("div",{className:"space-y-1.5",children:[r.jsx("div",{className:"text-[10px] text-fg-tertiary uppercase tracking-wider font-medium",children:s("deliverables:share.titleField",{defaultValue:"标题"})}),r.jsx("input",{value:I,onChange:n=>Y(n.target.value),placeholder:s("deliverables:share.titlePlaceholder",{defaultValue:"清晰、可检索的标题"}),className:"w-full px-3 py-2 text-sm rounded-lg bg-surface-elevated border border-border-default focus:border-brand-500/60 outline-none"})]}),r.jsxs("div",{className:"space-y-1.5",children:[r.jsx("div",{className:"text-[10px] text-fg-tertiary uppercase tracking-wider font-medium",children:s("deliverables:share.summary",{defaultValue:"摘要"})}),r.jsx("textarea",{value:C,onChange:n=>q(n.target.value),rows:3,placeholder:s("deliverables:share.summaryPlaceholder",{defaultValue:"简要描述该产出物…"}),className:"w-full px-3 py-2 text-sm rounded-lg bg-surface-elevated border border-border-default focus:border-brand-500/60 outline-none resize-y"})]}),r.jsxs("div",{className:"space-y-1.5",children:[r.jsx("div",{className:"text-[10px] text-fg-tertiary uppercase tracking-wider font-medium",children:s("deliverables:share.tags",{defaultValue:"标签"})}),r.jsx("div",{className:"flex flex-wrap gap-1.5 mb-1.5",children:g.map(n=>r.jsxs("span",{className:"inline-flex items-center gap-1 px-2 py-0.5 text-[11px] bg-surface-elevated rounded-md text-fg-secondary",children:[n,r.jsx("button",{onClick:()=>te(n),className:"text-fg-tertiary hover:text-red-500","aria-label":"remove",children:r.jsxs("svg",{width:"10",height:"10",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2.5",children:[r.jsx("line",{x1:"18",y1:"6",x2:"6",y2:"18"}),r.jsx("line",{x1:"6",y1:"6",x2:"18",y2:"18"})]})})]},n))}),r.jsx("input",{value:k,onChange:n=>M(n.target.value),onKeyDown:re,onBlur:E,placeholder:s("deliverables:share.tagsPlaceholder",{defaultValue:"输入标签后回车添加"}),className:"w-full px-3 py-2 text-sm rounded-lg bg-surface-elevated border border-border-default focus:border-brand-500/60 outline-none"})]}),S&&r.jsx("div",{className:"rounded-lg bg-red-500/10 border border-red-500/25 px-3 py-2 text-xs text-red-500",children:S}),r.jsxs("button",{type:"button",onClick:()=>{ae()},disabled:f==="busy"||!I.trim(),className:"w-full px-3 py-2.5 text-sm font-medium rounded-lg bg-brand-600 text-white hover:bg-brand-500 transition-colors disabled:opacity-60 flex items-center justify-center gap-2",children:[f==="busy"&&r.jsxs("svg",{className:"animate-spin",width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",children:[r.jsx("circle",{cx:"12",cy:"12",r:"10",stroke:"currentColor",strokeWidth:"3",opacity:"0.25"}),r.jsx("path",{d:"M22 12a10 10 0 0 0-10-10",stroke:"currentColor",strokeWidth:"3",strokeLinecap:"round"})]}),f==="busy"?s("deliverables:share.sharing",{defaultValue:"分享中…"}):s("deliverables:share.shareToHub",{defaultValue:"分享到 Hub"})]})]})})})]})]})}export{Ve as D,me as c};
|
|
1
|
+
import{u as ce,r as u,h as A,o as de,t as ue,l as N,j as r}from"./index-CiAGgfZx.js";const O=50*1024*1024;class H extends Error{constructor(e){super(e),this.name="DeliverableShareError"}}class Z extends H{constructor(){super("需要登录 Markus Hub 账号后才能分享产出物。"),this.name="NotLoggedIntoHubError"}}class fe extends H{bytes;limit;constructor(e,a){super(`产出物文件大小 ${e} 字节超过上限 ${a} 字节(50MB),请压缩或拒绝分享。`),this.name="DeliverableTooLargeError",this.bytes=e,this.limit=a}}class he extends H{status;constructor(e,a){super(`Hub 请求失败 (HTTP ${e}): ${a}`),this.name="HubApiError",this.status=e}}function be(t){const e=t.replace(/\s+/g,"");if(!e)return 0;let a=0;return e.endsWith("==")?a=2:e.endsWith("=")&&(a=1),Math.floor(e.length*3/4)-a}function V(t,e){const a=t&&typeof t=="object"?t:{},l=a.share??a.deliverable??{},s=m=>a[m]??l[m],i=s("id")??s("shareId")??"",c=s("slug"),o=c!=null?String(c):void 0,d=s("url")??s("shareUrl");let h=null;d!=null?h=String(d):o&&e&&(h=`${e.replace(/\/+$/,"")}/deliverable/${encodeURIComponent(o)}`);const f=s("reason")??s("rejectNote"),p=s("localDeliverableId")??s("localId");return{id:String(i),slug:o,visibility:s("visibility")??"public",status:s("status")??"pending_review",url:h,reason:f!=null?String(f):null,localId:p!=null?String(p):null}}class pe{basePath;fetchImpl;hubOrigin;constructor(e){this.getHubToken=e.getHubToken,this.hubOrigin=e.hubUrl,this.basePath=(e.proxyBasePath??"/api/hub").replace(/\/+$/,""),this.fetchImpl=e.fetch??(globalThis.fetch?globalThis.fetch.bind(globalThis):(()=>{throw new Error("fetch unavailable")}))}getHubToken;isHubLoggedIn(){return!!this.getHubToken()}assertHubLoggedIn(){if(!this.getHubToken())throw new Z}async doFetch(e,a){const l=this.getHubToken(),s={"Content-Type":"application/json",...a.headers};l&&(s.Authorization=`Bearer ${l}`);const i=await this.fetchImpl(`${this.basePath}${e}`,{...a,headers:s,credentials:"include"});let c=null;try{c=await i.json()}catch{c=null}if(!i.ok){const o=c&&typeof c=="object"&&"error"in c?String(c.error):i.statusText||`HTTP ${i.status}`;throw new he(i.status,o)}return{status:i.status,data:c}}async publish(e){this.assertHubLoggedIn();const a=e.fileSizeBytes??(e.fileBase64?be(e.fileBase64):0);if(a>O)throw new fe(a,O);const l={localDeliverableId:e.localId,visibility:e.visibility,title:e.title,summary:e.summary,tags:e.tags,filename:e.filename,format:e.format,producerAgent:{id:e.producerAgent.id,name:e.producerAgent.name,source:e.producerAgent.source}};e.content&&(l.content=e.content),e.fileBase64&&(l.fileBase64=e.fileBase64);const{data:s}=await this.doFetch("/deliverables/publish",{method:"POST",body:JSON.stringify(l)});return V(s,this.hubOrigin)}async pollStatus(e){this.assertHubLoggedIn();const{data:a}=await this.doFetch(`/deliverables/status?localId=${encodeURIComponent(e)}`,{method:"GET"});return V(a,this.hubOrigin)}async listMine(){this.assertHubLoggedIn();const{data:e}=await this.doFetch("/deliverables/mine",{method:"GET"}),a=e&&typeof e=="object"?e:{};return(Array.isArray(a.shares)?a.shares:[]).map(s=>V(s,this.hubOrigin))}async revoke(e){this.assertHubLoggedIn();const{data:a}=await this.doFetch("/deliverables/revoke",{method:"POST",body:JSON.stringify({localId:e})});return{...V(a,this.hubOrigin),status:"revoked",url:null}}}function me(t,e){return new pe({getHubToken:t,hubUrl:e,proxyBasePath:"/api/hub"})}const ge=/\.(png|jpe?g|gif|webp|svg|bmp|avif|ico)$/i,xe=/\.(mp4|webm|mp3|wav|ogg|m4a|mov|avi|mkv|flac)$/i;function K(t){return ge.test(t)?"image":xe.test(t)?"media":"other"}function ye(t){return t.replace(/^file:\/\//i,"").replace(/^file:/i,"")}function G(t){const e=t.match(/!?\[[^\]]*\]\(([^)]+)\)/);if(e)return e[1].trim().split(/\s+(?="|')/)[0].trim()||null;const a=t.match(/(?:src|href|poster)\s*=\s*["']([^"']+)["']/i);return a?a[1]:null}function X(t){return!t||/^(https?:|data:|mailto:|tel:|#)/i.test(t)||t.startsWith("//")?!1:(t.startsWith("/api/files/"),!0)}function J(t,e){if(!t)return null;const a=t.trim(),l=a.match(/^\/api\/files\/(?:image|stream|preview)\?path=([^&]+)/i);if(l)try{return decodeURIComponent(l[1])||null}catch{return l[1]||null}return/^file:\/\//i.test(a)?ye(a).replace(/\\/g,"/"):/^[a-zA-Z]:[\\/]/.test(a)?a.replace(/\\/g,"/"):a.startsWith("/")?a:e&&(a.startsWith("./")||a.startsWith("../")||!a.includes("://"))?`${e.replace(/\\/g,"/").replace(/\/+$/,"")}/${a.replace(/^\.\//,"").replace(/\\/g,"/")}`:null}function ve(t,e){const a=[],l=new Set,s=/!?\[[^\]]*\]\(([^)\s]+(?:\s+["'][^"']*["'])?)\)/g;for(const c of t.matchAll(s)){const o=c[0],d=G(o);if(!d||!X(d))continue;const h=J(d,e);!h||l.has(o)||(l.add(o),a.push({raw:o,localPath:h,kind:K(h.split("?")[0])}))}const i=/<[a-zA-Z][^>]*(?:src|href|poster)\s*=\s*["'][^"']+["'][^>]*>/gi;for(const c of t.matchAll(i)){const o=c[0],d=G(o);if(!d||!X(d))continue;const h=J(d,e);!h||l.has(o)||(l.add(o),a.push({raw:o,localPath:h,kind:K(h.split("?")[0])}))}return{refs:a,baseDir:e??""}}function ke(t,e){let a=t;for(const[l,s]of e){const i=we(l,s);a=a.split(l).join(i)}return a}function we(t,e){const a=t.match(/^(!?\[[^\]]*\])\([^)]*\)$/);if(a)return`${a[1]}(${e})`;const l=t.match(/(src|href|poster)(\s*=\s*)(["'])[^"']*\3/i);return l?t.replace(/(src|href|poster)(\s*=\s*)(["'])[^"']*\3/i,`${l[1]}${l[2]}${l[3]}${e}${l[3]}`):e}function je(t,e){return/^https?:\/\//i.test(t)?t:`${e.replace(/\/+$/,"")}${t.startsWith("/")?"":"/"}${t}`}function Ne(t,e,a){const l=new Map,s=new Map(t.map(i=>[i.localPath,i]));for(const i of e){if(!i.key)continue;const c=s.get(i.key);!c||!i.url||l.set(c.raw,je(i.url,a))}return l}async function He(t){try{const e=N.files.streamUrl(t),a=await fetch(e).then(d=>d.ok?d.blob():null);if(!a)return null;const l=await a.arrayBuffer(),s=new Uint8Array(l);let i="";const c=32768;for(let d=0;d<s.length;d+=c)i+=String.fromCharCode.apply(null,Array.from(s.subarray(d,d+c)));const o=t.split("/").pop()||"media";return{base64:btoa(i),filename:o}}catch{return null}}async function Ie(t,e){const a=new Map;if(t.length===0)return a;const l=[];for(const c of t){const o=await He(c.localPath);o&&l.push({key:c.localPath,filename:o.filename,base64:o.base64})}if(l.length===0)return a;const{files:s,errors:i}=await A.uploadMediaBatch(l);return i.length>0&&console.warn("[deliverable-share] media upload errors:",i),Ne(t,s,e)}async function Se(t,e,a){if(!t||e==="directory"||t.startsWith("http://")||t.startsWith("https://"))return{};try{const l=await N.files.preview(t);if((l.type==="text"||l.type==="markdown"||l.type==="html"||l.type==="json"||l.type==="csv")&&typeof l.content=="string"){if(!(l.type==="markdown"||l.type==="html"))return{content:l.content};const i=t.replace(/[/\\]/g,"/").split("/").slice(0,-1).join("/"),{refs:c}=ve(l.content,i);if(c.length===0)return{content:l.content};const o=await Ie(c,a);return o.size===0?{content:l.content}:{content:ke(l.content,o),uploadedMedia:o.size}}if(l.type==="image"||l.type==="audio"||l.type==="video"||l.type==="binary"){const s=l.streamUrl||(l.path?N.files.streamUrl(l.path):N.files.streamUrl(t)),c=await(await fetch(s).then(f=>f.blob())).arrayBuffer(),o=new Uint8Array(c);let d="";const h=32768;for(let f=0;f<o.length;f+=h)d+=String.fromCharCode.apply(null,Array.from(o.subarray(f,f+h)));return{fileBase64:btoa(d)}}return{}}catch{return{}}}function Ve({item:t,onClose:e,onShared:a,service:l}){const{t:s}=ce(["deliverables","common"]),i=u.useMemo(()=>l??me(de,A.getUrl()),[l]),[c,o]=u.useState(()=>i?i.isHubLoggedIn():null),[d,h]=u.useState(!1),[f,p]=u.useState(()=>{const n=t.shareStatus;return n==="published"?"published":n==="pending_review"?"pending_review":n==="rejected"?"rejected":"form"}),[m,B]=u.useState("public"),[I,Y]=u.useState(t.title||""),[C,q]=u.useState(t.summary||""),[g,$]=u.useState(Array.isArray(t.tags)?[...t.tags]:[]),[k,M]=u.useState(""),[L,Q]=u.useState(null),[R,P]=u.useState(!1),[S,x]=u.useState(null),U=u.useRef(a);U.current=a;const y=u.useCallback(n=>{Q(n);const b=n.status;p(b==="published"?"published":b==="rejected"?"rejected":b==="revoked"?"revoked":b==="pending_review"?"pending_review":"form"),U.current?.(n)},[]);u.useEffect(()=>{o(i.isHubLoggedIn())},[i]);const ee=u.useCallback(async()=>{h(!0),x(null);try{await ue({force:!0}),o(i.isHubLoggedIn())}catch{o(i.isHubLoggedIn())}finally{h(!1)}},[i]),E=u.useCallback(()=>{const n=k.trim().replace(/^#/,"");n&&!g.includes(n)&&$(b=>[...b,n]),M("")},[k,g]),te=u.useCallback(n=>{$(b=>b.filter(v=>v!==n))},[]),re=u.useCallback(n=>{n.key==="Enter"||n.key===","?(n.preventDefault(),E()):n.key==="Backspace"&&!k&&g.length&&$(b=>b.slice(0,-1))},[E,k,g.length]),se=u.useCallback(()=>{const n=L?.url??t.shareUrl;n&&navigator.clipboard?.writeText(n).then(()=>{P(!0),setTimeout(()=>P(!1),1500)}).catch(()=>{})},[L,t.shareUrl]),ae=u.useCallback(async()=>{x(null),p("busy");try{const n=t.reference.replace(/[/\\]/g,"/").split("/").pop()||"deliverable",b=A.getUrl(),{content:v,fileBase64:ne,uploadedMedia:W}=await Se(t.reference,t.type,b);W&&console.info(`[deliverable-share] uploaded ${W} local media reference(s) to Hub`);const w=t.agentId??"";let _=w;if(w)try{const{agents:ie}=await N.agents.list(),z=ie.find(oe=>oe.id===w);z&&(_=z.name||w)}catch{}const j=await i.publish({localId:t.id,title:I.trim()||t.title,summary:C.trim(),tags:g,visibility:m,filename:n,format:t.format||"markdown",content:v,fileBase64:ne,producerAgent:{id:w,name:_,source:"local"}});y(j),j.status==="rejected"?x(typeof j.reason=="string"&&j.reason?j.reason:"分享被拒绝"):e()}catch(n){if(p("form"),n instanceof Z){o(!1);return}x(n instanceof H||n instanceof Error?n.message:String(n))}},[i,t,I,C,g,m,y]),le=u.useCallback(async()=>{x(null);try{const n=await i.revoke(t.id);y({...n,status:"revoked",url:null})}catch(n){x(n instanceof H?n.message:String(n))}},[i,t.id,y]),D=u.useCallback(()=>{p("form"),x(null)},[]);u.useEffect(()=>{if(f!=="pending_review")return;let n=!1;const b=setInterval(async()=>{try{const v=await i.pollStatus(t.id);if(n)return;v.status!=="pending_review"&&y(v)}catch{}},8e3);return()=>{n=!0,clearInterval(b)}},[f,i,t.id,y]),u.useEffect(()=>{const n=b=>{b.key==="Escape"&&e()};return window.addEventListener("keydown",n),()=>window.removeEventListener("keydown",n)},[e]);const T=m==="link",F=L?.url??t.shareUrl;return r.jsxs("div",{className:"fixed inset-0 z-50 flex items-center justify-center p-4",onClick:e,children:[r.jsx("div",{className:"absolute inset-0 bg-black/50 backdrop-blur-sm"}),r.jsxs("div",{className:"relative bg-surface-primary rounded-2xl shadow-2xl border border-border-default w-full max-w-md max-h-[85vh] overflow-y-auto",onClick:n=>n.stopPropagation(),children:[r.jsxs("div",{className:"sticky top-0 bg-surface-primary/95 backdrop-blur-sm border-b border-border-default px-5 py-4 flex items-center justify-between rounded-t-2xl z-10",children:[r.jsx("h3",{className:"text-base font-semibold text-fg-primary",children:s("deliverables:share.title",{defaultValue:"分享到 Markus Hub"})}),r.jsx("button",{onClick:e,className:"p-1.5 rounded-lg hover:bg-surface-overlay transition-colors text-fg-tertiary hover:text-fg-primary",children:r.jsxs("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[r.jsx("line",{x1:"18",y1:"6",x2:"6",y2:"18"}),r.jsx("line",{x1:"6",y1:"6",x2:"18",y2:"18"})]})})]}),r.jsx("div",{className:"px-5 py-4 space-y-4",children:c===!1?r.jsxs("div",{className:"space-y-4 py-2",children:[r.jsxs("div",{className:"flex items-start gap-3 rounded-xl bg-amber-500/10 border border-amber-500/25 p-3",children:[r.jsx("span",{className:"text-lg",children:"🔑"}),r.jsx("p",{className:"text-sm text-fg-secondary",children:s("deliverables:share.needHubLogin",{defaultValue:"需登录 Markus Hub 账号后才能分享产出物。"})})]}),r.jsx("button",{onClick:()=>{ee()},disabled:d,className:"w-full px-3 py-2 text-sm font-medium rounded-lg bg-brand-600 text-white hover:bg-brand-500 transition-colors disabled:opacity-60",children:d?s("deliverables:share.loggingIn",{defaultValue:"正在打开登录…"}):s("deliverables:share.loginHub",{defaultValue:"登录 Markus Hub 账号"})}),r.jsx("p",{className:"text-[11px] text-fg-tertiary",children:s("deliverables:share.loginHint",{defaultValue:"解锁后将支持一键公开/链接分享产出物。"})})]}):r.jsx(r.Fragment,{children:f==="published"?r.jsxs("div",{className:"space-y-3",children:[r.jsxs("div",{className:"flex items-center gap-2",children:[r.jsx("span",{className:"px-2 py-0.5 text-[11px] rounded-full bg-green-500/15 text-green-500 font-medium",children:s("deliverables:share.published",{defaultValue:"已发布"})}),r.jsx("span",{className:"text-[11px] text-fg-tertiary",children:m==="link"?s("deliverables:share.linkVisibility",{defaultValue:"有链接可见"}):s("deliverables:share.publicVisibility",{defaultValue:"公开"})})]}),F?r.jsxs("div",{className:"flex items-center gap-2 bg-surface-elevated rounded-lg px-3 py-2",children:[r.jsx("span",{className:"text-xs text-fg-secondary font-mono break-all flex-1 select-all",children:F}),r.jsx("button",{onClick:se,className:`px-2 py-1 text-[10px] rounded transition-colors shrink-0 ${R?"bg-green-500/20 text-green-500":"bg-brand-600/20 text-brand-500 hover:bg-brand-600/30"}`,children:R?s("common:copied",{defaultValue:"已复制"}):s("common:copy",{defaultValue:"复制链接"})})]}):r.jsx("p",{className:"text-xs text-fg-tertiary",children:s("deliverables:share.urlPending",{defaultValue:"链接生成中,稍后刷新查看…"})}),r.jsx("button",{onClick:()=>{le()},className:"w-full px-3 py-2 text-xs font-medium rounded-lg text-red-500 border border-red-500/30 hover:bg-red-500/10 transition-colors",children:s("deliverables:share.revoke",{defaultValue:"取消分享"})})]}):f==="pending_review"?r.jsxs("div",{className:"space-y-3",children:[r.jsxs("div",{className:"flex items-center gap-2",children:[r.jsx("span",{className:"w-2.5 h-2.5 rounded-full bg-amber-500 animate-pulse"}),r.jsx("span",{className:"px-2 py-0.5 text-[11px] rounded-full bg-amber-500/15 text-amber-500 font-medium",children:s("deliverables:share.pendingReview",{defaultValue:"审核中"})})]}),r.jsx("p",{className:"text-sm text-fg-secondary",children:s("deliverables:share.pendingHint",{defaultValue:"你的产出物已提交审核,通过后将生成可分享链接。"})})]}):f==="rejected"?r.jsxs("div",{className:"space-y-3",children:[r.jsx("div",{className:"flex items-center gap-2",children:r.jsx("span",{className:"px-2 py-0.5 text-[11px] rounded-full bg-red-500/15 text-red-500 font-medium",children:s("deliverables:share.rejected",{defaultValue:"已拒绝"})})}),S&&r.jsx("div",{className:"rounded-lg bg-red-500/10 border border-red-500/25 px-3 py-2 text-xs text-red-500",children:S}),r.jsx("button",{onClick:D,className:"w-full px-3 py-2 text-sm font-medium rounded-lg bg-brand-600 text-white hover:bg-brand-500 transition-colors",children:s("deliverables:share.resubmit",{defaultValue:"重新提交"})})]}):f==="revoked"?r.jsxs("div",{className:"space-y-3",children:[r.jsx("p",{className:"text-sm text-fg-secondary",children:s("deliverables:share.revoked",{defaultValue:"已取消分享,该产出物不再公开可访问。"})}),r.jsx("button",{onClick:D,className:"w-full px-3 py-2 text-sm font-medium rounded-lg bg-brand-600 text-white hover:bg-brand-500 transition-colors",children:s("deliverables:share.shareAgain",{defaultValue:"重新分享"})})]}):r.jsxs(r.Fragment,{children:[r.jsxs("div",{className:"space-y-2",children:[r.jsx("div",{className:"text-[10px] text-fg-tertiary uppercase tracking-wider font-medium",children:s("deliverables:share.visibility",{defaultValue:"可见性"})}),r.jsxs("label",{className:`flex items-start gap-3 rounded-xl border p-3 cursor-pointer transition-colors ${T?"border-border-default hover:bg-surface-elevated":"border-brand-500/50 bg-brand-500/5"}`,children:[r.jsx("input",{type:"radio",name:"visibility",checked:!T,onChange:()=>B("public"),className:"mt-0.5 accent-brand-500"}),r.jsxs("span",{className:"space-y-0.5",children:[r.jsx("span",{className:"block text-sm font-medium text-fg-primary",children:s("deliverables:share.public",{defaultValue:"公开(所有人可见 + 搜索引擎)"})}),r.jsx("span",{className:"block text-[11px] text-fg-tertiary",children:s("deliverables:share.publicHint",{defaultValue:"公开产出物需经 Hub 审核后发布,发布后所有人可见并参与搜索"})})]})]}),r.jsxs("label",{className:`flex items-start gap-3 rounded-xl border p-3 cursor-pointer transition-colors ${T?"border-brand-500/50 bg-brand-500/5":"border-border-default hover:bg-surface-elevated"}`,children:[r.jsx("input",{type:"radio",name:"visibility",checked:T,onChange:()=>B("link"),className:"mt-0.5 accent-brand-500"}),r.jsxs("span",{className:"space-y-0.5",children:[r.jsx("span",{className:"block text-sm font-medium text-fg-primary",children:s("deliverables:share.link",{defaultValue:"有链接可见"})}),r.jsx("span",{className:"block text-[11px] text-fg-tertiary",children:s("deliverables:share.linkHint",{defaultValue:"仅获得链接的人可查看,不参与搜索引擎;同样需经 Hub 审核"})})]})]})]}),r.jsxs("div",{className:"space-y-1.5",children:[r.jsx("div",{className:"text-[10px] text-fg-tertiary uppercase tracking-wider font-medium",children:s("deliverables:share.titleField",{defaultValue:"标题"})}),r.jsx("input",{value:I,onChange:n=>Y(n.target.value),placeholder:s("deliverables:share.titlePlaceholder",{defaultValue:"清晰、可检索的标题"}),className:"w-full px-3 py-2 text-sm rounded-lg bg-surface-elevated border border-border-default focus:border-brand-500/60 outline-none"})]}),r.jsxs("div",{className:"space-y-1.5",children:[r.jsx("div",{className:"text-[10px] text-fg-tertiary uppercase tracking-wider font-medium",children:s("deliverables:share.summary",{defaultValue:"摘要"})}),r.jsx("textarea",{value:C,onChange:n=>q(n.target.value),rows:3,placeholder:s("deliverables:share.summaryPlaceholder",{defaultValue:"简要描述该产出物…"}),className:"w-full px-3 py-2 text-sm rounded-lg bg-surface-elevated border border-border-default focus:border-brand-500/60 outline-none resize-y"})]}),r.jsxs("div",{className:"space-y-1.5",children:[r.jsx("div",{className:"text-[10px] text-fg-tertiary uppercase tracking-wider font-medium",children:s("deliverables:share.tags",{defaultValue:"标签"})}),r.jsx("div",{className:"flex flex-wrap gap-1.5 mb-1.5",children:g.map(n=>r.jsxs("span",{className:"inline-flex items-center gap-1 px-2 py-0.5 text-[11px] bg-surface-elevated rounded-md text-fg-secondary",children:[n,r.jsx("button",{onClick:()=>te(n),className:"text-fg-tertiary hover:text-red-500","aria-label":"remove",children:r.jsxs("svg",{width:"10",height:"10",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2.5",children:[r.jsx("line",{x1:"18",y1:"6",x2:"6",y2:"18"}),r.jsx("line",{x1:"6",y1:"6",x2:"18",y2:"18"})]})})]},n))}),r.jsx("input",{value:k,onChange:n=>M(n.target.value),onKeyDown:re,onBlur:E,placeholder:s("deliverables:share.tagsPlaceholder",{defaultValue:"输入标签后回车添加"}),className:"w-full px-3 py-2 text-sm rounded-lg bg-surface-elevated border border-border-default focus:border-brand-500/60 outline-none"})]}),S&&r.jsx("div",{className:"rounded-lg bg-red-500/10 border border-red-500/25 px-3 py-2 text-xs text-red-500",children:S}),r.jsxs("button",{type:"button",onClick:()=>{ae()},disabled:f==="busy"||!I.trim(),className:"w-full px-3 py-2.5 text-sm font-medium rounded-lg bg-brand-600 text-white hover:bg-brand-500 transition-colors disabled:opacity-60 flex items-center justify-center gap-2",children:[f==="busy"&&r.jsxs("svg",{className:"animate-spin",width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",children:[r.jsx("circle",{cx:"12",cy:"12",r:"10",stroke:"currentColor",strokeWidth:"3",opacity:"0.25"}),r.jsx("path",{d:"M22 12a10 10 0 0 0-10-10",stroke:"currentColor",strokeWidth:"3",strokeLinecap:"round"})]}),f==="busy"?s("deliverables:share.sharing",{defaultValue:"分享中…"}):s("deliverables:share.shareToHub",{defaultValue:"分享到 Hub"})]})]})})})]})]})}export{Ve as D,me as c};
|