@kindgi/sdk 0.1.5-rc.0 → 0.1.5
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/dist/client.d.ts +6 -0
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +34 -1
- package/dist/client.js.map +1 -1
- package/package.json +10 -10
- package/skills/kindgi-authoring-agents/SKILL.md +4 -0
- package/skills/kindgi-authoring-tools/SKILL.md +39 -1
- package/skills/kindgi-python-authoring-agents/SKILL.md +4 -0
- package/skills/kindgi-python-authoring-tools/SKILL.md +9 -1
- package/src/client.ts +34 -1
package/dist/client.d.ts
CHANGED
|
@@ -15,6 +15,12 @@ export type { KindgiClient } from '@kindgi/client';
|
|
|
15
15
|
* browser, pass `apiUrl` and `auth`. `@kindgi/client`'s `createClient` is
|
|
16
16
|
* the explicit form underneath.
|
|
17
17
|
*
|
|
18
|
+
* The options are found on first use, not here: a module-scope
|
|
19
|
+
* `const kindgi = createClient()` is safe to import where the runtime's
|
|
20
|
+
* settings aren't set, as a production build (`next build`) imports every
|
|
21
|
+
* module. When they're missing, the first use (`kindgi.runs`, …) throws
|
|
22
|
+
* the error that says what to set; once they're set, the next use works.
|
|
23
|
+
*
|
|
18
24
|
* @example
|
|
19
25
|
* ```ts
|
|
20
26
|
* import { createClient } from '@kindgi/sdk/client';
|
package/dist/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAwBA,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAIlE,YAAY,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEnD
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAwBA,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAIlE,YAAY,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEnD;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,YAAY,CAAC,OAAO,GAAE,OAAO,CAAC,aAAa,CAAM,GAAG,YAAY,CA6B/E;AAGD,YAAY,EACV,qBAAqB,EACrB,aAAa,EACb,gBAAgB,EAChB,cAAc,EACd,kBAAkB,EAClB,YAAY,EACZ,kBAAkB,EAClB,cAAc,EACd,eAAe,EACf,cAAc,EACd,eAAe,EACf,WAAW,EACX,gBAAgB,EAChB,gBAAgB,EAChB,aAAa,EACb,kBAAkB,EAClB,gBAAgB,EAChB,aAAa,EACb,kBAAkB,EAClB,kBAAkB,EAClB,mBAAmB,EACnB,UAAU,EACV,WAAW,EACX,mBAAmB,EACnB,YAAY,EACZ,WAAW,EACX,UAAU,EACV,WAAW,EACX,kBAAkB,EAClB,eAAe,EACf,gBAAgB,EAChB,UAAU,EACV,SAAS,EACT,iBAAiB,EACjB,kBAAkB,EAClB,qBAAqB,EACrB,YAAY,EACZ,aAAa,EACb,iBAAiB,EACjB,kBAAkB,EAClB,UAAU,EACV,UAAU,EACV,WAAW,EACX,UAAU,EACV,aAAa,EACb,cAAc,EACd,gBAAgB,EAChB,oBAAoB,EACpB,mBAAmB,EACnB,iBAAiB,EACjB,eAAe,EACf,gBAAgB,EAChB,qBAAqB,EACrB,cAAc,EACd,eAAe,EACf,kBAAkB,EAClB,cAAc,EACd,cAAc,EACd,cAAc,EACd,cAAc,EACd,eAAe,EACf,qBAAqB,EACrB,GAAG,EACH,UAAU,EACV,eAAe,EACf,cAAc,EACd,aAAa,EACb,oBAAoB,EACpB,mBAAmB,EACnB,gBAAgB,EAChB,eAAe,EACf,WAAW,EACX,YAAY,EACZ,kBAAkB,EAClB,WAAW,EACX,YAAY,EACZ,0BAA0B,EAC1B,UAAU,EACV,iBAAiB,EACjB,WAAW,EACX,SAAS,EACT,gBAAgB,EAChB,WAAW,EACX,iBAAiB,EACjB,UAAU,EACV,WAAW,EACX,cAAc,EACd,qBAAqB,GACtB,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,uBAAuB,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAChG,YAAY,EACV,SAAS,EACT,aAAa,EACb,kBAAkB,EAClB,uBAAuB,EACvB,mBAAmB,EACnB,YAAY,EACZ,aAAa,EACb,4BAA4B,EAC5B,gBAAgB,EAChB,gBAAgB,EAChB,WAAW,EACX,WAAW,GACZ,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AACxD,YAAY,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAG/D,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACpD,YAAY,EACV,gBAAgB,EAChB,oBAAoB,EACpB,wBAAwB,EACxB,yBAAyB,GAC1B,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAC3D,YAAY,EACV,gBAAgB,EAChB,WAAW,EACX,gBAAgB,EAChB,qBAAqB,GACtB,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,YAAY,EACV,mBAAmB,EACnB,oBAAoB,EACpB,gBAAgB,EAChB,sBAAsB,EACtB,uBAAuB,GACxB,MAAM,gBAAgB,CAAC"}
|
package/dist/client.js
CHANGED
|
@@ -36,6 +36,12 @@ import { resolveClientOptions } from './runtime-config.js';
|
|
|
36
36
|
* browser, pass `apiUrl` and `auth`. `@kindgi/client`'s `createClient` is
|
|
37
37
|
* the explicit form underneath.
|
|
38
38
|
*
|
|
39
|
+
* The options are found on first use, not here: a module-scope
|
|
40
|
+
* `const kindgi = createClient()` is safe to import where the runtime's
|
|
41
|
+
* settings aren't set, as a production build (`next build`) imports every
|
|
42
|
+
* module. When they're missing, the first use (`kindgi.runs`, …) throws
|
|
43
|
+
* the error that says what to set; once they're set, the next use works.
|
|
44
|
+
*
|
|
39
45
|
* @example
|
|
40
46
|
* ```ts
|
|
41
47
|
* import { createClient } from '@kindgi/sdk/client';
|
|
@@ -44,7 +50,34 @@ import { resolveClientOptions } from './runtime-config.js';
|
|
|
44
50
|
* ```
|
|
45
51
|
*/
|
|
46
52
|
export function createClient(options = {}) {
|
|
47
|
-
|
|
53
|
+
let client;
|
|
54
|
+
// A failed lookup isn't kept: the env may be set by the next use.
|
|
55
|
+
const resolved = () => {
|
|
56
|
+
client ??= createKindgiClient(resolveClientOptions(options));
|
|
57
|
+
return client;
|
|
58
|
+
};
|
|
59
|
+
return new Proxy({}, {
|
|
60
|
+
get(_target, key) {
|
|
61
|
+
// Never resolve to answer whether the client is a promise (`await`,
|
|
62
|
+
// `return` from an async function), or for a symbol a tool inspects.
|
|
63
|
+
if (client === undefined && (key === 'then' || typeof key === 'symbol'))
|
|
64
|
+
return undefined;
|
|
65
|
+
return Reflect.get(resolved(), key);
|
|
66
|
+
},
|
|
67
|
+
// A write (a test swapping a resource) is a use: it lands on the client.
|
|
68
|
+
// A property defined non-configurable (`defineProperty`'s default) throws:
|
|
69
|
+
// a proxy can't hold one its target doesn't. Define it `configurable: true`.
|
|
70
|
+
set: (_target, key, value) => Reflect.set(resolved(), key, value),
|
|
71
|
+
defineProperty: (_target, key, descriptor) => Reflect.defineProperty(resolved(), key, descriptor),
|
|
72
|
+
deleteProperty: (_target, key) => Reflect.deleteProperty(resolved(), key),
|
|
73
|
+
has: (_target, key) => key in resolved(),
|
|
74
|
+
ownKeys: () => Reflect.ownKeys(resolved()),
|
|
75
|
+
getOwnPropertyDescriptor(_target, key) {
|
|
76
|
+
const descriptor = Reflect.getOwnPropertyDescriptor(resolved(), key);
|
|
77
|
+
// The target holds none of the client's fields, so none may be reported fixed.
|
|
78
|
+
return descriptor === undefined ? undefined : { ...descriptor, configurable: true };
|
|
79
|
+
},
|
|
80
|
+
});
|
|
48
81
|
}
|
|
49
82
|
// ---- Error surface ----
|
|
50
83
|
export { KindgiApiError, fromWire, notImplementedInPreview, notYetWired } from '@kindgi/client';
|
package/dist/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,iCAAiC;AAEjC;;;;;;;;;;;;;;;;;GAiBG;AAEH,6CAA6C;AAC7C,OAAO,EAAE,YAAY,IAAI,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAGpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAI3D
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,iCAAiC;AAEjC;;;;;;;;;;;;;;;;;GAiBG;AAEH,6CAA6C;AAC7C,OAAO,EAAE,YAAY,IAAI,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAGpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAI3D;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,MAAM,UAAU,YAAY,CAAC,UAAkC,EAAE;IAC/D,IAAI,MAAgC,CAAC;IACrC,kEAAkE;IAClE,MAAM,QAAQ,GAAG,GAAiB,EAAE;QAClC,MAAM,KAAK,kBAAkB,CAAC,oBAAoB,CAAC,OAAO,CAAC,CAAC,CAAC;QAC7D,OAAO,MAAM,CAAC;IAChB,CAAC,CAAC;IACF,OAAO,IAAI,KAAK,CAAC,EAAkB,EAAE;QACnC,GAAG,CAAC,OAAO,EAAE,GAAG;YACd,oEAAoE;YACpE,qEAAqE;YACrE,IAAI,MAAM,KAAK,SAAS,IAAI,CAAC,GAAG,KAAK,MAAM,IAAI,OAAO,GAAG,KAAK,QAAQ,CAAC;gBAAE,OAAO,SAAS,CAAC;YAC1F,OAAO,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE,GAAG,CAAC,CAAC;QACtC,CAAC;QACD,yEAAyE;QACzE,2EAA2E;QAC3E,6EAA6E;QAC7E,GAAG,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE,GAAG,EAAE,KAAK,CAAC;QACjE,cAAc,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,UAAU,EAAE,EAAE,CAC3C,OAAO,CAAC,cAAc,CAAC,QAAQ,EAAE,EAAE,GAAG,EAAE,UAAU,CAAC;QACrD,cAAc,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,EAAE,CAAC,OAAO,CAAC,cAAc,CAAC,QAAQ,EAAE,EAAE,GAAG,CAAC;QACzE,GAAG,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,EAAE,CAAC,GAAG,IAAI,QAAQ,EAAE;QACxC,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC;QAC1C,wBAAwB,CAAC,OAAO,EAAE,GAAG;YACnC,MAAM,UAAU,GAAG,OAAO,CAAC,wBAAwB,CAAC,QAAQ,EAAE,EAAE,GAAG,CAAC,CAAC;YACrE,+EAA+E;YAC/E,OAAO,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,GAAG,UAAU,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC;QACtF,CAAC;KACF,CAAC,CAAC;AACL,CAAC;AA8FD,0BAA0B;AAC1B,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,uBAAuB,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAgBhG,oDAAoD;AACpD,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAGxD,sDAAsD;AACtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAQpD,qFAAqF;AACrF,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAQ3D,+EAA+E;AAC/E,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kindgi/sdk",
|
|
3
|
-
"version": "0.1.5
|
|
3
|
+
"version": "0.1.5",
|
|
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.5
|
|
59
|
-
"@kindgi/client": "0.1.5
|
|
60
|
-
"@kindgi/crypto": "0.1.5
|
|
61
|
-
"@kindgi/flow": "0.1.5
|
|
62
|
-
"@kindgi/guardrails": "0.1.5
|
|
63
|
-
"@kindgi/handler-runtime": "0.1.5
|
|
64
|
-
"@kindgi/schema": "0.1.5
|
|
65
|
-
"@kindgi/tools": "0.1.5
|
|
66
|
-
"@kindgi/types": "0.1.5
|
|
58
|
+
"@kindgi/agents": "0.1.5",
|
|
59
|
+
"@kindgi/client": "0.1.5",
|
|
60
|
+
"@kindgi/crypto": "0.1.5",
|
|
61
|
+
"@kindgi/flow": "0.1.5",
|
|
62
|
+
"@kindgi/guardrails": "0.1.5",
|
|
63
|
+
"@kindgi/handler-runtime": "0.1.5",
|
|
64
|
+
"@kindgi/schema": "0.1.5",
|
|
65
|
+
"@kindgi/tools": "0.1.5",
|
|
66
|
+
"@kindgi/types": "0.1.5"
|
|
67
67
|
},
|
|
68
68
|
"peerDependencies": {
|
|
69
69
|
"zod": "^4.0.0"
|
|
@@ -174,6 +174,10 @@ export default defined.value;
|
|
|
174
174
|
own words only, unless `roles: ['user', 'agent']` (its own earlier
|
|
175
175
|
answers come back marked unverified). `same-segment`/`same-project`
|
|
176
176
|
recall other people's conversations, and publishing warns.
|
|
177
|
+
`same-user` memory (facts, recall or `remember`) is the run's end user's:
|
|
178
|
+
pass `participantId` on every run. A run without one reads and keeps
|
|
179
|
+
none (its result warns `memory-needs-participant`), never the memory of
|
|
180
|
+
the user a key acts for, who may serve many people.
|
|
177
181
|
- **`memory`** — `{ remember: { types, scope, keepDays? } }` gives the
|
|
178
182
|
turn the built-in tool `kindgi_remember` (name it exactly so in the
|
|
179
183
|
instructions; built-ins have no dots). The model picks the type, the
|
|
@@ -12,7 +12,7 @@ description: >
|
|
|
12
12
|
authoring agents is covered by kindgi-authoring-agents.
|
|
13
13
|
type: core
|
|
14
14
|
library: "@kindgi/sdk"
|
|
15
|
-
version: "0.4.
|
|
15
|
+
version: "0.4.5"
|
|
16
16
|
sdk_version: "0.0.0"
|
|
17
17
|
pack_languages: [node]
|
|
18
18
|
sources:
|
|
@@ -115,6 +115,16 @@ The handler gets the **parsed** input, typed `z.infer` of `input` (Zod's output
|
|
|
115
115
|
|
|
116
116
|
The output side is the reverse: the advertised output schema requires every field, defaulted ones included. Return them all.
|
|
117
117
|
|
|
118
|
+
### Logging from the handler
|
|
119
|
+
|
|
120
|
+
`ctx.log` is a logger bound to the call: its records carry the run's ids, the tool's id and the trace id. It has `info`, `warn`, `error`, `debug` and `trace`, each `(message, fields?)`. The pack service sets it; a context your own code builds (a test's) may not, so write `ctx.log?.`:
|
|
121
|
+
|
|
122
|
+
```ts
|
|
123
|
+
ctx.log?.info('refund issued', { orderId, amountCents });
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
Put values in `fields`, never in the message. Log ids, amounts and outcomes, never what a person typed (a refund's reason, a message, an address): the log is read by whoever operates the runtime, not only by the person the data is about. Docs: https://docs.kindgi.com/v0.1/guides/tools/write-a-tool/#log-from-a-tool
|
|
127
|
+
|
|
118
128
|
### Configuration and secrets
|
|
119
129
|
|
|
120
130
|
A secret that belongs to the tenant — an API key a customer gives you — is declared, and read from `ctx.secrets`:
|
|
@@ -202,6 +212,15 @@ export default defined.value;
|
|
|
202
212
|
|
|
203
213
|
So declare `mutating: false` on every tool that only reads, and never on one that writes.
|
|
204
214
|
|
|
215
|
+
A tool that writes also says what it writes, in `effects`, beside `mutating: true`:
|
|
216
|
+
|
|
217
|
+
```ts
|
|
218
|
+
effects: [{ kind: 'writes', resource: 'acme:refunds' }],
|
|
219
|
+
mutating: true,
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
The kinds are `reads`, `writes`, `deletes`, `network`, `spawns-run`, `emits-event`, `external-side-effect` and `sensitive-data-egress` (`EFFECT_KINDS` in `@kindgi/tools`); `defineTool` refuses any other. `resource` is free text naming what the tool touches. A read-only tool keeps `effects: []`.
|
|
223
|
+
|
|
205
224
|
## Tool id convention
|
|
206
225
|
|
|
207
226
|
`<pack-id>.<tool-name>` — kebab-case, dot-namespaced. The `<pack-id>`
|
|
@@ -236,6 +255,25 @@ range at run start. Compatible tool updates (patch, minor) reach the
|
|
|
236
255
|
agent without editing agent source; breaking updates (major) require
|
|
237
256
|
the agent-author to opt in.
|
|
238
257
|
|
|
258
|
+
## Testing a tool
|
|
259
|
+
|
|
260
|
+
Put a tool's tests beside it, `tools/<tool>/index.test.ts`. Discovery skips `*.test.*` and `*.spec.*` files (`.ts`, `.js`, `.mjs`, `.cjs`), so the indexer never loads a test as a primitive: don't move tests elsewhere to keep them out. `invokeTool(tool, input, ctx)` from `@kindgi/sdk/define` calls the tool the way Kindgi does, schemas included, and returns a `Result`. Its `ctx` needs a `tenantId` and an `abortSignal` (`ToolContext` in `@kindgi/tools`); the rest is optional. vitest doesn't typecheck, so a context missing them still passes the test: run `tsc --noEmit` too.
|
|
261
|
+
|
|
262
|
+
```ts
|
|
263
|
+
import { invokeTool } from '@kindgi/sdk/define';
|
|
264
|
+
import type { TenantId } from '@kindgi/sdk/types';
|
|
265
|
+
|
|
266
|
+
const ctx = { tenantId: 'test' as TenantId, abortSignal: new AbortController().signal };
|
|
267
|
+
// add `env: { STORE_URL: '…' }` for a tool that reads a declared env value
|
|
268
|
+
const result = await invokeTool(lookupOrder, { orderId: 'ord_1001' }, ctx);
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
`kindgi test` runs the pack's tests with vitest (`vitest run`; `--watch` keeps watching).
|
|
272
|
+
|
|
273
|
+
## Shared code
|
|
274
|
+
|
|
275
|
+
Code several tools share (schemas, a client, helpers) goes outside `tools/`, for example in `lib/` beside it. Discovery loads every `.ts`, `.js` and `.mjs` file under `tools/` (tests aside) as a primitive, so a helper there fails the index. Don't put it in the app's own source either: import the app's functions from where they are, and keep what's Kindgi's in the pack's folder.
|
|
276
|
+
|
|
239
277
|
## Wiring the tool onto an agent
|
|
240
278
|
|
|
241
279
|
Agents reference tools via `ToolRef[]`, NOT `string[]`. Each entry is
|
|
@@ -169,6 +169,10 @@ brief_writer = Agent(
|
|
|
169
169
|
fails the turn (`semantic-unavailable`). `{"source": "conversations",
|
|
170
170
|
"scope": "same-user"}` recalls this agent's earlier conversations: the
|
|
171
171
|
people's own words only, unless `"roles": ["user", "agent"]`.
|
|
172
|
+
`same-user` memory (facts, recall or `remember`) is the run's end user's:
|
|
173
|
+
pass `participantId` on every run. A run without one reads and keeps
|
|
174
|
+
none (its result warns `memory-needs-participant`), never the memory of
|
|
175
|
+
the user a key acts for, who may serve many people.
|
|
172
176
|
- **`memory`** — `{"remember": {"types": ["acme.preference"], "scope":
|
|
173
177
|
"same-user", "keepDays": 30}}` gives the turn the built-in tool
|
|
174
178
|
`kindgi_remember` (name it exactly so in the instructions). The model
|
|
@@ -14,7 +14,7 @@ description: >
|
|
|
14
14
|
kindgi-python-getting-started.
|
|
15
15
|
type: core
|
|
16
16
|
library: "kindgi (Python)"
|
|
17
|
-
version: "0.1.
|
|
17
|
+
version: "0.1.3"
|
|
18
18
|
sdk_version: "0.0.0"
|
|
19
19
|
pack_languages: [python]
|
|
20
20
|
sources:
|
|
@@ -121,6 +121,14 @@ def verify_citation(citation: Citation, ctx: ToolContext) -> Verdict:
|
|
|
121
121
|
(`kindgi env set NAME <value> --scope=project:<id> --env=<env>`).
|
|
122
122
|
Strings, and not secret. Empty from an older runtime.
|
|
123
123
|
- `ctx.config` — **reserved, empty today**.
|
|
124
|
+
- `ctx.log` — a logger bound to the call (its records carry the run's ids,
|
|
125
|
+
the tool's id and the trace id): `ctx.log.info("refund issued",
|
|
126
|
+
{"orderId": order_id, "amountCents": amount_cents})`, or the fields as
|
|
127
|
+
keywords. Values go in the fields, never in the message. Log ids,
|
|
128
|
+
amounts and outcomes, never what a person typed (a refund's reason, a
|
|
129
|
+
message, an address): the log is read by whoever operates the runtime.
|
|
130
|
+
`ToolContext.for_test(…)` logs nothing unless you pass it `log=`. Docs:
|
|
131
|
+
https://docs.kindgi.com/v0.1/guides/tools/write-a-tool/#log-from-a-tool
|
|
124
132
|
|
|
125
133
|
## Configuration and secrets
|
|
126
134
|
|
package/src/client.ts
CHANGED
|
@@ -43,6 +43,12 @@ export type { KindgiClient } from '@kindgi/client';
|
|
|
43
43
|
* browser, pass `apiUrl` and `auth`. `@kindgi/client`'s `createClient` is
|
|
44
44
|
* the explicit form underneath.
|
|
45
45
|
*
|
|
46
|
+
* The options are found on first use, not here: a module-scope
|
|
47
|
+
* `const kindgi = createClient()` is safe to import where the runtime's
|
|
48
|
+
* settings aren't set, as a production build (`next build`) imports every
|
|
49
|
+
* module. When they're missing, the first use (`kindgi.runs`, …) throws
|
|
50
|
+
* the error that says what to set; once they're set, the next use works.
|
|
51
|
+
*
|
|
46
52
|
* @example
|
|
47
53
|
* ```ts
|
|
48
54
|
* import { createClient } from '@kindgi/sdk/client';
|
|
@@ -51,7 +57,34 @@ export type { KindgiClient } from '@kindgi/client';
|
|
|
51
57
|
* ```
|
|
52
58
|
*/
|
|
53
59
|
export function createClient(options: Partial<ClientOptions> = {}): KindgiClient {
|
|
54
|
-
|
|
60
|
+
let client: KindgiClient | undefined;
|
|
61
|
+
// A failed lookup isn't kept: the env may be set by the next use.
|
|
62
|
+
const resolved = (): KindgiClient => {
|
|
63
|
+
client ??= createKindgiClient(resolveClientOptions(options));
|
|
64
|
+
return client;
|
|
65
|
+
};
|
|
66
|
+
return new Proxy({} as KindgiClient, {
|
|
67
|
+
get(_target, key) {
|
|
68
|
+
// Never resolve to answer whether the client is a promise (`await`,
|
|
69
|
+
// `return` from an async function), or for a symbol a tool inspects.
|
|
70
|
+
if (client === undefined && (key === 'then' || typeof key === 'symbol')) return undefined;
|
|
71
|
+
return Reflect.get(resolved(), key);
|
|
72
|
+
},
|
|
73
|
+
// A write (a test swapping a resource) is a use: it lands on the client.
|
|
74
|
+
// A property defined non-configurable (`defineProperty`'s default) throws:
|
|
75
|
+
// a proxy can't hold one its target doesn't. Define it `configurable: true`.
|
|
76
|
+
set: (_target, key, value) => Reflect.set(resolved(), key, value),
|
|
77
|
+
defineProperty: (_target, key, descriptor) =>
|
|
78
|
+
Reflect.defineProperty(resolved(), key, descriptor),
|
|
79
|
+
deleteProperty: (_target, key) => Reflect.deleteProperty(resolved(), key),
|
|
80
|
+
has: (_target, key) => key in resolved(),
|
|
81
|
+
ownKeys: () => Reflect.ownKeys(resolved()),
|
|
82
|
+
getOwnPropertyDescriptor(_target, key) {
|
|
83
|
+
const descriptor = Reflect.getOwnPropertyDescriptor(resolved(), key);
|
|
84
|
+
// The target holds none of the client's fields, so none may be reported fixed.
|
|
85
|
+
return descriptor === undefined ? undefined : { ...descriptor, configurable: true };
|
|
86
|
+
},
|
|
87
|
+
});
|
|
55
88
|
}
|
|
56
89
|
|
|
57
90
|
// ---- Resource client types + per-resource input shapes ----
|