[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill-promptfoo-promptfoo-provider-setup":3,"mdc-pvr3aj-key":51,"related-org-promptfoo-promptfoo-provider-setup":1264,"related-repo-promptfoo-promptfoo-provider-setup":1313},{"slug":4,"name":4,"fn":5,"description":6,"org":7,"tags":10,"stars":24,"repoUrl":25,"updatedAt":26,"license":27,"forks":28,"topics":29,"repo":46,"sourceUrl":49,"mdContent":50},"promptfoo-provider-setup","configure promptfoo providers and targets","Configure promptfoo providers or redteam targets for hosted models, live HTTP APIs, Python\u002FJavaScript local scripts, agent SDKs, or multi-input systems. Use when connecting promptfoo to the system under test, mapping vars, auth env vars, request bodies, response transforms, or static-code-derived provider wrappers. Do not use for choosing eval assertions or red team plugins unless a smoke test is needed to verify the connection.\n",{"slug":8,"name":8,"logoUrl":9,"githubOrg":8},"promptfoo","https:\u002F\u002Fpexgzepcugksgbtrxkhf.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Forg-logos\u002Fpromptfoo.png",[11,15,18,21],{"name":12,"slug":13,"type":14},"LLM","llm","tag",{"name":16,"slug":17,"type":14},"Evals","evals",{"name":19,"slug":20,"type":14},"API Development","api-development",{"name":22,"slug":23,"type":14},"Testing","testing",23182,"https:\u002F\u002Fgithub.com\u002Fpromptfoo\u002Fpromptfoo","2026-07-18T05:47:13.657873",null,2079,[30,31,32,33,34,13,35,36,37,38,39,40,41,42,43,44,23,45],"ci","ci-cd","cicd","evaluation","evaluation-framework","llm-eval","llm-evaluation","llm-evaluation-framework","llmops","pentesting","prompt-engineering","prompt-testing","prompts","rag","red-teaming","vulnerability-scanners",{"repoUrl":25,"stars":24,"forks":28,"topics":47,"description":48},[30,31,32,33,34,13,35,36,37,38,39,40,41,42,43,44,23,45],"Test your prompts, agents, and RAGs. Red teaming\u002Fpentesting\u002Fvulnerability scanning for AI. Compare performance of GPT, Claude, Gemini, DeepSeek, and more. Simple declarative configs with command line and CI\u002FCD integration.  Used by OpenAI and Anthropic.","https:\u002F\u002Fgithub.com\u002Fpromptfoo\u002Fpromptfoo\u002Ftree\u002FHEAD\u002Fplugins\u002Fpromptfoo\u002Fskills\u002Fpromptfoo-provider-setup","---\nname: promptfoo-provider-setup\ndescription: >\n  Configure promptfoo providers or redteam targets for hosted models, live HTTP\n  APIs, Python\u002FJavaScript local scripts, agent SDKs, or multi-input systems. Use\n  when connecting promptfoo to the system under test, mapping vars, auth env\n  vars, request bodies, response transforms, or static-code-derived provider\n  wrappers. Do not use for choosing eval assertions or red team plugins unless a\n  smoke test is needed to verify the connection.\n---\n\n# Promptfoo Provider Setup\n\nConnect Promptfoo to the system under test with the smallest reliable provider\nor target configuration. Prefer a working smoke test over a clever abstraction.\n\nRead `references\u002Fprovider-patterns.md` when you need concrete YAML or provider\nwrapper examples.\nFor OpenAPI specs, you can run the bundled\n`scripts\u002Fopenapi-operation-to-config.mjs` to draft a one-operation HTTP smoke\nconfig, then inspect and edit the result before probing. The script ships in this\nskill's `scripts\u002F` directory; when the skill is installed as a plugin it lives in\nthe plugin cache, not your project, so run it by its absolute path (or copy it in)\nrather than a bare `scripts\u002F...` path. With `--token-env`, it\ninfers Bearer\u002FOAuth2\u002FOpenID and header\u002Fquery\u002Fcookie API-key auth; use\n`--auth-header`\u002F`--auth-prefix` to override.\n\n## Inputs\n\nInfer from the repo or user prompt when possible:\n\n- Target surface: hosted model, live HTTP endpoint, local function\u002Fscript, agent\n  harness, MCP\u002Ftool agent, or redteam target.\n- Invocation shape: method, URL\u002Fpath, headers, request body, input vars, auth,\n  streaming\u002Fstatefulness, and expected response field.\n- Safety boundary: whether it is okay to call the live endpoint and which sample\n  payload is safe.\n- Output goal: eval provider block, redteam `targets` block, local provider\n  wrapper, or a minimal smoke-test suite.\n\nIf the contract is unclear, create a conservative TODO-marked starter and state\nexactly what must be verified before using it against production.\n\n## Workflow\n\n### 1. Pick discovery mode\n\nUse one of these modes, or combine them:\n\n- **Live HTTP endpoint**: probe an already-running endpoint with safe requests.\n- **Static code discovery**: inspect route handlers, OpenAPI specs, tests, SDK\n  clients, or existing fetch\u002Faxios calls.\n- **Hybrid**: compare static contract assumptions with a live probe.\n- **Wrapper mode**: write `provider.js` or `provider.py` when built-in providers\n  cannot express auth, signing, streaming, multi-step calls, or custom parsing.\n\nDo not send secrets to unknown endpoints. Use `{{env.VAR}}` placeholders in\nconfigs and local environment variables only in shell commands.\n\n### 2. Discover the contract\n\nFor live HTTP endpoints:\n\n1. Start with non-mutating checks: docs URL, OpenAPI URL, health endpoint,\n   `OPTIONS`, or a safe `GET`.\n2. Make at most one safe representative call before writing config.\n3. Capture the response shape and status\u002Ferror behavior.\n4. Prefer explicit JSON paths in `transformResponse`, such as `json.output`.\n5. Use `queryParams` for query-string fields on any HTTP method, and use the\n   `text` variable in `transformResponse` for plain-text responses.\n6. Set `stateful: false` for stateless endpoints; otherwise `validate target`\n   will run a session-memory check. For stateful apps, include `{{sessionId}}`\n   in the request or configure server-side session parsing.\n\nFor static code discovery:\n\n1. Search for route definitions, tests, and clients with `rg`.\n2. Identify method, path, required headers, request schema, response schema, and\n   authentication source.\n3. If the app constructs prompts dynamically, wrap the real code instead of\n   duplicating business logic in YAML.\n4. For agents\u002Ftools, identify whether Promptfoo should send one string input or\n   a structured object with named fields.\n\n### 3. Choose the provider pattern\n\n- Use `id: https` for straightforward JSON HTTP APIs.\n- Use `file:\u002F\u002Fprovider.js` or `file:\u002F\u002Fprovider.py` for custom auth, request\n  signing, streaming, retries, multi-step setup, local code, Python agent SDKs,\n  or complex parsing.\n- Use native model providers for direct model comparisons.\n- Use `targets` with `inputs` for redteam multi-input systems. Do not invent a\n  single `prompt` field when the real app accepts named inputs.\n\n### 4. Implement the minimal smoke test\n\nAdd or update a config with:\n\n- `# yaml-language-server: $schema=https:\u002F\u002Fpromptfoo.dev\u002Fconfig-schema.json`\n- A short `description`\n- Provider or `targets` config with `{{env.VAR}}` for secrets\n- One or two smoke tests that verify the request reaches the target and the\n  response transform extracts the right field\n- `--no-cache` run commands\n\nWhen writing a local wrapper, return `{ output }` and include structured errors\nwhen the target response is malformed. JavaScript providers receive config in\nconstructor `options.config` and expose `callApi(prompt, context)`; read named\ninputs from `context.vars`. Python providers use `file:\u002F\u002Fprovider.py` or\n`file:\u002F\u002Fprovider.py:function_name`; the function takes `(prompt, options,\ncontext)` and reads named inputs from `context.get(\"vars\", {})`. Set\n`config.workers: 1` for non-thread-safe SDKs, `config.timeout` for slow calls,\nand `config.pythonExecutable`\u002F`PROMPTFOO_PYTHON` for venvs. Add harmless\ndefaults because `validate target` may call providers without test-case vars.\n\n### 5. Validate and run\n\nFrom the promptfoo repo, use the local build:\n\n```bash\nnpm run local -- validate config -c path\u002Fto\u002Fpromptfooconfig.yaml\nnpm run local -- validate target -c path\u002Fto\u002Fpromptfooconfig.yaml\nnpm run local -- eval -c path\u002Fto\u002Fpromptfooconfig.yaml -o output.json --no-cache --no-share\n```\n\nOutside the promptfoo repo, use:\n\n```bash\nnpx promptfoo@latest validate config -c path\u002Fto\u002Fpromptfooconfig.yaml\nnpx promptfoo@latest validate target -c path\u002Fto\u002Fpromptfooconfig.yaml\nnpx promptfoo@latest eval -c path\u002Fto\u002Fpromptfooconfig.yaml -o output.json --no-cache --no-share\n```\n\nInspect the output file for `results.stats`, `response.output`, `score`, and\n`error`; do not rely only on the process exit code.\n\nUse `--no-share` by default while probing live or internal systems. Remove it\nonly when the user explicitly wants a cloud share URL.\n\n## Common Mistakes\n\n```yaml\n# WRONG: shell-style env vars are literal strings in YAML\napiKey: $API_KEY\n\n# CORRECT: promptfoo renders Nunjucks env references\napiKey: '{{env.API_KEY}}'\n```\n\n```yaml\n# WRONG: flattening a multi-input target into prompt loses attack surface\nbody:\n  prompt: '{{prompt}}'\n\n# BETTER: preserve the real app fields\nbody:\n  user_id: '{{user_id}}'\n  message: '{{message}}'\n```\n\n## Output Contract\n\nWhen done, state:\n\n- Connection mode used: live, static, hybrid, or wrapper\n- Files created or modified\n- Required environment variables\n- Safe smoke command with `--no-cache --no-share`\n- What was actually verified, and what remains a TODO\n",{"data":52,"body":53},{"name":4,"description":6},{"type":54,"children":55},"root",[56,64,70,132,139,144,177,182,188,195,200,260,273,279,284,395,400,430,436,501,507,512,570,676,682,687,837,842,944,980,992,998,1081,1213,1219,1224,1258],{"type":57,"tag":58,"props":59,"children":60},"element","h1",{"id":4},[61],{"type":62,"value":63},"text","Promptfoo Provider Setup",{"type":57,"tag":65,"props":66,"children":67},"p",{},[68],{"type":62,"value":69},"Connect Promptfoo to the system under test with the smallest reliable provider\nor target configuration. Prefer a working smoke test over a clever abstraction.",{"type":57,"tag":65,"props":71,"children":72},{},[73,75,82,84,90,92,98,100,106,108,114,116,122,124,130],{"type":62,"value":74},"Read ",{"type":57,"tag":76,"props":77,"children":79},"code",{"className":78},[],[80],{"type":62,"value":81},"references\u002Fprovider-patterns.md",{"type":62,"value":83}," when you need concrete YAML or provider\nwrapper examples.\nFor OpenAPI specs, you can run the bundled\n",{"type":57,"tag":76,"props":85,"children":87},{"className":86},[],[88],{"type":62,"value":89},"scripts\u002Fopenapi-operation-to-config.mjs",{"type":62,"value":91}," to draft a one-operation HTTP smoke\nconfig, then inspect and edit the result before probing. The script ships in this\nskill's ",{"type":57,"tag":76,"props":93,"children":95},{"className":94},[],[96],{"type":62,"value":97},"scripts\u002F",{"type":62,"value":99}," directory; when the skill is installed as a plugin it lives in\nthe plugin cache, not your project, so run it by its absolute path (or copy it in)\nrather than a bare ",{"type":57,"tag":76,"props":101,"children":103},{"className":102},[],[104],{"type":62,"value":105},"scripts\u002F...",{"type":62,"value":107}," path. With ",{"type":57,"tag":76,"props":109,"children":111},{"className":110},[],[112],{"type":62,"value":113},"--token-env",{"type":62,"value":115},", it\ninfers Bearer\u002FOAuth2\u002FOpenID and header\u002Fquery\u002Fcookie API-key auth; use\n",{"type":57,"tag":76,"props":117,"children":119},{"className":118},[],[120],{"type":62,"value":121},"--auth-header",{"type":62,"value":123},"\u002F",{"type":57,"tag":76,"props":125,"children":127},{"className":126},[],[128],{"type":62,"value":129},"--auth-prefix",{"type":62,"value":131}," to override.",{"type":57,"tag":133,"props":134,"children":136},"h2",{"id":135},"inputs",[137],{"type":62,"value":138},"Inputs",{"type":57,"tag":65,"props":140,"children":141},{},[142],{"type":62,"value":143},"Infer from the repo or user prompt when possible:",{"type":57,"tag":145,"props":146,"children":147},"ul",{},[148,154,159,164],{"type":57,"tag":149,"props":150,"children":151},"li",{},[152],{"type":62,"value":153},"Target surface: hosted model, live HTTP endpoint, local function\u002Fscript, agent\nharness, MCP\u002Ftool agent, or redteam target.",{"type":57,"tag":149,"props":155,"children":156},{},[157],{"type":62,"value":158},"Invocation shape: method, URL\u002Fpath, headers, request body, input vars, auth,\nstreaming\u002Fstatefulness, and expected response field.",{"type":57,"tag":149,"props":160,"children":161},{},[162],{"type":62,"value":163},"Safety boundary: whether it is okay to call the live endpoint and which sample\npayload is safe.",{"type":57,"tag":149,"props":165,"children":166},{},[167,169,175],{"type":62,"value":168},"Output goal: eval provider block, redteam ",{"type":57,"tag":76,"props":170,"children":172},{"className":171},[],[173],{"type":62,"value":174},"targets",{"type":62,"value":176}," block, local provider\nwrapper, or a minimal smoke-test suite.",{"type":57,"tag":65,"props":178,"children":179},{},[180],{"type":62,"value":181},"If the contract is unclear, create a conservative TODO-marked starter and state\nexactly what must be verified before using it against production.",{"type":57,"tag":133,"props":183,"children":185},{"id":184},"workflow",[186],{"type":62,"value":187},"Workflow",{"type":57,"tag":189,"props":190,"children":192},"h3",{"id":191},"_1-pick-discovery-mode",[193],{"type":62,"value":194},"1. Pick discovery mode",{"type":57,"tag":65,"props":196,"children":197},{},[198],{"type":62,"value":199},"Use one of these modes, or combine them:",{"type":57,"tag":145,"props":201,"children":202},{},[203,214,224,234],{"type":57,"tag":149,"props":204,"children":205},{},[206,212],{"type":57,"tag":207,"props":208,"children":209},"strong",{},[210],{"type":62,"value":211},"Live HTTP endpoint",{"type":62,"value":213},": probe an already-running endpoint with safe requests.",{"type":57,"tag":149,"props":215,"children":216},{},[217,222],{"type":57,"tag":207,"props":218,"children":219},{},[220],{"type":62,"value":221},"Static code discovery",{"type":62,"value":223},": inspect route handlers, OpenAPI specs, tests, SDK\nclients, or existing fetch\u002Faxios calls.",{"type":57,"tag":149,"props":225,"children":226},{},[227,232],{"type":57,"tag":207,"props":228,"children":229},{},[230],{"type":62,"value":231},"Hybrid",{"type":62,"value":233},": compare static contract assumptions with a live probe.",{"type":57,"tag":149,"props":235,"children":236},{},[237,242,244,250,252,258],{"type":57,"tag":207,"props":238,"children":239},{},[240],{"type":62,"value":241},"Wrapper mode",{"type":62,"value":243},": write ",{"type":57,"tag":76,"props":245,"children":247},{"className":246},[],[248],{"type":62,"value":249},"provider.js",{"type":62,"value":251}," or ",{"type":57,"tag":76,"props":253,"children":255},{"className":254},[],[256],{"type":62,"value":257},"provider.py",{"type":62,"value":259}," when built-in providers\ncannot express auth, signing, streaming, multi-step calls, or custom parsing.",{"type":57,"tag":65,"props":261,"children":262},{},[263,265,271],{"type":62,"value":264},"Do not send secrets to unknown endpoints. Use ",{"type":57,"tag":76,"props":266,"children":268},{"className":267},[],[269],{"type":62,"value":270},"{{env.VAR}}",{"type":62,"value":272}," placeholders in\nconfigs and local environment variables only in shell commands.",{"type":57,"tag":189,"props":274,"children":276},{"id":275},"_2-discover-the-contract",[277],{"type":62,"value":278},"2. Discover the contract",{"type":57,"tag":65,"props":280,"children":281},{},[282],{"type":62,"value":283},"For live HTTP endpoints:",{"type":57,"tag":285,"props":286,"children":287},"ol",{},[288,309,314,319,339,366],{"type":57,"tag":149,"props":289,"children":290},{},[291,293,299,301,307],{"type":62,"value":292},"Start with non-mutating checks: docs URL, OpenAPI URL, health endpoint,\n",{"type":57,"tag":76,"props":294,"children":296},{"className":295},[],[297],{"type":62,"value":298},"OPTIONS",{"type":62,"value":300},", or a safe ",{"type":57,"tag":76,"props":302,"children":304},{"className":303},[],[305],{"type":62,"value":306},"GET",{"type":62,"value":308},".",{"type":57,"tag":149,"props":310,"children":311},{},[312],{"type":62,"value":313},"Make at most one safe representative call before writing config.",{"type":57,"tag":149,"props":315,"children":316},{},[317],{"type":62,"value":318},"Capture the response shape and status\u002Ferror behavior.",{"type":57,"tag":149,"props":320,"children":321},{},[322,324,330,332,338],{"type":62,"value":323},"Prefer explicit JSON paths in ",{"type":57,"tag":76,"props":325,"children":327},{"className":326},[],[328],{"type":62,"value":329},"transformResponse",{"type":62,"value":331},", such as ",{"type":57,"tag":76,"props":333,"children":335},{"className":334},[],[336],{"type":62,"value":337},"json.output",{"type":62,"value":308},{"type":57,"tag":149,"props":340,"children":341},{},[342,344,350,352,357,359,364],{"type":62,"value":343},"Use ",{"type":57,"tag":76,"props":345,"children":347},{"className":346},[],[348],{"type":62,"value":349},"queryParams",{"type":62,"value":351}," for query-string fields on any HTTP method, and use the\n",{"type":57,"tag":76,"props":353,"children":355},{"className":354},[],[356],{"type":62,"value":62},{"type":62,"value":358}," variable in ",{"type":57,"tag":76,"props":360,"children":362},{"className":361},[],[363],{"type":62,"value":329},{"type":62,"value":365}," for plain-text responses.",{"type":57,"tag":149,"props":367,"children":368},{},[369,371,377,379,385,387,393],{"type":62,"value":370},"Set ",{"type":57,"tag":76,"props":372,"children":374},{"className":373},[],[375],{"type":62,"value":376},"stateful: false",{"type":62,"value":378}," for stateless endpoints; otherwise ",{"type":57,"tag":76,"props":380,"children":382},{"className":381},[],[383],{"type":62,"value":384},"validate target",{"type":62,"value":386},"\nwill run a session-memory check. For stateful apps, include ",{"type":57,"tag":76,"props":388,"children":390},{"className":389},[],[391],{"type":62,"value":392},"{{sessionId}}",{"type":62,"value":394},"\nin the request or configure server-side session parsing.",{"type":57,"tag":65,"props":396,"children":397},{},[398],{"type":62,"value":399},"For static code discovery:",{"type":57,"tag":285,"props":401,"children":402},{},[403,415,420,425],{"type":57,"tag":149,"props":404,"children":405},{},[406,408,414],{"type":62,"value":407},"Search for route definitions, tests, and clients with ",{"type":57,"tag":76,"props":409,"children":411},{"className":410},[],[412],{"type":62,"value":413},"rg",{"type":62,"value":308},{"type":57,"tag":149,"props":416,"children":417},{},[418],{"type":62,"value":419},"Identify method, path, required headers, request schema, response schema, and\nauthentication source.",{"type":57,"tag":149,"props":421,"children":422},{},[423],{"type":62,"value":424},"If the app constructs prompts dynamically, wrap the real code instead of\nduplicating business logic in YAML.",{"type":57,"tag":149,"props":426,"children":427},{},[428],{"type":62,"value":429},"For agents\u002Ftools, identify whether Promptfoo should send one string input or\na structured object with named fields.",{"type":57,"tag":189,"props":431,"children":433},{"id":432},"_3-choose-the-provider-pattern",[434],{"type":62,"value":435},"3. Choose the provider pattern",{"type":57,"tag":145,"props":437,"children":438},{},[439,451,470,475],{"type":57,"tag":149,"props":440,"children":441},{},[442,443,449],{"type":62,"value":343},{"type":57,"tag":76,"props":444,"children":446},{"className":445},[],[447],{"type":62,"value":448},"id: https",{"type":62,"value":450}," for straightforward JSON HTTP APIs.",{"type":57,"tag":149,"props":452,"children":453},{},[454,455,461,462,468],{"type":62,"value":343},{"type":57,"tag":76,"props":456,"children":458},{"className":457},[],[459],{"type":62,"value":460},"file:\u002F\u002Fprovider.js",{"type":62,"value":251},{"type":57,"tag":76,"props":463,"children":465},{"className":464},[],[466],{"type":62,"value":467},"file:\u002F\u002Fprovider.py",{"type":62,"value":469}," for custom auth, request\nsigning, streaming, retries, multi-step setup, local code, Python agent SDKs,\nor complex parsing.",{"type":57,"tag":149,"props":471,"children":472},{},[473],{"type":62,"value":474},"Use native model providers for direct model comparisons.",{"type":57,"tag":149,"props":476,"children":477},{},[478,479,484,486,491,493,499],{"type":62,"value":343},{"type":57,"tag":76,"props":480,"children":482},{"className":481},[],[483],{"type":62,"value":174},{"type":62,"value":485}," with ",{"type":57,"tag":76,"props":487,"children":489},{"className":488},[],[490],{"type":62,"value":135},{"type":62,"value":492}," for redteam multi-input systems. Do not invent a\nsingle ",{"type":57,"tag":76,"props":494,"children":496},{"className":495},[],[497],{"type":62,"value":498},"prompt",{"type":62,"value":500}," field when the real app accepts named inputs.",{"type":57,"tag":189,"props":502,"children":504},{"id":503},"_4-implement-the-minimal-smoke-test",[505],{"type":62,"value":506},"4. Implement the minimal smoke test",{"type":57,"tag":65,"props":508,"children":509},{},[510],{"type":62,"value":511},"Add or update a config with:",{"type":57,"tag":145,"props":513,"children":514},{},[515,524,535,554,559],{"type":57,"tag":149,"props":516,"children":517},{},[518],{"type":57,"tag":76,"props":519,"children":521},{"className":520},[],[522],{"type":62,"value":523},"# yaml-language-server: $schema=https:\u002F\u002Fpromptfoo.dev\u002Fconfig-schema.json",{"type":57,"tag":149,"props":525,"children":526},{},[527,529],{"type":62,"value":528},"A short ",{"type":57,"tag":76,"props":530,"children":532},{"className":531},[],[533],{"type":62,"value":534},"description",{"type":57,"tag":149,"props":536,"children":537},{},[538,540,545,547,552],{"type":62,"value":539},"Provider or ",{"type":57,"tag":76,"props":541,"children":543},{"className":542},[],[544],{"type":62,"value":174},{"type":62,"value":546}," config with ",{"type":57,"tag":76,"props":548,"children":550},{"className":549},[],[551],{"type":62,"value":270},{"type":62,"value":553}," for secrets",{"type":57,"tag":149,"props":555,"children":556},{},[557],{"type":62,"value":558},"One or two smoke tests that verify the request reaches the target and the\nresponse transform extracts the right field",{"type":57,"tag":149,"props":560,"children":561},{},[562,568],{"type":57,"tag":76,"props":563,"children":565},{"className":564},[],[566],{"type":62,"value":567},"--no-cache",{"type":62,"value":569}," run commands",{"type":57,"tag":65,"props":571,"children":572},{},[573,575,581,583,589,591,597,599,605,607,612,614,620,622,628,630,636,638,644,646,652,654,660,661,667,669,674],{"type":62,"value":574},"When writing a local wrapper, return ",{"type":57,"tag":76,"props":576,"children":578},{"className":577},[],[579],{"type":62,"value":580},"{ output }",{"type":62,"value":582}," and include structured errors\nwhen the target response is malformed. JavaScript providers receive config in\nconstructor ",{"type":57,"tag":76,"props":584,"children":586},{"className":585},[],[587],{"type":62,"value":588},"options.config",{"type":62,"value":590}," and expose ",{"type":57,"tag":76,"props":592,"children":594},{"className":593},[],[595],{"type":62,"value":596},"callApi(prompt, context)",{"type":62,"value":598},"; read named\ninputs from ",{"type":57,"tag":76,"props":600,"children":602},{"className":601},[],[603],{"type":62,"value":604},"context.vars",{"type":62,"value":606},". Python providers use ",{"type":57,"tag":76,"props":608,"children":610},{"className":609},[],[611],{"type":62,"value":467},{"type":62,"value":613}," or\n",{"type":57,"tag":76,"props":615,"children":617},{"className":616},[],[618],{"type":62,"value":619},"file:\u002F\u002Fprovider.py:function_name",{"type":62,"value":621},"; the function takes ",{"type":57,"tag":76,"props":623,"children":625},{"className":624},[],[626],{"type":62,"value":627},"(prompt, options, context)",{"type":62,"value":629}," and reads named inputs from ",{"type":57,"tag":76,"props":631,"children":633},{"className":632},[],[634],{"type":62,"value":635},"context.get(\"vars\", {})",{"type":62,"value":637},". Set\n",{"type":57,"tag":76,"props":639,"children":641},{"className":640},[],[642],{"type":62,"value":643},"config.workers: 1",{"type":62,"value":645}," for non-thread-safe SDKs, ",{"type":57,"tag":76,"props":647,"children":649},{"className":648},[],[650],{"type":62,"value":651},"config.timeout",{"type":62,"value":653}," for slow calls,\nand ",{"type":57,"tag":76,"props":655,"children":657},{"className":656},[],[658],{"type":62,"value":659},"config.pythonExecutable",{"type":62,"value":123},{"type":57,"tag":76,"props":662,"children":664},{"className":663},[],[665],{"type":62,"value":666},"PROMPTFOO_PYTHON",{"type":62,"value":668}," for venvs. Add harmless\ndefaults because ",{"type":57,"tag":76,"props":670,"children":672},{"className":671},[],[673],{"type":62,"value":384},{"type":62,"value":675}," may call providers without test-case vars.",{"type":57,"tag":189,"props":677,"children":679},{"id":678},"_5-validate-and-run",[680],{"type":62,"value":681},"5. Validate and run",{"type":57,"tag":65,"props":683,"children":684},{},[685],{"type":62,"value":686},"From the promptfoo repo, use the local build:",{"type":57,"tag":688,"props":689,"children":694},"pre",{"className":690,"code":691,"language":692,"meta":693,"style":693},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","npm run local -- validate config -c path\u002Fto\u002Fpromptfooconfig.yaml\nnpm run local -- validate target -c path\u002Fto\u002Fpromptfooconfig.yaml\nnpm run local -- eval -c path\u002Fto\u002Fpromptfooconfig.yaml -o output.json --no-cache --no-share\n","bash","",[695],{"type":57,"tag":76,"props":696,"children":697},{"__ignoreMap":693},[698,746,783],{"type":57,"tag":699,"props":700,"children":703},"span",{"class":701,"line":702},"line",1,[704,710,716,721,726,731,736,741],{"type":57,"tag":699,"props":705,"children":707},{"style":706},"--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B",[708],{"type":62,"value":709},"npm",{"type":57,"tag":699,"props":711,"children":713},{"style":712},"--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D",[714],{"type":62,"value":715}," run",{"type":57,"tag":699,"props":717,"children":718},{"style":712},[719],{"type":62,"value":720}," local",{"type":57,"tag":699,"props":722,"children":723},{"style":712},[724],{"type":62,"value":725}," --",{"type":57,"tag":699,"props":727,"children":728},{"style":712},[729],{"type":62,"value":730}," validate",{"type":57,"tag":699,"props":732,"children":733},{"style":712},[734],{"type":62,"value":735}," config",{"type":57,"tag":699,"props":737,"children":738},{"style":712},[739],{"type":62,"value":740}," -c",{"type":57,"tag":699,"props":742,"children":743},{"style":712},[744],{"type":62,"value":745}," path\u002Fto\u002Fpromptfooconfig.yaml\n",{"type":57,"tag":699,"props":747,"children":749},{"class":701,"line":748},2,[750,754,758,762,766,770,775,779],{"type":57,"tag":699,"props":751,"children":752},{"style":706},[753],{"type":62,"value":709},{"type":57,"tag":699,"props":755,"children":756},{"style":712},[757],{"type":62,"value":715},{"type":57,"tag":699,"props":759,"children":760},{"style":712},[761],{"type":62,"value":720},{"type":57,"tag":699,"props":763,"children":764},{"style":712},[765],{"type":62,"value":725},{"type":57,"tag":699,"props":767,"children":768},{"style":712},[769],{"type":62,"value":730},{"type":57,"tag":699,"props":771,"children":772},{"style":712},[773],{"type":62,"value":774}," target",{"type":57,"tag":699,"props":776,"children":777},{"style":712},[778],{"type":62,"value":740},{"type":57,"tag":699,"props":780,"children":781},{"style":712},[782],{"type":62,"value":745},{"type":57,"tag":699,"props":784,"children":786},{"class":701,"line":785},3,[787,791,795,799,803,808,812,817,822,827,832],{"type":57,"tag":699,"props":788,"children":789},{"style":706},[790],{"type":62,"value":709},{"type":57,"tag":699,"props":792,"children":793},{"style":712},[794],{"type":62,"value":715},{"type":57,"tag":699,"props":796,"children":797},{"style":712},[798],{"type":62,"value":720},{"type":57,"tag":699,"props":800,"children":801},{"style":712},[802],{"type":62,"value":725},{"type":57,"tag":699,"props":804,"children":805},{"style":712},[806],{"type":62,"value":807}," eval",{"type":57,"tag":699,"props":809,"children":810},{"style":712},[811],{"type":62,"value":740},{"type":57,"tag":699,"props":813,"children":814},{"style":712},[815],{"type":62,"value":816}," path\u002Fto\u002Fpromptfooconfig.yaml",{"type":57,"tag":699,"props":818,"children":819},{"style":712},[820],{"type":62,"value":821}," -o",{"type":57,"tag":699,"props":823,"children":824},{"style":712},[825],{"type":62,"value":826}," output.json",{"type":57,"tag":699,"props":828,"children":829},{"style":712},[830],{"type":62,"value":831}," --no-cache",{"type":57,"tag":699,"props":833,"children":834},{"style":712},[835],{"type":62,"value":836}," --no-share\n",{"type":57,"tag":65,"props":838,"children":839},{},[840],{"type":62,"value":841},"Outside the promptfoo repo, use:",{"type":57,"tag":688,"props":843,"children":845},{"className":690,"code":844,"language":692,"meta":693,"style":693},"npx promptfoo@latest validate config -c path\u002Fto\u002Fpromptfooconfig.yaml\nnpx promptfoo@latest validate target -c path\u002Fto\u002Fpromptfooconfig.yaml\nnpx promptfoo@latest eval -c path\u002Fto\u002Fpromptfooconfig.yaml -o output.json --no-cache --no-share\n",[846],{"type":57,"tag":76,"props":847,"children":848},{"__ignoreMap":693},[849,878,905],{"type":57,"tag":699,"props":850,"children":851},{"class":701,"line":702},[852,857,862,866,870,874],{"type":57,"tag":699,"props":853,"children":854},{"style":706},[855],{"type":62,"value":856},"npx",{"type":57,"tag":699,"props":858,"children":859},{"style":712},[860],{"type":62,"value":861}," promptfoo@latest",{"type":57,"tag":699,"props":863,"children":864},{"style":712},[865],{"type":62,"value":730},{"type":57,"tag":699,"props":867,"children":868},{"style":712},[869],{"type":62,"value":735},{"type":57,"tag":699,"props":871,"children":872},{"style":712},[873],{"type":62,"value":740},{"type":57,"tag":699,"props":875,"children":876},{"style":712},[877],{"type":62,"value":745},{"type":57,"tag":699,"props":879,"children":880},{"class":701,"line":748},[881,885,889,893,897,901],{"type":57,"tag":699,"props":882,"children":883},{"style":706},[884],{"type":62,"value":856},{"type":57,"tag":699,"props":886,"children":887},{"style":712},[888],{"type":62,"value":861},{"type":57,"tag":699,"props":890,"children":891},{"style":712},[892],{"type":62,"value":730},{"type":57,"tag":699,"props":894,"children":895},{"style":712},[896],{"type":62,"value":774},{"type":57,"tag":699,"props":898,"children":899},{"style":712},[900],{"type":62,"value":740},{"type":57,"tag":699,"props":902,"children":903},{"style":712},[904],{"type":62,"value":745},{"type":57,"tag":699,"props":906,"children":907},{"class":701,"line":785},[908,912,916,920,924,928,932,936,940],{"type":57,"tag":699,"props":909,"children":910},{"style":706},[911],{"type":62,"value":856},{"type":57,"tag":699,"props":913,"children":914},{"style":712},[915],{"type":62,"value":861},{"type":57,"tag":699,"props":917,"children":918},{"style":712},[919],{"type":62,"value":807},{"type":57,"tag":699,"props":921,"children":922},{"style":712},[923],{"type":62,"value":740},{"type":57,"tag":699,"props":925,"children":926},{"style":712},[927],{"type":62,"value":816},{"type":57,"tag":699,"props":929,"children":930},{"style":712},[931],{"type":62,"value":821},{"type":57,"tag":699,"props":933,"children":934},{"style":712},[935],{"type":62,"value":826},{"type":57,"tag":699,"props":937,"children":938},{"style":712},[939],{"type":62,"value":831},{"type":57,"tag":699,"props":941,"children":942},{"style":712},[943],{"type":62,"value":836},{"type":57,"tag":65,"props":945,"children":946},{},[947,949,955,957,963,964,970,972,978],{"type":62,"value":948},"Inspect the output file for ",{"type":57,"tag":76,"props":950,"children":952},{"className":951},[],[953],{"type":62,"value":954},"results.stats",{"type":62,"value":956},", ",{"type":57,"tag":76,"props":958,"children":960},{"className":959},[],[961],{"type":62,"value":962},"response.output",{"type":62,"value":956},{"type":57,"tag":76,"props":965,"children":967},{"className":966},[],[968],{"type":62,"value":969},"score",{"type":62,"value":971},", and\n",{"type":57,"tag":76,"props":973,"children":975},{"className":974},[],[976],{"type":62,"value":977},"error",{"type":62,"value":979},"; do not rely only on the process exit code.",{"type":57,"tag":65,"props":981,"children":982},{},[983,984,990],{"type":62,"value":343},{"type":57,"tag":76,"props":985,"children":987},{"className":986},[],[988],{"type":62,"value":989},"--no-share",{"type":62,"value":991}," by default while probing live or internal systems. Remove it\nonly when the user explicitly wants a cloud share URL.",{"type":57,"tag":133,"props":993,"children":995},{"id":994},"common-mistakes",[996],{"type":62,"value":997},"Common Mistakes",{"type":57,"tag":688,"props":999,"children":1003},{"className":1000,"code":1001,"language":1002,"meta":693,"style":693},"language-yaml shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","# WRONG: shell-style env vars are literal strings in YAML\napiKey: $API_KEY\n\n# CORRECT: promptfoo renders Nunjucks env references\napiKey: '{{env.API_KEY}}'\n","yaml",[1004],{"type":57,"tag":76,"props":1005,"children":1006},{"__ignoreMap":693},[1007,1016,1036,1045,1054],{"type":57,"tag":699,"props":1008,"children":1009},{"class":701,"line":702},[1010],{"type":57,"tag":699,"props":1011,"children":1013},{"style":1012},"--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic",[1014],{"type":62,"value":1015},"# WRONG: shell-style env vars are literal strings in YAML\n",{"type":57,"tag":699,"props":1017,"children":1018},{"class":701,"line":748},[1019,1025,1031],{"type":57,"tag":699,"props":1020,"children":1022},{"style":1021},"--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178",[1023],{"type":62,"value":1024},"apiKey",{"type":57,"tag":699,"props":1026,"children":1028},{"style":1027},"--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF",[1029],{"type":62,"value":1030},":",{"type":57,"tag":699,"props":1032,"children":1033},{"style":712},[1034],{"type":62,"value":1035}," $API_KEY\n",{"type":57,"tag":699,"props":1037,"children":1038},{"class":701,"line":785},[1039],{"type":57,"tag":699,"props":1040,"children":1042},{"emptyLinePlaceholder":1041},true,[1043],{"type":62,"value":1044},"\n",{"type":57,"tag":699,"props":1046,"children":1048},{"class":701,"line":1047},4,[1049],{"type":57,"tag":699,"props":1050,"children":1051},{"style":1012},[1052],{"type":62,"value":1053},"# CORRECT: promptfoo renders Nunjucks env references\n",{"type":57,"tag":699,"props":1055,"children":1057},{"class":701,"line":1056},5,[1058,1062,1066,1071,1076],{"type":57,"tag":699,"props":1059,"children":1060},{"style":1021},[1061],{"type":62,"value":1024},{"type":57,"tag":699,"props":1063,"children":1064},{"style":1027},[1065],{"type":62,"value":1030},{"type":57,"tag":699,"props":1067,"children":1068},{"style":1027},[1069],{"type":62,"value":1070}," '",{"type":57,"tag":699,"props":1072,"children":1073},{"style":712},[1074],{"type":62,"value":1075},"{{env.API_KEY}}",{"type":57,"tag":699,"props":1077,"children":1078},{"style":1027},[1079],{"type":62,"value":1080},"'\n",{"type":57,"tag":688,"props":1082,"children":1084},{"className":1000,"code":1083,"language":1002,"meta":693,"style":693},"# WRONG: flattening a multi-input target into prompt loses attack surface\nbody:\n  prompt: '{{prompt}}'\n\n# BETTER: preserve the real app fields\nbody:\n  user_id: '{{user_id}}'\n  message: '{{message}}'\n",[1085],{"type":57,"tag":76,"props":1086,"children":1087},{"__ignoreMap":693},[1088,1096,1109,1134,1141,1149,1161,1187],{"type":57,"tag":699,"props":1089,"children":1090},{"class":701,"line":702},[1091],{"type":57,"tag":699,"props":1092,"children":1093},{"style":1012},[1094],{"type":62,"value":1095},"# WRONG: flattening a multi-input target into prompt loses attack surface\n",{"type":57,"tag":699,"props":1097,"children":1098},{"class":701,"line":748},[1099,1104],{"type":57,"tag":699,"props":1100,"children":1101},{"style":1021},[1102],{"type":62,"value":1103},"body",{"type":57,"tag":699,"props":1105,"children":1106},{"style":1027},[1107],{"type":62,"value":1108},":\n",{"type":57,"tag":699,"props":1110,"children":1111},{"class":701,"line":785},[1112,1117,1121,1125,1130],{"type":57,"tag":699,"props":1113,"children":1114},{"style":1021},[1115],{"type":62,"value":1116},"  prompt",{"type":57,"tag":699,"props":1118,"children":1119},{"style":1027},[1120],{"type":62,"value":1030},{"type":57,"tag":699,"props":1122,"children":1123},{"style":1027},[1124],{"type":62,"value":1070},{"type":57,"tag":699,"props":1126,"children":1127},{"style":712},[1128],{"type":62,"value":1129},"{{prompt}}",{"type":57,"tag":699,"props":1131,"children":1132},{"style":1027},[1133],{"type":62,"value":1080},{"type":57,"tag":699,"props":1135,"children":1136},{"class":701,"line":1047},[1137],{"type":57,"tag":699,"props":1138,"children":1139},{"emptyLinePlaceholder":1041},[1140],{"type":62,"value":1044},{"type":57,"tag":699,"props":1142,"children":1143},{"class":701,"line":1056},[1144],{"type":57,"tag":699,"props":1145,"children":1146},{"style":1012},[1147],{"type":62,"value":1148},"# BETTER: preserve the real app fields\n",{"type":57,"tag":699,"props":1150,"children":1152},{"class":701,"line":1151},6,[1153,1157],{"type":57,"tag":699,"props":1154,"children":1155},{"style":1021},[1156],{"type":62,"value":1103},{"type":57,"tag":699,"props":1158,"children":1159},{"style":1027},[1160],{"type":62,"value":1108},{"type":57,"tag":699,"props":1162,"children":1164},{"class":701,"line":1163},7,[1165,1170,1174,1178,1183],{"type":57,"tag":699,"props":1166,"children":1167},{"style":1021},[1168],{"type":62,"value":1169},"  user_id",{"type":57,"tag":699,"props":1171,"children":1172},{"style":1027},[1173],{"type":62,"value":1030},{"type":57,"tag":699,"props":1175,"children":1176},{"style":1027},[1177],{"type":62,"value":1070},{"type":57,"tag":699,"props":1179,"children":1180},{"style":712},[1181],{"type":62,"value":1182},"{{user_id}}",{"type":57,"tag":699,"props":1184,"children":1185},{"style":1027},[1186],{"type":62,"value":1080},{"type":57,"tag":699,"props":1188,"children":1190},{"class":701,"line":1189},8,[1191,1196,1200,1204,1209],{"type":57,"tag":699,"props":1192,"children":1193},{"style":1021},[1194],{"type":62,"value":1195},"  message",{"type":57,"tag":699,"props":1197,"children":1198},{"style":1027},[1199],{"type":62,"value":1030},{"type":57,"tag":699,"props":1201,"children":1202},{"style":1027},[1203],{"type":62,"value":1070},{"type":57,"tag":699,"props":1205,"children":1206},{"style":712},[1207],{"type":62,"value":1208},"{{message}}",{"type":57,"tag":699,"props":1210,"children":1211},{"style":1027},[1212],{"type":62,"value":1080},{"type":57,"tag":133,"props":1214,"children":1216},{"id":1215},"output-contract",[1217],{"type":62,"value":1218},"Output Contract",{"type":57,"tag":65,"props":1220,"children":1221},{},[1222],{"type":62,"value":1223},"When done, state:",{"type":57,"tag":145,"props":1225,"children":1226},{},[1227,1232,1237,1242,1253],{"type":57,"tag":149,"props":1228,"children":1229},{},[1230],{"type":62,"value":1231},"Connection mode used: live, static, hybrid, or wrapper",{"type":57,"tag":149,"props":1233,"children":1234},{},[1235],{"type":62,"value":1236},"Files created or modified",{"type":57,"tag":149,"props":1238,"children":1239},{},[1240],{"type":62,"value":1241},"Required environment variables",{"type":57,"tag":149,"props":1243,"children":1244},{},[1245,1247],{"type":62,"value":1246},"Safe smoke command with ",{"type":57,"tag":76,"props":1248,"children":1250},{"className":1249},[],[1251],{"type":62,"value":1252},"--no-cache --no-share",{"type":57,"tag":149,"props":1254,"children":1255},{},[1256],{"type":62,"value":1257},"What was actually verified, and what remains a TODO",{"type":57,"tag":1259,"props":1260,"children":1261},"style",{},[1262],{"type":62,"value":1263},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"items":1265,"total":1047},[1266,1277,1284,1300],{"slug":1267,"name":1267,"fn":1268,"description":1269,"org":1270,"tags":1271,"stars":24,"repoUrl":25,"updatedAt":1276},"promptfoo-evals","run and refine promptfoo evaluation suites","Write, refine, run, and QA non-redteam promptfoo eval suites after the target or provider already works: prompts, vars, test cases, assertions, model-graded rubrics, transforms, datasets, output exports, filters, and CI gates. Use for regression tests and eval-suite authoring. Do not use for connecting a new target\u002Fprovider, mapping HTTP requests or auth, smoke-testing an endpoint, or redteam plugin\u002Fstrategy setup; use `promptfoo-provider-setup` for connection work instead.\n",{"slug":8,"name":8,"logoUrl":9,"githubOrg":8},[1272,1273,1274,1275],{"name":16,"slug":17,"type":14},{"name":12,"slug":13,"type":14},{"name":8,"slug":8,"type":14},{"name":22,"slug":23,"type":14},"2026-07-18T05:48:36.3451",{"slug":4,"name":4,"fn":5,"description":6,"org":1278,"tags":1279,"stars":24,"repoUrl":25,"updatedAt":26},{"slug":8,"name":8,"logoUrl":9,"githubOrg":8},[1280,1281,1282,1283],{"name":19,"slug":20,"type":14},{"name":16,"slug":17,"type":14},{"name":12,"slug":13,"type":14},{"name":22,"slug":23,"type":14},{"slug":1285,"name":1285,"fn":1286,"description":1287,"org":1288,"tags":1289,"stars":24,"repoUrl":25,"updatedAt":1299},"promptfoo-redteam-run","run promptfoo redteam security scans","Run, rerun, inspect, and QA promptfoo redteam scans from generated redteam YAML or an existing redteam setup config. Use when executing `promptfoo redteam eval` or `promptfoo redteam run`, exporting results, triaging attack success rate, grader failures, target errors, filter\u002Frerun commands, reports, or CI gates. Do not use for initial provider wiring or for choosing plugins and strategies before generation.\n",{"slug":8,"name":8,"logoUrl":9,"githubOrg":8},[1290,1293,1294,1295,1298],{"name":1291,"slug":1292,"type":14},"Code Analysis","code-analysis",{"name":16,"slug":17,"type":14},{"name":8,"slug":8,"type":14},{"name":1296,"slug":1297,"type":14},"Security","security",{"name":22,"slug":23,"type":14},"2026-07-18T05:48:03.576002",{"slug":1301,"name":1301,"fn":1302,"description":1303,"org":1304,"tags":1305,"stars":24,"repoUrl":25,"updatedAt":1312},"promptfoo-redteam-setup","configure promptfoo redteam security setups","Create or refine promptfoo redteam setup configs: purpose, targets, plugins, strategies, frameworks, multi-input target inputs, policy text, grader guidance, contexts, and static-code-derived target\u002Fthreat mapping. Use when preparing a red team scan plan from live probes, code evidence, or provider configs, or when generating adversarial test cases for QA. Do not use for basic provider wiring alone or for running\u002Fevaluating an already-generated redteam scan.\n",{"slug":8,"name":8,"logoUrl":9,"githubOrg":8},[1306,1309,1310,1311],{"name":1307,"slug":1308,"type":14},"Configuration","configuration",{"name":16,"slug":17,"type":14},{"name":8,"slug":8,"type":14},{"name":1296,"slug":1297,"type":14},"2026-07-18T05:48:36.82567",{"items":1314,"total":1047},[1315,1322,1329,1337],{"slug":1267,"name":1267,"fn":1268,"description":1269,"org":1316,"tags":1317,"stars":24,"repoUrl":25,"updatedAt":1276},{"slug":8,"name":8,"logoUrl":9,"githubOrg":8},[1318,1319,1320,1321],{"name":16,"slug":17,"type":14},{"name":12,"slug":13,"type":14},{"name":8,"slug":8,"type":14},{"name":22,"slug":23,"type":14},{"slug":4,"name":4,"fn":5,"description":6,"org":1323,"tags":1324,"stars":24,"repoUrl":25,"updatedAt":26},{"slug":8,"name":8,"logoUrl":9,"githubOrg":8},[1325,1326,1327,1328],{"name":19,"slug":20,"type":14},{"name":16,"slug":17,"type":14},{"name":12,"slug":13,"type":14},{"name":22,"slug":23,"type":14},{"slug":1285,"name":1285,"fn":1286,"description":1287,"org":1330,"tags":1331,"stars":24,"repoUrl":25,"updatedAt":1299},{"slug":8,"name":8,"logoUrl":9,"githubOrg":8},[1332,1333,1334,1335,1336],{"name":1291,"slug":1292,"type":14},{"name":16,"slug":17,"type":14},{"name":8,"slug":8,"type":14},{"name":1296,"slug":1297,"type":14},{"name":22,"slug":23,"type":14},{"slug":1301,"name":1301,"fn":1302,"description":1303,"org":1338,"tags":1339,"stars":24,"repoUrl":25,"updatedAt":1312},{"slug":8,"name":8,"logoUrl":9,"githubOrg":8},[1340,1341,1342,1343],{"name":1307,"slug":1308,"type":14},{"name":16,"slug":17,"type":14},{"name":8,"slug":8,"type":14},{"name":1296,"slug":1297,"type":14}]