@kindgi/sdk 0.0.0-bootstrap.0 → 0.1.1
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/LICENSE +201 -0
- package/README.md +187 -1
- package/dist/build.d.ts +10 -0
- package/dist/build.d.ts.map +1 -0
- package/dist/build.js +11 -0
- package/dist/build.js.map +1 -0
- package/dist/client.d.ts +33 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +55 -0
- package/dist/client.js.map +1 -0
- package/dist/define.d.ts +25 -0
- package/dist/define.d.ts.map +1 -0
- package/dist/define.js +37 -0
- package/dist/define.js.map +1 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +19 -0
- package/dist/index.js.map +1 -0
- package/dist/runtime-config.d.ts +53 -0
- package/dist/runtime-config.d.ts.map +1 -0
- package/dist/runtime-config.js +114 -0
- package/dist/runtime-config.js.map +1 -0
- package/dist/types.d.ts +16 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +4 -0
- package/dist/types.js.map +1 -0
- package/dist/webhooks.d.ts +15 -0
- package/dist/webhooks.d.ts.map +1 -0
- package/dist/webhooks.js +16 -0
- package/dist/webhooks.js.map +1 -0
- package/package.json +88 -4
- package/skills/kindgi-authoring-agents/SKILL.md +252 -0
- package/skills/kindgi-authoring-flows/SKILL.md +302 -0
- package/skills/kindgi-authoring-guardrails/SKILL.md +297 -0
- package/skills/kindgi-authoring-mcp-servers/SKILL.md +289 -0
- package/skills/kindgi-authoring-providers/SKILL.md +705 -0
- package/skills/kindgi-authoring-tools/SKILL.md +298 -0
- package/skills/kindgi-framework-feedback/SKILL.md +211 -0
- package/skills/kindgi-getting-started/SKILL.md +189 -0
- package/skills/kindgi-python-authoring-agents/SKILL.md +205 -0
- package/skills/kindgi-python-authoring-flows/SKILL.md +325 -0
- package/skills/kindgi-python-authoring-guardrails/SKILL.md +176 -0
- package/skills/kindgi-python-authoring-tools/SKILL.md +305 -0
- package/skills/kindgi-python-getting-started/SKILL.md +242 -0
- package/src/build.ts +18 -0
- package/src/client.ts +177 -0
- package/src/define.ts +75 -0
- package/src/index.ts +20 -0
- package/src/runtime-config.ts +180 -0
- package/src/types.ts +86 -0
- package/src/webhooks.ts +34 -0
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Where an app's client finds its Kindgi runtime when `createClient` is
|
|
3
|
+
* called without `apiUrl` / `auth`:
|
|
4
|
+
*
|
|
5
|
+
* 1. `KINDGI_API_URL` and `KINDGI_API_TOKEN` from the environment;
|
|
6
|
+
* 2. outside production, the running `kindgi dev`, from the nearest
|
|
7
|
+
* `.kindgirc.json` at or above the working directory (it records the
|
|
8
|
+
* runtime's `apiUrl` and the dev `token`), with a one-time warning to
|
|
9
|
+
* put them in the app's env file;
|
|
10
|
+
* 3. otherwise, an error that says what to set.
|
|
11
|
+
*
|
|
12
|
+
* Production (`NODE_ENV` or `KINDGI_ENV` set to `production`) never reads
|
|
13
|
+
* `.kindgirc.json`. Whatever the source, a token that differs from the
|
|
14
|
+
* running `kindgi dev`'s for the same `apiUrl` (the stale token after
|
|
15
|
+
* `kindgi dev --reset`) is warned about once.
|
|
16
|
+
*
|
|
17
|
+
* Node only: the file is read through `process.getBuiltinModule`, never a
|
|
18
|
+
* static `node:` import, so the module stays safe to bundle for browsers,
|
|
19
|
+
* where only explicit options apply.
|
|
20
|
+
*/
|
|
21
|
+
import type { ClientOptions } from '@kindgi/client';
|
|
22
|
+
/** The file `kindgi dev` writes in the pack directory. */
|
|
23
|
+
export declare const DEV_RUNTIME_FILE = ".kindgirc.json";
|
|
24
|
+
/** What a client needs from a running `kindgi dev`. */
|
|
25
|
+
export interface DevRuntime {
|
|
26
|
+
readonly apiUrl: string;
|
|
27
|
+
readonly token: string;
|
|
28
|
+
/** The `.kindgirc.json` it came from. */
|
|
29
|
+
readonly path: string;
|
|
30
|
+
}
|
|
31
|
+
/** Where the lookup runs: the process's own environment by default (tests pass their own). */
|
|
32
|
+
export interface RuntimeConfigContext {
|
|
33
|
+
readonly env: Readonly<Record<string, string | undefined>>;
|
|
34
|
+
/** The directory the `.kindgirc.json` search starts from. */
|
|
35
|
+
readonly cwd: string | undefined;
|
|
36
|
+
readonly warn: (message: string) => void;
|
|
37
|
+
}
|
|
38
|
+
export declare function defaultContext(): RuntimeConfigContext;
|
|
39
|
+
export declare function isProduction(env: RuntimeConfigContext['env']): boolean;
|
|
40
|
+
/**
|
|
41
|
+
* The client options with every missing field resolved (see the module
|
|
42
|
+
* comment). Throws when no `apiUrl` or no token can be found.
|
|
43
|
+
*/
|
|
44
|
+
export declare function resolveClientOptions(options: Partial<ClientOptions>, context?: RuntimeConfigContext): ClientOptions;
|
|
45
|
+
/**
|
|
46
|
+
* The running `kindgi dev`'s `apiUrl` and `token`, from the nearest
|
|
47
|
+
* `.kindgirc.json` at or above `from`; `undefined` when there's none, it
|
|
48
|
+
* can't be read, or the runtime can't read files (a browser).
|
|
49
|
+
*/
|
|
50
|
+
export declare function findDevRuntime(from: string | undefined): DevRuntime | undefined;
|
|
51
|
+
/** Tests only: forget which warnings were printed. */
|
|
52
|
+
export declare function resetWarningsForTests(): void;
|
|
53
|
+
//# sourceMappingURL=runtime-config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime-config.d.ts","sourceRoot":"","sources":["../src/runtime-config.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EAAc,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAEhE,0DAA0D;AAC1D,eAAO,MAAM,gBAAgB,mBAAmB,CAAC;AAEjD,uDAAuD;AACvD,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,yCAAyC;IACzC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,8FAA8F;AAC9F,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,GAAG,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC;IAC3D,6DAA6D;IAC7D,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,QAAQ,CAAC,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CAC1C;AAYD,wBAAgB,cAAc,IAAI,oBAAoB,CAOrD;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,oBAAoB,CAAC,KAAK,CAAC,GAAG,OAAO,CAEtE;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,OAAO,CAAC,aAAa,CAAC,EAC/B,OAAO,GAAE,oBAAuC,GAC/C,aAAa,CAqDf;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,UAAU,GAAG,SAAS,CAU/E;AA+BD,sDAAsD;AACtD,wBAAgB,qBAAqB,IAAI,IAAI,CAE5C"}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
// Copyright (C) 2026 Kindgi Inc.
|
|
3
|
+
/** The file `kindgi dev` writes in the pack directory. */
|
|
4
|
+
export const DEV_RUNTIME_FILE = '.kindgirc.json';
|
|
5
|
+
const ENV_FILE_HINT = 'your env file (.env / .env.local)';
|
|
6
|
+
const warned = new Set();
|
|
7
|
+
function warnOnce(context, key, message) {
|
|
8
|
+
if (warned.has(key))
|
|
9
|
+
return;
|
|
10
|
+
warned.add(key);
|
|
11
|
+
context.warn(`[kindgi] ${message}`);
|
|
12
|
+
}
|
|
13
|
+
export function defaultContext() {
|
|
14
|
+
const proc = typeof process === 'undefined' ? undefined : process;
|
|
15
|
+
return {
|
|
16
|
+
env: proc?.env ?? {},
|
|
17
|
+
cwd: typeof proc?.cwd === 'function' ? proc.cwd() : undefined,
|
|
18
|
+
warn: (message) => console.warn(message),
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
export function isProduction(env) {
|
|
22
|
+
return env.NODE_ENV === 'production' || env.KINDGI_ENV === 'production';
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* The client options with every missing field resolved (see the module
|
|
26
|
+
* comment). Throws when no `apiUrl` or no token can be found.
|
|
27
|
+
*/
|
|
28
|
+
export function resolveClientOptions(options, context = defaultContext()) {
|
|
29
|
+
const { env } = context;
|
|
30
|
+
const dev = isProduction(env) ? undefined : findDevRuntime(context.cwd);
|
|
31
|
+
let apiUrl = options.apiUrl ?? nonEmpty(env.KINDGI_API_URL);
|
|
32
|
+
let auth = options.auth ??
|
|
33
|
+
(nonEmpty(env.KINDGI_API_TOKEN) !== undefined
|
|
34
|
+
? { kind: 'apiToken', token: env.KINDGI_API_TOKEN }
|
|
35
|
+
: undefined);
|
|
36
|
+
if ((apiUrl === undefined || auth === undefined) && dev !== undefined) {
|
|
37
|
+
const used = [];
|
|
38
|
+
if (apiUrl === undefined) {
|
|
39
|
+
apiUrl = dev.apiUrl;
|
|
40
|
+
used.push('KINDGI_API_URL');
|
|
41
|
+
}
|
|
42
|
+
if (auth === undefined) {
|
|
43
|
+
auth = { kind: 'apiToken', token: dev.token };
|
|
44
|
+
used.push('KINDGI_API_TOKEN');
|
|
45
|
+
}
|
|
46
|
+
warnOnce(context, `fallback:${dev.path}`, `Using the running kindgi dev from ${dev.path} for ${used.join(' and ')}. Set them in ${ENV_FILE_HINT}, and in production, where there's no ${DEV_RUNTIME_FILE}.`);
|
|
47
|
+
}
|
|
48
|
+
if (apiUrl === undefined || auth === undefined) {
|
|
49
|
+
const missing = [
|
|
50
|
+
...(apiUrl === undefined ? ['KINDGI_API_URL'] : []),
|
|
51
|
+
...(auth === undefined ? ['KINDGI_API_TOKEN'] : []),
|
|
52
|
+
];
|
|
53
|
+
throw new Error(`createClient(): ${missing.join(' and ')} ${missing.length === 1 ? "isn't" : "aren't"} set. Set ${missing.length === 1 ? 'it' : 'them'} in ${ENV_FILE_HINT}, or pass { apiUrl, auth }.${isProduction(env)
|
|
54
|
+
? ''
|
|
55
|
+
: ` In development, run \`kindgi dev\` in the app: it writes them to ${DEV_RUNTIME_FILE}, which the client reads.`}`);
|
|
56
|
+
}
|
|
57
|
+
if (dev !== undefined && auth.kind === 'apiToken' && auth.token !== dev.token) {
|
|
58
|
+
if (sameUrl(apiUrl, dev.apiUrl)) {
|
|
59
|
+
warnOnce(context, `stale:${dev.path}:${dev.token}`, `The API token doesn't match the running kindgi dev's (${dev.path}). After \`kindgi dev --reset\` the token changes: copy the new one into ${ENV_FILE_HINT}.`);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return { ...options, apiUrl, auth };
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* The running `kindgi dev`'s `apiUrl` and `token`, from the nearest
|
|
66
|
+
* `.kindgirc.json` at or above `from`; `undefined` when there's none, it
|
|
67
|
+
* can't be read, or the runtime can't read files (a browser).
|
|
68
|
+
*/
|
|
69
|
+
export function findDevRuntime(from) {
|
|
70
|
+
if (from === undefined)
|
|
71
|
+
return undefined;
|
|
72
|
+
const fs = builtin('node:fs');
|
|
73
|
+
const path = builtin('node:path');
|
|
74
|
+
if (fs === undefined || path === undefined)
|
|
75
|
+
return undefined;
|
|
76
|
+
for (let dir = from;; dir = path.dirname(dir)) {
|
|
77
|
+
const candidate = path.join(dir, DEV_RUNTIME_FILE);
|
|
78
|
+
if (fs.existsSync(candidate))
|
|
79
|
+
return readDevRuntime(fs, candidate);
|
|
80
|
+
if (path.dirname(dir) === dir)
|
|
81
|
+
return undefined;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
function readDevRuntime(fs, file) {
|
|
85
|
+
try {
|
|
86
|
+
const parsed = JSON.parse(fs.readFileSync(file, 'utf8'));
|
|
87
|
+
const apiUrl = parsed.apiUrl;
|
|
88
|
+
const token = parsed.token;
|
|
89
|
+
if (typeof apiUrl !== 'string' || apiUrl === '' || typeof token !== 'string' || token === '') {
|
|
90
|
+
return undefined;
|
|
91
|
+
}
|
|
92
|
+
return { apiUrl, token, path: file };
|
|
93
|
+
}
|
|
94
|
+
catch {
|
|
95
|
+
return undefined;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
function builtin(id) {
|
|
99
|
+
const proc = typeof process === 'undefined' ? undefined : process;
|
|
100
|
+
const get = proc
|
|
101
|
+
?.getBuiltinModule;
|
|
102
|
+
return typeof get === 'function' ? get.call(proc, id) : undefined;
|
|
103
|
+
}
|
|
104
|
+
function nonEmpty(value) {
|
|
105
|
+
return value === undefined || value === '' ? undefined : value;
|
|
106
|
+
}
|
|
107
|
+
function sameUrl(a, b) {
|
|
108
|
+
return a.replace(/\/+$/, '') === b.replace(/\/+$/, '');
|
|
109
|
+
}
|
|
110
|
+
/** Tests only: forget which warnings were printed. */
|
|
111
|
+
export function resetWarningsForTests() {
|
|
112
|
+
warned.clear();
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=runtime-config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime-config.js","sourceRoot":"","sources":["../src/runtime-config.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@kindgi/sdk/types` — branded IDs, framework-wide result envelope,
|
|
3
|
+
* pagination, refs, temporal + version primitives.
|
|
4
|
+
*
|
|
5
|
+
* Re-exports types from `@kindgi/types` under their own names. These
|
|
6
|
+
* are the workspace-wide identifiers callers pass across the SDK
|
|
7
|
+
* boundary.
|
|
8
|
+
*
|
|
9
|
+
* The /types sub-path is where branded identifiers live in the public
|
|
10
|
+
* facade.
|
|
11
|
+
*
|
|
12
|
+
* @module @kindgi/sdk/types
|
|
13
|
+
*/
|
|
14
|
+
export type { BlobRef, Brand, ContentHash, Cursor, DatasetRef, DurationMs, ErrOf, Filter, IsoDuration, OkOf, Page, Result, SchemaMajor, Semver, SignatureValue, Timestamp, VersionedRef, } from '@kindgi/types';
|
|
15
|
+
export type { AgentId, ApiTokenId, ApprovalId, ArtifactId, AuditBundleId, ComplianceEvidenceId, ConversationId, DatasetId, EdgeId, EventId, FactId, FixProposalId, FlowId, InstallationId, GuardrailId, KeyId, LogEntryId, NodeId, ObservationId, OrgId, PackId, PolicyId, ProjectId, ProvenanceId, ProviderId, ReviewerId, RunId, ScheduleId, SessionId, SigningKeyId, SubscriptionId, SupervisorId, TeamId, TenantId, ThreadId, ToolId, TriggerId, UserId, WaitTokenId, WebhookDeliveryId, WebhookId, } from '@kindgi/types';
|
|
16
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;GAYG;AAEH,YAAY,EACV,OAAO,EACP,KAAK,EACL,WAAW,EACX,MAAM,EACN,UAAU,EACV,UAAU,EACV,KAAK,EACL,MAAM,EACN,WAAW,EACX,IAAI,EACJ,IAAI,EACJ,MAAM,EACN,WAAW,EACX,MAAM,EACN,cAAc,EACd,SAAS,EACT,YAAY,GACb,MAAM,eAAe,CAAC;AAQvB,YAAY,EACV,OAAO,EACP,UAAU,EACV,UAAU,EACV,UAAU,EACV,aAAa,EACb,oBAAoB,EACpB,cAAc,EACd,SAAS,EACT,MAAM,EACN,OAAO,EACP,MAAM,EACN,aAAa,EACb,MAAM,EACN,cAAc,EACd,WAAW,EACX,KAAK,EACL,UAAU,EACV,MAAM,EACN,aAAa,EACb,KAAK,EACL,MAAM,EACN,QAAQ,EACR,SAAS,EACT,YAAY,EACZ,UAAU,EACV,UAAU,EACV,KAAK,EACL,UAAU,EACV,SAAS,EACT,YAAY,EACZ,cAAc,EACd,YAAY,EACZ,MAAM,EACN,QAAQ,EACR,QAAQ,EACR,MAAM,EACN,SAAS,EACT,MAAM,EACN,WAAW,EACX,iBAAiB,EACjB,SAAS,GACV,MAAM,eAAe,CAAC"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,iCAAiC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@kindgi/sdk/webhooks` — receiving Kindgi's webhooks. Server only: it
|
|
3
|
+
* uses `node:crypto`, so it stays out of `/client` (browser-safe) and the
|
|
4
|
+
* flat barrel.
|
|
5
|
+
*
|
|
6
|
+
* Re-exports the Standard Webhooks helpers from `@kindgi/crypto`:
|
|
7
|
+
* `verifyWebhook` for a receiver, `generateWebhookSecret` for the secret an
|
|
8
|
+
* app registers by name, and `signWebhook` / `webhookHeaders` to test a
|
|
9
|
+
* receiver.
|
|
10
|
+
*
|
|
11
|
+
* @module @kindgi/sdk/webhooks
|
|
12
|
+
*/
|
|
13
|
+
export { DEFAULT_WEBHOOK_TOLERANCE_SECONDS, generateWebhookSecret, isStrongWebhookSecret, signWebhook, verifyWebhook, WEBHOOK_HEADERS, WEBHOOK_SECRET_MIN_BYTES, WEBHOOK_SECRET_PREFIX, webhookHeaders, } from '@kindgi/crypto';
|
|
14
|
+
export type { SignWebhookInput, VerifyWebhookFailure, VerifyWebhookInput, VerifyWebhookResult, WebhookRequestHeaders, } from '@kindgi/crypto';
|
|
15
|
+
//# sourceMappingURL=webhooks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webhooks.d.ts","sourceRoot":"","sources":["../src/webhooks.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;GAWG;AAEH,OAAO,EACL,iCAAiC,EACjC,qBAAqB,EACrB,qBAAqB,EACrB,WAAW,EACX,aAAa,EACb,eAAe,EACf,wBAAwB,EACxB,qBAAqB,EACrB,cAAc,GACf,MAAM,gBAAgB,CAAC;AACxB,YAAY,EACV,gBAAgB,EAChB,oBAAoB,EACpB,kBAAkB,EAClB,mBAAmB,EACnB,qBAAqB,GACtB,MAAM,gBAAgB,CAAC"}
|
package/dist/webhooks.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
// Copyright (C) 2026 Kindgi Inc.
|
|
3
|
+
/**
|
|
4
|
+
* `@kindgi/sdk/webhooks` — receiving Kindgi's webhooks. Server only: it
|
|
5
|
+
* uses `node:crypto`, so it stays out of `/client` (browser-safe) and the
|
|
6
|
+
* flat barrel.
|
|
7
|
+
*
|
|
8
|
+
* Re-exports the Standard Webhooks helpers from `@kindgi/crypto`:
|
|
9
|
+
* `verifyWebhook` for a receiver, `generateWebhookSecret` for the secret an
|
|
10
|
+
* app registers by name, and `signWebhook` / `webhookHeaders` to test a
|
|
11
|
+
* receiver.
|
|
12
|
+
*
|
|
13
|
+
* @module @kindgi/sdk/webhooks
|
|
14
|
+
*/
|
|
15
|
+
export { DEFAULT_WEBHOOK_TOLERANCE_SECONDS, generateWebhookSecret, isStrongWebhookSecret, signWebhook, verifyWebhook, WEBHOOK_HEADERS, WEBHOOK_SECRET_MIN_BYTES, WEBHOOK_SECRET_PREFIX, webhookHeaders, } from '@kindgi/crypto';
|
|
16
|
+
//# sourceMappingURL=webhooks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webhooks.js","sourceRoot":"","sources":["../src/webhooks.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,iCAAiC;AAEjC;;;;;;;;;;;GAWG;AAEH,OAAO,EACL,iCAAiC,EACjC,qBAAqB,EACrB,qBAAqB,EACrB,WAAW,EACX,aAAa,EACb,eAAe,EACf,wBAAwB,EACxB,qBAAqB,EACrB,cAAc,GACf,MAAM,gBAAgB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,91 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kindgi/sdk",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.1.1",
|
|
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
|
-
"repository": {
|
|
7
|
-
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/kindgi/kindgi-sdk.git",
|
|
9
|
+
"directory": "packages/sdk"
|
|
10
|
+
},
|
|
11
|
+
"homepage": "https://github.com/kindgi/kindgi-sdk/tree/main/packages/sdk#readme",
|
|
12
|
+
"bugs": {
|
|
13
|
+
"url": "https://github.com/kindgi/kindgi-sdk/issues"
|
|
14
|
+
},
|
|
15
|
+
"type": "module",
|
|
16
|
+
"main": "./dist/index.js",
|
|
17
|
+
"types": "./dist/index.d.ts",
|
|
18
|
+
"exports": {
|
|
19
|
+
"./define": {
|
|
20
|
+
"types": "./dist/define.d.ts",
|
|
21
|
+
"import": "./dist/define.js"
|
|
22
|
+
},
|
|
23
|
+
"./client": {
|
|
24
|
+
"types": "./dist/client.d.ts",
|
|
25
|
+
"import": "./dist/client.js"
|
|
26
|
+
},
|
|
27
|
+
"./types": {
|
|
28
|
+
"types": "./dist/types.d.ts",
|
|
29
|
+
"import": "./dist/types.js"
|
|
30
|
+
},
|
|
31
|
+
"./webhooks": {
|
|
32
|
+
"types": "./dist/webhooks.d.ts",
|
|
33
|
+
"import": "./dist/webhooks.js"
|
|
34
|
+
},
|
|
35
|
+
"./build": {
|
|
36
|
+
"types": "./dist/build.d.ts",
|
|
37
|
+
"import": "./dist/build.js"
|
|
38
|
+
},
|
|
39
|
+
".": {
|
|
40
|
+
"types": "./dist/index.d.ts",
|
|
41
|
+
"import": "./dist/index.js"
|
|
42
|
+
},
|
|
43
|
+
"./package.json": "./package.json"
|
|
44
|
+
},
|
|
45
|
+
"files": [
|
|
46
|
+
"dist",
|
|
47
|
+
"src",
|
|
48
|
+
"skills",
|
|
49
|
+
"README.md"
|
|
50
|
+
],
|
|
51
|
+
"dependencies": {
|
|
52
|
+
"@kindgi/agents": "0.1.1",
|
|
53
|
+
"@kindgi/client": "0.1.1",
|
|
54
|
+
"@kindgi/crypto": "0.1.1",
|
|
55
|
+
"@kindgi/flow": "0.1.1",
|
|
56
|
+
"@kindgi/guardrails": "0.1.1",
|
|
57
|
+
"@kindgi/handler-runtime": "0.1.1",
|
|
58
|
+
"@kindgi/schema": "0.1.1",
|
|
59
|
+
"@kindgi/tools": "0.1.1",
|
|
60
|
+
"@kindgi/types": "0.1.1"
|
|
61
|
+
},
|
|
62
|
+
"peerDependencies": {
|
|
63
|
+
"zod": "^4.0.0"
|
|
64
|
+
},
|
|
65
|
+
"peerDependenciesMeta": {
|
|
66
|
+
"zod": {
|
|
67
|
+
"optional": true
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
"devDependencies": {
|
|
71
|
+
"@types/node": "^22.10.5",
|
|
72
|
+
"typedoc": "^0.28.20",
|
|
73
|
+
"typedoc-plugin-markdown": "^4.13.1",
|
|
74
|
+
"typescript": "^5.7.3",
|
|
75
|
+
"vitest": "^2.1.8"
|
|
76
|
+
},
|
|
77
|
+
"engines": {
|
|
78
|
+
"node": ">=22.0.0"
|
|
79
|
+
},
|
|
80
|
+
"publishConfig": {
|
|
81
|
+
"access": "public",
|
|
82
|
+
"provenance": true
|
|
83
|
+
},
|
|
84
|
+
"scripts": {
|
|
85
|
+
"build": "tsc -p tsconfig.build.json",
|
|
86
|
+
"typecheck": "tsc --noEmit",
|
|
87
|
+
"test": "vitest run",
|
|
88
|
+
"docs": "typedoc",
|
|
89
|
+
"clean": "rm -rf dist docs *.tsbuildinfo"
|
|
90
|
+
}
|
|
91
|
+
}
|
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: kindgi-authoring-agents
|
|
3
|
+
description: >
|
|
4
|
+
Covers writing agents for a Kindgi pack with @kindgi/sdk:
|
|
5
|
+
defining agents via defineAgent, tool wiring with ToolRef versioning,
|
|
6
|
+
guardrail references, conversation policy, turn budgets, LLM
|
|
7
|
+
capability declarations, and prompt template variables. Load this
|
|
8
|
+
whenever you are authoring or editing code inside a pack's agents/
|
|
9
|
+
directory, defining an agent, or when the user asks to add, modify,
|
|
10
|
+
or refactor an agent. Authoring tools is covered by
|
|
11
|
+
kindgi-authoring-tools; authoring guardrails is covered by
|
|
12
|
+
kindgi-authoring-guardrails.
|
|
13
|
+
type: core
|
|
14
|
+
library: "@kindgi/sdk"
|
|
15
|
+
version: "0.4.2"
|
|
16
|
+
sdk_version: "0.0.0"
|
|
17
|
+
pack_languages: [node]
|
|
18
|
+
sources:
|
|
19
|
+
- packages/agents/src/types.ts
|
|
20
|
+
- packages/agents/src/define.ts
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
# Authoring Kindgi agents
|
|
24
|
+
|
|
25
|
+
> **Running `kindgi`:** the CLI is a devDependency of the project (`@kindgi/cli`),
|
|
26
|
+
> not a global command. Run it through the project's package manager —
|
|
27
|
+
> `pnpm exec kindgi …`, `npx --no kindgi …` (npm), `yarn kindgi …` or
|
|
28
|
+
> `bun run kindgi …`. Commands below are written `kindgi …` for brevity.
|
|
29
|
+
|
|
30
|
+
An **agent** is a versioned LLM-powered orchestrator: instructions (a
|
|
31
|
+
prompt template), a declared set of tools it can call, capability
|
|
32
|
+
declarations for the LLM provider, guardrails that gate its outputs,
|
|
33
|
+
and optional multi-turn conversation policy. Agents live at
|
|
34
|
+
`agents/<name>/index.ts` inside a pack.
|
|
35
|
+
|
|
36
|
+
## Ask before building
|
|
37
|
+
|
|
38
|
+
Requests like "add an agent" / "create an agent" / "I need an agent"
|
|
39
|
+
are conversation openers, not tickets. Before writing any file, ask:
|
|
40
|
+
|
|
41
|
+
- **What should the agent DO?** The purpose is the load-bearing thing.
|
|
42
|
+
Everything else derives from it.
|
|
43
|
+
- **Which tools does it need?** New tools, or reuses of existing?
|
|
44
|
+
- **Multi-turn or one-shot?** Conversation history changes the shape.
|
|
45
|
+
- **Any specific guardrails?** Safety rules the agent must respect.
|
|
46
|
+
|
|
47
|
+
The pack's existing agents are examples that prove the framework runs
|
|
48
|
+
end-to-end. They are NOT the shape you imitate unless the user
|
|
49
|
+
explicitly asks for that. Inferring purpose from surrounding pack
|
|
50
|
+
shape is how confident, wrong code gets shipped.
|
|
51
|
+
|
|
52
|
+
## Minimal agent
|
|
53
|
+
|
|
54
|
+
```ts
|
|
55
|
+
// agents/brief-writer/index.ts
|
|
56
|
+
import { defineAgent } from '@kindgi/sdk/define';
|
|
57
|
+
import type { AgentId, Semver } from '@kindgi/sdk/types';
|
|
58
|
+
|
|
59
|
+
const defined = defineAgent({
|
|
60
|
+
id: 'acme.brief-writer' as AgentId,
|
|
61
|
+
version: '0.1.0' as Semver,
|
|
62
|
+
name: 'Brief Writer',
|
|
63
|
+
description:
|
|
64
|
+
'Drafts appellate briefs from a case file. Cites precedents; escalates novel legal questions.',
|
|
65
|
+
instructions:
|
|
66
|
+
'You are drafting a brief in {{ jurisdiction }}. The user provides the case facts; you produce a Section IV argument citing at least two precedents. Use `acme.verify-citation` on every cite before including it. Refuse to fabricate citations — always call the tool.',
|
|
67
|
+
capabilities: [{ needs: [{ feature: 'tool-use' as const }] }],
|
|
68
|
+
tools: [
|
|
69
|
+
{ id: 'acme.verify-citation', version: '^0.1.0' },
|
|
70
|
+
{ id: 'acme.fetch-precedent', version: '^0.1.0' },
|
|
71
|
+
],
|
|
72
|
+
retrieval: [],
|
|
73
|
+
guardrails: ['acme.no-fabricated-quotes'],
|
|
74
|
+
parameters: [
|
|
75
|
+
{ name: 'jurisdiction', type: 'string', required: true },
|
|
76
|
+
],
|
|
77
|
+
conversationPolicy: { historyLimit: 20 },
|
|
78
|
+
budget: { maxSteps: 8, maxCostUsd: 0.5, maxWallMs: 60_000 },
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
if (defined.kind === 'err') {
|
|
82
|
+
throw new Error(`acme.brief-writer failed to compile: ${defined.error.message}`);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export default defined.value;
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## Field-by-field
|
|
89
|
+
|
|
90
|
+
- **`id`** — `<pack-id>.<agent-name>` (kebab-case, dot-namespaced).
|
|
91
|
+
Enforced.
|
|
92
|
+
- **`version`** — Semver. Runs pin to a specific version; upgrading
|
|
93
|
+
the agent doesn't retroactively rewrite in-flight conversations.
|
|
94
|
+
- **`instructions`** — LiquidJS template. `{{ variable }}` substitutes
|
|
95
|
+
from `parameters` or framework auto-vars (`today`, `now`, `agent.*`,
|
|
96
|
+
`conversation.*`). Rendered with `strictVariables: true` — unresolved
|
|
97
|
+
references fail loudly at invoke time. Frame instructions like a
|
|
98
|
+
competent employee brief: what the agent does, what tools to prefer,
|
|
99
|
+
what to refuse, what quality bar to hit.
|
|
100
|
+
- **`capabilities`** — declares the resource kinds the agent needs at
|
|
101
|
+
runtime. `{feature: 'tool-use'}` is standard for tool-calling
|
|
102
|
+
agents. The router picks the concrete LLM provider at turn time.
|
|
103
|
+
- **`tools`** — `readonly ToolRef[]`, NOT `string[]`. Each entry is
|
|
104
|
+
`{id, version}` where `version` is an npm-style semver **range**
|
|
105
|
+
(`'^0.1.0'`, `'~1.2.3'`, `'>=1.0.0 <2.0.0'`). Empty array = chat-only
|
|
106
|
+
agent.
|
|
107
|
+
- **`guardrails`** — array of guardrail `id` strings. Resolved at turn
|
|
108
|
+
start against the guardrails bound for the run (the tenant's
|
|
109
|
+
registered guardrails). If a guardrail id isn't registered, the turn
|
|
110
|
+
fails with `unresolved-guardrail`. Guardrails are evaluated once per
|
|
111
|
+
turn, on the final response before it is stored — a blocking
|
|
112
|
+
(`halt`) violation fails the turn and the response is never written
|
|
113
|
+
to the conversation.
|
|
114
|
+
- **`parameters`** — typed inputs the caller supplies at invoke time.
|
|
115
|
+
UI builds a "configure agent" form from these; runtime validates
|
|
116
|
+
each required parameter is provided.
|
|
117
|
+
- **`preferredProvider`** — optional soft hint. When set to a
|
|
118
|
+
`ProviderMetadata.id` (e.g. `'anthropic'`, `'groq'`), the router
|
|
119
|
+
prefers that provider when at least one of its models satisfies the
|
|
120
|
+
agent's `capabilities.needs` + tenant policy. Falls back to normal
|
|
121
|
+
capability-based selection when the preferred provider is
|
|
122
|
+
unregistered or filtered out.
|
|
123
|
+
- **`preferredModel`** — optional soft hint at the model level: set to
|
|
124
|
+
a `ModelInfo.name` (e.g. `'gemini-2.5-pro'`), the router prefers
|
|
125
|
+
`(provider, model)` tuples whose model matches. To require a model
|
|
126
|
+
rather than prefer it, add a hard requirement to the capability:
|
|
127
|
+
`capabilities: [{ needs: [{ feature: 'tool-use' }, { models: { allow: ['gemini-2.5-pro'] } }] }]`.
|
|
128
|
+
- **`conversationPolicy`** — optional. Absent = each turn loads the
|
|
129
|
+
conversation's full history and no HITL gates apply. `historyLimit`
|
|
130
|
+
caps how many prior messages are loaded; `hitl` configures approval
|
|
131
|
+
gates (a turn-count gate and per-tool gates). A tenant's `hitl`
|
|
132
|
+
policy can tighten these — a shorter approval timeout, a higher
|
|
133
|
+
reviewer role, a stricter gate for a tool — never loosen them.
|
|
134
|
+
- **`budget`** — per-turn ceiling. `maxSteps` caps model-call cycles
|
|
135
|
+
(default 8); `maxCostUsd` caps model spend; `maxWallMs` caps wall
|
|
136
|
+
time (default 120 000). Exceeding steps or cost fails the turn with
|
|
137
|
+
`budget-exceeded`; running out of wall time aborts it
|
|
138
|
+
(`agent-turn-aborted`, reason `timeout`).
|
|
139
|
+
|
|
140
|
+
- **`output`** — optional typed result: `{ schema, name?, maxRepairs? }`
|
|
141
|
+
(JSON Schema, or Zod). The final answer must be JSON matching
|
|
142
|
+
`schema` (a fenced JSON block is accepted). An answer that doesn't fit
|
|
143
|
+
goes back to the model with the problems listed, up to `maxRepairs`
|
|
144
|
+
times (default 1); then the turn fails with `output-schema-violation`.
|
|
145
|
+
The parsed answer is the turn result's `output`, and in a flow
|
|
146
|
+
`nodeOutputs.<step>.output.<field>`. A Zod `.default()` field must be
|
|
147
|
+
in the answer: downstream steps read every field.
|
|
148
|
+
- **`toolErrors`** — optional: what the turn does when a tool call
|
|
149
|
+
fails. The failure goes back to the model as the call's result (what
|
|
150
|
+
failed and why) so it can correct the call, up to `maxRetries` times
|
|
151
|
+
per turn (default 1), for the kinds in `retryOn` (default
|
|
152
|
+
`['invalid-arguments', 'unknown-tool']`, failures where nothing ran).
|
|
153
|
+
Add `'tool-error'` to retry a tool that ran and failed — only when
|
|
154
|
+
retrying it is safe (a mutating tool may have changed something before
|
|
155
|
+
failing). Each retry costs a step against `budget.maxSteps`. Past the
|
|
156
|
+
retries the turn fails as before, with `toolRetries` on the error. A
|
|
157
|
+
tenant's `tool-errors` policy can lower these (fewer retries, fewer
|
|
158
|
+
kinds), never raise them.
|
|
159
|
+
|
|
160
|
+
## What a turn receives
|
|
161
|
+
|
|
162
|
+
- **Run directly** (`kindgi runs start --agent=… --input='{…}'`, or
|
|
163
|
+
`POST /v1/runs { agent, input }`), the input is `{ userMessage,
|
|
164
|
+
conversationId?, participantId?, parameters? }`:
|
|
165
|
+
- `userMessage` is the turn's message;
|
|
166
|
+
- `conversationId` continues a conversation;
|
|
167
|
+
- `parameters` fills the agent's `parameters` (string, number or
|
|
168
|
+
boolean values).
|
|
169
|
+
- **As a flow step** (`{ kind: 'agent', ref: 'acme.brief-writer' }`), the
|
|
170
|
+
agent gets the step's input in two ways:
|
|
171
|
+
- as **structured input**, which the instructions read as
|
|
172
|
+
`{{ input.caseFacts }}`;
|
|
173
|
+
- as the user message (the input as JSON).
|
|
174
|
+
|
|
175
|
+
The step's `config.parameters` fills `parameters`, and `config.version`
|
|
176
|
+
pins a version. With a typed `output`, the flow reads the answer at
|
|
177
|
+
`nodeOutputs.<step>.output.<field>`. See `kindgi-authoring-flows`.
|
|
178
|
+
|
|
179
|
+
`{{ input.* }}` is set only in a flow step, so an agent that reads it
|
|
180
|
+
belongs in a flow. Rendering is strict: a direct run of such an agent
|
|
181
|
+
fails when its instructions render.
|
|
182
|
+
|
|
183
|
+
## Iterating on an agent
|
|
184
|
+
|
|
185
|
+
Edit `agents/<name>/index.ts`, save. The next `kindgi runs start`
|
|
186
|
+
sees the change — new instructions, new tool bindings, new
|
|
187
|
+
capabilities, new preferredProvider, new budget. No version bump,
|
|
188
|
+
no restart. Source is truth in dev.
|
|
189
|
+
|
|
190
|
+
The `version` field is a **semver contract for humans reading the
|
|
191
|
+
source** — it declares what conversations pinned to this agent can
|
|
192
|
+
rely on. Bump because you're breaking that contract (removed a
|
|
193
|
+
parameter, tightened the instructions in a user-visible way,
|
|
194
|
+
switched to an incompatible provider policy), not because you saved
|
|
195
|
+
the file. If you're iterating on the prompt, leave version alone.
|
|
196
|
+
|
|
197
|
+
**When version matters:** conversations persist their `agentVersion`
|
|
198
|
+
at start and pin resume-across-turn to that version. `kindgi deploy`
|
|
199
|
+
publishes to a durable production registry that enforces the
|
|
200
|
+
immutable `(id, version)` contract. Both surfaces are deploy-time
|
|
201
|
+
concerns, not author-time.
|
|
202
|
+
|
|
203
|
+
## Common mistakes
|
|
204
|
+
|
|
205
|
+
1. **Adding an agent without asking what it should do.** The most
|
|
206
|
+
common failure mode. "Add an agent" without a stated purpose gets
|
|
207
|
+
answered by imitating the shape of the pack's example agent. Ask
|
|
208
|
+
first.
|
|
209
|
+
|
|
210
|
+
2. **`tools: ['id-string']`** — `tools` is `ToolRef[]`, so TypeScript
|
|
211
|
+
rejects bare strings, and `defineAgent` returns `invalid-agent` for
|
|
212
|
+
one that slips through (plain JavaScript, a cast). Use
|
|
213
|
+
`[{id: 'acme.x', version: '^0.1.0'}]`.
|
|
214
|
+
|
|
215
|
+
3. **Referencing guardrails that aren't registered.** If
|
|
216
|
+
`agent.guardrails` contains an id the tenant has no guardrail for
|
|
217
|
+
(registered via `POST /v1/guardrails`, a deploy, or `kindgi dev`),
|
|
218
|
+
turn setup fails with `unresolved-guardrail`. Either author the
|
|
219
|
+
guardrail first or drop it from the agent's list.
|
|
220
|
+
|
|
221
|
+
4. **Un-declared `{{ variable }}` in instructions.** LiquidJS renders
|
|
222
|
+
with `strictVariables: true` — a reference to `{{ jurisdiction }}`
|
|
223
|
+
that isn't in `parameters` OR an auto-var throws at invoke time.
|
|
224
|
+
Either add it to `parameters` or use a framework auto-var.
|
|
225
|
+
|
|
226
|
+
5. **Empty `capabilities`.** `defineAgent` rejects an empty
|
|
227
|
+
`capabilities` array (`invalid-agent`) — the turn routes its first
|
|
228
|
+
capability to pick a model. Declare
|
|
229
|
+
`[{needs: [{feature: 'tool-use' as const}]}]` (or the matching
|
|
230
|
+
feature set for your use case).
|
|
231
|
+
|
|
232
|
+
6. **Missing `Result` unwrap.** `defineAgent` returns `Result<Agent,
|
|
233
|
+
InvalidAgentError>`. Always check `defined.kind === 'err' && throw`
|
|
234
|
+
so a broken agent fails at module load.
|
|
235
|
+
|
|
236
|
+
## References
|
|
237
|
+
|
|
238
|
+
- Type surface: `hover any @kindgi/sdk/define export` in your editor
|
|
239
|
+
for full JSDoc.
|
|
240
|
+
- API reference: https://docs.kindgi.com/v0.1/reference/typescript/sdk/kindgi/sdk/define/ (every `define*` spec, field by field).
|
|
241
|
+
- Common patterns: the `sample` template's `agents/echo-agent`
|
|
242
|
+
demonstrates the smallest tool-calling shape.
|
|
243
|
+
|
|
244
|
+
## When the framework itself is the problem
|
|
245
|
+
|
|
246
|
+
If you diagnose that the bug lives in Kindgi/`@kindgi/sdk` itself (SDK
|
|
247
|
+
type drift, wire schema silently dropping a field like
|
|
248
|
+
`preferredProvider`, router picking the wrong provider, misleading
|
|
249
|
+
error message, CLI friction) — not in the pack's own code — load the
|
|
250
|
+
`kindgi-framework-feedback` skill and file a structured report with
|
|
251
|
+
`kindgi feedback write`. That diagnostic is high-signal input the
|
|
252
|
+
maintainers can act on; don't let it disappear into the transcript.
|