diff --git a/agent-tools/neo4jTools.js b/agent-tools/neo4jTools.js index 1d5b46a..8b14369 100644 --- a/agent-tools/neo4jTools.js +++ b/agent-tools/neo4jTools.js @@ -1,4 +1,5 @@ const neo4jDriver = require('./mentionsNeo4jDriver'); +const { publicAudioUrl } = require('../utils/audioFormat'); // Neo4j query tools - each does exactly one thing const neo4jTools = { @@ -34,7 +35,7 @@ const neo4jTools = { return result.records.map(record => ({ episode: record.get('episode'), creator: record.get('creator'), - audioUrl: record.get('audioUrl'), + audioUrl: publicAudioUrl(record.get('audioUrl')), artworkUrl: record.get('artworkUrl'), quote: record.get('quote'), date: record.get('date'), diff --git a/docs/details-apis/HIERARCHY_API.md b/docs/details-apis/HIERARCHY_API.md index a2a91e6..71a1eda 100644 --- a/docs/details-apis/HIERARCHY_API.md +++ b/docs/details-apis/HIERARCHY_API.md @@ -50,7 +50,7 @@ curl -X GET "http://localhost:4132/api/get-hierarchy?paragraphId=https___lexfrid "paragraph": { "id": "https___lexfridman_com__p_6320_p715", "metadata": { - "audioUrl": "https://cascdr-chads-stay-winning.nyc3.cdn.digitaloceanspaces.com/745287/httpslexfridmancomp6320.mp3", + "audioUrl": "https://audio.pullthatupjamie.ai/745287/httpslexfridmancomp6320.mp3", "creator": "Lex Fridman Podcast", "end_time": 15686.3545, "episode": "#481 – Norman Ohler: Hitler, Nazis, Drugs, WW2, Blitzkrieg, LSD, MKUltra & CIA", @@ -96,7 +96,7 @@ curl -X GET "http://localhost:4132/api/get-hierarchy?paragraphId=https___lexfrid "episode": { "id": "episode_https___lexfridman_com__p_6320", "metadata": { - "audioUrl": "https://cascdr-chads-stay-winning.nyc3.cdn.digitaloceanspaces.com/745287/httpslexfridmancomp6320.mp3", + "audioUrl": "https://audio.pullthatupjamie.ai/745287/httpslexfridmancomp6320.mp3", "creator": "Lex Fridman", "description": "Norman Ohler is a historian and author of \"Blitzed: Drugs in the Third Reich\"...", "duration": 16281, diff --git a/routes/jamieExploreRoutes.js b/routes/jamieExploreRoutes.js index 28334df..564e292 100644 --- a/routes/jamieExploreRoutes.js +++ b/routes/jamieExploreRoutes.js @@ -1,4 +1,5 @@ const express = require('express'); +const { publicAudioUrl } = require('../utils/audioFormat'); const router = express.Router(); const { OpenAI } = require('openai'); const { findSimilarDiscussions, getEpisodeByGuid, getParagraphWithEpisodeData, getClipById, formatResults } = require('../agent-tools/pineconeTools.js'); @@ -373,7 +374,7 @@ router.post('/search-quotes-3d', serviceHmac({ optional: true }), createEntitlem if (ep.episodeImage) result.episodeImage = ep.episodeImage; } if (!result.audioUrl || result.audioUrl === 'URL unavailable') { - if (ep.audioUrl) result.audioUrl = ep.audioUrl; + if (ep.audioUrl) result.audioUrl = publicAudioUrl(ep.audioUrl); } if (!result.creator || result.creator === 'Creator not specified') { if (ep.creator) result.creator = ep.creator; @@ -1383,7 +1384,7 @@ router.post('/fetch-research-id', async (req, res) => { if (ep.episodeImage) result.episodeImage = ep.episodeImage; } if (!result.audioUrl || result.audioUrl === 'URL unavailable') { - if (ep.audioUrl) result.audioUrl = ep.audioUrl; + if (ep.audioUrl) result.audioUrl = publicAudioUrl(ep.audioUrl); } if (!result.creator || result.creator === 'Creator not specified') { if (ep.creator) result.creator = ep.creator; diff --git a/routes/researchSessions.js b/routes/researchSessions.js index c8f5e1f..981aa30 100644 --- a/routes/researchSessions.js +++ b/routes/researchSessions.js @@ -1,4 +1,5 @@ const express = require('express'); +const { publicAudioUrl } = require('../utils/audioFormat'); const router = express.Router(); const mongoose = require('mongoose'); @@ -1694,7 +1695,7 @@ router.post('/enrich', async (req, res) => { episode: rest.episode || 'Unknown episode', creator: rest.creator || 'Unknown creator', episodeImage: rest.episodeImage || null, - audioUrl: rest.audioUrl || null, + audioUrl: publicAudioUrl(rest.audioUrl) || null, date: rest.date || null, feedId: rest.additionalFields?.feedId || null, guid: rest.additionalFields?.guid || null, diff --git a/services/tape/tapeShared.js b/services/tape/tapeShared.js index ae7de4f..9f9cf8a 100644 --- a/services/tape/tapeShared.js +++ b/services/tape/tapeShared.js @@ -5,6 +5,7 @@ */ const crypto = require('crypto'); +const { publicAudioUrl } = require('../../utils/audioFormat'); const { TapeHttpError } = require('./tapeErrors'); /** @@ -28,7 +29,7 @@ function candidateFromResult(r) { creator: r.creator || null, feedId: r.feedId != null ? String(r.feedId) : null, // for source gating (tapeTaste.feed_allow) episodeImage: r.episodeImage && r.episodeImage !== 'Image unavailable' ? r.episodeImage : null, - audioUrl: r.audioUrl && r.audioUrl !== 'URL unavailable' ? r.audioUrl : null, + audioUrl: publicAudioUrl(r.audioUrl && r.audioUrl !== 'URL unavailable' ? r.audioUrl : null), startTime: Number.isFinite(start) ? start : null, endTime: Number.isFinite(end) ? end : null, publishedDate: r.date && r.date !== 'Date not provided' ? r.date : null, diff --git a/skills/pullthatupjamie/references/podcast-rra.md b/skills/pullthatupjamie/references/podcast-rra.md index 4820940..93e9456 100644 --- a/skills/pullthatupjamie/references/podcast-rra.md +++ b/skills/pullthatupjamie/references/podcast-rra.md @@ -243,7 +243,7 @@ Each result contains: - `quote` — transcript text - `episode` — episode title - `creator` — podcast name -- `audioUrl` — direct audio file link +- `audioUrl` — direct audio file link. **Use this value verbatim** to play or download audio; do not construct audio URLs from `feedId`/`guid` or hardcode a CDN host. - `date` — publish date - `similarity.combined` — relevance score (0-1, aim for >0.84) - `timeContext.start_time` / `end_time` — timestamp in seconds diff --git a/utils/entitlementMiddleware.js b/utils/entitlementMiddleware.js index 50ff2dc..61bc60b 100644 --- a/utils/entitlementMiddleware.js +++ b/utils/entitlementMiddleware.js @@ -6,6 +6,7 @@ */ const { resolveIdentity, TIERS } = require('./identityResolver'); +const { publicAudioUrl } = require('./audioFormat'); const { Entitlement } = require('../models/Entitlement'); const { AgentInvoice } = require('../models/AgentInvoice'); const JamieVectorMetadata = require('../models/JamieVectorMetadata'); @@ -438,7 +439,7 @@ async function generateDebugMockResponse(entitlementType, query) { description: null, episode: doc.episode || doc.metadataRaw?.episode || 'Mock Episode', creator: doc.creator || doc.metadataRaw?.creator || 'Mock Creator', - audioUrl: doc.audioUrl || doc.metadataRaw?.audioUrl || '', + audioUrl: publicAudioUrl(doc.audioUrl || doc.metadataRaw?.audioUrl) || '', episodeImage: doc.episodeImage || doc.metadataRaw?.episodeImage || '', date: doc.publishedDate || 'Date not provided', published: doc.publishedDate || null, diff --git a/utils/workflowOutputFormatter.js b/utils/workflowOutputFormatter.js index 1947ad5..dfce591 100644 --- a/utils/workflowOutputFormatter.js +++ b/utils/workflowOutputFormatter.js @@ -1,4 +1,5 @@ const BASE_URL = process.env.FRONTEND_URL || 'https://www.pullthatupjamie.ai'; +const { publicAudioUrl } = require('./audioFormat'); /** * Format workflow results based on the requested outputFormat. @@ -48,7 +49,7 @@ function formatAsStructured(result) { : null, episode: item.episode || null, speaker: item.creator || null, - audioUrl: item.audioUrl || null, + audioUrl: publicAudioUrl(item.audioUrl) || null, }, guid: item.guid || null, feedId: item.feedId || null, diff --git a/utils/workflowSteps.js b/utils/workflowSteps.js index 268bf36..c132043 100644 --- a/utils/workflowSteps.js +++ b/utils/workflowSteps.js @@ -1,4 +1,5 @@ const { printLog } = require('../constants.js'); +const { publicAudioUrl } = require('./audioFormat'); const JamieVectorMetadata = require('../models/JamieVectorMetadata'); const WorkProductV2 = require('../models/WorkProductV2'); const { findSimilarDiscussions } = require('../agent-tools/pineconeTools'); @@ -26,7 +27,7 @@ function buildMiniPlayer(result) { : null, episode: result.episode || null, speaker: result.creator || null, - audioUrl: result.audioUrl || null, + audioUrl: publicAudioUrl(result.audioUrl) || null, }; } @@ -132,7 +133,7 @@ async function stepSearchQuotes({ query, feedIds = [], guids = [], limit = 10, m quote: metadata.text || metadata.summary || metadata.headline || 'Quote unavailable', episode: metadata.episode || metadata.title || 'Unknown episode', creator: metadata.creator || 'Unknown', - audioUrl: metadata.audioUrl || null, + audioUrl: publicAudioUrl(metadata.audioUrl) || null, episodeImage: metadata.episodeImage || null, date: metadata.publishedDate || null, similarity: parseFloat(r.score.toFixed(4)),