@kindgi/sdk 0.1.2 → 0.1.3

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kindgi/sdk",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "description": "@kindgi/sdk — the authoring SDK for Kindgi™. Facade over the individual @kindgi/* packages + @kindgi/client. Unifies pack authoring (defineTool / defineCheck / defineAgent / defineFlow) and client callsites (createClient) behind three sub-paths: /define, /client, /types. Re-export facade; zero behavior.",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -55,15 +55,15 @@
55
55
  "README.md"
56
56
  ],
57
57
  "dependencies": {
58
- "@kindgi/agents": "0.1.2",
59
- "@kindgi/client": "0.1.2",
60
- "@kindgi/crypto": "0.1.2",
61
- "@kindgi/flow": "0.1.2",
62
- "@kindgi/guardrails": "0.1.2",
63
- "@kindgi/handler-runtime": "0.1.2",
64
- "@kindgi/schema": "0.1.2",
65
- "@kindgi/tools": "0.1.2",
66
- "@kindgi/types": "0.1.2"
58
+ "@kindgi/agents": "0.1.3",
59
+ "@kindgi/client": "0.1.3",
60
+ "@kindgi/crypto": "0.1.3",
61
+ "@kindgi/flow": "0.1.3",
62
+ "@kindgi/guardrails": "0.1.3",
63
+ "@kindgi/handler-runtime": "0.1.3",
64
+ "@kindgi/schema": "0.1.3",
65
+ "@kindgi/tools": "0.1.3",
66
+ "@kindgi/types": "0.1.3"
67
67
  },
68
68
  "peerDependencies": {
69
69
  "zod": "^4.0.0"
@@ -22,7 +22,7 @@ description: >
22
22
  kindgi-getting-started.
23
23
  type: core
24
24
  library: "@kindgi/sdk"
25
- version: "0.9.2"
25
+ version: "0.9.3"
26
26
  sdk_version: "0.0.0"
27
27
  pack_languages: [node, python]
28
28
  sources:
@@ -126,12 +126,46 @@ credential on argv.
126
126
  kindgi providers register --preset=anthropic # Opus 5.5, Sonnet 5.5, Haiku 4.5
127
127
  kindgi providers register --preset=anthropic --models=claude-haiku-4-5 # just one
128
128
  ```
129
- The preset carries the models, context windows and current prices
130
- (`kindgi providers presets` lists the presets and when their prices were
131
- checked). In a pack it refuses until the key is in the pack's env files —
129
+ The preset carries the models, context windows, output limits and current
130
+ prices (`kindgi providers presets` lists the presets and when their prices
131
+ were checked); `--max-output-tokens=<n>` sets another output limit. In a pack it refuses until the key is in the pack's env files —
132
132
  step 1. That's all for Anthropic; go to step 4. The rest of this path is
133
133
  the same registration by hand, for a spec of your own.
134
134
 
135
+ **Or declare it in the pack's config**, and `kindgi dev` registers it on
136
+ every boot: in every git worktree (each has its own dev database), after
137
+ `--reset`, and on a teammate's machine. Prefer this for any provider the pack
138
+ needs under `kindgi dev`:
139
+ ```ts
140
+ // in kindgi.config.ts
141
+ providers: [
142
+ { preset: 'anthropic', models: ['claude-haiku-4-5'] }, // key ANTHROPIC_API_KEY, from the env files
143
+ { preset: 'gemini', project: 'acme-gcp', models: ['gemini-2.5-flash'] },
144
+ { spec: { /* the provider.json body below */ } },
145
+ ],
146
+ ```
147
+ ```toml
148
+ # in pyproject.toml: one table per provider, same keys
149
+ [[tool.kindgi.providers]]
150
+ preset = "anthropic"
151
+ models = ["claude-haiku-4-5"]
152
+ ```
153
+ - A preset entry takes `models`, `project`, `secret` (the key's name, in place
154
+ of the preset's) and `maxOutputTokens`, spelled the same in `pyproject.toml`;
155
+ a `spec` entry is a `--spec` body. A
156
+ key is always a secret's name (`secret_ref`); a credential in
157
+ `adapter_config` is refused.
158
+ - Each boot prints `Providers from kindgi.config.ts:` with one line each:
159
+ `registered`, `unchanged`, `registered again (changed in kindgi.config.ts)`,
160
+ `unregistered (no longer in kindgi.config.ts)`, or ⚠ `not registered: <KEY>
161
+ is not in .env, .env.local` (set the key, then restart: the config isn't
162
+ watched).
163
+ - A provider with that id that `kindgi dev` didn't register is left as it is;
164
+ if its region or models differ, a ⚠ line names the
165
+ `kindgi providers unregister` that lets the config's version apply.
166
+ - A runtime `kindgi dev` doesn't run (staging, production) still gets its
167
+ providers with `kindgi providers register`.
168
+
135
169
  **Step 2 (by hand) — write `provider.json`** at the pack root. One connection,
136
170
  three models — matches how the Anthropic SDK actually works (the API
137
171
  key is per-vendor; the model is per-call):
@@ -438,7 +472,7 @@ outside Google Cloud: put a service-account key (its JSON) in a secret
438
472
  "name": "gemini-2.5-pro",
439
473
  "contextWindow": 1048576,
440
474
  "features": ["tool-use"],
441
- "maxOutputTokens": 8192,
475
+ "maxOutputTokens": 65536,
442
476
  "cost": {
443
477
  "promptUsdPer1kTokens": 0.00125,
444
478
  "completionUsdPer1kTokens": 0.01,
@@ -453,6 +487,7 @@ outside Google Cloud: put a service-account key (its JSON) in a secret
453
487
  "name": "gemini-2.5-flash",
454
488
  "contextWindow": 1048576,
455
489
  "features": ["tool-use"],
490
+ "maxOutputTokens": 65536,
456
491
  "cost": { "promptUsdPer1kTokens": 0.0003, "completionUsdPer1kTokens": 0.0025 }
457
492
  }
458
493
  ]
@@ -88,7 +88,8 @@ const defined = defineTool({
88
88
  effects: [],
89
89
  mutating: false,
90
90
  handler: async (input, ctx) => {
91
- // ctx.tenantId, ctx.abortSignal, ctx.secrets (what needsSpec declares) available
91
+ // ctx.tenantId, ctx.abortSignal, ctx.secrets (what needsSpec declares) available;
92
+ // in a run, ctx.projectId and ctx.orgId (set from the run, never from the input)
92
93
  // Return type MUST match Output schema (validated at invoke time)
93
94
  return { found: true, canonicalCite: '...' };
94
95
  },
@@ -14,7 +14,7 @@ description: >
14
14
  primitive.
15
15
  type: core
16
16
  library: "@kindgi/sdk"
17
- version: "0.3.5"
17
+ version: "0.3.7"
18
18
  sdk_version: "0.0.0"
19
19
  pack_languages: [node]
20
20
  ---
@@ -158,8 +158,11 @@ Most of the setup is automatable, but two require your knowledge:
158
158
  - **Real LLM provider credentials** — the built-in dev-echo provider
159
159
  returns canned responses (great for the loop test, useless for real
160
160
  agents). It is a fallback, so it steps aside once a real provider is
161
- registered — `kindgi providers register --preset=anthropic` with the
162
- key in `.env`; see `kindgi-authoring-providers`.
161
+ registered. Declare it in `kindgi.config.ts`
162
+ (`providers: [{ preset: 'anthropic' }]`, the key in `.env`) and `kindgi dev`
163
+ registers it on every boot, in every worktree and after `--reset`; or once,
164
+ by hand: `kindgi providers register --preset=anthropic`. See
165
+ `kindgi-authoring-providers`.
163
166
 
164
167
  ## Your app and Kindgi's data
165
168
 
@@ -189,8 +192,37 @@ const run = await kindgi.runs.start({
189
192
  (`GET /v1/provenance/{runId}`). A flow run has none of its own: each agent
190
193
  step's `step.completed` entry in the flow's journal names its turn's run
191
194
  (`payload.output.runId`).
192
- - **When a run finished:** the `run.finished` webhook (the run's id and
193
- outcome, no output; then `runs.get`), not polling.
195
+ - **What it cost:** `kindgi.cost.usage.query({ rootRunId: runId })`
196
+ (`GET /v1/cost/records?rootRunId={runId}`): `.items`, one record per model
197
+ call, with its `model`, `usage` (`promptTokens`, `completionTokens`) and
198
+ `costUsd` (a number, US dollars), a flow's agent steps included. For one
199
+ customer's spend, see below.
200
+ - **When a run finished:** the `run.finished` webhook (the run's id, its
201
+ outcome and its cost in `data.run.usage`; no output, so then `runs.get`),
202
+ not polling.
203
+
204
+ **One customer's spend:** give each customer an org, and start their runs in a
205
+ project of that org. Then one call sums their month:
206
+
207
+ ```ts
208
+ import type { Timestamp } from '@kindgi/sdk/types';
209
+
210
+ // Once per customer. Project slugs are unique across the tenant: put the customer in them.
211
+ const org = await kindgi.orgs.create({ slug: 'acme-customer-one', name: 'Customer one' });
212
+ const project = await kindgi.projects.create({ orgId: org.id, slug: 'acme-customer-one-app', name: 'App' });
213
+ // save org.id and project.id on the customer's row; start their runs with projectId: project.id
214
+
215
+ const now = new Date();
216
+ const month = await kindgi.cost.usage.summary({
217
+ scope: { kind: 'org', orgId: org.id },
218
+ from: new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), 1)).toISOString() as Timestamp,
219
+ to: now.toISOString() as Timestamp, // exclusive
220
+ groupBy: ['month'],
221
+ });
222
+ // month.totalUsd; month.groups[i].key ({ month: '2026-10' }), .totalUsd, .tokens
223
+ ```
224
+
225
+ Docs: https://docs.kindgi.com/v0.1/guides/observability/cost-per-run/
194
226
 
195
227
  Show it in the app's own UI. **Never:**
196
228
 
@@ -103,6 +103,10 @@ def verify_citation(citation: Citation, ctx: ToolContext) -> Verdict:
103
103
  - `ctx.run_id` — the run (an agent turn or a flow step) the call belongs to.
104
104
  - `ctx.request_id` — this call, e.g. the model's tool-call id; useful
105
105
  for logs and idempotency keys.
106
+ - `ctx.project_id`, `ctx.org_id` — the run's project, and that project's
107
+ org (`None` when it has none). The runtime sets them from the run, never
108
+ from the input: to check an org or project id the input names, compare
109
+ it with these instead of trusting it.
106
110
  - `ctx.cancellation` — fires when the call's deadline passes or the
107
111
  caller disconnects. An `async def` handler is also cancelled at its
108
112
  next `await`. A `def` handler keeps running in its thread: check
@@ -14,7 +14,7 @@ description: >
14
14
  kindgi-python-authoring-agents; models by kindgi-authoring-providers.
15
15
  type: core
16
16
  library: "kindgi (Python)"
17
- version: "0.1.3"
17
+ version: "0.1.5"
18
18
  sdk_version: "0.0.0"
19
19
  pack_languages: [python]
20
20
  sources:
@@ -129,8 +129,16 @@ kindgi secrets set ANTHROPIC_API_KEY --env=local --scope=tenant # no-echo prom
129
129
  kindgi providers register --preset=anthropic
130
130
  ```
131
131
 
132
- It takes over at the next turn. Details and other providers:
133
- `kindgi-authoring-providers`.
132
+ It takes over at the next turn. That registration is in this project's dev
133
+ database only. To have `kindgi dev` register it on every boot, in every
134
+ worktree and after `--reset`, declare it in `pyproject.toml` instead:
135
+
136
+ ```toml
137
+ [[tool.kindgi.providers]]
138
+ preset = "anthropic" # its key, ANTHROPIC_API_KEY, from the env files
139
+ ```
140
+
141
+ Details and other providers: `kindgi-authoring-providers`.
134
142
 
135
143
  `uv run python -m kindgi.pack index --pack-dir .` prints what Kindgi
136
144
  sees (the index); `kindgi dev` reports a broken file with its path and
@@ -198,8 +206,38 @@ then `run.id`). The app reads the rest through the API, server side, with
198
206
  (`GET /v1/provenance/{runId}`). A flow run has none of its own: each agent
199
207
  step's `step.completed` entry in the flow's journal names its turn's run
200
208
  (`entry.payload["output"]["runId"]`).
201
- - **When a run finished:** the `run.finished` webhook (the run's id and
202
- outcome, no output; then `runs.get`), not polling.
209
+ - **What it cost:** `client.cost.records.list(root_run_id=run_id).data`
210
+ (`GET /v1/cost/records?rootRunId={runId}`): one record per model call,
211
+ with its `model`, `usage` (`prompt_tokens`, `completion_tokens`) and
212
+ `cost_usd` (a float, US dollars), a flow's agent steps included. For one
213
+ customer's spend, see below.
214
+ - **When a run finished:** the `run.finished` webhook (the run's id, its
215
+ outcome and its cost in `data.run.usage`; no output, so then `runs.get`),
216
+ not polling.
217
+
218
+ **One customer's spend:** give each customer an org, and start their runs in a
219
+ project of that org. Then one call sums their month:
220
+
221
+ ```python
222
+ from datetime import datetime, timezone
223
+
224
+ # Once per customer. Project slugs are unique across the tenant: put the customer in them.
225
+ org = client.orgs.create(slug="acme-customer-one", name="Customer one")
226
+ project = client.projects.create(org_id=str(org.id), slug="acme-customer-one-app", name="App")
227
+ # save org.id and project.id on the customer's row; start their runs with project_id=project.id
228
+
229
+ now = datetime.now(timezone.utc)
230
+ month = client.cost.aggregate(
231
+ group_by="month",
232
+ scope_kind="org",
233
+ scope_id=str(org.id),
234
+ from_=now.replace(day=1, hour=0, minute=0, second=0, microsecond=0).isoformat(),
235
+ to=now.isoformat(), # exclusive
236
+ )
237
+ # month.total_usd; month.groups[i].key ({"month": "2026-10"}), .total_usd, .tokens
238
+ ```
239
+
240
+ Docs: https://docs.kindgi.com/v0.1/guides/observability/cost-per-run/
203
241
 
204
242
  Show it in the app's own UI. **Never:**
205
243