{"ref":"artifact:miyasuta-cap-openai","page":"/artifacts/miyasuta-cap-openai","json":"/artifacts/miyasuta-cap-openai.json","generated":"2026-10-26","drafted_with_ai":true,"entity":{"id":"miyasuta-cap-openai","name":"cap-openai","artifact_type":"sample","ecosystem":"cap","domain":"ai-and-agents","secondary_domains":["integration-and-messaging"],"origin_ring":"independent","description":{"one_line":"Two actions on one CAP service that reach OpenAI's chat completions endpoint by two routes: the `openai` npm client with the key from the environment, and a CAP remote service of `kind: rest` that goes through a destination in production.","short":"CAP service actions calling OpenAI chat completions two ways","what_it_solves":"`chat_sdk` builds `new OpenAI({ apiKey: process.env['OPENAI_API_KEY'] })` and calls `openai.chat.completions.create` against `gpt-4o`. `chat_api` connects to `OpenAI.Chat.Completion.API`, which `cds.requires` declares as `kind: rest` with the url `https://api.openai.com` and the path `/v1`, replaced in `[production]` by `credentials.destination: 'openai'`, then sends a POST to `/chat/completions`. The key stays in `OPENAI_API_KEY` on both routes, pushed by a `set-env` script that calls `cf set-env` and restages, so the [SAP Destination service](artifact:btp-destination) carries the address while the code still builds the Authorization header itself. There is no model and no `app` folder: one `.cds` file with the two actions, one handler, and a `test/test.http` to call them."},"links":{"repo":"https://github.com/miyasuta/cap-openai"},"compat":{"runtimes":["node"],"deployment":["cf"]},"demonstrates":["capability:llm-integration","capability:service-integration","capability:destinations"],"requires":[{"ref":"artifact:btp-destination","for":"The production profile replaces the OpenAI url with a destination named `openai`, so once deployed the address comes from the destination rather than from the configuration.","sources":[{"url":"https://raw.githubusercontent.com/miyasuta/cap-openai/main/package.json","title":"miyasuta/cap-openai — package.json","checked":"2026-10-15","quote":"\"[production]\": { \"credentials\": { \"destination\": \"openai\", \"path\": \"/v1\" } }"}]}],"maintainers":["actor:mio-yasutake"],"contributors":["actor:mio-yasutake"],"use_as":"reference","provenance":{"discovered_via":[{"source":"source:github","channel":"miyasuta"}],"first_seen":"2026-10-15"},"drafted_with_ai":true},"effective_normative_relations":[],"readings":{"liveness":[{"label":"Maintenance","tier":"unknown","evidence":"no release data"},{"label":"Continuity","tier":"fair","evidence":"2 contributors"},{"label":"Repository","tier":"good","evidence":"pushed 2026-06, not archived"}],"compatibility":[{"label":"Declared for","tier":"fair","evidence":"nothing declared"},{"label":"Survived majors","tier":"unknown","evidence":"no release dates"},{"label":"Maintainer's CI","tier":"fair","evidence":"no CI configured"}],"practice":[{"label":"Tests","tier":"good","evidence":"1 test file"},{"label":"Docs","tier":"poor","evidence":"README 1 KB"},{"label":"Changelog","tier":"fair","evidence":"none in the repo"}],"reach":[{"value":null,"unit":"installs/week"},{"value":2,"unit":"watching"}]},"signals":{"crawled_at":"2026-10-25","npm":"not published under this name","stars":2,"forks":1,"open_issues":7,"archived":false,"pushed_at":"2026-06-05","license_spdx":null,"org_owned":false,"default_branch":"main","created_at":"2024-05-25T22:06:05Z","open_prs":7,"tree_truncated":false,"test_files":1,"workflows":0,"other_ci":false,"readme_bytes":674,"docs_files":0,"changelog":false,"license_file":false,"dts_files":0,"first_commit":"2024-05-25","last_commit":"2026-03-26","commits":31,"contributors":2,"readme_path":"README.md","readme_sha":"dbac29eb1594d1dd9e9cd90a11879f1495caa4b6","repo_read":"2026-10-25"},"edges":{"maintainers":[{"ref":"actor:mio-yasutake","name":"Mio Yasutake","json":"/actors/mio-yasutake.json"}],"contributors":[{"ref":"actor:mio-yasutake","name":"Mio Yasutake","json":"/actors/mio-yasutake.json"}],"explained_by":[],"alternative_to_this":[],"needed_by":[],"available_via":[],"parts":[],"add_ons":[],"answered_through_parts":[]}}