Python 3.12 runtime — pw-enterprise/.python-version:1 (3.12) and pw-enterprise/pyproject.toml:10 (requires-python = ">=3.12") both pin Python 3.12. ✅
Flask 3.1.2 — pw-enterprise/pyproject.toml:44 (flask>=3.1.2) and pw-enterprise/uv.lock:1452-1453 resolve to 3.1.2. ✅
SQLAlchemy 2.0.46 — pw-enterprise/uv.lock:6393-6394 resolves to 2.0.46; transitive via flask-sqlalchemy (pyproject.toml:47), not declared directly. ✅
psycopg2 2.9.11 — pw-enterprise/pyproject.toml:70 (psycopg2-binary>=2.9.11) and :103 (psycopg2>=2.9.11); uv.lock:4690-4691 resolves to 2.9.11. ✅
redis client 7.1.0 — pw-enterprise/uv.lock:5730-5731 resolves to 7.1.0; cache.py:10 (import redis) confirms direct use. Transitive (via rq), not in pyproject.toml. ✅
RQ 2.6.1 — pw-enterprise/pyproject.toml:82 (rq>=2.6.1) and uv.lock:6097-6098 resolve to 2.6.1. ✅
Elasticsearch client 9.2.1 — pw-enterprise/uv.lock:1132-1133 resolves to 9.2.1; pyproject.toml:37 floor is >=9.2.0 (one patch below). ✅
Gunicorn 24.1.1 — pw-enterprise/uv.lock:2097-2098 resolves to 24.1.1; pyproject.toml:51 floor is >=23.0.0 (a major below the resolved version). ✅
Marshmallow 3.26.2 — pw-enterprise/uv.lock:3447-3448 resolves to 3.26.2; transitive via flask-marshmallow/marshmallow-sqlalchemy, not declared directly. ✅
Sentry SDK 2.51.0 — pw-enterprise/pyproject.toml:85 (sentry-sdk[langchain,langgraph,rq]>=2.47.0) and uv.lock:6278-6279 resolve to 2.51.0. ✅
vite-plus floats to latest in package.json (the Vite+ toolchain self-manages its tool versions); all other dependencies use caret (^) ranges that allow minor/patch upgrades — the numbers above are the declared floors.
📎 Evidence
React / React DOM 19.1.0 — pw-enterprise-frontend/package.json:108 (react: ^19.1.0) and :114 (react-dom: ^19.1.0). Caret range, not exact pin. ✅
vite-plus pinned latest — pw-enterprise-frontend/package.json:171 ("vite-plus": "latest"); :168 aliases vite to npm:@voidzero-dev/vite-plus-core@latest. ✅
Vite+ unified toolchain — pw-enterprise-frontend/CLAUDE.md:1 describes it built on Vite, Rolldown, Vitest, tsdown, Oxlint, Oxfmt; package.json:177 overrides vitest to @voidzero-dev/vite-plus-test. ✅
Server-side versions of PostgreSQL/Elasticsearch are infra-managed — to be confirmed once cloud access is granted (see Environments & Infrastructure).
📎 Evidence
PostgreSQL system of record (server version pending) — pw-enterprise/.env:128SQLALCHEMY_DATABASE_URI and :140-141POSTGRES_HOST/POSTGRES_PORT confirm a Postgres connection; server version is infra-managed and not in any manifest. 🔍 Needs cloud/host access (SELECT version()).
Redis row = client 7.1.0; server pending — pw-enterprise/uv.lock:5730-5731 pins the Python redis client to 7.1.0; .env:41-43redis_host/redis_port/redis_password confirm connectivity. Table now marks the server version pending and labels 7.1.0 as the client. ✅
Elasticsearch 9.2.x (client-derived) — pw-enterprise/uv.lock:1132-1133 pins client to 9.2.1; .env:26elastic_key confirms connectivity. Doc says ‘9.2.x’ (appropriately fuzzy for server). ✅
BigQuery client 3.40.0 — pw-enterprise/pyproject.toml:100 (google-cloud-bigquery>=3.39.0) and uv.lock:1745-1746 resolve to 3.40.0. Doc correctly labels it ‘client’. ✅
Node version: CI uses lts/* (Node 22) — pw-enterprise-frontend/.github/workflows/playwright.yml:26 uses node-version: lts/*; no .nvmrc/.node-version/engines field is declared, so the project floor is inferred (package-lock.json:2044 shows a transitive "node": ">=18.0.0"). Table now cites the CI version. ✅
Google Gemini LLM — pw-enterprise/app.py:5859-5860 builds ChatGoogleGenerativeAI(model="gemini-3-flash-preview"); gemini_grounded_call defined in pw-enterprise/library/ai_services.py:63 and imported in app.py:166. ✅
Cohere — pw-enterprise/api/planner.py:12,63 does import cohere and cohere_api_key = os.environ["cohere_api_key"]; .env:4 defines the key. ✅
Cerebras fast-inference LLM — pw-enterprise/v3/langraph_main.py:30,397-399 reads CEREBRAS-API-KEY, imports from cerebras.cloud.sdk import Cerebras, and calls cerebras_client.chat.completions.create; dep in pyproject.toml:30. ✅
DeepSeek LLM — pw-enterprise/api/assets/routers/transparency.py:2280-2284 active ChatOpenAI(openai_api_key=deepseek_api_key, model="deepseek-chat", base_url="https://api.deepseek.com"); secret mapped in app.py:43. ✅
Perplexity answer engine — pw-enterprise/library/ai_services.py:311-316 reads perplexity_api_key and POSTs to https://api.perplexity.ai/chat/completions with a Bearer header. ✅
SambaNova LLM — pw-enterprise/api/planner.py:9591-9598 active ChatOpenAI(openai_api_key=SAMBAVERSE_API_KEY, openai_api_base="https://api.sambanova.ai/v1", tags=[..., "sambanova"]); secret mapped in app.py:46. ✅
LlamaIndex (local library) — pw-enterprise/api/assets/routers/assets_uploads.py:110 imports from llama_index.core import SimpleDirectoryReader; app.py:32 loads LLAMAINDEX-API-KEY but no LlamaIndex Cloud endpoint call was found — so this is the local library, as the table now states. ✅
fal.ai media generation — pw-enterprise/api/meetings.py:3105,3251 imports fal_client and calls fal_client.submit("fal-ai/flux-pro/v1.1", ...); dep in pyproject.toml:39; key loaded in app.py:35. ✅
Replicate generation — pw-enterprise/api/planner_creative.py:29,93,7149-7150 does import replicate, reads REPLICATE_API_TOKEN, and calls replicate.run(...); dep in pyproject.toml:80. ✅
Stability AI image gen — pw-enterprise/api/assets/routers/personas.py:4232,4234 POSTs to https://api.stability.ai/v2beta/stable-image/generate/core with Bearer {stability_ai_token}. ✅
Leonardo AI image gen — pw-enterprise/api/planner_creative.py:92,7551,7565 reads leonardo_key and calls https://cloud.leonardo.ai/api/rest/v1/generations with Bearer {leonardo_key}. ✅
Midjourney via GoAPI + TheNextLeg — pw-enterprise/api/planner_creative.py:90,94 read the_next_leg and go_api_midjourney; GoAPI endpoint https://api.midjourneyapi.xyz/mj/v2/imagine at 6641 and TheNextLeg Bearer headers at 6566/6607. ✅
Napkin (key only, no call site) — napkin_api_key is read at module load in pw-enterprise/config/constants.py:52 and api/assets/main.py:58, but a repo-wide grep found NO HTTP call to any Napkin endpoint. ⚠️ Integration is provisioned but no active call site was found; confirm before listing as an active service.
Tavus AI video/avatars — pw-enterprise/api/assets/routers/conversations.py:2941,2958,3042,3058 calls https://tavusapi.com/v2/personas and /v2/conversations with x-api-key: TAVUS_API_KEY. ✅
Whisper transcription — pw-enterprise/api/planner_creative.py:95,3258 reads whisperapi_key and posts to https://transcribe.whisperapi.com with a Bearer header. ✅
Langfuse tracing, separate App/Dev/Test — .env:152-166 has four key-pairs (local, DEV, TEST, APP); library/langsmith_metadata.py:16-34 calls get_client() + LangChainInstrumentor().instrument(); scripts/push_see_trace_prompt.py:100-105 selects LANGFUSE_*_KEY_{DEV,TEST,APP}. ✅
LangSmith tracing — pw-enterprise/library/langsmith_metadata.py:37-57setup_langsmith_tracing() requires LANGCHAIN_API_KEY then sets LANGCHAIN_TRACING_V2/LANGSMITH_TRACING; dep langsmith in pyproject.toml:17. ✅
Tavily (env key only — no code usage) — .env:137 defines TAVILY_API_KEY but a repo-wide grep for tavily across all .py (incl. v3/, ai_twin/, research_setup/) returned ZERO matches: no import, no HTTP call, no LangChain tool. 🔍 Needs a confirmed call site (or a runtime trace) before listing Tavily as an active Search API; currently only a provisioned key.
Serper search API — pw-enterprise/api/intent_insights.py:7766,7768 POSTs to https://google.serper.dev/search with X-API-KEY: serper_api_key. ✅
SerpWow search API — pw-enterprise/library/google_ads_package.py:4949 calls https://api.serpwow.com/live/search?api_key={}... with serpwow_api_key. ✅
ValueSERP search API — pw-enterprise/library/ai_services.py:226,237 reads valueserp_api_key and calls https://api.valueserp.com/search. ✅
DataForSEO SERP data (actively called) — pw-enterprise/api/intent_insights.py:9635 calls https://api.dataforseo.com/v3/keywords_data/bing/search_volume/live (plus 9362, 9775, 10153, 12256, and v3/tools.py:11984); secret loaded in app.py:36. ✅
ZenRows scraping — pw-enterprise/api/misc.py:2044,2065 sends apikey: zenrow_token to https://api.zenrows.com/v1/. ✅
ScrapingNarf (key read; call site not pinned) — pw-enterprise/app.py:309 reads scraping_narf_ai_key = os.environ["scraping_narf_ai_key"] and .env:27 defines it; finder asserts use in 10+ modules but cited only the env read, not an HTTP endpoint. ⚠️ Confirm an actual scrapingnarf API call site.
Unwrangle extraction — pw-enterprise/api/product.py:96,1590,1598 reads unwrangle_api_key and GETs https://data.unwrangle.com/api/getter/. ✅
RapidAPI marketplace — pw-enterprise/library/google_ads_package.py:4814,4819 calls https://youtube-v31.p.rapidapi.com/search with x-rapidapi-key header. ✅
BuzzSumo analytics — pw-enterprise/api/intent_insights.py:623,630 sends api_key: buzz_sumo to https://api.buzzsumo.com/search/articles.json. ✅
SMMRY summarization — pw-enterprise/library/algorithms.py:24,258,266 defines smmry() posting to https://api.smmry.com with SM_API_KEY: smmry_key. ✅
NewsData feeds — pw-enterprise/cron/top_daily_news_by_country_cron.py:16,86 reads newsdata_api_key and GETs https://newsdata.io/api/1/latest. ✅
US Census demographics — pw-enterprise/ai_twin/respondents/universe_stage_fetcher.py:63,247,310 reads CENSUS_API_KEY and calls https://api.census.gov/data/{acs_year}/acs/acs1. ✅
Rainforest Amazon data — pw-enterprise/api/product.py:311,482 have active requests.get("https://api.rainforestapi.com/request", ...) (finder’s cited line 118 is commented, but 311/482 are live). ✅
BigBox Home Depot data — pw-enterprise/api/social_insights.py:79,670,676 reads bigbox_key and GETs https://api.bigboxapi.com/request; secret mapped in app.py:37. ✅
BlueCart Walmart data — pw-enterprise/api/social_insights.py:80,530,536 reads bluecart_key and GETs https://api.bluecartapi.com/request; secret mapped in app.py:38. ✅
RedCircle Target data — pw-enterprise/api/social_insights.py:81,603 reads redcircle_key and GETs https://api.redcircleapi.com/request; secret mapped in app.py:39. ✅
Meta / Facebook Ads + BM + Power Editor — pw-enterprise/library/facebook_package.py:51,75 reads fb_version and calls https://graph.facebook.com/{fb_version}/me?fields=adaccounts; .env:39-40,10-15,20 define facebook + BM + power-editor creds. ✅
Google Ads / DV360 — pw-enterprise/library/google_ads_package.py:51,66 reads google_client_secret + google_ads_auth(); library/dv360_package.py:32-33,36 reads dv360_client_id/secret + dv360_auth(); dep google-ads in pyproject.toml:49. ✅
Snapchat Ads (dev + prod apps) — pw-enterprise/library/snapchat_package.py:13-16,33-36 reads dev_/prod_snapchat_client_id/secret and branches on environment; .env:29-34 define all three pairs. ✅
TikTok Ads — pw-enterprise/library/tiktok_package.py:20-21,155 reads tiktok_client_id/secret and calls https://business-api.tiktok.com/open_api/v1.3/ad/audience_size/estimate/. ✅
Pinterest Ads — pw-enterprise/library/pinterest_package.py:18-19,43 reads PINTEREST_CLIENT_ID/SECRET and calls https://api.pinterest.com/v5/oauth/token. ✅
Twitter / X Ads — pw-enterprise/api/twitter.py:12,14-15 reads twitter_consumer_key, twitter_access_token(_secret); dep twitter-ads in pyproject.toml:91; five creds in .env:60-64. ✅
LinkedIn Ads (in-house wrapper) — pw-enterprise/library/linkedin_package.py:19-20,41,157 does OAuth at https://www.linkedin.com/oauth/v2/accessToken and ad targeting at https://api.linkedin.com/rest/adTargetingEntities. ✅ Note: lines 19-20 contain hardcoded default client_id/secret fallbacks (a security smell worth flagging separately).
YouTube data — pw-enterprise/library/youtube_package.py:14,57 reads youtube_client_secret and builds build("youtube", "v3", credentials=credentials). ✅
Spotify (in-house wrapper) — pw-enterprise/library/spotify_package.py:6-7spotify_access_token() calls https://accounts.spotify.com/api/token; no dedicated .env key (creds likely in GCP Secret Manager, per finder note). ✅
GA4 analytics — pw-enterprise/library/google_analytics_4_package.py:33,44 has google_analytics_auth() + get_kv_user_platform_token(..., "google_analytics"); a separate library/google_analytics_package.py (GA3) also exists. ✅
Cloudflare R2 + Images + Browser Rendering — library/storage.py:37,104 uses r2.cloudflarestorage.com and api.cloudflare.com/.../images/v1; api/misc.py:2131 calls .../browser-rendering/screenshot; .env:118,120,124-125,144-148 define R2/Images/Browser/general keys. ✅ (Workers/Pages hosting is via frontend Wrangler — not evidenced in backend, but consistent with tech-stack table.)
Azure Key Vault + Blob (legacy) — library/storage.py:6-7 states the backend “migrated from Azure Blob Storage to Cloudflare R2”; library/secrets.py:109-116 Key-Vault-named functions now delegate to GCP Secret Manager; deps remain in pyproject.toml:27-28 but NO from azure import exists in any .py. ✅ (legacy is accurate)
Sentry monitoring — pw-enterprise/library/sentry_client.py:41,62 is a dedicated client using SENTRY_API_BASE_URL + SENTRY_API_TOKEN; dep sentry-sdk[langchain,langgraph,rq] in pyproject.toml:85. ✅
Datadog monitoring — pw-enterprise/cron/iam_checks.py:17-18,106,109 reads both Datadog keys and calls https://api.us3.datadoghq.com/api/v1/synthetics/... with DD-API-KEY/DD-APPLICATION-KEY. ✅
Mailgun email — pw-enterprise/airflow_monitor.py:20-22,180-181 reads Mailgun creds and sends via smtplib.SMTP("smtp.mailgun.org", 587) with .login(...). ✅
Jobs / async: rq, nest-asyncio (plus an in-house Airflow REST client library/airflow_client.py — Airflow itself runs externally and is not a PyPI dependency)
Web/API group — pw-enterprise/pyproject.toml:40,43-48,51,84,94 — flask, flask-cors, flask-sqlalchemy, flask-marshmallow, flask-sse, fastapi[standard], uvicorn, gunicorn, flasgger, security all present. ✅
AI frameworks group — pw-enterprise/pyproject.toml:12-25,33,57,105-106 — langchain(+sub-packages), langgraph(+prebuilt,cli), langsmith, crewai, llama-index, langfuse, openinference-instrumentation-langchain all present. ✅
Airflow is an in-house REST client, not a PyPI dep — pw-enterprise/pyproject.toml has no apache-airflow; library/airflow_client.py (HTTP wrapper) is imported at api/product_health.py:46. Inventory now states this. ✅
~100 backend deps — pw-enterprise/pyproject.toml app branch: 95 in [project].dependencies + 3 in [dependency-groups].dev = 98 (~100). ✅
Airtable absent — grep -ri airtable pw-enterprise returns no matches; not in pyproject.toml nor .env. Correctly flagged as a non-code operational tool. ✅
Comparing the committed manifests across branches, dev and test carry a newer backend dependency set than prod app — most notably a bumped LangChain / LangGraph / LangSmith / OpenAI cluster plus a few extra packages. app is the lowest-version baseline.
Backend — shared dependencies bumped on dev (and test) vs prod app:
Package
prod (app)
dev / test
langchain
>=1.2.6
>=1.3.1
langgraph
>=1.0.6
>=1.2.0
langchain-core
>=1.2.7
>=1.4.0
langsmith
>=0.6.4
>=0.8.5
langchain-anthropic
>=1.3.1
>=1.4.3
langchain-openai
>=1.1.7
>=1.2.1
langchain-google-community
>=3.0.5
>=4.0.0
openai
>=2.9.0
>=2.26.0
The full langchain-* / langgraph-* family moves together; the table lists the headline bumps.
Backend — extra packages on dev / test beyond prod app:
Environment
Adds (beyond app)
Dev (dev)
deepagents==0.6.2 + the bumped LangChain/LangGraph cluster above
Test (test)
deepagents==0.6.2, crawl4ai==0.8.0, cryptography>=46.0.6 + the same bumped cluster
Prod (app)
— (baseline)
tensorflow, tensorflow-hub, prophet, and matplotlib live in the opt-in [dependency-groups].airflow group (not the core [project].dependencies), so they are not installed by default in any environment. db-dtypes is in the app baseline, not a dev-only extra.
Frontend — only the Vite+ toolchain differs (dev and test share one package.json):
Package
dev / test
prod (main)
vite-plus (@voidzero-dev/vite-plus-core)
^0.1.18
latest
@vitejs/plugin-react
^5.2.0
^6.0.1
All other frontend dependencies are identical across Dev / Test / Prod.
Net: the frontend differs only in the Vite+ toolchain, but the backend dev/test branches run a materially newer LangChain / LangGraph / OpenAI stack than prod app — a real source-level version difference, not parity.
📎 Evidence
FE vite-plus dev/test ^0.1.18 — git show origin/dev:package.json & origin/test:package.json (line 171) both "vite-plus": "^0.1.18", vite alias @^0.1.18. ✅
FE vite-plus main latest — pw-enterprise-frontend/package.json:171 on origin/main "vite-plus": "latest" (vite alias @latest). ✅
@vitejs/plugin-react 5.2.0 vs 6.0.1 — git diff origin/main origin/dev -- package.json shows ^6.0.1→^5.2.0; test identical to dev. ✅
FE otherwise identical — git diff origin/main origin/dev -- package.json shows only @vitejs/plugin-react, vite-plus, vite alias version changes + xlsx/overrides reorder. ✅
Shared-dependency bumps on dev/test — git diff origin/app origin/dev -- pyproject.toml shows langchain 1.2.6→1.3.1, langgraph 1.0.6→1.2.0, langchain-core 1.2.7→1.4.0, langsmith 0.6.4→0.8.5, langchain-anthropic 1.3.1→1.4.3, langchain-openai 1.1.7→1.2.1, langchain-google-community 3.0.5→4.0.0, openai 2.9.0→2.26.0; origin/test bumps the same cluster. Section now documents these. ✅
Dev/test extra packages — git diff origin/app origin/dev and …origin/test -- pyproject.toml: both add deepagents==0.6.2; test also adds crawl4ai==0.8.0 + cryptography>=46.0.6. The earlier bigquery>=0.0.1 entry did not exist (only google-cloud-bigquery>=3.39.0, present in app too) and has been removed. ✅
tensorflow/matplotlib are opt-in, db-dtypes is baseline — they live in [dependency-groups].airflow, and db-dtypes is in the app[project].dependencies (:35), not a dev-only extra; the note now states this. ✅
App baseline — git show origin/app:pyproject.toml lacks crawl4ai, deepagents, cryptography>=46 and runs the lower LangChain/LangGraph floors; it is the lowest-version baseline. ✅