@clubnet/seedclub 0.2.36 → 0.2.37
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.
|
@@ -147,6 +147,10 @@ function inferContentType(fileName: string) {
|
|
|
147
147
|
return "video/mp4";
|
|
148
148
|
}
|
|
149
149
|
|
|
150
|
+
function isIsoDate(value: string) {
|
|
151
|
+
return /^\d{4}-\d{2}-\d{2}$/.test(value);
|
|
152
|
+
}
|
|
153
|
+
|
|
150
154
|
async function inferMediaOrientation(
|
|
151
155
|
filePath: string,
|
|
152
156
|
contentType: string,
|
|
@@ -180,143 +184,6 @@ async function inferMediaOrientation(
|
|
|
180
184
|
}
|
|
181
185
|
}
|
|
182
186
|
|
|
183
|
-
async function publishClipAsset(args: {
|
|
184
|
-
programSlug: string;
|
|
185
|
-
storageUrl: string;
|
|
186
|
-
associationPolicy?: "required" | "preferred" | "none" | null;
|
|
187
|
-
meetingId?: string | null;
|
|
188
|
-
guestName?: string | null;
|
|
189
|
-
primaryPartyId?: string | null;
|
|
190
|
-
partyIds?: string[] | null;
|
|
191
|
-
audioUrl?: string | null;
|
|
192
|
-
contentType?: string | null;
|
|
193
|
-
description?: string | null;
|
|
194
|
-
durationSeconds?: number | null;
|
|
195
|
-
eventDate?: string | null;
|
|
196
|
-
fileName?: string | null;
|
|
197
|
-
fileSize?: number | null;
|
|
198
|
-
keyQuestion?: string | null;
|
|
199
|
-
orientation?: string | null;
|
|
200
|
-
publicationUrls?: {
|
|
201
|
-
instagram?: string | null;
|
|
202
|
-
tiktok?: string | null;
|
|
203
|
-
x?: string | null;
|
|
204
|
-
youtube?: string | null;
|
|
205
|
-
zora?: string | null;
|
|
206
|
-
} | null;
|
|
207
|
-
thumbnailUrl?: string | null;
|
|
208
|
-
title?: string | null;
|
|
209
|
-
transcriptEdited?: string | null;
|
|
210
|
-
transcriptRaw?: string | null;
|
|
211
|
-
transcriptVtt?: string | null;
|
|
212
|
-
triggerTranscription?: boolean | null;
|
|
213
|
-
visibility?: string | null;
|
|
214
|
-
workflowStatus?: string | null;
|
|
215
|
-
publishingJob?: {
|
|
216
|
-
platform: string;
|
|
217
|
-
title?: string | null;
|
|
218
|
-
description?: string | null;
|
|
219
|
-
scheduledFor?: string | null;
|
|
220
|
-
publishedAt?: string | null;
|
|
221
|
-
status?: string | null;
|
|
222
|
-
isImmediate?: boolean;
|
|
223
|
-
tags?: string[] | null;
|
|
224
|
-
thumbnailAssetId?: string | null;
|
|
225
|
-
legacyAssetSourceId?: string | null;
|
|
226
|
-
metadataJson?: Record<string, unknown> | null;
|
|
227
|
-
destination?: {
|
|
228
|
-
accountId?: string | null;
|
|
229
|
-
username?: string | null;
|
|
230
|
-
displayName?: string | null;
|
|
231
|
-
profileImageUrl?: string | null;
|
|
232
|
-
configJson?: Record<string, unknown> | null;
|
|
233
|
-
} | null;
|
|
234
|
-
} | null;
|
|
235
|
-
}) {
|
|
236
|
-
try {
|
|
237
|
-
const storageUrl = normalizeOptionalString(args.storageUrl);
|
|
238
|
-
if (!storageUrl) {
|
|
239
|
-
return {
|
|
240
|
-
error: "Provide the uploaded clip storageUrl for the final rendered clip.",
|
|
241
|
-
};
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
const assetResponse = await api.post<any>(`/programs/${args.programSlug}/media/assets`, {
|
|
245
|
-
asset_kind: "clip",
|
|
246
|
-
association_policy: normalizeOptionalString(args.associationPolicy),
|
|
247
|
-
audio_url: normalizeOptionalString(args.audioUrl),
|
|
248
|
-
content_type: normalizeOptionalString(args.contentType),
|
|
249
|
-
description: normalizeOptionalString(args.description),
|
|
250
|
-
duration_seconds: normalizeOptionalNumber(args.durationSeconds),
|
|
251
|
-
event_date: normalizeOptionalString(args.eventDate),
|
|
252
|
-
file_name: normalizeOptionalString(args.fileName),
|
|
253
|
-
file_size: normalizeOptionalNumber(args.fileSize),
|
|
254
|
-
guest_name: normalizeOptionalString(args.guestName),
|
|
255
|
-
key_question: normalizeOptionalString(args.keyQuestion),
|
|
256
|
-
meeting_id: normalizeOptionalString(args.meetingId),
|
|
257
|
-
orientation: normalizeOptionalString(args.orientation),
|
|
258
|
-
party_ids: Array.isArray(args.partyIds) ? args.partyIds : null,
|
|
259
|
-
primary_party_id: normalizeOptionalString(args.primaryPartyId),
|
|
260
|
-
publication_urls: args.publicationUrls ?? null,
|
|
261
|
-
storage_url: storageUrl,
|
|
262
|
-
thumbnail_url: normalizeOptionalString(args.thumbnailUrl),
|
|
263
|
-
title: normalizeOptionalString(args.title),
|
|
264
|
-
trigger_transcription: normalizeOptionalBoolean(args.triggerTranscription),
|
|
265
|
-
transcript_edited: normalizeOptionalString(args.transcriptEdited),
|
|
266
|
-
transcript_raw: normalizeOptionalString(args.transcriptRaw),
|
|
267
|
-
transcript_vtt: normalizeOptionalString(args.transcriptVtt),
|
|
268
|
-
visibility: normalizeOptionalString(args.visibility),
|
|
269
|
-
workflow_status: normalizeOptionalString(args.workflowStatus),
|
|
270
|
-
});
|
|
271
|
-
|
|
272
|
-
let publishingJob: any = null;
|
|
273
|
-
if (args.publishingJob?.platform?.trim()) {
|
|
274
|
-
const createdAssetId = assetResponse?.asset?.id;
|
|
275
|
-
publishingJob = await api.post<any>(`/programs/${args.programSlug}/publishing/jobs`, {
|
|
276
|
-
platform: args.publishingJob.platform.trim(),
|
|
277
|
-
asset_id: typeof createdAssetId === "string" ? createdAssetId : null,
|
|
278
|
-
title: normalizeOptionalString(args.publishingJob.title),
|
|
279
|
-
description: normalizeOptionalString(args.publishingJob.description),
|
|
280
|
-
scheduled_for: normalizeOptionalString(args.publishingJob.scheduledFor),
|
|
281
|
-
published_at: normalizeOptionalString(args.publishingJob.publishedAt),
|
|
282
|
-
status: normalizeOptionalString(args.publishingJob.status),
|
|
283
|
-
is_immediate: args.publishingJob.isImmediate === true,
|
|
284
|
-
tags: Array.isArray(args.publishingJob.tags)
|
|
285
|
-
? args.publishingJob.tags.filter((tag) => typeof tag === "string" && tag.trim()).map((tag) => tag.trim())
|
|
286
|
-
: [],
|
|
287
|
-
thumbnail_asset_id: normalizeOptionalString(args.publishingJob.thumbnailAssetId),
|
|
288
|
-
legacy_asset_source_id: normalizeOptionalString(args.publishingJob.legacyAssetSourceId),
|
|
289
|
-
metadata_json: args.publishingJob.metadataJson ?? {},
|
|
290
|
-
destination: args.publishingJob.destination
|
|
291
|
-
? {
|
|
292
|
-
account_id: normalizeOptionalString(args.publishingJob.destination.accountId),
|
|
293
|
-
username: normalizeOptionalString(args.publishingJob.destination.username),
|
|
294
|
-
display_name: normalizeOptionalString(args.publishingJob.destination.displayName),
|
|
295
|
-
profile_image_url: normalizeOptionalString(args.publishingJob.destination.profileImageUrl),
|
|
296
|
-
config_json: args.publishingJob.destination.configJson ?? null,
|
|
297
|
-
}
|
|
298
|
-
: null,
|
|
299
|
-
});
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
return {
|
|
303
|
-
program: assetResponse?.program ?? null,
|
|
304
|
-
asset: shapeMediaAssetRow(assetResponse?.asset, false),
|
|
305
|
-
primary_party: assetResponse?.primary_party ?? null,
|
|
306
|
-
parties: Array.isArray(assetResponse?.parties) ? assetResponse.parties : [],
|
|
307
|
-
matched_funnels: Array.isArray(assetResponse?.matched_funnels) ? assetResponse.matched_funnels : [],
|
|
308
|
-
publications: Array.isArray(assetResponse?.publications) ? assetResponse.publications : [],
|
|
309
|
-
publishing_job: publishingJob?.data ?? null,
|
|
310
|
-
linkage: assetResponse?.linkage ?? null,
|
|
311
|
-
note:
|
|
312
|
-
"Created the linked media record for an already-hosted clip URL. For local files, use seedclub_upload_clip_asset so seedclub-api handles the 11am Spaces upload.",
|
|
313
|
-
};
|
|
314
|
-
} catch (error) {
|
|
315
|
-
if (error instanceof ApiError) return { error: error.message, status: error.status };
|
|
316
|
-
throw error;
|
|
317
|
-
}
|
|
318
|
-
}
|
|
319
|
-
|
|
320
187
|
async function uploadClipAsset(args: {
|
|
321
188
|
programSlug: string;
|
|
322
189
|
filePath: string;
|
|
@@ -384,17 +251,39 @@ async function uploadClipAsset(args: {
|
|
|
384
251
|
|
|
385
252
|
const resolvedFileName = normalizeOptionalString(args.fileName) ?? basename(filePath);
|
|
386
253
|
const resolvedContentType = normalizeOptionalString(args.contentType) ?? inferContentType(resolvedFileName);
|
|
254
|
+
const resolvedTitle = normalizeOptionalString(args.title);
|
|
255
|
+
const resolvedEventDate = normalizeOptionalString(args.eventDate);
|
|
256
|
+
const resolvedMeetingId = normalizeOptionalString(args.meetingId);
|
|
257
|
+
const resolvedWorkflowStatus = normalizeOptionalString(args.workflowStatus) ?? "published";
|
|
258
|
+
const missingFields = [
|
|
259
|
+
...(resolvedTitle ? [] : ["title"]),
|
|
260
|
+
...(resolvedMeetingId ? [] : ["meetingId"]),
|
|
261
|
+
];
|
|
262
|
+
if (missingFields.length) {
|
|
263
|
+
return {
|
|
264
|
+
error:
|
|
265
|
+
`Before uploading, ask the user for the missing clip metadata: ${missingFields.join(", ")}. ` +
|
|
266
|
+
"For finished clips, workflowStatus is usually published.",
|
|
267
|
+
missing_fields: missingFields,
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
const uploadTitle = resolvedTitle as string;
|
|
271
|
+
const uploadMeetingId = resolvedMeetingId as string;
|
|
272
|
+
const uploadWorkflowStatus = resolvedWorkflowStatus as string;
|
|
273
|
+
if (resolvedEventDate && !isIsoDate(resolvedEventDate)) {
|
|
274
|
+
return { error: "eventDate must use YYYY-MM-DD format.", field: "eventDate" };
|
|
275
|
+
}
|
|
387
276
|
const resolvedOrientation =
|
|
388
277
|
normalizeOptionalString(args.orientation) ??
|
|
389
278
|
(await inferMediaOrientation(filePath, resolvedContentType));
|
|
390
279
|
const presignResponse = await api.post<any>(`/programs/${args.programSlug}/media/ingests`, {
|
|
391
280
|
association_policy: normalizeOptionalString(args.associationPolicy),
|
|
392
281
|
content_type: resolvedContentType,
|
|
393
|
-
event_date:
|
|
282
|
+
event_date: resolvedEventDate,
|
|
394
283
|
file_name: resolvedFileName,
|
|
395
284
|
guest_name: normalizeOptionalString(args.guestName),
|
|
396
285
|
kind: resolvedContentType.startsWith("audio/") ? "audio" : "clip",
|
|
397
|
-
meeting_id:
|
|
286
|
+
meeting_id: uploadMeetingId,
|
|
398
287
|
party_ids: Array.isArray(args.partyIds) ? args.partyIds : null,
|
|
399
288
|
person_name: normalizeOptionalString(args.personName),
|
|
400
289
|
primary_party_id: normalizeOptionalString(args.primaryPartyId),
|
|
@@ -464,12 +353,12 @@ async function uploadClipAsset(args: {
|
|
|
464
353
|
description: normalizeOptionalString(args.description),
|
|
465
354
|
derived_from_asset_id: normalizeOptionalString(args.derivedFromAssetId),
|
|
466
355
|
duration_seconds: normalizeOptionalNumber(args.durationSeconds),
|
|
467
|
-
event_date:
|
|
356
|
+
event_date: resolvedEventDate,
|
|
468
357
|
file_name: resolvedFileName,
|
|
469
358
|
file_size: fileStats.size,
|
|
470
359
|
guest_name: normalizeOptionalString(args.guestName),
|
|
471
360
|
key_question: normalizeOptionalString(args.keyQuestion),
|
|
472
|
-
meeting_id:
|
|
361
|
+
meeting_id: uploadMeetingId,
|
|
473
362
|
orientation: resolvedOrientation,
|
|
474
363
|
party_ids: Array.isArray(args.partyIds) ? args.partyIds : null,
|
|
475
364
|
primary_party_id: normalizeOptionalString(args.primaryPartyId),
|
|
@@ -478,12 +367,12 @@ async function uploadClipAsset(args: {
|
|
|
478
367
|
source_recording_id: normalizeOptionalString(args.sourceRecordingId),
|
|
479
368
|
source_stream_id: normalizeOptionalString(args.sourceStreamId),
|
|
480
369
|
thumbnail_url: normalizeOptionalString(args.thumbnailUrl),
|
|
481
|
-
title:
|
|
370
|
+
title: uploadTitle,
|
|
482
371
|
transcript_edited: normalizeOptionalString(args.transcriptEdited),
|
|
483
372
|
transcript_raw: normalizeOptionalString(args.transcriptRaw),
|
|
484
373
|
transcript_vtt: normalizeOptionalString(args.transcriptVtt),
|
|
485
374
|
visibility: normalizeOptionalString(args.visibility),
|
|
486
|
-
workflow_status:
|
|
375
|
+
workflow_status: uploadWorkflowStatus,
|
|
487
376
|
});
|
|
488
377
|
|
|
489
378
|
return {
|
|
@@ -696,12 +585,12 @@ export function registerMediaTools(pi: ExtensionAPI) {
|
|
|
696
585
|
name: "seedclub_upload_clip_asset",
|
|
697
586
|
label: "Upload Clip Asset",
|
|
698
587
|
description:
|
|
699
|
-
"Upload a locally rendered 11am clip file to DigitalOcean Spaces through seedclub-api, then create the linked media asset record and optional publishing job. Use this after ffmpeg has cut the clip and appended the current season bumper. The CLI receives only a short-lived upload URL; DigitalOcean keys stay on seedclub-api.",
|
|
588
|
+
"Upload a locally rendered 11am clip file to DigitalOcean Spaces through seedclub-api, then create the linked media asset record and optional publishing job. Use this after ffmpeg has cut the clip and appended the current season bumper. Before calling this tool, ask for or confidently infer title and meetingId; do not upload without them. eventDate is optional because seedclub-api infers it from meetingId when completing the upload; if supplied, it must be YYYY-MM-DD. workflowStatus defaults to published for finished clips unless the user chooses another status. The CLI receives only a short-lived upload URL; DigitalOcean keys stay on seedclub-api.",
|
|
700
589
|
parameters: Type.Object({
|
|
701
590
|
programSlug: Type.String({ description: "Program slug. Currently the upload backend is configured for 11am." }),
|
|
702
591
|
filePath: Type.String({ description: "Local path to the final rendered clip file after bumper append." }),
|
|
703
592
|
associationPolicy: Type.Optional(Type.Union([Type.String(), Type.Null()], { description: "Optional association policy passed through to seedclub-api. Use required, preferred, or none." })),
|
|
704
|
-
meetingId: Type.Optional(Type.Union([Type.String(), Type.Null()], { description: "
|
|
593
|
+
meetingId: Type.Optional(Type.Union([Type.String(), Type.Null()], { description: "Required for upload. Exact meeting id for the source show/interview. Ask the user or resolve it from transcript/recording context before uploading." })),
|
|
705
594
|
guestName: Type.Optional(Type.Union([Type.String(), Type.Null()], { description: "Optional guest name passed through to seedclub-api for meeting resolution." })),
|
|
706
595
|
primaryPartyId: Type.Optional(Type.Union([Type.String(), Type.Null()], { description: "Optional primary guest party id. If omitted, seedclub-api will infer it from meetingId when possible." })),
|
|
707
596
|
partyIds: Type.Optional(Type.Union([Type.Array(Type.String()), Type.Null()], { description: "Optional additional related party ids. If omitted, seedclub-api will infer them from meetingId when possible." })),
|
|
@@ -710,7 +599,7 @@ export function registerMediaTools(pi: ExtensionAPI) {
|
|
|
710
599
|
description: Type.Optional(Type.Union([Type.String(), Type.Null()])),
|
|
711
600
|
derivedFromAssetId: Type.Optional(Type.Union([Type.String(), Type.Null()])),
|
|
712
601
|
durationSeconds: Type.Optional(Type.Union([Type.Number(), Type.Null()])),
|
|
713
|
-
eventDate: Type.Optional(Type.Union([Type.String(), Type.Null()], { description: "Optional YYYY-MM-DD event date
|
|
602
|
+
eventDate: Type.Optional(Type.Union([Type.String(), Type.Null()], { description: "Optional YYYY-MM-DD event date for the presigned storage path. seedclub-api infers final media event_date from meetingId on complete." })),
|
|
714
603
|
fileName: Type.Optional(Type.Union([Type.String(), Type.Null()], { description: "Optional storage/display file name. Defaults to basename(filePath)." })),
|
|
715
604
|
keyQuestion: Type.Optional(Type.Union([Type.String(), Type.Null()])),
|
|
716
605
|
orientation: Type.Optional(Type.Union([Type.String(), Type.Null()], { description: "Optional orientation such as vertical or horizontal. If omitted for a local upload, the tool will infer it from the media dimensions when possible." })),
|
|
@@ -730,12 +619,12 @@ export function registerMediaTools(pi: ExtensionAPI) {
|
|
|
730
619
|
sourceRecordingId: Type.Optional(Type.Union([Type.String(), Type.Null()])),
|
|
731
620
|
sourceStreamId: Type.Optional(Type.Union([Type.String(), Type.Null()])),
|
|
732
621
|
thumbnailUrl: Type.Optional(Type.Union([Type.String(), Type.Null()])),
|
|
733
|
-
title: Type.Optional(Type.Union([Type.String(), Type.Null()])),
|
|
622
|
+
title: Type.Optional(Type.Union([Type.String(), Type.Null()], { description: "Required for upload. Human-readable clip title. Ask the user if it cannot be confidently inferred." })),
|
|
734
623
|
transcriptEdited: Type.Optional(Type.Union([Type.String(), Type.Null()])),
|
|
735
624
|
transcriptRaw: Type.Optional(Type.Union([Type.String(), Type.Null()])),
|
|
736
625
|
transcriptVtt: Type.Optional(Type.Union([Type.String(), Type.Null()])),
|
|
737
626
|
visibility: Type.Optional(Type.Union([Type.String(), Type.Null()])),
|
|
738
|
-
workflowStatus: Type.Optional(Type.Union([Type.String(), Type.Null()])),
|
|
627
|
+
workflowStatus: Type.Optional(Type.Union([Type.String(), Type.Null()], { description: "Optional media workflow state. Defaults to published for finished clips unless the user chooses another status." })),
|
|
739
628
|
publishingJob: Type.Optional(
|
|
740
629
|
Type.Union([
|
|
741
630
|
Type.Object({
|
|
@@ -775,91 +664,6 @@ export function registerMediaTools(pi: ExtensionAPI) {
|
|
|
775
664
|
}),
|
|
776
665
|
});
|
|
777
666
|
|
|
778
|
-
pi.registerTool({
|
|
779
|
-
name: "seedclub_publish_clip_asset",
|
|
780
|
-
label: "Publish Clip Asset",
|
|
781
|
-
description:
|
|
782
|
-
"Create a clip media asset linked to the correct meeting and party records, then optionally create a publishing job for an already-hosted clip URL. For local ffmpeg outputs, prefer seedclub_upload_clip_asset so seedclub-api handles the DigitalOcean Spaces presigned upload.",
|
|
783
|
-
parameters: Type.Object({
|
|
784
|
-
programSlug: Type.String({ description: "Program slug" }),
|
|
785
|
-
storageUrl: Type.String({ description: "Public or internal URL for the final rendered clip file." }),
|
|
786
|
-
associationPolicy: Type.Optional(Type.Union([Type.String(), Type.Null()], { description: "Optional association policy passed through to seedclub-api. Use required, preferred, or none." })),
|
|
787
|
-
meetingId: Type.Optional(Type.Union([Type.String(), Type.Null()], { description: "Optional exact meeting id. If omitted, seedclub-api can resolve it from guestName and eventDate." })),
|
|
788
|
-
guestName: Type.Optional(Type.Union([Type.String(), Type.Null()], { description: "Optional guest name passed through to seedclub-api for meeting resolution." })),
|
|
789
|
-
primaryPartyId: Type.Optional(Type.Union([Type.String(), Type.Null()], { description: "Optional primary guest party id. If omitted, the tool will try to infer it from the meeting." })),
|
|
790
|
-
partyIds: Type.Optional(Type.Union([Type.Array(Type.String()), Type.Null()], { description: "Optional additional related party ids. primaryPartyId will be included automatically." })),
|
|
791
|
-
audioUrl: Type.Optional(Type.Union([Type.String(), Type.Null()])),
|
|
792
|
-
contentType: Type.Optional(Type.Union([Type.String(), Type.Null()])),
|
|
793
|
-
description: Type.Optional(Type.Union([Type.String(), Type.Null()])),
|
|
794
|
-
durationSeconds: Type.Optional(Type.Union([Type.Number(), Type.Null()])),
|
|
795
|
-
eventDate: Type.Optional(Type.Union([Type.String(), Type.Null()], { description: "Optional YYYY-MM-DD event date passed through to seedclub-api for association resolution." })),
|
|
796
|
-
fileName: Type.Optional(Type.Union([Type.String(), Type.Null()])),
|
|
797
|
-
fileSize: Type.Optional(Type.Union([Type.Number(), Type.Null()])),
|
|
798
|
-
keyQuestion: Type.Optional(Type.Union([Type.String(), Type.Null()])),
|
|
799
|
-
orientation: Type.Optional(Type.Union([Type.String(), Type.Null()], { description: "Optional orientation such as vertical or horizontal." })),
|
|
800
|
-
publicationUrls: Type.Optional(
|
|
801
|
-
Type.Union([
|
|
802
|
-
Type.Object({
|
|
803
|
-
instagram: Type.Optional(Type.Union([Type.String(), Type.Null()])),
|
|
804
|
-
tiktok: Type.Optional(Type.Union([Type.String(), Type.Null()])),
|
|
805
|
-
x: Type.Optional(Type.Union([Type.String(), Type.Null()])),
|
|
806
|
-
youtube: Type.Optional(Type.Union([Type.String(), Type.Null()])),
|
|
807
|
-
zora: Type.Optional(Type.Union([Type.String(), Type.Null()])),
|
|
808
|
-
}),
|
|
809
|
-
Type.Null(),
|
|
810
|
-
]),
|
|
811
|
-
),
|
|
812
|
-
thumbnailUrl: Type.Optional(Type.Union([Type.String(), Type.Null()])),
|
|
813
|
-
title: Type.Optional(Type.Union([Type.String(), Type.Null()])),
|
|
814
|
-
transcriptEdited: Type.Optional(Type.Union([Type.String(), Type.Null()])),
|
|
815
|
-
transcriptRaw: Type.Optional(Type.Union([Type.String(), Type.Null()])),
|
|
816
|
-
transcriptVtt: Type.Optional(Type.Union([Type.String(), Type.Null()])),
|
|
817
|
-
triggerTranscription: Type.Optional(Type.Union([Type.Boolean(), Type.Null()])),
|
|
818
|
-
visibility: Type.Optional(Type.Union([Type.String(), Type.Null()])),
|
|
819
|
-
workflowStatus: Type.Optional(Type.Union([Type.String(), Type.Null()])),
|
|
820
|
-
publishingJob: Type.Optional(
|
|
821
|
-
Type.Union([
|
|
822
|
-
Type.Object({
|
|
823
|
-
platform: Type.String({ description: "Publishing platform slug/name for the downstream job." }),
|
|
824
|
-
title: Type.Optional(Type.Union([Type.String(), Type.Null()])),
|
|
825
|
-
description: Type.Optional(Type.Union([Type.String(), Type.Null()])),
|
|
826
|
-
scheduledFor: Type.Optional(Type.Union([Type.String(), Type.Null()])),
|
|
827
|
-
publishedAt: Type.Optional(Type.Union([Type.String(), Type.Null()])),
|
|
828
|
-
status: Type.Optional(Type.Union([Type.String(), Type.Null()])),
|
|
829
|
-
isImmediate: Type.Optional(Type.Boolean()),
|
|
830
|
-
tags: Type.Optional(Type.Union([Type.Array(Type.String()), Type.Null()])),
|
|
831
|
-
thumbnailAssetId: Type.Optional(Type.Union([Type.String(), Type.Null()])),
|
|
832
|
-
legacyAssetSourceId: Type.Optional(Type.Union([Type.String(), Type.Null()])),
|
|
833
|
-
metadataJson: Type.Optional(Type.Union([Type.Record(Type.String(), Type.Unknown()), Type.Null()])),
|
|
834
|
-
destination: Type.Optional(
|
|
835
|
-
Type.Union([
|
|
836
|
-
Type.Object({
|
|
837
|
-
accountId: Type.Optional(Type.Union([Type.String(), Type.Null()])),
|
|
838
|
-
username: Type.Optional(Type.Union([Type.String(), Type.Null()])),
|
|
839
|
-
displayName: Type.Optional(Type.Union([Type.String(), Type.Null()])),
|
|
840
|
-
profileImageUrl: Type.Optional(Type.Union([Type.String(), Type.Null()])),
|
|
841
|
-
configJson: Type.Optional(Type.Union([Type.Record(Type.String(), Type.Unknown()), Type.Null()])),
|
|
842
|
-
}),
|
|
843
|
-
Type.Null(),
|
|
844
|
-
]),
|
|
845
|
-
),
|
|
846
|
-
}),
|
|
847
|
-
Type.Null(),
|
|
848
|
-
]),
|
|
849
|
-
),
|
|
850
|
-
}),
|
|
851
|
-
execute: wrapExecute(publishClipAsset),
|
|
852
|
-
renderCall: makeProgressCallRenderer(getToolCallLabel("seedclub_publish_clip_asset"), (args) => args?.title || args?.guestName || args?.meetingId || args?.programSlug || undefined),
|
|
853
|
-
renderResult: makeProgressResultRenderer(getToolSuccessLabel("seedclub_publish_clip_asset"), (details) => {
|
|
854
|
-
const asset = details?.asset ?? {};
|
|
855
|
-
const assetId = typeof asset?.id === "string" ? asset.id : null;
|
|
856
|
-
const meetingId = typeof details?.linkage?.meeting_id === "string" ? details.linkage.meeting_id : null;
|
|
857
|
-
const partyId = typeof details?.linkage?.primary_party_id === "string" ? details.linkage.primary_party_id : null;
|
|
858
|
-
const pieces = [assetId, meetingId, partyId].filter(Boolean);
|
|
859
|
-
return pieces.length ? pieces.join(" · ") : undefined;
|
|
860
|
-
}),
|
|
861
|
-
});
|
|
862
|
-
|
|
863
667
|
pi.registerTool({
|
|
864
668
|
name: "seedclub_list_program_headlines",
|
|
865
669
|
label: "List Program Headlines",
|
|
@@ -38,7 +38,6 @@ export const TOOL_CALL_LABELS: Record<string, string> = {
|
|
|
38
38
|
seedclub_list_program_media_assets: "Checking media assets",
|
|
39
39
|
seedclub_get_program_media_asset: "Loading media asset details",
|
|
40
40
|
seedclub_upload_clip_asset: "Uploading clip asset",
|
|
41
|
-
seedclub_publish_clip_asset: "Publishing clip asset",
|
|
42
41
|
seedclub_list_program_headlines: "Loading program headlines",
|
|
43
42
|
seedclub_create_program_headline: "Saving headline",
|
|
44
43
|
seedclub_update_program_headline: "Updating headline",
|
|
@@ -85,7 +84,6 @@ export const TOOL_SUCCESS_LABELS: Record<string, string> = {
|
|
|
85
84
|
seedclub_list_program_media_assets: "Media assets checked",
|
|
86
85
|
seedclub_get_program_media_asset: "Media asset details loaded",
|
|
87
86
|
seedclub_upload_clip_asset: "Clip asset uploaded",
|
|
88
|
-
seedclub_publish_clip_asset: "Clip asset published",
|
|
89
87
|
seedclub_list_program_headlines: "Program headlines loaded",
|
|
90
88
|
seedclub_create_program_headline: "Headline saved",
|
|
91
89
|
seedclub_update_program_headline: "Headline updated",
|
package/package.json
CHANGED