@kindgi/cli 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -5
- package/dist/cli.js +4 -3
- package/dist/cli.js.map +1 -1
- package/dist/commands/agents.d.ts.map +1 -1
- package/dist/commands/agents.js +75 -19
- package/dist/commands/agents.js.map +1 -1
- package/dist/commands/approval-wait.d.ts +90 -0
- package/dist/commands/approval-wait.d.ts.map +1 -0
- package/dist/commands/approval-wait.js +154 -0
- package/dist/commands/approval-wait.js.map +1 -0
- package/dist/commands/artifacts.d.ts.map +1 -1
- package/dist/commands/artifacts.js +131 -14
- package/dist/commands/artifacts.js.map +1 -1
- package/dist/commands/auth.d.ts.map +1 -1
- package/dist/commands/auth.js +48 -5
- package/dist/commands/auth.js.map +1 -1
- package/dist/commands/deploy.js +7 -3
- package/dist/commands/deploy.js.map +1 -1
- package/dist/commands/deployments.d.ts.map +1 -1
- package/dist/commands/deployments.js +36 -13
- package/dist/commands/deployments.js.map +1 -1
- package/dist/commands/doctor.d.ts +3 -2
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +47 -14
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/eval-runs.d.ts.map +1 -1
- package/dist/commands/eval-runs.js +21 -9
- package/dist/commands/eval-runs.js.map +1 -1
- package/dist/commands/helpers.d.ts +31 -1
- package/dist/commands/helpers.d.ts.map +1 -1
- package/dist/commands/helpers.js +45 -2
- package/dist/commands/helpers.js.map +1 -1
- package/dist/commands/init.js +5 -4
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/mail-triggers.d.ts.map +1 -1
- package/dist/commands/mail-triggers.js +27 -3
- package/dist/commands/mail-triggers.js.map +1 -1
- package/dist/commands/promote.d.ts.map +1 -1
- package/dist/commands/promote.js +133 -11
- package/dist/commands/promote.js.map +1 -1
- package/dist/commands/provenance.d.ts.map +1 -1
- package/dist/commands/provenance.js +13 -5
- package/dist/commands/provenance.js.map +1 -1
- package/dist/commands/providers.d.ts.map +1 -1
- package/dist/commands/providers.js +47 -4
- package/dist/commands/providers.js.map +1 -1
- package/dist/commands/schedules.d.ts.map +1 -1
- package/dist/commands/schedules.js +25 -9
- package/dist/commands/schedules.js.map +1 -1
- package/dist/commands/skills.d.ts +16 -0
- package/dist/commands/skills.d.ts.map +1 -1
- package/dist/commands/skills.js +122 -36
- package/dist/commands/skills.js.map +1 -1
- package/dist/commands/webhooks.d.ts.map +1 -1
- package/dist/commands/webhooks.js +21 -5
- package/dist/commands/webhooks.js.map +1 -1
- package/dist/config.d.ts +8 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +11 -0
- package/dist/config.js.map +1 -1
- package/dist/context.d.ts +7 -3
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +1 -0
- package/dist/context.js.map +1 -1
- package/dist/dev/runtime-image.d.ts +1 -1
- package/dist/dev/runtime-image.js +1 -1
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +14 -1
- package/dist/errors.js.map +1 -1
- package/dist/exports/plan.d.ts.map +1 -1
- package/dist/exports/plan.js +50 -0
- package/dist/exports/plan.js.map +1 -1
- package/dist/init/augment-scaffolder.d.ts +1 -1
- package/dist/init/augment-scaffolder.js +9 -8
- package/dist/init/augment-scaffolder.js.map +1 -1
- package/dist/init/java-augment.d.ts.map +1 -1
- package/dist/init/java-augment.js +7 -6
- package/dist/init/java-augment.js.map +1 -1
- package/dist/init/python-augment.d.ts.map +1 -1
- package/dist/init/python-augment.js +7 -6
- package/dist/init/python-augment.js.map +1 -1
- package/dist/init/scala-augment.js +7 -6
- package/dist/init/scala-augment.js.map +1 -1
- package/dist/main.d.ts +3 -0
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +1 -0
- package/dist/main.js.map +1 -1
- package/dist/providers/presets/anthropic.json +15 -3
- package/dist/providers/presets/azure-openai.json +10 -2
- package/dist/providers/presets/bedrock.json +6 -2
- package/dist/providers/presets/gemini-api.json +6 -2
- package/dist/providers/presets/openai.json +15 -3
- package/dist/sdk-skills/kindgi-authoring-agents/SKILL.md +21 -9
- package/dist/sdk-skills/kindgi-authoring-flows/SKILL.md +5 -3
- package/dist/sdk-skills/kindgi-authoring-guardrails/SKILL.md +202 -68
- package/dist/sdk-skills/kindgi-authoring-mcp-servers/SKILL.md +12 -188
- package/dist/sdk-skills/kindgi-authoring-mcp-servers/common-mistakes.md +44 -0
- package/dist/sdk-skills/kindgi-authoring-mcp-servers/how-it-works.md +41 -0
- package/dist/sdk-skills/kindgi-authoring-mcp-servers/other-clients.md +19 -0
- package/dist/sdk-skills/kindgi-authoring-mcp-servers/postgres.md +45 -0
- package/dist/sdk-skills/kindgi-authoring-mcp-servers/several-servers.md +32 -0
- package/dist/sdk-skills/kindgi-authoring-providers/SKILL.md +49 -906
- package/dist/sdk-skills/kindgi-authoring-providers/bedrock.md +64 -0
- package/dist/sdk-skills/kindgi-authoring-providers/common-mistakes.md +125 -0
- package/dist/sdk-skills/kindgi-authoring-providers/keys-and-registration.md +58 -0
- package/dist/sdk-skills/kindgi-authoring-providers/kindgi-cloud.md +36 -0
- package/dist/sdk-skills/kindgi-authoring-providers/path-a-anthropic.md +216 -0
- package/dist/sdk-skills/kindgi-authoring-providers/path-b-openai-compat.md +127 -0
- package/dist/sdk-skills/kindgi-authoring-providers/path-c-onnx.md +97 -0
- package/dist/sdk-skills/kindgi-authoring-providers/path-d-vertex.md +95 -0
- package/dist/sdk-skills/kindgi-authoring-providers/router.md +113 -0
- package/dist/sdk-skills/kindgi-authoring-tools/SKILL.md +12 -387
- package/dist/sdk-skills/kindgi-authoring-tools/common-mistakes.md +135 -0
- package/dist/sdk-skills/kindgi-authoring-tools/declarative-http.md +34 -0
- package/dist/sdk-skills/kindgi-authoring-tools/imperative-handler.md +65 -0
- package/dist/sdk-skills/kindgi-authoring-tools/iterating-and-testing.md +45 -0
- package/dist/sdk-skills/kindgi-authoring-tools/secrets-and-connections.md +79 -0
- package/dist/sdk-skills/kindgi-authoring-tools/tool-flags.md +45 -0
- package/dist/sdk-skills/kindgi-fix-corrections/SKILL.md +13 -178
- package/dist/sdk-skills/kindgi-fix-corrections/make-the-change.md +25 -0
- package/dist/sdk-skills/kindgi-fix-corrections/publish-and-promote.md +76 -0
- package/dist/sdk-skills/kindgi-fix-corrections/pull-corrections.md +48 -0
- package/dist/sdk-skills/kindgi-fix-corrections/worked-example.md +27 -0
- package/dist/sdk-skills/kindgi-framework-feedback/SKILL.md +10 -180
- package/dist/sdk-skills/kindgi-framework-feedback/common-mistakes.md +19 -0
- package/dist/sdk-skills/kindgi-framework-feedback/editing-feedback-file.md +33 -0
- package/dist/sdk-skills/kindgi-framework-feedback/fields-and-entry-shape.md +53 -0
- package/dist/sdk-skills/kindgi-framework-feedback/hearing-back.md +24 -0
- package/dist/sdk-skills/kindgi-framework-feedback/sending.md +50 -0
- package/dist/sdk-skills/kindgi-getting-started/SKILL.md +24 -21
- package/dist/sdk-skills/kindgi-java-authoring-agents/SKILL.md +12 -4
- package/dist/sdk-skills/kindgi-java-authoring-flows/SKILL.md +6 -4
- package/dist/sdk-skills/kindgi-java-authoring-guardrails/SKILL.md +33 -23
- package/dist/sdk-skills/kindgi-java-authoring-tools/SKILL.md +19 -12
- package/dist/sdk-skills/kindgi-java-getting-started/SKILL.md +16 -16
- package/dist/sdk-skills/kindgi-python-authoring-agents/SKILL.md +18 -6
- package/dist/sdk-skills/kindgi-python-authoring-flows/SKILL.md +6 -4
- package/dist/sdk-skills/kindgi-python-authoring-guardrails/SKILL.md +39 -30
- package/dist/sdk-skills/kindgi-python-authoring-tools/SKILL.md +19 -9
- package/dist/sdk-skills/kindgi-python-getting-started/SKILL.md +24 -21
- package/dist/sdk-skills/kindgi-scala-authoring-agents/SKILL.md +12 -4
- package/dist/sdk-skills/kindgi-scala-authoring-flows/SKILL.md +6 -4
- package/dist/sdk-skills/kindgi-scala-authoring-guardrails/SKILL.md +34 -23
- package/dist/sdk-skills/kindgi-scala-authoring-tools/SKILL.md +15 -9
- package/dist/sdk-skills/kindgi-scala-getting-started/SKILL.md +16 -16
- package/dist/sdk-skills/kindgi-using/SKILL.md +11 -11
- package/dist/templates/sample/README.md.tmpl +8 -7
- package/dist/templates/sample/agents/echo-agent/index.ts.tmpl +1 -1
- package/dist/templates/sample/kindgi.config.ts.tmpl +1 -1
- package/dist/templates/sample/package.json.tmpl +1 -1
- package/dist/templates/woocommerce/README.md.tmpl +9 -3
- package/package.json +13 -13
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# Amazon Bedrock
|
|
2
|
+
|
|
3
|
+
Nova, Claude and GPT on Amazon Bedrock. The `bedrock` preset signs in as the
|
|
4
|
+
runtime's own AWS identity (`KINDGI_AWS_IDENTITY` says where it comes from),
|
|
5
|
+
so it takes no key:
|
|
6
|
+
```sh
|
|
7
|
+
kindgi providers register --preset=bedrock --region=us-east-2
|
|
8
|
+
kindgi providers register --preset=bedrock --region=us-east-2 \
|
|
9
|
+
--models=us.anthropic.claude-haiku-4-5-20251001-v1:0 # Claude, not Nova Pro
|
|
10
|
+
```
|
|
11
|
+
`--region` is the US Region the account uses Bedrock in: the preset's models
|
|
12
|
+
are US cross-region inference profiles. Its default model is Amazon Nova Pro
|
|
13
|
+
(`us.amazon.nova-pro-v1:0`). Claude and GPT also need the AWS account's
|
|
14
|
+
access to their vendor's models
|
|
15
|
+
(https://docs.aws.amazon.com/bedrock/latest/userguide/model-access.html).
|
|
16
|
+
|
|
17
|
+
**On a runtime with `KINDGI_TENANT_HOST_ACCESS=isolated`, use a Bedrock API
|
|
18
|
+
key.** That runtime doesn't lend its own credentials to tenant configuration,
|
|
19
|
+
so it refuses the preset at registration and stores nothing:
|
|
20
|
+
```text
|
|
21
|
+
✗ /adapter_config/auth: adapter_config.auth = aws-identity (the default) signs in as the runtime's own AWS identity, which this deployment doesn't let tenant configuration use (KINDGI_TENANT_HOST_ACCESS). Set auth = api-key, with secret_ref naming a Bedrock API key.
|
|
22
|
+
```
|
|
23
|
+
`--secret` doesn't change that: the preset still signs in as the runtime.
|
|
24
|
+
Register from a spec whose `adapter_config.auth` is `api-key` and whose
|
|
25
|
+
`secret_ref` names the key:
|
|
26
|
+
|
|
27
|
+
1. **A long-term Bedrock API key**, made in the Region the provider uses. A
|
|
28
|
+
short-term key lasts 12 hours at most, so a registration can't keep one,
|
|
29
|
+
and a key works only in the Region it was made in. AWS recommends
|
|
30
|
+
long-term keys for exploration only: tell the person so, with AWS's page
|
|
31
|
+
(https://docs.aws.amazon.com/bedrock/latest/userguide/api-keys.html).
|
|
32
|
+
2. **Stored as a tenant secret**, with the no-echo prompt:
|
|
33
|
+
`kindgi secrets set BEDROCK_API_KEY --env=production --scope=tenant`.
|
|
34
|
+
3. **Registered:** `kindgi providers register --spec=@bedrock.json`, with
|
|
35
|
+
```json
|
|
36
|
+
{
|
|
37
|
+
"adapter_id": "@kindgi/adapter-model-bedrock",
|
|
38
|
+
"adapter_config": { "auth": "api-key" },
|
|
39
|
+
"secret_ref": { "envName": "production", "name": "BEDROCK_API_KEY" },
|
|
40
|
+
"metadata": {
|
|
41
|
+
"id": "bedrock",
|
|
42
|
+
"region": "us-east-2",
|
|
43
|
+
"models": [
|
|
44
|
+
{ "name": "us.anthropic.claude-haiku-4-5-20251001-v1:0", "contextWindow": 200000,
|
|
45
|
+
"maxOutputTokens": 16000, "features": ["tool-use", "parallel-tool-use"],
|
|
46
|
+
"cost": { "promptUsdPer1kTokens": 0.0011, "completionUsdPer1kTokens": 0.0055 } }
|
|
47
|
+
]
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
One provider is one Region and one key: another Region is another provider,
|
|
53
|
+
with a key made there. The key is read when a turn calls the model, not at
|
|
54
|
+
registration.
|
|
55
|
+
|
|
56
|
+
The same holds for the other providers that can sign in as the runtime on
|
|
57
|
+
`isolated`. Gemini on Vertex AI takes a service-account key in `secret_ref`
|
|
58
|
+
(Path D). Azure OpenAI's `auth: entra` is refused: use the `azure-openai`
|
|
59
|
+
preset, with the resource's key. A provider registered before the runtime
|
|
60
|
+
moved to `isolated` that signs in as the runtime isn't used there: a turn
|
|
61
|
+
that needs it fails with `422 capability-routing-failed`. Unregister it, and
|
|
62
|
+
register it again with a key.
|
|
63
|
+
|
|
64
|
+
Docs: https://docs.kindgi.com/v0.3/guides/models/#with-a-bedrock-api-key
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
# Common mistakes
|
|
2
|
+
|
|
3
|
+
## Contents
|
|
4
|
+
|
|
5
|
+
- 0. `adapter_id` uses the short name.
|
|
6
|
+
- 1. `envName` mismatch between the key and the provider's `secret_ref`.
|
|
7
|
+
- 2. Missing `features` on the model.
|
|
8
|
+
- 3. Empty `models[]`.
|
|
9
|
+
- 4. Setting `secret_ref` for the in-process adapter.
|
|
10
|
+
- 5. Registering the same provider id twice with different config.
|
|
11
|
+
- 6. Key not found by the runtime.
|
|
12
|
+
- 7. Forgetting to restart `kindgi dev` after registering a provider.
|
|
13
|
+
- 8. Compound `preferredProvider` strings.
|
|
14
|
+
- 9. Replies still come from dev-echo
|
|
15
|
+
- 10. A setting the adapter can't use.
|
|
16
|
+
- 11. A provider registered by hand under `kindgi dev`, with nothing committed.
|
|
17
|
+
|
|
18
|
+
0. **`adapter_id` uses the short name.** The `adapter_id` field must
|
|
19
|
+
be the FULL npm package name of the adapter — `"@kindgi/adapter-model-anthropic"`,
|
|
20
|
+
NOT `"anthropic"`. Adapters are registered with the runtime under
|
|
21
|
+
their full package names, and a short name matches none of them, so
|
|
22
|
+
registering is refused: the runtime has no adapter by that name
|
|
23
|
+
(`✗ /adapter_id: …`). The model adapters are
|
|
24
|
+
`@kindgi/adapter-model-anthropic`, `@kindgi/adapter-model-gemini`,
|
|
25
|
+
`@kindgi/adapter-model-openai-compat`,
|
|
26
|
+
`@kindgi/adapter-model-azure-openai`, `@kindgi/adapter-model-bedrock` and
|
|
27
|
+
`@kindgi/adapter-model-in-process`; `kindgi providers presets` shows
|
|
28
|
+
the id each preset uses.
|
|
29
|
+
|
|
30
|
+
1. **`envName` mismatch between the key and the provider's `secret_ref`.**
|
|
31
|
+
The runtime reads a provider's key in the environment its
|
|
32
|
+
`secret_ref.envName` names, at tenant scope. The SecretBinding refuses
|
|
33
|
+
to cross-resolve, so a key held under another environment gives
|
|
34
|
+
`secret-not-found` at agent-turn time. Where each one lands:
|
|
35
|
+
`kindgi secrets set` needs `--env=<name>`; `kindgi providers register
|
|
36
|
+
--preset` writes `--env`'s name, or `local` without it; a `--spec` file
|
|
37
|
+
names its own (`"secret_ref": {"envName": "production", ...}`). Under
|
|
38
|
+
`kindgi dev`, `local` is the project's env files (`.env`, `.env.local`)
|
|
39
|
+
and `.kindgi/secrets.env`; any other name is `.env.<envName>`. Match
|
|
40
|
+
them. On Kindgi Cloud, both are `prod`.
|
|
41
|
+
|
|
42
|
+
2. **Missing `features` on the model.** Agent declares
|
|
43
|
+
`capabilities: [{needs: [{feature: 'tool-use'}]}]`; at least one
|
|
44
|
+
model inside `metadata.models[]` must list `"features":
|
|
45
|
+
["tool-use"]` or the router filters every tuple out. If `kindgi
|
|
46
|
+
runs start` returns "no provider satisfies capability", check the
|
|
47
|
+
per-model `features` list — not a provider-level field anymore.
|
|
48
|
+
|
|
49
|
+
3. **Empty `models[]`.** Registration rejects with `empty-models`. Every
|
|
50
|
+
provider row must expose at least one model. Duplicate `name` within
|
|
51
|
+
the same array is also rejected (`duplicate-model-name`).
|
|
52
|
+
|
|
53
|
+
4. **Setting `secret_ref` for the in-process adapter.** `in-process`
|
|
54
|
+
ignores `secret_ref` — no key needed. Leaving it in is harmless but
|
|
55
|
+
noisy.
|
|
56
|
+
|
|
57
|
+
5. **Registering the same provider id twice with different config.**
|
|
58
|
+
Returns `409 provider-already-registered`. Unregister first:
|
|
59
|
+
```sh
|
|
60
|
+
kindgi providers unregister <provider-id>
|
|
61
|
+
```
|
|
62
|
+
Then re-register.
|
|
63
|
+
|
|
64
|
+
6. **Key not found by the runtime.** `kindgi dev` reads the env files
|
|
65
|
+
at the PACK ROOT (the directory with `kindgi.config.ts`, a Python
|
|
66
|
+
pack's `pyproject.toml` with `[tool.kindgi]`, or a Java or Scala pack's
|
|
67
|
+
`kindgi.config.json`) — `.env` and
|
|
68
|
+
`.env.local`, or whatever `dev.envFiles` lists; the boot log prints
|
|
69
|
+
which files it found. A `KINDGI_`-prefixed name is Kindgi runtime
|
|
70
|
+
config and never resolves as a secret. Outside `kindgi dev`, the
|
|
71
|
+
runtime resolves secrets through the deployment's `SecretBinding`
|
|
72
|
+
(a KMS- or database-backed store, for example).
|
|
73
|
+
|
|
74
|
+
7. **Forgetting to restart `kindgi dev` after registering a provider.**
|
|
75
|
+
You don't need to — provider registrations go to the running runtime
|
|
76
|
+
over HTTP (`POST /v1/providers`), which invalidates the tenant's
|
|
77
|
+
cached provider set. The next `kindgi runs start` sees the new
|
|
78
|
+
provider.
|
|
79
|
+
|
|
80
|
+
8. **Compound `preferredProvider` strings.** `preferredProvider` is a
|
|
81
|
+
provider (connection) id such as `'anthropic'`; the model is a
|
|
82
|
+
separate choice. A value like `'anthropic-claude-sonnet-5-5'`
|
|
83
|
+
(vendor + model baked together) matches no provider id, so the hint
|
|
84
|
+
does nothing. Pin the model with a `models: { allow: [...] }`
|
|
85
|
+
requirement instead.
|
|
86
|
+
|
|
87
|
+
9. **Replies still come from dev-echo** (`⚠ dev-echo isn't a real model: …`
|
|
88
|
+
then `Tool responded: …`; the turn's result has the `fallback-provider`
|
|
89
|
+
and `dev-echo-not-a-model` warnings). dev-echo is a fallback: it
|
|
90
|
+
answers only when no registered provider satisfies the agent. So your
|
|
91
|
+
provider doesn't — check its models' `features` against the agent's
|
|
92
|
+
`capabilities.needs` (mistake 2), a `models` / `providers` allow-list
|
|
93
|
+
that names nothing registered, and the tenant's policy. `kindgi
|
|
94
|
+
providers list` shows what is registered.
|
|
95
|
+
|
|
96
|
+
10. **A setting the adapter can't use.** Registering checks the spec
|
|
97
|
+
against its adapter (no network call, no key read) and refuses what
|
|
98
|
+
it can't use: `422 provider-config-invalid`, nothing stored, one line
|
|
99
|
+
per problem with its JSON-pointer path:
|
|
100
|
+
```text
|
|
101
|
+
Error [invalid-request]: Provider "ollama" doesn't fit adapter @kindgi/adapter-model-openai-compat: adapter_config.api must be one of responses, chat-completions.
|
|
102
|
+
✗ /adapter_config/api: adapter_config.api must be one of responses, chat-completions.
|
|
103
|
+
```
|
|
104
|
+
Fix each `✗` line's setting and register again. A key the adapter
|
|
105
|
+
needs is checked too (`✗ /secret_ref: …`); whether the key works, or
|
|
106
|
+
the endpoint answers, isn't (the first turn finds out). So is each
|
|
107
|
+
`adapter_config` key: one the adapter doesn't take is refused, naming
|
|
108
|
+
the ones it takes (`✗ /adapter_config/timeout: adapter_config.timeout
|
|
109
|
+
isn't a setting of this adapter: it takes baseURL, api,
|
|
110
|
+
extraBody.<field>.`), and one that moved names its new place. A
|
|
111
|
+
registration stored before 0.1.5 wasn't checked: `kindgi doctor`
|
|
112
|
+
names its problems (`GET /v1/providers/<id>/check`); unregister it
|
|
113
|
+
and register it again. A stored registration with a key its adapter
|
|
114
|
+
doesn't take still builds, without reading it: the check lists it in
|
|
115
|
+
`warnings`, apart from `issues`, and `kindgi doctor` shows it as a
|
|
116
|
+
warning.
|
|
117
|
+
|
|
118
|
+
11. **A provider registered by hand under `kindgi dev`, with nothing
|
|
119
|
+
committed.** `kindgi providers register` puts it in this worktree's dev
|
|
120
|
+
database only. Another worktree, a `kindgi dev --reset`, or a
|
|
121
|
+
teammate's `kindgi dev` has no provider, and its turns land on
|
|
122
|
+
dev-echo (mistake 9). Declare the provider in the pack's config and
|
|
123
|
+
commit it (step 2 of your path). `.kindgi/dev/providers.json` isn't the file to
|
|
124
|
+
commit: it's `kindgi dev`'s local record of what it registered, and
|
|
125
|
+
`.kindgi/` is gitignored.
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# Mental model: keys, registration and fallbacks
|
|
2
|
+
|
|
3
|
+
```
|
|
4
|
+
Project .env / .env.local dotenv SecretBinding runtime ProviderRegistry
|
|
5
|
+
───────────────────────── ───────────────────── ────────────────────────
|
|
6
|
+
ANTHROPIC_API_KEY=sk-... → resolve('local', hydrated per tenant on first
|
|
7
|
+
'ANTHROPIC_API_KEY') access; each row =
|
|
8
|
+
{ metadata, adapter_id,
|
|
9
|
+
secret_ref?,
|
|
10
|
+
adapter_config? }
|
|
11
|
+
│ │
|
|
12
|
+
▼ ▼
|
|
13
|
+
adapter factory ──── resolves apiKey lazily via closure
|
|
14
|
+
│
|
|
15
|
+
▼
|
|
16
|
+
ModelProvider ────── router picks a (provider, model)
|
|
17
|
+
tuple when an agent's
|
|
18
|
+
capabilities.needs matches
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Three moving parts:
|
|
22
|
+
1. **API key on disk** — in `kindgi dev` (environment `local`) the dotenv
|
|
23
|
+
secret binding reads the project's own env files: `.env`, then
|
|
24
|
+
`.env.local` on top (change the list with `dev.envFiles` in
|
|
25
|
+
`kindgi.config.ts`, `envFiles` under `[tool.kindgi.dev]` in a Python
|
|
26
|
+
pack's `pyproject.toml`, or `dev.envFiles` in a Java or Scala pack's
|
|
27
|
+
`kindgi.config.json`), then Kindgi's own `.kindgi/secrets.env` on top.
|
|
28
|
+
A key already in the app's `.env` just works. `kindgi secrets set`
|
|
29
|
+
(interactive, no-echo) writes `.kindgi/secrets.env`, a file the app
|
|
30
|
+
doesn't load (a framework loads `.env.local` into every route); `--app`
|
|
31
|
+
writes the app's file instead, for a value the app reads too (a webhook
|
|
32
|
+
signing secret). For non-sensitive values (log levels, region names,
|
|
33
|
+
feature flags), `kindgi env set NAME VALUE --env=local` writes the app's
|
|
34
|
+
`.env.local` with a positional value — never route real secrets
|
|
35
|
+
through it. `KINDGI_*`
|
|
36
|
+
names configure Kindgi itself and are never resolvable as secrets.
|
|
37
|
+
2. **Provider registration** — declared in the pack's config, which is
|
|
38
|
+
committed, and registered by `kindgi dev` at each boot; on a runtime
|
|
39
|
+
`kindgi dev` doesn't run, `kindgi providers register` (`POST /v1/providers`)
|
|
40
|
+
3. **Agent's `capabilities.needs`** — matched at the (provider, model) tuple level at turn time
|
|
41
|
+
|
|
42
|
+
**Registration body:** `{ metadata, adapter_id, secret_ref?, adapter_config? }`.
|
|
43
|
+
`secret_ref` points at the credential; `adapter_config` holds the adapter's
|
|
44
|
+
non-secret connection settings (a cloud project, a base URL) as flat string,
|
|
45
|
+
number or boolean values. Both are stored with the provider and handed to the
|
|
46
|
+
runtime; `kindgi providers list` / `get` show only `metadata`. Never put a
|
|
47
|
+
credential in `adapter_config`.
|
|
48
|
+
|
|
49
|
+
**Shape rule:** `ProviderMetadata.id` names the CONNECTION (e.g. `anthropic`,
|
|
50
|
+
`groq`, `local-onnx`); per-model fields (`name`, `contextWindow`, `cost`,
|
|
51
|
+
`features`) live inside `metadata.models[]`. One row can expose many models
|
|
52
|
+
under the same API key.
|
|
53
|
+
|
|
54
|
+
**Fallbacks:** `"fallback": true` in `metadata` makes a provider a
|
|
55
|
+
fallback — the router considers it only when no other provider satisfies
|
|
56
|
+
the agent's capability, and the turn's result then carries a
|
|
57
|
+
`fallback-provider` warning. `dev-echo` is one; a cheap local model can be
|
|
58
|
+
yours.
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# On Kindgi Cloud: the key and its provider go under `prod`
|
|
2
|
+
|
|
3
|
+
A pack deployed with `kindgi deploy --hosted` runs on your workspace's
|
|
4
|
+
runtime on Kindgi Cloud, and that runtime serves the `prod` environment,
|
|
5
|
+
before and after you go live. The other files' examples use `--env=local`, for
|
|
6
|
+
`kindgi dev`. For Kindgi Cloud, name `prod` instead:
|
|
7
|
+
|
|
8
|
+
```sh
|
|
9
|
+
kindgi secrets set ANTHROPIC_API_KEY --env=prod --scope=tenant # a no-echo prompt
|
|
10
|
+
kindgi providers register --preset=anthropic --env=prod
|
|
11
|
+
kindgi deploy --hosted --env=prod
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
- The runtime reads a provider's key in the environment its
|
|
15
|
+
`secret_ref.envName` names, at tenant scope. Keep the key and the
|
|
16
|
+
provider both on `prod`. A provider registered without `--env` reads
|
|
17
|
+
`local`, not the `prod` key: `register` refuses when the pack's own env
|
|
18
|
+
files lack the key (its message names `--env`), and otherwise the first
|
|
19
|
+
turn can't find the key (mistake 1 in `common-mistakes.md`). By hand, `provider.json` has
|
|
20
|
+
`"secret_ref": { "envName": "prod", … }`.
|
|
21
|
+
- `kindgi secrets set` has no default environment: name `--env` every time.
|
|
22
|
+
- The deployment `kindgi deploy` sends names no environment. Its
|
|
23
|
+
`--env=prod` picks the pack's own `prod` settings, such as its signing
|
|
24
|
+
key.
|
|
25
|
+
- `kindgi deploy` doesn't register providers, and the providers declared in
|
|
26
|
+
the pack's config are `kindgi dev`'s only. Register once on `prod`, by
|
|
27
|
+
hand, and again when you add a provider or change one.
|
|
28
|
+
- OpenAI, the Gemini API, Groq and OpenRouter take the same two lines,
|
|
29
|
+
with their preset and key: `openai` and `OPENAI_API_KEY`, `gemini-api`
|
|
30
|
+
and `GEMINI_API_KEY`, `groq` and `GROQ_API_KEY`, `openrouter` and
|
|
31
|
+
`OPENROUTER_API_KEY`. Bedrock, Vertex AI and Azure OpenAI don't fit
|
|
32
|
+
them: see `bedrock.md` and `path-d-vertex.md`, and `kindgi providers
|
|
33
|
+
presets` for `azure-openai`'s settings.
|
|
34
|
+
|
|
35
|
+
The whole flow, from signing the CLI in to going live:
|
|
36
|
+
https://docs.kindgi.com/v0.3/hosted/deploy-your-agent/#your-model-key-and-its-provider
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
# Path A — Hosted, native Anthropic
|
|
2
|
+
|
|
3
|
+
## Contents
|
|
4
|
+
|
|
5
|
+
- Step 1 — set the key
|
|
6
|
+
- Step 2 — declare it in the pack's config, and commit it
|
|
7
|
+
- Staging and production: register by hand, once per runtime
|
|
8
|
+
- Step 2 (by hand) — write `provider.json`
|
|
9
|
+
- Step 3 — register
|
|
10
|
+
- Step 4 — verify
|
|
11
|
+
- Step 5 — run
|
|
12
|
+
- The other one-key presets
|
|
13
|
+
|
|
14
|
+
Best fidelity to Anthropic's API (prompt caching, latest models, tool
|
|
15
|
+
use). Requires an `ANTHROPIC_API_KEY`.
|
|
16
|
+
|
|
17
|
+
A model's `structured-output` feature is a routing label: the model can
|
|
18
|
+
follow a JSON schema natively, but Kindgi's typed outputs use instructions,
|
|
19
|
+
then parse, check against the schema and repair, on every provider.
|
|
20
|
+
|
|
21
|
+
**Step 1 — set the key:**
|
|
22
|
+
```sh
|
|
23
|
+
kindgi secrets set ANTHROPIC_API_KEY --env=local --scope=tenant
|
|
24
|
+
# Prompts twice, echo disabled: paste the key, then again to confirm.
|
|
25
|
+
```
|
|
26
|
+
Under `kindgi dev`, this writes to `.kindgi/secrets.env` at the pack root
|
|
27
|
+
via the dotenv secret binding — or add `ANTHROPIC_API_KEY=…` to that file yourself; `kindgi dev`
|
|
28
|
+
also reads the app's `.env` / `.env.local`. If the pack lives inside an app
|
|
29
|
+
whose env file already has the key, it works as it is; `kindgi secrets copy`
|
|
30
|
+
gives Kindgi its own copy and never edits the app's files (the app may use
|
|
31
|
+
the key itself: leave removing it to the person). Keep env files gitignored. For pipelines/CI, pipe the value with
|
|
32
|
+
`echo -n "$KEY" | kindgi secrets set ANTHROPIC_API_KEY --env=local --scope=tenant --from-stdin`,
|
|
33
|
+
or read from a mode-0600 file with `--from-file <path>`. Never pass a
|
|
34
|
+
credential on argv.
|
|
35
|
+
|
|
36
|
+
For a pack on Kindgi Cloud, `--env=prod` instead: the key goes to your
|
|
37
|
+
workspace's runtime, not to a file (`kindgi-cloud.md`).
|
|
38
|
+
|
|
39
|
+
**Step 2 — declare it in the pack's config, and commit it.** `kindgi dev`
|
|
40
|
+
registers what the config declares on every boot: in every git worktree
|
|
41
|
+
(each has its own dev database), after `--reset`, and on a teammate's
|
|
42
|
+
machine. The declaration holds a key's name, never the key, so it goes in
|
|
43
|
+
git with the rest of the config. Committing it is how a teammate's
|
|
44
|
+
`kindgi dev`, or another worktree's, gets the same provider:
|
|
45
|
+
```ts
|
|
46
|
+
// in kindgi.config.ts
|
|
47
|
+
providers: [
|
|
48
|
+
{ preset: 'anthropic', models: ['claude-sonnet-5-5'] }, // key ANTHROPIC_API_KEY, from the env files
|
|
49
|
+
{ preset: 'gemini', project: 'acme-gcp', models: ['gemini-3.8-flash'] },
|
|
50
|
+
{ spec: { /* the provider.json body below */ } },
|
|
51
|
+
],
|
|
52
|
+
```
|
|
53
|
+
```toml
|
|
54
|
+
# in pyproject.toml: one table per provider, same keys
|
|
55
|
+
[[tool.kindgi.providers]]
|
|
56
|
+
preset = "anthropic"
|
|
57
|
+
models = ["claude-sonnet-5-5"]
|
|
58
|
+
```
|
|
59
|
+
In a Java or Scala pack's `kindgi.config.json`, the same keys:
|
|
60
|
+
`"providers": [{"preset": "anthropic", "models": ["claude-sonnet-5-5"]}]`.
|
|
61
|
+
- A preset entry takes `models`, the settings its preset asks for (`project`
|
|
62
|
+
for `gemini`; `resourceName` and `deployments` for `azure-openai`; `region`
|
|
63
|
+
for `bedrock`), `secret` (the key's name, in place of the preset's) and
|
|
64
|
+
`maxOutputTokens`, spelled the same in `pyproject.toml` and
|
|
65
|
+
`kindgi.config.json`. Its own settings are required and another preset's
|
|
66
|
+
are refused. `deployments` is a map of model to deployment
|
|
67
|
+
(`{ "gpt-6.1-sol": "gpt-6-1-sol" }`, a `[tool.kindgi.providers.deployments]`
|
|
68
|
+
table in `pyproject.toml`, model names quoted), not the `--deployments` flag's
|
|
69
|
+
`model=deployment,…`, and it names exactly the models the entry registers;
|
|
70
|
+
a `spec` entry is a `--spec` body. A
|
|
71
|
+
key is always a secret's name (`secret_ref`); a credential in
|
|
72
|
+
`adapter_config` is refused.
|
|
73
|
+
- Each boot prints `Providers from kindgi.config.ts:` (the pack's config file) with one line each:
|
|
74
|
+
`registered`, `unchanged`, `registered again (changed in kindgi.config.ts)`,
|
|
75
|
+
`unregistered (no longer in kindgi.config.ts)`, or ⚠ `not registered: <KEY>
|
|
76
|
+
is not in .env, .env.local, .kindgi/secrets.env` (set the key, then
|
|
77
|
+
restart: the config isn't watched).
|
|
78
|
+
- A declaration applies at the next boot: the config isn't watched, so
|
|
79
|
+
restart `kindgi dev` after changing it. Each person, and each worktree,
|
|
80
|
+
sets the key in its own env files (step 1).
|
|
81
|
+
- A provider with that id that `kindgi dev` didn't register is left as it is;
|
|
82
|
+
if its region or models differ, a ⚠ line names the
|
|
83
|
+
`kindgi providers unregister` that lets the config's version apply.
|
|
84
|
+
- `.kindgi/dev/providers.json` is `kindgi dev`'s own record of what it
|
|
85
|
+
registered. `.kindgi/` is gitignored, so that record stays in this
|
|
86
|
+
worktree, and it isn't where a provider is declared.
|
|
87
|
+
|
|
88
|
+
Before pinning a Claude model, check its status on Anthropic's model
|
|
89
|
+
deprecations page (https://platform.claude.com/docs/en/about-claude/model-deprecations): a turn routed to a retired model fails. Prefer the
|
|
90
|
+
preset's default model. `anthropic` without `models` registers Opus 5.5,
|
|
91
|
+
Sonnet 5.5 (the default), Haiku 5.5 and Haiku 4.5. Each
|
|
92
|
+
preset names a default model (`metadata.defaultModel`, marked `(default)`
|
|
93
|
+
when it registers), which an agent with no preference gets. A preset
|
|
94
|
+
registered before 0.1.4 has none: unregister it and register it again.
|
|
95
|
+
The Claude 5.5 and GPT-6 models take no `temperature` (`"sampling": false`:
|
|
96
|
+
the call goes without it, with a `sampling-unsupported` warning), and a
|
|
97
|
+
model's `thinking` says how it thinks and the levels it takes (the presets
|
|
98
|
+
list each model's). An agent asks for a level with `thinking` in its model
|
|
99
|
+
settings; one the model doesn't take is rounded up, or to its highest, with
|
|
100
|
+
a `thinking-level-adjusted` warning. Thinking counts against
|
|
101
|
+
`maxOutputTokens` and bills as output.
|
|
102
|
+
The preset carries the models, context windows, default output caps (what
|
|
103
|
+
a call asks for when its agent sets no `maxOutputTokens`; not the model's own
|
|
104
|
+
limit) and current prices (`kindgi providers presets` lists the presets and
|
|
105
|
+
when their prices were checked); an entry's `maxOutputTokens` sets another cap. That's
|
|
106
|
+
all for Anthropic; go to step 4. The rest of this path is a spec of your
|
|
107
|
+
own, by hand.
|
|
108
|
+
|
|
109
|
+
**Staging and production: register by hand, once per runtime.** The
|
|
110
|
+
declaration drives `kindgi dev` only. A runtime `kindgi dev` doesn't run
|
|
111
|
+
(staging, production, Kindgi Cloud) gets its providers from
|
|
112
|
+
`kindgi providers register` against that runtime, once, and again when you
|
|
113
|
+
add a provider or change one. A registration is the runtime's, shared by
|
|
114
|
+
every environment it serves: register once in all when one runtime serves
|
|
115
|
+
both staging and prod, and once on each when they're separate runtimes. The
|
|
116
|
+
key isn't shared: set it first in each environment that runs the pack
|
|
117
|
+
(`kindgi secrets set ANTHROPIC_API_KEY --env=<environment>`), then:
|
|
118
|
+
```sh
|
|
119
|
+
kindgi providers register --preset=anthropic --env=<env> # the preset's models
|
|
120
|
+
kindgi providers register --preset=anthropic --models=claude-sonnet-5-5 --env=<env> # just one
|
|
121
|
+
```
|
|
122
|
+
- `--env` names one of the pack's environments. On a runtime that keeps
|
|
123
|
+
its values under one env, the key goes in that environment's project, and
|
|
124
|
+
`register` with it prints the `kindgi secrets set` line, to run again with
|
|
125
|
+
each other environment's name. On a runtime that serves several
|
|
126
|
+
environments, or with an `--env` that isn't one of the pack's,
|
|
127
|
+
`kindgi secrets set` asks for a `--scope`. On Kindgi Cloud, it's `prod`
|
|
128
|
+
(`kindgi-cloud.md`; mistake 1 in `common-mistakes.md`). `--max-output-tokens=<n>` sets
|
|
129
|
+
another output cap.
|
|
130
|
+
- To change a provider there, unregister it first (mistake 5 in `common-mistakes.md`), then
|
|
131
|
+
register it again.
|
|
132
|
+
- `kindgi deploy` doesn't register providers. `kindgi promote` checks the
|
|
133
|
+
target first and stops (exit 1) while it has no provider, naming
|
|
134
|
+
`kindgi providers register --preset=<name>`.
|
|
135
|
+
- Nothing in git records what a runtime has registered:
|
|
136
|
+
`kindgi providers list` against it shows it.
|
|
137
|
+
- Under `kindgi dev`, `kindgi providers register` puts a provider in this
|
|
138
|
+
worktree's dev database only, and leaves nothing to commit. Use it to try a
|
|
139
|
+
provider, then declare it.
|
|
140
|
+
|
|
141
|
+
**Step 2 (by hand) — write `provider.json`** at the pack root, and commit it:
|
|
142
|
+
like the declaration, it names its key (`secret_ref`) and never holds it.
|
|
143
|
+
Under `kindgi dev`, declare its body as a `spec` entry; on another runtime,
|
|
144
|
+
register it with `--spec` (step 3). One connection,
|
|
145
|
+
two models — matches how the Anthropic SDK actually works (the API
|
|
146
|
+
key is per-vendor; the model is per-call):
|
|
147
|
+
```json
|
|
148
|
+
{
|
|
149
|
+
"metadata": {
|
|
150
|
+
"id": "anthropic",
|
|
151
|
+
"region": "us-east-1",
|
|
152
|
+
"models": [
|
|
153
|
+
{
|
|
154
|
+
"name": "claude-opus-5-5",
|
|
155
|
+
"contextWindow": 1000000,
|
|
156
|
+
"features": ["tool-use", "structured-output"],
|
|
157
|
+
"cost": {
|
|
158
|
+
"promptUsdPer1kTokens": 0.004,
|
|
159
|
+
"completionUsdPer1kTokens": 0.02
|
|
160
|
+
},
|
|
161
|
+
"description": "Most capable Opus — long-running agentic and knowledge work."
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
"name": "claude-sonnet-5-5",
|
|
165
|
+
"contextWindow": 1000000,
|
|
166
|
+
"features": ["tool-use", "structured-output"],
|
|
167
|
+
"cost": {
|
|
168
|
+
"promptUsdPer1kTokens": 0.002,
|
|
169
|
+
"completionUsdPer1kTokens": 0.01
|
|
170
|
+
},
|
|
171
|
+
"description": "Balanced performance/cost."
|
|
172
|
+
}
|
|
173
|
+
],
|
|
174
|
+
"description": "Anthropic Claude via native adapter."
|
|
175
|
+
},
|
|
176
|
+
"adapter_id": "@kindgi/adapter-model-anthropic",
|
|
177
|
+
"secret_ref": { "envName": "local", "name": "ANTHROPIC_API_KEY" }
|
|
178
|
+
}
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
> ⚠ **Units gotcha:** the field is `promptUsdPer1kTokens` (per THOUSAND
|
|
182
|
+
> tokens), but every vendor pricing page (Anthropic, OpenAI, Groq)
|
|
183
|
+
> advertises rates PER MILLION. Divide by 1000 before you paste. Sonnet
|
|
184
|
+
> 5.5 is "$2 / MTok input" → `0.002`, "$10 / MTok output" → `0.01`. A
|
|
185
|
+
> misplaced factor makes real cost look 1000× real; a $0.15 budget
|
|
186
|
+
> blows in the first turn.
|
|
187
|
+
|
|
188
|
+
**Step 3 — register:**
|
|
189
|
+
```sh
|
|
190
|
+
kindgi providers register --spec=@provider.json
|
|
191
|
+
```
|
|
192
|
+
Returns `{providerId: "anthropic"}` on success. Idempotent in the sense
|
|
193
|
+
that re-registering the same id returns `provider-already-registered`;
|
|
194
|
+
unregister first if the config actually changed.
|
|
195
|
+
|
|
196
|
+
**Step 4 — verify:**
|
|
197
|
+
```sh
|
|
198
|
+
kindgi providers list
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
**Step 5 — run:** any agent whose `capabilities: [{needs: [{feature:
|
|
202
|
+
'tool-use'}]}]` is now routed to a (`anthropic`, `<one of the models>`)
|
|
203
|
+
tuple. The router picks by score; prefer a provider with
|
|
204
|
+
`preferredProvider` and pin a model with a `models: { allow: [...] }`
|
|
205
|
+
capability requirement (`router.md`).
|
|
206
|
+
|
|
207
|
+
Nothing to switch off: `dev-echo` is a fallback, so the new provider
|
|
208
|
+
answers every agent it satisfies. A turn that still lands on dev-echo
|
|
209
|
+
carries the `fallback-provider` and `dev-echo-not-a-model` warnings — see
|
|
210
|
+
mistake 9 in `common-mistakes.md`.
|
|
211
|
+
|
|
212
|
+
**The other one-key presets** work the same way, with their own key:
|
|
213
|
+
`--preset=openai` (`OPENAI_API_KEY`), `--preset=gemini-api` (`GEMINI_API_KEY`,
|
|
214
|
+
a Google AI Studio key; `gemini` is Vertex AI), `--preset=groq`
|
|
215
|
+
(`GROQ_API_KEY`) and `--preset=openrouter` (`OPENROUTER_API_KEY`).
|
|
216
|
+
`kindgi providers presets` lists them with their models.
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
# Path B — Hosted via OpenAI-compat
|
|
2
|
+
|
|
3
|
+
## Contents
|
|
4
|
+
|
|
5
|
+
- Step 1 — set the key
|
|
6
|
+
- Step 2 — `provider.json`
|
|
7
|
+
- Steps 3 to 5 — register, verify, run
|
|
8
|
+
- Local via Ollama
|
|
9
|
+
- Any model you serve yourself
|
|
10
|
+
|
|
11
|
+
Works with **any** OpenAI-compatible endpoint. Same adapter, different
|
|
12
|
+
`baseURL`:
|
|
13
|
+
|
|
14
|
+
| Provider | baseURL |
|
|
15
|
+
|---|---|
|
|
16
|
+
| OpenAI | `https://api.openai.com/v1` |
|
|
17
|
+
| Groq | `https://api.groq.com/openai/v1` |
|
|
18
|
+
| Together | `https://api.together.xyz/v1` |
|
|
19
|
+
| Fireworks | `https://api.fireworks.ai/inference/v1` |
|
|
20
|
+
| DeepSeek | `https://api.deepseek.com/v1` |
|
|
21
|
+
| LiteLLM proxy | `http://localhost:4000/v1` |
|
|
22
|
+
| OpenRouter (a hosted gateway) | `https://openrouter.ai/api/v1` |
|
|
23
|
+
|
|
24
|
+
The connection carries the `baseURL` (in `adapter_config`);
|
|
25
|
+
each endpoint is a separate provider row because each has its own API
|
|
26
|
+
key + region. Within one row, list every model that endpoint exposes.
|
|
27
|
+
|
|
28
|
+
**Step 1 — set the key:**
|
|
29
|
+
```sh
|
|
30
|
+
kindgi secrets set GROQ_API_KEY --env=local --scope=tenant
|
|
31
|
+
# Interactive prompt; paste and enter.
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
**Step 2 — `provider.json`** (Groq, exposing two Llama variants):
|
|
35
|
+
```json
|
|
36
|
+
{
|
|
37
|
+
"metadata": {
|
|
38
|
+
"id": "groq",
|
|
39
|
+
"region": "us-central-1",
|
|
40
|
+
"models": [
|
|
41
|
+
{
|
|
42
|
+
"name": "llama-3.3-70b-versatile",
|
|
43
|
+
"contextWindow": 128000,
|
|
44
|
+
"features": ["tool-use"],
|
|
45
|
+
"cost": {
|
|
46
|
+
"promptUsdPer1kTokens": 0.00059,
|
|
47
|
+
"completionUsdPer1kTokens": 0.00079
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
"name": "llama-3.1-8b-instant",
|
|
52
|
+
"contextWindow": 128000,
|
|
53
|
+
"features": ["tool-use"],
|
|
54
|
+
"cost": {
|
|
55
|
+
"promptUsdPer1kTokens": 0.00005,
|
|
56
|
+
"completionUsdPer1kTokens": 0.00008
|
|
57
|
+
},
|
|
58
|
+
"description": "Fast + cheap tier — routing, classification."
|
|
59
|
+
}
|
|
60
|
+
],
|
|
61
|
+
"description": "Groq-hosted Llama via OpenAI-compat."
|
|
62
|
+
},
|
|
63
|
+
"adapter_id": "@kindgi/adapter-model-openai-compat",
|
|
64
|
+
"secret_ref": { "envName": "local", "name": "GROQ_API_KEY" },
|
|
65
|
+
"adapter_config": { "baseURL": "https://api.groq.com/openai/v1" }
|
|
66
|
+
}
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
**Steps 3 to 5 — register, verify, run:**
|
|
70
|
+
```sh
|
|
71
|
+
kindgi providers register --spec=@provider.json
|
|
72
|
+
kindgi providers list
|
|
73
|
+
```
|
|
74
|
+
Then run an agent whose `capabilities.needs` one of the listed models'
|
|
75
|
+
`features` satisfy. Registering the same id again returns
|
|
76
|
+
`provider-already-registered`: unregister first when the config changed
|
|
77
|
+
(mistake 5 in `common-mistakes.md`).
|
|
78
|
+
|
|
79
|
+
## Local via Ollama
|
|
80
|
+
|
|
81
|
+
For bigger local models — Ollama runs them, we point at the OpenAI-compat
|
|
82
|
+
endpoint it exposes:
|
|
83
|
+
|
|
84
|
+
```json
|
|
85
|
+
{
|
|
86
|
+
"metadata": {
|
|
87
|
+
"id": "ollama",
|
|
88
|
+
"region": "local",
|
|
89
|
+
"models": [
|
|
90
|
+
{
|
|
91
|
+
"name": "llama3",
|
|
92
|
+
"contextWindow": 8192,
|
|
93
|
+
"features": ["tool-use"],
|
|
94
|
+
"cost": {
|
|
95
|
+
"promptUsdPer1kTokens": 0,
|
|
96
|
+
"completionUsdPer1kTokens": 0
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
],
|
|
100
|
+
"description": "Local Ollama Llama 3 8B."
|
|
101
|
+
},
|
|
102
|
+
"adapter_id": "@kindgi/adapter-model-openai-compat",
|
|
103
|
+
"adapter_config": { "baseURL": "http://localhost:11434/v1" }
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Ollama doesn't check a key, so the row has no `secret_ref`: without one,
|
|
108
|
+
the adapter sends a placeholder key, as local servers expect.
|
|
109
|
+
|
|
110
|
+
**Any model you serve yourself** (Ollama, vLLM, llama.cpp's
|
|
111
|
+
`llama-server`, LM Studio) must do two things for an agent:
|
|
112
|
+
- **Call tools in the OpenAI format.** Serve it with tool calling on
|
|
113
|
+
(vLLM `--enable-auto-tool-choice --tool-call-parser <the model's>`,
|
|
114
|
+
`llama-server --jinja`), and pick a model that supports tools.
|
|
115
|
+
- **Answer without its thinking.** A thinking model (Qwen and others)
|
|
116
|
+
writes its reasoning first unless asked not to, and a typed answer then
|
|
117
|
+
isn't JSON (`output-schema-violation`). Turn thinking off on the server
|
|
118
|
+
(vLLM `--default-chat-template-kwargs '{"enable_thinking": false}'`,
|
|
119
|
+
`llama-server --reasoning off`), or, for a shared server you can't
|
|
120
|
+
reconfigure, per request from the provider row:
|
|
121
|
+
`"extraBody.chat_template_kwargs.enable_thinking": false` in
|
|
122
|
+
`adapter_config`. `adapter_config` is flat: one key per request field,
|
|
123
|
+
dots nest.
|
|
124
|
+
|
|
125
|
+
Assumes Ollama is installed + the model is pulled (`ollama pull llama3`).
|
|
126
|
+
See ollama.com for install / hardware requirements — Llama 3 8B needs
|
|
127
|
+
~8GB RAM, Llama 3 70B needs ~48GB VRAM or ~140GB RAM.
|