paperclip-plugin-telegram 0.7.1 → 0.8.0
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/README.md +5 -5
- package/dist/acp-bridge.d.ts +9 -2
- package/dist/acp-bridge.js +65 -7
- package/dist/acp-bridge.js.map +1 -1
- package/dist/agent-status.d.ts +26 -0
- package/dist/agent-status.js +33 -0
- package/dist/agent-status.js.map +1 -0
- package/dist/commands.js +41 -9
- package/dist/commands.js.map +1 -1
- package/dist/constants.d.ts +1 -1
- package/dist/constants.js +1 -1
- package/dist/escalation.d.ts +1 -1
- package/dist/escalation.js +3 -1
- package/dist/escalation.js.map +1 -1
- package/dist/formatters.js +17 -5
- package/dist/formatters.js.map +1 -1
- package/dist/manifest.js +27 -0
- package/dist/manifest.js.map +1 -1
- package/dist/media-pipeline.js +12 -3
- package/dist/media-pipeline.js.map +1 -1
- package/dist/runtime-token.d.ts +10 -3
- package/dist/runtime-token.js +18 -8
- package/dist/runtime-token.js.map +1 -1
- package/dist/secret-ref-validation.d.ts +29 -1
- package/dist/secret-ref-validation.js +33 -1
- package/dist/secret-ref-validation.js.map +1 -1
- package/dist/ui/index.js +90 -36
- package/dist/ui/index.js.map +1 -1
- package/dist/watch-registry.d.ts +1 -1
- package/dist/watch-registry.js +7 -6
- package/dist/watch-registry.js.map +1 -1
- package/dist/worker.d.ts +1 -0
- package/dist/worker.js +715 -424
- package/dist/worker.js.map +1 -1
- package/package.json +4 -4
|
@@ -5,11 +5,43 @@ const FIELDS = [
|
|
|
5
5
|
{ key: "transcriptionApiKeyRef", required: false },
|
|
6
6
|
];
|
|
7
7
|
export function isValidSecretRef(value) {
|
|
8
|
-
|
|
8
|
+
if (typeof value === "string")
|
|
9
|
+
return UUID_RE.test(value.trim());
|
|
10
|
+
if (typeof value === "object" && value !== null) {
|
|
11
|
+
const record = value;
|
|
12
|
+
return (record.type === "secret_ref" &&
|
|
13
|
+
typeof record.secretId === "string" &&
|
|
14
|
+
UUID_RE.test(record.secretId.trim()));
|
|
15
|
+
}
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Coerce a secret ref into the shape THIS host accepts before calling
|
|
20
|
+
* ctx.secrets.resolve().
|
|
21
|
+
*
|
|
22
|
+
* Refs reach us in both shapes: config validated by a current host holds
|
|
23
|
+
* `{ type: "secret_ref", secretId }`, while refs persisted earlier — notably
|
|
24
|
+
* the board-access state written by the Board Access panel — hold a bare UUID
|
|
25
|
+
* string. Hosts that require the object form reject the bare string with
|
|
26
|
+
* "Invalid secret reference for plugin: <uuid>. Use { type: "secret_ref" ... }",
|
|
27
|
+
* which surfaces to the user as an unexplained 403 from whatever the token was
|
|
28
|
+
* needed for.
|
|
29
|
+
*
|
|
30
|
+
* Passing the object through unchanged keeps older hosts working, since they
|
|
31
|
+
* accept it as an opaque ref.
|
|
32
|
+
*/
|
|
33
|
+
export function normalizeSecretRef(value) {
|
|
34
|
+
if (typeof value === "string") {
|
|
35
|
+
const trimmed = value.trim();
|
|
36
|
+
return UUID_RE.test(trimmed) ? { type: "secret_ref", secretId: trimmed } : null;
|
|
37
|
+
}
|
|
38
|
+
return isValidSecretRef(value) ? value : null;
|
|
9
39
|
}
|
|
10
40
|
function describeBadValue(value) {
|
|
11
41
|
if (value === undefined || value === null)
|
|
12
42
|
return "<empty>";
|
|
43
|
+
if (typeof value === "object")
|
|
44
|
+
return "<object>";
|
|
13
45
|
if (typeof value !== "string")
|
|
14
46
|
return `<${typeof value}>`;
|
|
15
47
|
const trimmed = value.trim();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"secret-ref-validation.js","sourceRoot":"","sources":["../src/secret-ref-validation.ts"],"names":[],"mappings":"AAMA,MAAM,OAAO,GAAG,iEAAiE,CAAC;AAElF,MAAM,MAAM,GAAG;IACb,EAAE,GAAG,EAAE,qBAAqB,EAAE,QAAQ,EAAE,IAAI,EAAE;IAC9C,EAAE,GAAG,EAAE,2BAA2B,EAAE,QAAQ,EAAE,KAAK,EAAE;IACrD,EAAE,GAAG,EAAE,wBAAwB,EAAE,QAAQ,EAAE,KAAK,EAAE;CAC1C,CAAC;
|
|
1
|
+
{"version":3,"file":"secret-ref-validation.js","sourceRoot":"","sources":["../src/secret-ref-validation.ts"],"names":[],"mappings":"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"}
|
package/dist/ui/index.js
CHANGED
|
@@ -345,14 +345,23 @@ async function fetchBoardAccessIdentity(boardApiToken) {
|
|
|
345
345
|
});
|
|
346
346
|
return getIdentityLabel(identity);
|
|
347
347
|
}
|
|
348
|
-
|
|
349
|
-
const
|
|
348
|
+
function pluginConfigPath(companyId) {
|
|
349
|
+
const base = `/api/plugins/${encodeURIComponent(TELEGRAM_PLUGIN_ID)}/config`;
|
|
350
|
+
const scopedCompanyId = companyId?.trim();
|
|
351
|
+
return scopedCompanyId ? `${base}?companyId=${encodeURIComponent(scopedCompanyId)}` : base;
|
|
352
|
+
}
|
|
353
|
+
async function fetchPluginConfig(companyId) {
|
|
354
|
+
const record = await fetchHostJson(pluginConfigPath(companyId));
|
|
350
355
|
return record?.configJson && typeof record.configJson === "object" ? record.configJson : {};
|
|
351
356
|
}
|
|
352
|
-
async function
|
|
353
|
-
|
|
357
|
+
async function fetchCompanySecrets(companyId) {
|
|
358
|
+
return fetchHostJson(`/api/companies/${encodeURIComponent(companyId)}/secrets`);
|
|
359
|
+
}
|
|
360
|
+
async function savePluginConfig(configJson, companyId) {
|
|
361
|
+
const scopedCompanyId = companyId?.trim();
|
|
362
|
+
await fetchHostJson(pluginConfigPath(), {
|
|
354
363
|
method: "POST",
|
|
355
|
-
body: JSON.stringify({ configJson }),
|
|
364
|
+
body: JSON.stringify(scopedCompanyId ? { configJson, companyId: scopedCompanyId } : { configJson }),
|
|
356
365
|
});
|
|
357
366
|
}
|
|
358
367
|
async function resolveOrCreateCompanySecret(companyId, name, value) {
|
|
@@ -426,7 +435,7 @@ export function TelegramSettingsPage({ context }) {
|
|
|
426
435
|
setRoutingLoading(true);
|
|
427
436
|
setRoutingMessage(null);
|
|
428
437
|
try {
|
|
429
|
-
const config = await fetchPluginConfig();
|
|
438
|
+
const config = await fetchPluginConfig(companyId);
|
|
430
439
|
if (cancelled)
|
|
431
440
|
return;
|
|
432
441
|
const nextRoutingConfig = extractRoutingConfig(config);
|
|
@@ -452,14 +461,14 @@ export function TelegramSettingsPage({ context }) {
|
|
|
452
461
|
return () => {
|
|
453
462
|
cancelled = true;
|
|
454
463
|
};
|
|
455
|
-
}, []);
|
|
464
|
+
}, [companyId]);
|
|
456
465
|
useEffect(() => {
|
|
457
466
|
let cancelled = false;
|
|
458
467
|
async function loadProactiveConfig() {
|
|
459
468
|
setProactiveLoading(true);
|
|
460
469
|
setProactiveMessage(null);
|
|
461
470
|
try {
|
|
462
|
-
const config = await fetchPluginConfig();
|
|
471
|
+
const config = await fetchPluginConfig(companyId);
|
|
463
472
|
if (cancelled)
|
|
464
473
|
return;
|
|
465
474
|
const nextProactiveConfig = extractProactiveConfig(config);
|
|
@@ -485,14 +494,14 @@ export function TelegramSettingsPage({ context }) {
|
|
|
485
494
|
return () => {
|
|
486
495
|
cancelled = true;
|
|
487
496
|
};
|
|
488
|
-
}, []);
|
|
497
|
+
}, [companyId]);
|
|
489
498
|
useEffect(() => {
|
|
490
499
|
let cancelled = false;
|
|
491
500
|
async function loadEscalationConfig() {
|
|
492
501
|
setEscalationLoading(true);
|
|
493
502
|
setEscalationMessage(null);
|
|
494
503
|
try {
|
|
495
|
-
const config = await fetchPluginConfig();
|
|
504
|
+
const config = await fetchPluginConfig(companyId);
|
|
496
505
|
if (cancelled)
|
|
497
506
|
return;
|
|
498
507
|
const nextEscalationConfig = extractEscalationConfig(config);
|
|
@@ -518,14 +527,14 @@ export function TelegramSettingsPage({ context }) {
|
|
|
518
527
|
return () => {
|
|
519
528
|
cancelled = true;
|
|
520
529
|
};
|
|
521
|
-
}, []);
|
|
530
|
+
}, [companyId]);
|
|
522
531
|
useEffect(() => {
|
|
523
532
|
let cancelled = false;
|
|
524
533
|
async function loadMediaConfig() {
|
|
525
534
|
setMediaLoading(true);
|
|
526
535
|
setMediaMessage(null);
|
|
527
536
|
try {
|
|
528
|
-
const config = await fetchPluginConfig();
|
|
537
|
+
const config = await fetchPluginConfig(companyId);
|
|
529
538
|
if (cancelled)
|
|
530
539
|
return;
|
|
531
540
|
const nextMediaConfig = extractMediaConfig(config);
|
|
@@ -551,14 +560,14 @@ export function TelegramSettingsPage({ context }) {
|
|
|
551
560
|
return () => {
|
|
552
561
|
cancelled = true;
|
|
553
562
|
};
|
|
554
|
-
}, []);
|
|
563
|
+
}, [companyId]);
|
|
555
564
|
useEffect(() => {
|
|
556
565
|
let cancelled = false;
|
|
557
566
|
async function loadAccessConfig() {
|
|
558
567
|
setAccessLoading(true);
|
|
559
568
|
setAccessMessage(null);
|
|
560
569
|
try {
|
|
561
|
-
const config = await fetchPluginConfig();
|
|
570
|
+
const config = await fetchPluginConfig(companyId);
|
|
562
571
|
if (cancelled)
|
|
563
572
|
return;
|
|
564
573
|
const nextAccessConfig = extractAccessConfig(config);
|
|
@@ -584,14 +593,14 @@ export function TelegramSettingsPage({ context }) {
|
|
|
584
593
|
return () => {
|
|
585
594
|
cancelled = true;
|
|
586
595
|
};
|
|
587
|
-
}, []);
|
|
596
|
+
}, [companyId]);
|
|
588
597
|
useEffect(() => {
|
|
589
598
|
let cancelled = false;
|
|
590
599
|
async function loadConnectionConfig() {
|
|
591
600
|
setConnectionLoading(true);
|
|
592
601
|
setConnectionMessage(null);
|
|
593
602
|
try {
|
|
594
|
-
const config = await fetchPluginConfig();
|
|
603
|
+
const config = await fetchPluginConfig(companyId);
|
|
595
604
|
if (cancelled)
|
|
596
605
|
return;
|
|
597
606
|
const nextConnectionConfig = extractConnectionConfig(config);
|
|
@@ -617,14 +626,14 @@ export function TelegramSettingsPage({ context }) {
|
|
|
617
626
|
return () => {
|
|
618
627
|
cancelled = true;
|
|
619
628
|
};
|
|
620
|
-
}, []);
|
|
629
|
+
}, [companyId]);
|
|
621
630
|
useEffect(() => {
|
|
622
631
|
let cancelled = false;
|
|
623
632
|
async function loadBoardConfig() {
|
|
624
633
|
setBoardConfigLoading(true);
|
|
625
634
|
setBoardConfigMessage(null);
|
|
626
635
|
try {
|
|
627
|
-
const config = await fetchPluginConfig();
|
|
636
|
+
const config = await fetchPluginConfig(companyId);
|
|
628
637
|
if (cancelled)
|
|
629
638
|
return;
|
|
630
639
|
const nextBoardConfig = extractBoardConfig(config);
|
|
@@ -650,7 +659,7 @@ export function TelegramSettingsPage({ context }) {
|
|
|
650
659
|
return () => {
|
|
651
660
|
cancelled = true;
|
|
652
661
|
};
|
|
653
|
-
}, []);
|
|
662
|
+
}, [companyId]);
|
|
654
663
|
function updateRoutingField(key, value) {
|
|
655
664
|
setRoutingConfig((current) => ({ ...current, [key]: value }));
|
|
656
665
|
setRoutingMessage(null);
|
|
@@ -683,9 +692,9 @@ export function TelegramSettingsPage({ context }) {
|
|
|
683
692
|
setBoardConfigSaving(true);
|
|
684
693
|
setBoardConfigMessage(null);
|
|
685
694
|
try {
|
|
686
|
-
const currentConfig = await fetchPluginConfig();
|
|
695
|
+
const currentConfig = await fetchPluginConfig(companyId);
|
|
687
696
|
const nextConfig = { ...currentConfig, ...boardConfig };
|
|
688
|
-
await savePluginConfig(nextConfig);
|
|
697
|
+
await savePluginConfig(nextConfig, companyId);
|
|
689
698
|
setBoardSnapshot(boardConfig);
|
|
690
699
|
setBoardConfigMessage({
|
|
691
700
|
tone: "success",
|
|
@@ -708,9 +717,9 @@ export function TelegramSettingsPage({ context }) {
|
|
|
708
717
|
setAccessSaving(true);
|
|
709
718
|
setAccessMessage(null);
|
|
710
719
|
try {
|
|
711
|
-
const currentConfig = await fetchPluginConfig();
|
|
720
|
+
const currentConfig = await fetchPluginConfig(companyId);
|
|
712
721
|
const nextConfig = { ...currentConfig, ...accessConfig };
|
|
713
|
-
await savePluginConfig(nextConfig);
|
|
722
|
+
await savePluginConfig(nextConfig, companyId);
|
|
714
723
|
setAccessSnapshot(accessConfig);
|
|
715
724
|
setAccessMessage({
|
|
716
725
|
tone: "success",
|
|
@@ -733,9 +742,9 @@ export function TelegramSettingsPage({ context }) {
|
|
|
733
742
|
setRoutingSaving(true);
|
|
734
743
|
setRoutingMessage(null);
|
|
735
744
|
try {
|
|
736
|
-
const currentConfig = await fetchPluginConfig();
|
|
745
|
+
const currentConfig = await fetchPluginConfig(companyId);
|
|
737
746
|
const nextConfig = { ...currentConfig, ...routingConfig };
|
|
738
|
-
await savePluginConfig(nextConfig);
|
|
747
|
+
await savePluginConfig(nextConfig, companyId);
|
|
739
748
|
setRoutingSnapshot(routingConfig);
|
|
740
749
|
setRoutingMessage({
|
|
741
750
|
tone: "success",
|
|
@@ -758,9 +767,9 @@ export function TelegramSettingsPage({ context }) {
|
|
|
758
767
|
setConnectionSaving(true);
|
|
759
768
|
setConnectionMessage(null);
|
|
760
769
|
try {
|
|
761
|
-
const currentConfig = await fetchPluginConfig();
|
|
770
|
+
const currentConfig = await fetchPluginConfig(companyId);
|
|
762
771
|
const nextConfig = { ...currentConfig, ...connectionConfig };
|
|
763
|
-
await savePluginConfig(nextConfig);
|
|
772
|
+
await savePluginConfig(nextConfig, companyId);
|
|
764
773
|
setConnectionSnapshot(connectionConfig);
|
|
765
774
|
setConnectionMessage({
|
|
766
775
|
tone: "success",
|
|
@@ -783,9 +792,9 @@ export function TelegramSettingsPage({ context }) {
|
|
|
783
792
|
setMediaSaving(true);
|
|
784
793
|
setMediaMessage(null);
|
|
785
794
|
try {
|
|
786
|
-
const currentConfig = await fetchPluginConfig();
|
|
795
|
+
const currentConfig = await fetchPluginConfig(companyId);
|
|
787
796
|
const nextConfig = { ...currentConfig, ...mediaConfig };
|
|
788
|
-
await savePluginConfig(nextConfig);
|
|
797
|
+
await savePluginConfig(nextConfig, companyId);
|
|
789
798
|
setMediaSnapshot(mediaConfig);
|
|
790
799
|
setMediaMessage({
|
|
791
800
|
tone: "success",
|
|
@@ -808,9 +817,9 @@ export function TelegramSettingsPage({ context }) {
|
|
|
808
817
|
setEscalationSaving(true);
|
|
809
818
|
setEscalationMessage(null);
|
|
810
819
|
try {
|
|
811
|
-
const currentConfig = await fetchPluginConfig();
|
|
820
|
+
const currentConfig = await fetchPluginConfig(companyId);
|
|
812
821
|
const nextConfig = { ...currentConfig, ...escalationConfig };
|
|
813
|
-
await savePluginConfig(nextConfig);
|
|
822
|
+
await savePluginConfig(nextConfig, companyId);
|
|
814
823
|
setEscalationSnapshot(escalationConfig);
|
|
815
824
|
setEscalationMessage({
|
|
816
825
|
tone: "success",
|
|
@@ -833,9 +842,9 @@ export function TelegramSettingsPage({ context }) {
|
|
|
833
842
|
setProactiveSaving(true);
|
|
834
843
|
setProactiveMessage(null);
|
|
835
844
|
try {
|
|
836
|
-
const currentConfig = await fetchPluginConfig();
|
|
845
|
+
const currentConfig = await fetchPluginConfig(companyId);
|
|
837
846
|
const nextConfig = { ...currentConfig, ...proactiveConfig };
|
|
838
|
-
await savePluginConfig(nextConfig);
|
|
847
|
+
await savePluginConfig(nextConfig, companyId);
|
|
839
848
|
setProactiveSnapshot(proactiveConfig);
|
|
840
849
|
setProactiveMessage({
|
|
841
850
|
tone: "success",
|
|
@@ -929,7 +938,7 @@ export function TelegramSettingsPage({ context }) {
|
|
|
929
938
|
display: "grid",
|
|
930
939
|
gap: 18,
|
|
931
940
|
padding: 18,
|
|
932
|
-
}, children: [_jsxs("div", { style: { display: "grid", gap: 4 }, children: [_jsx("h2", { style: { fontSize: 18, fontWeight: 700, lineHeight: "28px", margin: 0 }, children: "Connection & URLs" }), _jsx("p", { style: { color: "#6b7280", margin: 0 }, children: "Core connection values used by the Telegram worker.
|
|
941
|
+
}, children: [_jsxs("div", { style: { display: "grid", gap: 4 }, children: [_jsx("h2", { style: { fontSize: 18, fontWeight: 700, lineHeight: "28px", margin: 0 }, children: "Connection & URLs" }), _jsx("p", { style: { color: "#6b7280", margin: 0 }, children: "Core connection values used by the Telegram worker. Select company secrets for sensitive values; secret values are never shown here." })] }), _jsxs("div", { style: { display: "grid", gap: 12 }, children: [_jsx(SecretRefField, { companyId: companyId, disabled: connectionLoading || connectionSaving, label: "Telegram bot token secret ref", onChange: (value) => updateConnectionField("telegramBotTokenRef", value), placeholder: "Secret UUID fallback", value: connectionConfig.telegramBotTokenRef, children: "Select the company secret that stores your Telegram bot token from @BotFather. The plugin resolves this secret before polling Telegram." }), _jsx(TextField, { disabled: connectionLoading || connectionSaving, label: "Paperclip API URL", onChange: (value) => updateConnectionField("paperclipBaseUrl", value), placeholder: "http://localhost:3100", value: connectionConfig.paperclipBaseUrl, children: "Internal Paperclip API URL used by the plugin for actions such as approvals and comments. Keep localhost for same-server deployments." }), _jsx(TextField, { disabled: connectionLoading || connectionSaving, label: "Paperclip public URL", onChange: (value) => updateConnectionField("paperclipPublicUrl", value), placeholder: "https://paperclip.example.com", value: connectionConfig.paperclipPublicUrl, children: "Public URL used in Telegram links. Leave empty to fall back to the API URL." })] }), connectionMessage ? _jsx(NoticeBlock, { notice: connectionMessage }) : null, _jsxs("div", { style: { display: "flex", gap: 10, justifyContent: "flex-end" }, children: [_jsx("button", { disabled: connectionLoading || connectionSaving, onClick: () => {
|
|
933
942
|
setConnectionConfig(connectionSnapshot);
|
|
934
943
|
setConnectionMessage(null);
|
|
935
944
|
}, style: {
|
|
@@ -993,7 +1002,7 @@ export function TelegramSettingsPage({ context }) {
|
|
|
993
1002
|
fontWeight: 700,
|
|
994
1003
|
minWidth: 190,
|
|
995
1004
|
padding: "10px 14px",
|
|
996
|
-
}, type: "button", children: connecting ? "Waiting for approval..." : configured ? "Reconnect board access" : "Connect board access" })] }), _jsxs("div", { style: { borderTop: "1px solid #e5e7eb", display: "grid", gap: 12, paddingTop: 14 }, children: [_jsx(
|
|
1005
|
+
}, type: "button", children: connecting ? "Waiting for approval..." : configured ? "Reconnect board access" : "Connect board access" })] }), _jsxs("div", { style: { borderTop: "1px solid #e5e7eb", display: "grid", gap: 12, paddingTop: 14 }, children: [_jsx(SecretRefField, { companyId: companyId, disabled: boardConfigLoading || boardConfigSaving, label: "Board API token secret ref fallback", onChange: (value) => updateBoardField("paperclipBoardApiTokenRef", value), placeholder: "Optional secret UUID fallback", value: boardConfig.paperclipBoardApiTokenRef, children: "Optional manual fallback for approval buttons and /approve. The Board Access Connection above is preferred because it creates and tracks the company-scoped secret for you." }), boardConfigMessage ? _jsx(NoticeBlock, { notice: boardConfigMessage }) : null, _jsxs("div", { style: { display: "flex", gap: 10, justifyContent: "flex-end" }, children: [_jsx("button", { disabled: boardConfigLoading || boardConfigSaving, onClick: () => {
|
|
997
1006
|
setBoardConfig(boardSnapshot);
|
|
998
1007
|
setBoardConfigMessage(null);
|
|
999
1008
|
}, style: {
|
|
@@ -1132,7 +1141,7 @@ export function TelegramSettingsPage({ context }) {
|
|
|
1132
1141
|
display: "grid",
|
|
1133
1142
|
gap: 18,
|
|
1134
1143
|
padding: 18,
|
|
1135
|
-
}, children: [_jsxs("div", { style: { display: "grid", gap: 4 }, children: [_jsx("h2", { style: { fontSize: 18, fontWeight: 700, lineHeight: "28px", margin: 0 }, children: "Media Intake / Brief Agent" }), _jsx("p", { style: { color: "#6b7280", margin: 0 }, children: "Routes Telegram voice, audio, documents, and photos either to a Brief Agent intake flow or to active agent sessions inside forum topics." })] }), _jsxs("div", { style: { display: "grid", gap: 12 }, children: [_jsx(
|
|
1144
|
+
}, children: [_jsxs("div", { style: { display: "grid", gap: 4 }, children: [_jsx("h2", { style: { fontSize: 18, fontWeight: 700, lineHeight: "28px", margin: 0 }, children: "Media Intake / Brief Agent" }), _jsx("p", { style: { color: "#6b7280", margin: 0 }, children: "Routes Telegram voice, audio, documents, and photos either to a Brief Agent intake flow or to active agent sessions inside forum topics." })] }), _jsxs("div", { style: { display: "grid", gap: 12 }, children: [_jsx(SecretRefField, { companyId: companyId, disabled: mediaLoading || mediaSaving, label: "OpenAI transcription secret", onChange: (value) => updateMediaField("transcriptionApiKeyRef", value), placeholder: "OpenAI API key secret UUID fallback", value: mediaConfig.transcriptionApiKeyRef, children: "Select the company secret used for audio transcription. Secret values are never shown to the plugin UI." }), _jsx(TextField, { disabled: mediaLoading || mediaSaving, label: "Brief Agent ID", onChange: (value) => updateMediaField("briefAgentId", value), placeholder: "Paperclip agent ID", value: mediaConfig.briefAgentId, children: "Agent ID that processes media intake briefs. Leave empty to disable the dedicated Brief Agent intake flow." }), _jsx(ArrayField, { disabled: mediaLoading || mediaSaving, emptyValueLabel: "No intake chat IDs configured", label: "Brief Agent intake chat IDs", newItemLabel: "Add intake chat ID", onChange: (value) => updateMediaField("briefAgentChatIds", value), placeholder: "-1003800613668", value: mediaConfig.briefAgentChatIds, children: "Telegram chat IDs where media is routed to the Brief Agent. Media in other chats goes to active agent sessions when a matching forum topic session exists." })] }), mediaMessage ? _jsx(NoticeBlock, { notice: mediaMessage }) : null, _jsxs("div", { style: { display: "flex", gap: 10, justifyContent: "flex-end" }, children: [_jsx("button", { disabled: mediaLoading || mediaSaving, onClick: () => {
|
|
1136
1145
|
setMediaConfig(mediaSnapshot);
|
|
1137
1146
|
setMediaMessage(null);
|
|
1138
1147
|
}, style: {
|
|
@@ -1230,6 +1239,51 @@ function NoticeBlock({ notice }) {
|
|
|
1230
1239
|
padding: 12,
|
|
1231
1240
|
}, children: [_jsx("strong", { children: notice.title }), notice.text ? _jsx("p", { style: { margin: "6px 0 0" }, children: notice.text }) : null] }));
|
|
1232
1241
|
}
|
|
1242
|
+
function SecretRefField({ label, value, placeholder, disabled, companyId, children, onChange, }) {
|
|
1243
|
+
const [secrets, setSecrets] = useState([]);
|
|
1244
|
+
const [loading, setLoading] = useState(false);
|
|
1245
|
+
const [error, setError] = useState(null);
|
|
1246
|
+
useEffect(() => {
|
|
1247
|
+
let cancelled = false;
|
|
1248
|
+
async function loadSecrets() {
|
|
1249
|
+
if (!companyId) {
|
|
1250
|
+
setSecrets([]);
|
|
1251
|
+
return;
|
|
1252
|
+
}
|
|
1253
|
+
setLoading(true);
|
|
1254
|
+
setError(null);
|
|
1255
|
+
try {
|
|
1256
|
+
const nextSecrets = await fetchCompanySecrets(companyId);
|
|
1257
|
+
if (!cancelled) {
|
|
1258
|
+
setSecrets(nextSecrets.filter((secret) => secret.status !== "deleted"));
|
|
1259
|
+
}
|
|
1260
|
+
}
|
|
1261
|
+
catch (err) {
|
|
1262
|
+
if (!cancelled) {
|
|
1263
|
+
setError(getErrorMessage(err));
|
|
1264
|
+
}
|
|
1265
|
+
}
|
|
1266
|
+
finally {
|
|
1267
|
+
if (!cancelled) {
|
|
1268
|
+
setLoading(false);
|
|
1269
|
+
}
|
|
1270
|
+
}
|
|
1271
|
+
}
|
|
1272
|
+
void loadSecrets();
|
|
1273
|
+
return () => {
|
|
1274
|
+
cancelled = true;
|
|
1275
|
+
};
|
|
1276
|
+
}, [companyId]);
|
|
1277
|
+
const selectedValue = secrets.some((secret) => secret.id === value) ? value : "";
|
|
1278
|
+
const fieldDisabled = disabled || loading || !companyId;
|
|
1279
|
+
return (_jsxs("label", { style: { display: "grid", gap: 5 }, children: [_jsx("span", { style: { color: "#4b5563", fontSize: 12, fontWeight: 700 }, children: label }), _jsxs("select", { disabled: fieldDisabled, onChange: (event) => onChange(event.currentTarget.value), style: standardInputStyle, value: selectedValue, children: [_jsx("option", { value: "", children: !companyId
|
|
1280
|
+
? "Open inside a company to select a secret"
|
|
1281
|
+
: loading
|
|
1282
|
+
? "Loading company secrets..."
|
|
1283
|
+
: value && !selectedValue
|
|
1284
|
+
? "Manual UUID selected"
|
|
1285
|
+
: "Select a company secret" }), secrets.map((secret) => (_jsxs("option", { value: secret.id, children: [secret.name || secret.key || secret.id, secret.key && secret.key !== secret.name ? ` (${secret.key})` : "", secret.latestVersion ? ` · v${secret.latestVersion}` : ""] }, secret.id)))] }), _jsx("input", { disabled: disabled, onChange: (event) => onChange(event.currentTarget.value), placeholder: placeholder, style: standardInputStyle, type: "text", value: value }), _jsx("span", { style: { color: "#6b7280", fontSize: 12 }, children: children }), error ? _jsxs("span", { style: { color: "#b91c1c", fontSize: 12 }, children: ["Could not load company secrets: ", error] }) : null] }));
|
|
1286
|
+
}
|
|
1233
1287
|
function TextField({ label, value, placeholder, disabled, children, onChange, }) {
|
|
1234
1288
|
return (_jsxs("label", { style: { display: "grid", gap: 5 }, children: [_jsx("span", { style: { color: "#4b5563", fontSize: 12, fontWeight: 700 }, children: label }), _jsx("input", { disabled: disabled, onChange: (event) => onChange(event.currentTarget.value), placeholder: placeholder, style: {
|
|
1235
1289
|
border: "1px solid #d1d5db",
|