AI generation for code.json
Fields the AI should fill
Free text:
longDescription
description
tags
Picked from a fixed list of values:
softwareType, platforms, repositoryType, subsetInHealthcare, userType, which are enums in the schema, so anything off-list gets rejected for us
categories, where the schema takes any string and only points at the publiccode list in its description, so we'd check that one against the list ourselves
Something to consider: localisation and userInput have no blank state, so the AI would be overwriting false rather than filling a gap.
The flow
When the action runs to update code.json, either triggered manually or on a schedule:
- The action reads the repo and fills in the fields it can work out on its own.
- If the AI settings are missing it stops here and opens the PR as normal.
- It picks out the fields above that are still blank. With the regen flag on it takes all of them.
- If nothing is blank, no request goes out.
- It sends one request: the top level file tree, the README, the current code.json, the blank fields, and the valid values for each one. It asks for JSON back.
- Every answer gets checked against the schema on its own. Bad ones are dropped and logged.
- What passes goes into those blank fields and nowhere else.
- The PR opens, and the body says which fields the AI wrote.
Two minute timeout, no retry. If the call fails we log it, open the PR anyway, and the next run tries again.
The action's other mode is the PR check. When code.json is edited in a pull request, that run only validates the file against the schema, so none of the above applies there, AI included.
Config
AI_MODEL: "claude-sonnet-5"
AI_API_KEY: ${{ secrets.AI_API_KEY }}
AI_REGENERATE: "false"
All optional, since the action works without any of them. For AI generation the model and key are both required, and missing either turns the step off. AI_REGENERATE defaults to false.
The user only names a model. We work the endpoint out from the name, so gpt- goes to OpenAI, claude- to Anthropic and gemini- to Google. Matching on the prefix means new model versions work without a code change, and anything outside those three is rejected with a message saying which are supported.
The request itself is OpenAI chat completions shaped, which all three of those accept.
Guardrails
Anything that comes back is checked against the schema before it goes near code.json, and the list of fields the AI can write lives in our code rather than the prompt, so a bad response can't widen its own scope.
The schema only checks longDescription for length though, not for whether any of it is accurate. So the PR body lists every field the AI wrote and says plainly that they need a human read before merge.
Fields that already have a value are left alone unless the regen flag is on. If the call fails we log it and finish the run without it, so a broken endpoint can't take the action down with it.
Enabling this sends repo contents to whichever provider the model name resolves to. That should be documented in the README alongside the AI inputs and in the action.yml input descriptions, so it's visible while the workflow is being set up.
This plan was created by @haseebmalik18!
AI generation for code.json
Fields the AI should fill
Free text:
longDescriptiondescriptiontagsPicked from a fixed list of values:
softwareType,platforms,repositoryType,subsetInHealthcare,userType, which are enums in the schema, so anything off-list gets rejected for uscategories, where the schema takes any string and only points at the publiccode list in its description, so we'd check that one against the list ourselvesSomething to consider:
localisationanduserInputhave no blank state, so the AI would be overwritingfalserather than filling a gap.The flow
When the action runs to update code.json, either triggered manually or on a schedule:
Two minute timeout, no retry. If the call fails we log it, open the PR anyway, and the next run tries again.
The action's other mode is the PR check. When code.json is edited in a pull request, that run only validates the file against the schema, so none of the above applies there, AI included.
Config
All optional, since the action works without any of them. For AI generation the model and key are both required, and missing either turns the step off.
AI_REGENERATEdefaults tofalse.The user only names a model. We work the endpoint out from the name, so
gpt-goes to OpenAI,claude-to Anthropic andgemini-to Google. Matching on the prefix means new model versions work without a code change, and anything outside those three is rejected with a message saying which are supported.The request itself is OpenAI chat completions shaped, which all three of those accept.
Guardrails
Anything that comes back is checked against the schema before it goes near code.json, and the list of fields the AI can write lives in our code rather than the prompt, so a bad response can't widen its own scope.
The schema only checks
longDescriptionfor length though, not for whether any of it is accurate. So the PR body lists every field the AI wrote and says plainly that they need a human read before merge.Fields that already have a value are left alone unless the regen flag is on. If the call fails we log it and finish the run without it, so a broken endpoint can't take the action down with it.
Enabling this sends repo contents to whichever provider the model name resolves to. That should be documented in the README alongside the AI inputs and in the
action.ymlinput descriptions, so it's visible while the workflow is being set up.