ai-chat-for-amazon-bedrock
by noteflowai
README.md
# AI Chatbot & Agents for Amazon Bedrock
Product direction and acceptance milestones: [Roadmap](ROADMAP.md).
The source for the WordPress plugin published at
<https://wordpress.org/plugins/ai-chat-for-amazon-bedrock/>. This tree is what the
released package is built from, so the code here is the code that gets installed.
Streaming chat and tool-using agents on Amazon Bedrock, an MCP server that exposes the
site to AI clients, retrieval over published content, and an evaluation harness for
checking answers.
## What it does with your AWS account
The plugin signs Bedrock calls with whatever credentials the host already has. On EC2 and
in ECS that is the instance or task role, and nothing is stored. Long-lived keys are
supported but are not the intended path, and the Diagnostics screen names which source
resolved so the answer is not a guess.
Some deliberate limits, which the test suites assert rather than merely document:
- Guest chat is off by default, and an unknown profile key falls back without unlocking it.
- Content tools create drafts and write protected editorial editions/attestations on
existing posts. They never change a published post's canonical body or publish/send.
No order or customer data is exposed.
- Automatic WeChat selection requires an explicit public edition and independent
digest-bound review. See [the edition contract](docs/wechat-curation.md).
- Retrieval indexes published, non-password-protected content only.
- Tool output is wrapped as untrusted data before it reaches the model.
- Tokens are stored as SHA-256 only, compared with `hash_equals`.
- Credentials never appear in an export file.
- The generated IAM policy is least-privilege, and the identity line is masked.
## Development notes
User facing documentation lives in `readme.txt`, which is what the plugin directory
renders. `README.md` is for people working on the code and never ships.
## Layout
| Path | Purpose |
| --- | --- |
| `ai-chat-for-amazon-bedrock.php` | Plugin header, activation and bootstrap |
| `includes/` | Bedrock client, MCP, retrieval, embeddings, OAuth, usage, CLI |
| `admin/` | Settings screens, dashboards and their assets |
| `public/` | Front-end chat, block and assets |
| `tests/` | Standalone test suites, run by PHP with no framework |
| `bin/` | Release tooling |
| `phpcs.xml.dist` | WordPress coding standards for this plugin |
| `.distignore` | The only list of what does not ship |
The WordPress.org SVN repository is a distribution channel. This tree is the source of
truth, including the tests and tooling that never reach SVN.
## Requirements
- PHP 7.4 or newer, matching the plugin header
- WordPress 6.4 or newer
- An AWS account with Amazon Bedrock model access for anything that calls a model
- `python3`, `curl` and `bash` for the release tooling
- For `phpcs`: a PHP with the tokenizer, xmlwriter and SimpleXML extensions
## Working on it
```bash
bin/setup-tools.sh # pinned phpcs, WPCS, PHPCSUtils, PHPCSExtra into .tools/
composer test # or run each tests/*.php directly
bin/prerelease.sh --php "$(which php)"
```
Useful options:
```bash
bin/prerelease.sh \
--php /path/to/php \ # tests and linting
--phpcs-php /path/to/php-with-tokenizer \ # only if the first lacks the extensions
--wp-cli "wp --path=/var/www/html" # enables the official Plugin Check
```
`--skip-phpcs` and `--skip-plugin-check` exist for a quick loop, but a release should
run everything.
## The gate
`bin/prerelease.sh` is what must pass before publishing. It checks:
- every PHP file parses
- the plugin header, the runtime constant and the readme stable tag agree
- the changelog documents the version being released
- readme limits: description plus privacy policy under 2,500 words, short description
under 150 characters, every upgrade notice under 300
- every suite in `tests/`
- WordPress coding standards through the pinned `phpcs`
- the official Plugin Check, when a WP-CLI command is supplied
- the file list that would ship, resolved from `.distignore`, including a scan for
anything shaped like a credential
Two behaviours are deliberate:
**A check that cannot run reports `skip`, never `ok`.** An absent linter or a suite that
declined to run must not look like a pass. The same applies to a suite that prints
`SKIP:` as its first line.
**`.distignore` is the only exclusion list.** `bin/build-package.py` reads it and the
gate asks that script what would ship, so adding a development directory in one place is
enough. This mattered in practice: three hand maintained lists once disagreed, and a new
tools directory ended up inside the audit.
## Testing the gate
`tests/tooling.php` exercises the tooling. It copies the project to a scratch directory,
breaks one thing, and asserts that the responsible check reports a failure. Assertions
look for the message on a `FAIL` line rather than anywhere in the output, because a check
that still prints its message while no longer failing is precisely the regression worth
catching.
This suite exists because the gate shipped two false passes during development: `phpcs`
failing to start was reported as clean, and the credential scan never ran in the mode the
gate called. Each of the gate's checks was then disabled in turn to confirm the suite
notices.
The gate marks its environment with `AICFAB_GATE_SELFTEST=1` so this suite skips rather
than running the gate inside the gate. CI runs it as a separate step.
## Accessibility
`bin/audit-accessibility.py` checks the admin screens for controls without an accessible
name, skipped heading levels and tables without scoped headers. It drives a real browser,
so it needs a running site and is a manual check rather than a gate step.
It has earned its place twice: once finding twenty unnamed controls, and once finding that
every row of a generated table exposed the same name, so a screen reader user could not
tell the fields apart. Static analysis found neither, because both only exist once the
page is rendered.
`bin/audit-frontend.py` does the same for the visitor-facing chat: it counts live-region
updates during one streamed answer and checks the layout at phone width. It found that
streaming rewrote the answer into an aria-live region on every chunk, so a 77 character
answer produced fifteen updates and a screen reader read the growing answer out each time.
Its known limitation is documented in the file: it does not report the announced text,
because reading that from the harness disagreed with a simpler direct check.
## Continuous integration
`.github/workflows/gate.yml` runs on every push and pull request:
- the gate on PHP 7.4 and 8.3
- `tests/tooling.php`
- a package build, verified against `.distignore`
- the official Plugin Check against a real WordPress install
## Releasing
1. Update the version in the plugin header, the `AI_CHAT_BEDROCK_VERSION` constant and
the readme stable tag, and add a changelog entry and an upgrade notice.
2. Rebuild `languages/ai-chat-for-amazon-bedrock.pot` from the changed code with
`wp i18n make-pot`. Update both the `zh_CN` and `ja` `.po` files, preserving
translation contexts, plural forms and numbered placeholders, then regenerate
their `.mo` files with GNU gettext's `msgfmt --check --check-format --no-hash`
and their `.l10n.php` files with `wp i18n make-php languages/`. For example:
`msgfmt --check --check-format --no-hash -o languages/ai-chat-for-amazon-bedrock-ja.mo languages/ai-chat-for-amazon-bedrock-ja.po`.
Use the same command for `zh_CN`. Some `wp i18n make-mo` versions omit the
plural source string in single-form locales; the translation suite verifies
the compiled catalogs' contexts, plural sources and translations. The full
gate also compares the template with the code; passing the PHP-only jobs is
not enough.
3. Run `bin/prerelease.sh` with everything enabled. Fix anything it reports.
4. `bin/build-package.py` and check the file count and checksum it prints.
5. Copy the package contents into the SVN working copy, commit trunk, then tag.
6. Confirm the directory shows the new version and that the package on
downloads.wordpress.org contains what you built.
Screenshots in `assets/` must be real captures of the current interface. Retake them
when a screen changes rather than shipping a stale image.
## License
GPL-2.0-or-later.
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues