theokit 0.11.7 → 0.12.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/LICENSE +201 -0
- package/dist/actions-virtual-module-SQDY3V5X.js +0 -0
- package/dist/add-W6FNTAFS.js +0 -0
- package/dist/app-typed-client-QG7BVZYW.js +0 -0
- package/dist/aws-lambda-7GSCNLPY.js +0 -0
- package/dist/broadcast-LUMOJIJT.js +0 -0
- package/dist/build-QFRLSEZ4.js +0 -0
- package/dist/build-request-body-preview-QMWD2IXK.js +0 -0
- package/dist/bun-KP2KES6S.js +0 -0
- package/dist/check-PD2FTKMM.js +0 -0
- package/dist/chunk-3LVRAGAZ.js +0 -0
- package/dist/chunk-43D6XNDR.js +0 -0
- package/dist/chunk-45C3WUQ7.js +0 -0
- package/dist/chunk-5ODOE6EF.js +0 -0
- package/dist/chunk-6FYD34NX.js +0 -0
- package/dist/chunk-7YZHAQU7.js +0 -0
- package/dist/{chunk-GEEMNDPH.js → chunk-AD74EAK3.js} +30 -1
- package/dist/chunk-AD74EAK3.js.map +1 -0
- package/dist/chunk-FOZIR3TG.js +0 -0
- package/dist/chunk-GFMQJHXX.js +0 -0
- package/dist/chunk-HGZL5EOI.js +0 -0
- package/dist/chunk-HNBWZKIQ.js +0 -0
- package/dist/chunk-IEES3CHD.js +0 -0
- package/dist/chunk-JAIKGP3Q.js +0 -0
- package/dist/chunk-JQSFBJR5.js +0 -0
- package/dist/chunk-NAZ4E2GT.js +0 -0
- package/dist/chunk-PBEH6NXR.js +0 -0
- package/dist/chunk-YJAUJXZS.js +0 -0
- package/dist/cloudflare-C6E5SPAE.js +0 -0
- package/dist/configure-agent-registry-ZOBVU3MV.js +0 -0
- package/dist/db-3UNAMSFK.js +0 -0
- package/dist/deno-deploy-RFZN56X4.js +0 -0
- package/dist/dev-GBXOTXUP.js +0 -0
- package/dist/dev-emit-FEFEDLZF.js +0 -0
- package/dist/dispatcher-EJHL6JMJ.js +0 -0
- package/dist/docker-LZZB4D5E.js +0 -0
- package/dist/generate-OMKHQ7OM.js +0 -0
- package/dist/info-OUEUZOT7.js +0 -0
- package/dist/netlify-PMLHVPN4.js +0 -0
- package/dist/node-BPJ3Z4DT.js +0 -0
- package/dist/openapi-VR6AFBLJ.js +0 -0
- package/dist/registry-Q2TZQLUH.js +0 -0
- package/dist/router-TLEAOFID.js +0 -0
- package/dist/routes-LRYOIIAI.js +0 -0
- package/dist/scan-7MJC6PYU.js +0 -0
- package/dist/schema-7CAY6IZR.js +0 -0
- package/dist/server/define/index.js +5 -3
- package/dist/server/index.js +4 -2
- package/dist/server/index.js.map +1 -1
- package/dist/server-error-to-envelope-UUXDSLAZ.js +0 -0
- package/dist/server-routes-hmr-VZXOP5YT.js +0 -0
- package/dist/services-json-Y3XODNB5.js +0 -0
- package/dist/services-typed-client-32KMTTXR.js +0 -0
- package/dist/start-3ZHAXSJE.js +0 -0
- package/dist/static-55G3LX2I.js +0 -0
- package/dist/storage-manager-ZSQFLEYT.js +0 -0
- package/dist/theo-cloud-DQRP6S6M.js +0 -0
- package/dist/upgrade-readiness-ACGW44JC.js +0 -0
- package/dist/vercel-J6G7ZHYQ.js +0 -0
- package/dist/vite-plugin-WO72VLYR.js +0 -0
- package/package.json +12 -8
- package/dist/adapters/web-shim.d.ts +0 -67
- package/dist/adapters/ws-shim.d.ts +0 -55
- package/dist/agent-events-DosDXkSV.d.ts +0 -94
- package/dist/audit-log-BQWM5YLG.d.ts +0 -60
- package/dist/boot/index.d.ts +0 -39
- package/dist/chunk-GEEMNDPH.js.map +0 -1
- package/dist/client/index.d.ts +0 -362
- package/dist/csrf-BBrEZSBW.d.ts +0 -107
- package/dist/csrf-readiness-store-CjIoub3U.d.ts +0 -43
- package/dist/define-websocket-CdK94O-D.d.ts +0 -64
- package/dist/devtools/entry.d.ts +0 -5
- package/dist/error-envelope-BsNzzAV5.d.ts +0 -62
- package/dist/health-route-C0hk64_U.d.ts +0 -57
- package/dist/index-B40qUSrQ.d.ts +0 -575
- package/dist/index.d.ts +0 -361
- package/dist/job-backend-CgC8Xf33.d.ts +0 -68
- package/dist/match-CfbEFRG4.d.ts +0 -26
- package/dist/plugin-runner-BGBkzgi0.d.ts +0 -95
- package/dist/plugin-types-DNJGxr4Z.d.ts +0 -79
- package/dist/rate-limit-BdNDZ3vt.d.ts +0 -58
- package/dist/rate-limit-store-BEJnhWdw.d.ts +0 -72
- package/dist/react-query/index.d.ts +0 -33
- package/dist/schema-BpH6ivDY.d.ts +0 -74
- package/dist/server/agent/index.d.ts +0 -229
- package/dist/server/auth/index.d.ts +0 -419
- package/dist/server/cost/index.d.ts +0 -177
- package/dist/server/cron/index.d.ts +0 -208
- package/dist/server/define/index.d.ts +0 -310
- package/dist/server/http/index.d.ts +0 -11
- package/dist/server/index.d.ts +0 -847
- package/dist/server/jobs/index.d.ts +0 -348
- package/dist/server/observability/index.d.ts +0 -324
- package/dist/server/plugins/index.d.ts +0 -17
- package/dist/server/rate-limit/index.d.ts +0 -105
- package/dist/server/realtime/index.d.ts +0 -15
- package/dist/server/scan/index.d.ts +0 -106
- package/dist/server/security/index.d.ts +0 -193
- package/dist/server/storage/index.d.ts +0 -22
- package/dist/server/webhook/index.d.ts +0 -148
- package/dist/storage-manager-C4jsO0Tp.d.ts +0 -89
- package/dist/storage-types-DsDTCPbp.d.ts +0 -96
- package/dist/vite-plugin/index.d.ts +0 -115
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
import { IncomingMessage } from 'node:http';
|
|
2
|
-
import { R as RateLimitStore } from './rate-limit-store-BEJnhWdw.js';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Rate limit configuration — basic single-bucket shape. Per ADR D2, the
|
|
6
|
-
* per-route + per-user variant is layered on top via T2.2; this base
|
|
7
|
-
* struct is the smallest unit.
|
|
8
|
-
*/
|
|
9
|
-
interface RateLimitConfig {
|
|
10
|
-
windowMs: number;
|
|
11
|
-
max: number;
|
|
12
|
-
}
|
|
13
|
-
interface RateLimitResult {
|
|
14
|
-
limited: boolean;
|
|
15
|
-
headers: Record<string, string>;
|
|
16
|
-
}
|
|
17
|
-
/**
|
|
18
|
-
* Create a rate limiter that consumes a pluggable `RateLimitStore`.
|
|
19
|
-
*
|
|
20
|
-
* Backwards-compatible signature: callers passing only `config` get the
|
|
21
|
-
* default `InMemoryStore`. Distributed deployments pass a Redis adapter
|
|
22
|
-
* (or any other `RateLimitStore` implementation) via `opts.store`.
|
|
23
|
-
*
|
|
24
|
-
* T2.1: synchronous return for back-compat with the current
|
|
25
|
-
* `api-middleware.ts` integration point. The async store contract is
|
|
26
|
-
* exercised lazily — we use a sync fast-path against the in-memory store
|
|
27
|
-
* (single-thread JS makes this safe). External stores remain async and
|
|
28
|
-
* would require a different async wrapper at the middleware layer.
|
|
29
|
-
*/
|
|
30
|
-
declare function createRateLimiter(config: RateLimitConfig, opts?: {
|
|
31
|
-
store?: RateLimitStore;
|
|
32
|
-
}): (req: IncomingMessage) => RateLimitResult;
|
|
33
|
-
/**
|
|
34
|
-
* T5a.2 Phase D slice 2/3 — Web-Standards single-bucket rate limiter.
|
|
35
|
-
*
|
|
36
|
-
* Mirror of `createRateLimiter(config, opts)` returning a checker that
|
|
37
|
-
* accepts `(clientIp: string)` instead of `(req: IncomingMessage)`. Web
|
|
38
|
-
* `Request` has no `req.socket.remoteAddress` — the IP is resolved by
|
|
39
|
-
* the caller per-runtime (Node adapter from socket; CF Workers from
|
|
40
|
-
* `cf-connecting-ip`; etc., same convention as Phase D slice 1/3's
|
|
41
|
-
* `DeriveKeyRequestContext.clientIp`).
|
|
42
|
-
*
|
|
43
|
-
* Same `RateLimitConfig`, same `InMemoryStore` default, same async
|
|
44
|
-
* store rejection (use a dedicated async middleware for external stores).
|
|
45
|
-
* Same `RateLimitResult` return shape.
|
|
46
|
-
*
|
|
47
|
-
* **Signature difference from `createRateLimiter`:** this Web factory's
|
|
48
|
-
* checker takes a raw IP string instead of a Request object. The IP is
|
|
49
|
-
* the ONLY input the bucket needs; passing a Request object would force
|
|
50
|
-
* the caller to populate `request.headers.get('x-forwarded-for')` or
|
|
51
|
-
* similar without giving us any safer extraction. KISS — accept the IP
|
|
52
|
-
* directly, document the per-runtime resolution at the adapter boundary.
|
|
53
|
-
*/
|
|
54
|
-
declare function createRateLimiterWeb(config: RateLimitConfig, opts?: {
|
|
55
|
-
store?: RateLimitStore;
|
|
56
|
-
}): (clientIp: string) => RateLimitResult;
|
|
57
|
-
|
|
58
|
-
export { type RateLimitConfig as R, type RateLimitResult as a, createRateLimiterWeb as b, createRateLimiter as c };
|
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* T2.1 — RateLimitStore interface.
|
|
3
|
-
*
|
|
4
|
-
* Pluggable backend for the rate limiter. The default `InMemoryStore`
|
|
5
|
-
* preserves current single-instance behavior. Multi-instance deployments
|
|
6
|
-
* (TheoCloud canary, K8s replicas) opt in to a distributed adapter
|
|
7
|
-
* (Redis, Cloudflare KV) without bloating single-instance apps.
|
|
8
|
-
*
|
|
9
|
-
* Contract per ADR D1:
|
|
10
|
-
* - `incr` is atomic — concurrent calls for the same key both observe
|
|
11
|
-
* the same `resetAt` and increment count by 1.
|
|
12
|
-
* - `get` returns `null` for expired entries (not just absent — checks
|
|
13
|
-
* `now > resetAt`).
|
|
14
|
-
* - `reset` removes the key entirely; next `incr` creates fresh.
|
|
15
|
-
*
|
|
16
|
-
* Async signature is honest about Redis adapters even though in-memory
|
|
17
|
-
* implementation is synchronous. Callers MUST await.
|
|
18
|
-
*/
|
|
19
|
-
interface RateLimitState {
|
|
20
|
-
/** Number of requests counted in the current window. */
|
|
21
|
-
count: number;
|
|
22
|
-
/** Absolute timestamp (ms since epoch) when this window expires. */
|
|
23
|
-
resetAt: number;
|
|
24
|
-
}
|
|
25
|
-
interface RateLimitStore {
|
|
26
|
-
/**
|
|
27
|
-
* Atomic increment-and-get. If the key is missing OR the previous
|
|
28
|
-
* window expired (`now >= resetAt`), create with `count=1, resetAt=now+windowMs`.
|
|
29
|
-
* Otherwise increment count by 1, preserving the original resetAt.
|
|
30
|
-
*/
|
|
31
|
-
incr(key: string, windowMs: number): Promise<RateLimitState>;
|
|
32
|
-
/** Read current state. Returns `null` for missing or expired entries. */
|
|
33
|
-
get(key: string): Promise<RateLimitState | null>;
|
|
34
|
-
/** Remove a key. Used by login throttling on success (T6.1). */
|
|
35
|
-
reset(key: string): Promise<void>;
|
|
36
|
-
}
|
|
37
|
-
/**
|
|
38
|
-
* Default in-memory store. Backed by `Map<string, RateLimitState>`.
|
|
39
|
-
*
|
|
40
|
-
* GC: every 1000 `incr` calls, expired entries are removed. Pathological
|
|
41
|
-
* key explosion is bounded by `MAX_ENTRIES` (LRU-evict oldest insertion).
|
|
42
|
-
*
|
|
43
|
-
* Single-thread by virtue of Node's event loop — `incr` is atomic at the
|
|
44
|
-
* JavaScript level (no preemption between Map.get and Map.set).
|
|
45
|
-
*/
|
|
46
|
-
declare class InMemoryStore implements RateLimitStore {
|
|
47
|
-
private store;
|
|
48
|
-
/** Bound the map to prevent unbounded growth from pathological inputs. */
|
|
49
|
-
static readonly MAX_ENTRIES = 100000;
|
|
50
|
-
/** GC sweep interval, milliseconds. */
|
|
51
|
-
static readonly GC_INTERVAL_MS = 30000;
|
|
52
|
-
private gcTimer;
|
|
53
|
-
constructor();
|
|
54
|
-
/**
|
|
55
|
-
* Synchronous fast-path used by the legacy sync `createRateLimiter`
|
|
56
|
-
* surface (`api-middleware.ts` is sync). The async `incr` delegates to
|
|
57
|
-
* this for in-memory; external adapters override `incr` directly.
|
|
58
|
-
*/
|
|
59
|
-
incrSync(key: string, windowMs: number): RateLimitState;
|
|
60
|
-
/** Sweep expired entries. Called by the GC timer; safe to call manually. */
|
|
61
|
-
sweepExpired(): void;
|
|
62
|
-
/**
|
|
63
|
-
* Stop the GC timer. Call from tests or when discarding the store. After
|
|
64
|
-
* `dispose`, the store still works but no longer auto-sweeps.
|
|
65
|
-
*/
|
|
66
|
-
dispose(): void;
|
|
67
|
-
incr(key: string, windowMs: number): Promise<RateLimitState>;
|
|
68
|
-
get(key: string): Promise<RateLimitState | null>;
|
|
69
|
-
reset(key: string): Promise<void>;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
export { InMemoryStore as I, type RateLimitStore as R, type RateLimitState as a };
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* T5.3 — React Query adapter primitives.
|
|
3
|
-
*
|
|
4
|
-
* Exposes:
|
|
5
|
-
* - `stableQueryKey(path, options)` — produces a deterministic queryKey
|
|
6
|
-
* that is equal across calls when the logical content of query/body is
|
|
7
|
-
* equal, regardless of property order or inline-object identity. Solves
|
|
8
|
-
* EC-10 (inline-object → infinite refetch).
|
|
9
|
-
* - `buildUseTheoQueryConfig(path, options, fetcher)` — produces the
|
|
10
|
-
* `{ queryKey, queryFn }` pair that consumers pass to `useQuery` from
|
|
11
|
-
* `@tanstack/react-query`.
|
|
12
|
-
*
|
|
13
|
-
* The canonical implementation lives here in `theokit/client`. The
|
|
14
|
-
* dedicated subpath `theokit/react-query` re-exports this surface so
|
|
15
|
-
* consumers who only need the React Query bridge can import from a
|
|
16
|
-
* clearly named entry point — same shape as `theokit/server`,
|
|
17
|
-
* `theokit/vite-plugin`, etc. No separate npm package.
|
|
18
|
-
*/
|
|
19
|
-
interface FetchOptionsLike {
|
|
20
|
-
query?: unknown;
|
|
21
|
-
body?: unknown;
|
|
22
|
-
params?: unknown;
|
|
23
|
-
}
|
|
24
|
-
type QueryKey = readonly unknown[];
|
|
25
|
-
declare function stableQueryKey(path: string, options: FetchOptionsLike): QueryKey;
|
|
26
|
-
type Fetcher<TResult = unknown> = (path: string, options: FetchOptionsLike) => Promise<TResult>;
|
|
27
|
-
interface UseTheoQueryConfig<TResult = unknown> {
|
|
28
|
-
queryKey: QueryKey;
|
|
29
|
-
queryFn: () => Promise<TResult>;
|
|
30
|
-
}
|
|
31
|
-
declare function buildUseTheoQueryConfig<TResult = unknown>(path: string, options: FetchOptionsLike, fetcher: Fetcher<TResult>): UseTheoQueryConfig<TResult>;
|
|
32
|
-
|
|
33
|
-
export { type FetchOptionsLike, type Fetcher, type Fetcher as FetcherFn, type QueryKey, type UseTheoQueryConfig, type UseTheoQueryConfig as UseTheoQueryInternals, buildUseTheoQueryConfig, buildUseTheoQueryConfig as buildUseTheoQueryInternals, stableQueryKey };
|
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
import { z } from 'zod';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Wave 2 — Polyglot Services Orchestration (T1.1).
|
|
5
|
-
*
|
|
6
|
-
* Declarative `services: {}` primitive for `theo.config.ts`. Each entry
|
|
7
|
-
* declares an external sidecar process (Python FastAPI / Node Hono) that
|
|
8
|
-
* boots alongside the TheoKit TS app. Empty `services: {}` is the default
|
|
9
|
-
* and preserves Wave 1 behavior (no impact on TS-only apps).
|
|
10
|
-
*
|
|
11
|
-
* See ADRs 0012-0015 + plan: docs/plans/wave-2-polyglot-services-plan.md
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Single service definition. All commands run from `services/<name>/` cwd.
|
|
16
|
-
*
|
|
17
|
-
* EC-4 fix: `proxy` regex requires NON-EMPTY path after `/` (the `+` quantifier)
|
|
18
|
-
* to reject `/` which would catch-all and conflict with TheoKit's own routing.
|
|
19
|
-
*/
|
|
20
|
-
declare const ServiceDefinitionSchema: z.ZodObject<{
|
|
21
|
-
runtime: z.ZodEnum<{
|
|
22
|
-
python: "python";
|
|
23
|
-
node: "node";
|
|
24
|
-
}>;
|
|
25
|
-
type: z.ZodOptional<z.ZodEnum<{
|
|
26
|
-
server: "server";
|
|
27
|
-
worker: "worker";
|
|
28
|
-
}>>;
|
|
29
|
-
port: z.ZodNumber;
|
|
30
|
-
proxy: z.ZodString;
|
|
31
|
-
dev: z.ZodString;
|
|
32
|
-
build: z.ZodOptional<z.ZodString>;
|
|
33
|
-
start: z.ZodString;
|
|
34
|
-
openapi: z.ZodOptional<z.ZodURL>;
|
|
35
|
-
healthcheck: z.ZodDefault<z.ZodString>;
|
|
36
|
-
cors: z.ZodDefault<z.ZodBoolean>;
|
|
37
|
-
env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
38
|
-
dependsOn: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
39
|
-
passSetCookie: z.ZodDefault<z.ZodBoolean>;
|
|
40
|
-
}, z.core.$strip>;
|
|
41
|
-
type ServiceDefinition = z.infer<typeof ServiceDefinitionSchema>;
|
|
42
|
-
type ServicesConfig = Record<string, ServiceDefinition>;
|
|
43
|
-
/**
|
|
44
|
-
* Full services config schema with cross-service refines.
|
|
45
|
-
*
|
|
46
|
-
* EC-1 fix: detect duplicate ports across services.
|
|
47
|
-
* EC-13: empty `dependsOn: []` accepted as no-deps.
|
|
48
|
-
* Self-dep, missing-ref, and cycles rejected via topological check.
|
|
49
|
-
*/
|
|
50
|
-
declare const servicesConfigSchema: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
51
|
-
runtime: z.ZodEnum<{
|
|
52
|
-
python: "python";
|
|
53
|
-
node: "node";
|
|
54
|
-
}>;
|
|
55
|
-
type: z.ZodOptional<z.ZodEnum<{
|
|
56
|
-
server: "server";
|
|
57
|
-
worker: "worker";
|
|
58
|
-
}>>;
|
|
59
|
-
port: z.ZodNumber;
|
|
60
|
-
proxy: z.ZodString;
|
|
61
|
-
dev: z.ZodString;
|
|
62
|
-
build: z.ZodOptional<z.ZodString>;
|
|
63
|
-
start: z.ZodString;
|
|
64
|
-
openapi: z.ZodOptional<z.ZodURL>;
|
|
65
|
-
healthcheck: z.ZodDefault<z.ZodString>;
|
|
66
|
-
cors: z.ZodDefault<z.ZodBoolean>;
|
|
67
|
-
env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
68
|
-
dependsOn: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
69
|
-
passSetCookie: z.ZodDefault<z.ZodBoolean>;
|
|
70
|
-
}, z.core.$strip>>>;
|
|
71
|
-
type ServicesConfigInput = z.input<typeof servicesConfigSchema>;
|
|
72
|
-
type ServicesConfigOutput = z.output<typeof servicesConfigSchema>;
|
|
73
|
-
|
|
74
|
-
export type { ServicesConfig as S, ServiceDefinition as a, ServicesConfigInput as b, ServicesConfigOutput as c };
|
|
@@ -1,229 +0,0 @@
|
|
|
1
|
-
import { a as AgentErrorEvent, A as AgentEvent } from '../../agent-events-DosDXkSV.js';
|
|
2
|
-
export { b as AgentMessageEvent, f as AgentRunErrorCode, c as AgentThinkingEvent, d as AgentToolCallEvent, e as AgentToolResultEvent } from '../../agent-events-DosDXkSV.js';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Item #4 — `streamAgentRun`
|
|
6
|
-
*
|
|
7
|
-
* Adapter that consumes the `@theokit/sdk` `Run.stream()` async generator
|
|
8
|
-
* (SDKMessage variants) and yields TheoKit `AgentEvent`s suitable for SSE
|
|
9
|
-
* via `defineAgentEndpoint`. One line at the consumer side:
|
|
10
|
-
*
|
|
11
|
-
* ```ts
|
|
12
|
-
* const run = await agent.send(message)
|
|
13
|
-
* yield* streamAgentRun(run)
|
|
14
|
-
* ```
|
|
15
|
-
*
|
|
16
|
-
* Mapping table (SDK → AgentEvent):
|
|
17
|
-
*
|
|
18
|
-
* | SDK message | AgentEvent yielded |
|
|
19
|
-
* |---|---|
|
|
20
|
-
* | assistant.content[].type==='text' | { type: 'message', content } |
|
|
21
|
-
* | assistant.content[].type==='tool_use'| (none — covered by tool_call below) |
|
|
22
|
-
* | tool_call(status='running') | { type: 'tool_call', name, args, id } |
|
|
23
|
-
* | tool_call(status='completed') | { type: 'tool_result', name, data, id }|
|
|
24
|
-
* | tool_call(status='error') | { type: 'error', message, id } |
|
|
25
|
-
* | run.wait() status==='error' | { type: 'error', message } |
|
|
26
|
-
* | run.wait() status==='cancelled' | (none — cancel ≠ error) |
|
|
27
|
-
* | system / user / thinking / status / | (none — internal SDK telemetry) |
|
|
28
|
-
* | task / request / object_delta | |
|
|
29
|
-
*
|
|
30
|
-
* Abort semantics: when the consumer calls `generator.return()` on the
|
|
31
|
-
* outer `defineAgentEndpoint` generator, `streamAgentRun` exits the
|
|
32
|
-
* `for await` loop and does NOT call `run.wait()`. Cleanup of in-flight
|
|
33
|
-
* SDK resources is the SDK consumer's responsibility (`run.cancel()`).
|
|
34
|
-
*/
|
|
35
|
-
/**
|
|
36
|
-
* Local mirror of the SDK's `Run` interface — only the surfaces we consume.
|
|
37
|
-
* The message contract is minimal (just `{ type: string }`) so the SDK's
|
|
38
|
-
* `SDKMessage` discriminated union IS structurally assignable without any
|
|
39
|
-
* cast at the consumer site (covariant — TS accepts the SDK's typed message
|
|
40
|
-
* as the wider `{ type: string }`). Property access inside `streamAgentRun`
|
|
41
|
-
* narrows via runtime type guards.
|
|
42
|
-
*
|
|
43
|
-
* `import type` from `@theokit/sdk` would couple TheoKit to the SDK at type-
|
|
44
|
-
* resolution time even for consumers who never use the agent surface.
|
|
45
|
-
*/
|
|
46
|
-
interface AgentRunLike {
|
|
47
|
-
stream: () => AsyncIterable<{
|
|
48
|
-
type: string;
|
|
49
|
-
}>;
|
|
50
|
-
wait: () => Promise<AgentRunResult>;
|
|
51
|
-
}
|
|
52
|
-
/**
|
|
53
|
-
* Re-exported as a convenience for test fixtures. Production code typically
|
|
54
|
-
* passes an SDK `Run` directly (structural match via `{ type: string }`).
|
|
55
|
-
*/
|
|
56
|
-
type AgentRunStreamMessage = {
|
|
57
|
-
type: 'assistant';
|
|
58
|
-
message: {
|
|
59
|
-
role: 'assistant';
|
|
60
|
-
content: {
|
|
61
|
-
type: string;
|
|
62
|
-
text?: string;
|
|
63
|
-
}[];
|
|
64
|
-
};
|
|
65
|
-
} | {
|
|
66
|
-
type: 'tool_call';
|
|
67
|
-
name: string;
|
|
68
|
-
status: 'running' | 'completed' | 'error';
|
|
69
|
-
args?: unknown;
|
|
70
|
-
result?: unknown;
|
|
71
|
-
call_id: string;
|
|
72
|
-
} | {
|
|
73
|
-
type: string;
|
|
74
|
-
[k: string]: unknown;
|
|
75
|
-
};
|
|
76
|
-
/** Subset of the SDK `RunResult` we consume. */
|
|
77
|
-
interface AgentRunResult {
|
|
78
|
-
status: 'finished' | 'error' | 'cancelled';
|
|
79
|
-
error?: {
|
|
80
|
-
message: string;
|
|
81
|
-
code?: string;
|
|
82
|
-
cause?: unknown;
|
|
83
|
-
};
|
|
84
|
-
}
|
|
85
|
-
/**
|
|
86
|
-
* Map an SDK error to the AgentErrorEvent shape. Pure function — easy to test.
|
|
87
|
-
*
|
|
88
|
-
* Backward compat (D4): non-AgentRunError throws yield only `message` field
|
|
89
|
-
* (legacy shape); discriminated fields stay `undefined`.
|
|
90
|
-
*
|
|
91
|
-
* Return type is the specific `AgentErrorEvent` (not the union) for ergonomic
|
|
92
|
-
* call-site access — `errorToEvent(err).code` works without narrowing.
|
|
93
|
-
*/
|
|
94
|
-
declare function errorToEvent(err: unknown, id?: string): AgentErrorEvent;
|
|
95
|
-
declare function streamAgentRun(run: AgentRunLike): AsyncGenerator<AgentEvent, void, unknown>;
|
|
96
|
-
|
|
97
|
-
/**
|
|
98
|
-
* Item #5 — `createConversationHistory`
|
|
99
|
-
*
|
|
100
|
-
* Orchestrator that resolves a stable `agentId` from (explicit → session →
|
|
101
|
-
* cookie → fresh UUID), then returns an `@theokit/sdk` `Agent` via
|
|
102
|
-
* `Agent.getOrCreate(agentId, options)`. Conversation turns auto-persist in
|
|
103
|
-
* `<cwd>/.theokit/agents/<agentId>/messages.jsonl` — SDK owns the storage
|
|
104
|
-
* (ADR D1). `MemorySettings` (facts recall layer) is opt-in passthrough via
|
|
105
|
-
* `options.memory` (ADR D2).
|
|
106
|
-
*
|
|
107
|
-
* Security: agentId from cookie/explicit is attacker-controlled. The SDK
|
|
108
|
-
* uses it as a filesystem path component AND we serialize it into Set-Cookie.
|
|
109
|
-
* EC-1 enforces a strict regex `^[a-zA-Z0-9_-]{1,128}$` at every entry point;
|
|
110
|
-
* invalid values fall through (treated as "missing") rather than throw.
|
|
111
|
-
*/
|
|
112
|
-
/**
|
|
113
|
-
* Minimum surface of an SDK Agent that consumers care about post-creation.
|
|
114
|
-
* Structural match — any object with `send` + `dispose` of compatible
|
|
115
|
-
* shape works. `send` returns a `SdkRunLike` (a Run-shaped object) that
|
|
116
|
-
* `streamAgentRun` can consume. Permissive `unknown` for now; consumers
|
|
117
|
-
* who want stricter types can cast to the SDK's own types.
|
|
118
|
-
*
|
|
119
|
-
* **T5.2 (architecture-cleanup) — DP-7 decision: KEEP (Opt B).** The 5 duck-typed
|
|
120
|
-
* mirrors below were flagged as "over-engineered" by the 2026-05-27 architecture
|
|
121
|
-
* review. Decision: KEEP them because `@theokit/sdk` is `devDependency` (not
|
|
122
|
-
* required at runtime for consumers that don't use agent features). Removing
|
|
123
|
-
* the mirrors would force a hard runtime dep on the SDK, breaking consumers
|
|
124
|
-
* who build TheoKit apps without the agent layer.
|
|
125
|
-
*
|
|
126
|
-
* @kept Defensive duck-type. Do NOT replace with direct SDK type imports unless
|
|
127
|
-
* `@theokit/sdk` is promoted from devDependency to dependency. If promoting,
|
|
128
|
-
* ALSO drop the mirrors (Opt A from the architecture-cleanup plan T5.2).
|
|
129
|
-
*/
|
|
130
|
-
interface SdkRunLike {
|
|
131
|
-
stream: () => AsyncIterable<{
|
|
132
|
-
type: string;
|
|
133
|
-
}>;
|
|
134
|
-
wait: () => Promise<{
|
|
135
|
-
status: 'finished' | 'error' | 'cancelled';
|
|
136
|
-
error?: {
|
|
137
|
-
message: string;
|
|
138
|
-
};
|
|
139
|
-
}>;
|
|
140
|
-
}
|
|
141
|
-
interface SdkAgent {
|
|
142
|
-
send: (message: string, options?: unknown) => Promise<SdkRunLike>;
|
|
143
|
-
dispose: () => Promise<void>;
|
|
144
|
-
}
|
|
145
|
-
/**
|
|
146
|
-
* Phase 2 — structural duck-type of `@theokit/sdk`'s `ConversationStorageAdapter`.
|
|
147
|
-
*
|
|
148
|
-
* D2 (decoupling): we mirror the SDK's shape locally rather than hard-import
|
|
149
|
-
* the SDK type. This lets consumers pass any object matching the structural
|
|
150
|
-
* contract (own implementation, SDK's `FileSystemConversationStorage`,
|
|
151
|
-
* `InMemoryConversationStorage`, or a Postgres/Redis recipe).
|
|
152
|
-
*
|
|
153
|
-
* EC-5 (SHOULD TEST — sync drift detection): the SDK type MUST be assignable
|
|
154
|
-
* to this interface AND vice-versa. A contract test asserts both directions.
|
|
155
|
-
*
|
|
156
|
-
* `unknown` for the message payload avoids coupling to the SDK's `SDKMessage`
|
|
157
|
-
* shape. Real consumers cast at the call site if they need stricter types.
|
|
158
|
-
*/
|
|
159
|
-
interface ConversationStorageLike {
|
|
160
|
-
getMessages(conversationId: string): Promise<readonly unknown[]>;
|
|
161
|
-
appendMessage(conversationId: string, message: unknown): Promise<void>;
|
|
162
|
-
deleteConversation(conversationId: string): Promise<void>;
|
|
163
|
-
listConversationIds?(opts?: {
|
|
164
|
-
limit?: number;
|
|
165
|
-
}): Promise<readonly string[] | undefined>;
|
|
166
|
-
dispose?(): Promise<void>;
|
|
167
|
-
}
|
|
168
|
-
/**
|
|
169
|
-
* Minimum surface of `AgentOptions` accepted by `Agent.getOrCreate`. Forward-
|
|
170
|
-
* compatible: callers pass whatever the SDK supports (memory, tools, etc.).
|
|
171
|
-
*
|
|
172
|
-
* Phase 2 adds typed `conversationStorage` slot. The index signature still
|
|
173
|
-
* passes everything else opaquely.
|
|
174
|
-
*/
|
|
175
|
-
interface SdkAgentOptions {
|
|
176
|
-
apiKey?: string;
|
|
177
|
-
model?: {
|
|
178
|
-
id: string;
|
|
179
|
-
};
|
|
180
|
-
tools?: readonly unknown[];
|
|
181
|
-
memory?: Record<string, unknown>;
|
|
182
|
-
/**
|
|
183
|
-
* Phase 2 (Production-Readiness #1) — pluggable conversation persistence.
|
|
184
|
-
* Default (when omitted): SDK falls back to `FileSystemConversationStorage`.
|
|
185
|
-
* Required for serverless / multi-host deploys.
|
|
186
|
-
*/
|
|
187
|
-
conversationStorage?: ConversationStorageLike;
|
|
188
|
-
[key: string]: unknown;
|
|
189
|
-
}
|
|
190
|
-
interface ConversationHistoryArgs {
|
|
191
|
-
/** Request — for reading the conversation cookie. */
|
|
192
|
-
request: Request | {
|
|
193
|
-
headers?: {
|
|
194
|
-
cookie?: string;
|
|
195
|
-
} | Headers;
|
|
196
|
-
};
|
|
197
|
-
/**
|
|
198
|
-
* Response-like surface that accepts a `Set-Cookie` header. The primitive
|
|
199
|
-
* appends a Set-Cookie line when issuing a new conversation id. If absent,
|
|
200
|
-
* the primitive still reads the existing cookie but cannot issue a new
|
|
201
|
-
* one — useful for read-only contexts.
|
|
202
|
-
*/
|
|
203
|
-
response?: {
|
|
204
|
-
headers: Headers;
|
|
205
|
-
};
|
|
206
|
-
/** Explicit override — wins over session/cookie/uuid (ADR D3 step 1). */
|
|
207
|
-
agentId?: string;
|
|
208
|
-
/** Auth session containing a `conversationId` field — ADR D3 step 2. */
|
|
209
|
-
session?: {
|
|
210
|
-
conversationId?: string;
|
|
211
|
-
} | null;
|
|
212
|
-
/** SDK AgentOptions forwarded to Agent.getOrCreate. apiKey + model required. */
|
|
213
|
-
options: SdkAgentOptions;
|
|
214
|
-
/** Cookie name override. Default: 'theo_conversation'. */
|
|
215
|
-
cookieName?: string;
|
|
216
|
-
/** Cookie max-age in seconds. Default + min: 30 days. Non-positive coerced to default (EC-4). */
|
|
217
|
-
cookieMaxAge?: number;
|
|
218
|
-
}
|
|
219
|
-
interface ConversationHistoryResult {
|
|
220
|
-
/** The SDK Agent, ready to receive `agent.send(message)`. */
|
|
221
|
-
agent: SdkAgent;
|
|
222
|
-
/** The resolved conversation id (useful for logging / debugging). */
|
|
223
|
-
conversationId: string;
|
|
224
|
-
/** True when the id was newly generated (no prior cookie / session). */
|
|
225
|
-
isNew: boolean;
|
|
226
|
-
}
|
|
227
|
-
declare function createConversationHistory(args: ConversationHistoryArgs): Promise<ConversationHistoryResult>;
|
|
228
|
-
|
|
229
|
-
export { AgentErrorEvent, AgentEvent, type AgentRunLike, type AgentRunResult, type AgentRunStreamMessage, type ConversationHistoryArgs, type ConversationHistoryResult, type ConversationStorageLike, type SdkAgent, type SdkAgentOptions, type SdkRunLike, createConversationHistory, errorToEvent, streamAgentRun };
|