@theokit/sdk 2.3.0 → 2.5.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/CHANGELOG.md +113 -0
- package/dist/a2a/index.cjs +103 -48
- package/dist/a2a/index.cjs.map +1 -1
- package/dist/a2a/index.js +104 -49
- package/dist/a2a/index.js.map +1 -1
- package/dist/compaction.cjs +78 -0
- package/dist/compaction.cjs.map +1 -0
- package/dist/compaction.d.cts +76 -0
- package/dist/compaction.d.ts +76 -0
- package/dist/compaction.js +70 -0
- package/dist/compaction.js.map +1 -0
- package/dist/{cron-B_H8rn-j.d.cts → cron-B656C3iq.d.cts} +8 -0
- package/dist/{cron-DX6HbHxd.d.ts → cron-CM2M9mhB.d.ts} +8 -0
- package/dist/cron.cjs +104 -57
- package/dist/cron.cjs.map +1 -1
- package/dist/cron.d.cts +1 -1
- package/dist/cron.d.ts +1 -1
- package/dist/cron.js +104 -57
- package/dist/cron.js.map +1 -1
- package/dist/eval.cjs +296 -73
- package/dist/eval.cjs.map +1 -1
- package/dist/eval.d.cts +2 -0
- package/dist/eval.d.ts +2 -0
- package/dist/eval.js +295 -75
- package/dist/eval.js.map +1 -1
- package/dist/index.cjs +135 -65
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +42 -7
- package/dist/index.d.ts +42 -7
- package/dist/index.js +135 -66
- package/dist/index.js.map +1 -1
- package/dist/internal/agent-loop/loop.d.ts +5 -0
- package/dist/internal/eval/code-runner.d.ts +28 -0
- package/dist/internal/llm/model-capabilities.d.ts +40 -0
- package/dist/internal/llm/model-identifier.d.ts +9 -1
- package/dist/internal/llm/model-option.d.ts +38 -0
- package/dist/internal/persistence/index.cjs +68 -0
- package/dist/internal/persistence/index.cjs.map +1 -1
- package/dist/internal/persistence/index.d.cts +1 -0
- package/dist/internal/persistence/index.d.ts +1 -0
- package/dist/internal/persistence/index.js +65 -1
- package/dist/internal/persistence/index.js.map +1 -1
- package/dist/internal/persistence/jsonl.d.cts +34 -0
- package/dist/internal/persistence/jsonl.d.ts +34 -0
- package/dist/internal/runtime/compression/compression-attempt.d.ts +24 -0
- package/dist/internal/runtime/compression/compression-config.d.ts +33 -0
- package/dist/internal/runtime/compression/compression-decision.d.ts +10 -0
- package/dist/internal/runtime/compression/compression-helpers.d.ts +18 -0
- package/dist/internal/runtime/compression/compression-model-registry.d.ts +41 -0
- package/dist/internal/runtime/compression/compression-summarizer.d.ts +29 -0
- package/dist/internal/runtime/context/project-instructions.d.ts +66 -0
- package/dist/internal/runtime/context/replay-history.d.ts +43 -0
- package/dist/internal/runtime/hooks/hooks-frontmatter.d.ts +1 -1
- package/dist/internal/runtime/skills/discover-skills.d.ts +68 -0
- package/dist/internal/runtime/skills/skills-block.d.ts +18 -0
- package/dist/internal/runtime/skills/subagent-tool-scope.d.ts +25 -0
- package/dist/messages.cjs +24 -0
- package/dist/messages.cjs.map +1 -0
- package/dist/messages.d.cts +33 -0
- package/dist/messages.d.ts +33 -0
- package/dist/messages.js +20 -0
- package/dist/messages.js.map +1 -0
- package/dist/models.cjs +233 -0
- package/dist/models.cjs.map +1 -0
- package/dist/models.d.cts +16 -0
- package/dist/models.d.ts +16 -0
- package/dist/models.js +228 -0
- package/dist/models.js.map +1 -0
- package/dist/permission-engine.d.ts +12 -4
- package/dist/project.cjs +149 -0
- package/dist/project.cjs.map +1 -0
- package/dist/project.d.cts +14 -0
- package/dist/project.d.ts +14 -0
- package/dist/project.js +146 -0
- package/dist/project.js.map +1 -0
- package/dist/sandbox/index.cjs +71 -1
- package/dist/sandbox/index.cjs.map +1 -1
- package/dist/sandbox/index.d.cts +1 -0
- package/dist/sandbox/index.d.ts +1 -0
- package/dist/sandbox/index.js +70 -2
- package/dist/sandbox/index.js.map +1 -1
- package/dist/sandbox/provision.d.cts +53 -0
- package/dist/sandbox/provision.d.ts +53 -0
- package/dist/sandbox/shell-escape.d.cts +8 -0
- package/dist/sandbox/shell-escape.d.ts +8 -0
- package/dist/scorers.d.ts +19 -1
- package/dist/skills.cjs +282 -0
- package/dist/skills.cjs.map +1 -0
- package/dist/skills.d.cts +19 -0
- package/dist/skills.d.ts +19 -0
- package/dist/skills.js +279 -0
- package/dist/skills.js.map +1 -0
- package/dist/subagents.cjs +24 -0
- package/dist/subagents.cjs.map +1 -0
- package/dist/subagents.d.cts +14 -0
- package/dist/subagents.d.ts +14 -0
- package/dist/subagents.js +21 -0
- package/dist/subagents.js.map +1 -0
- package/dist/types/agent.d.ts +8 -0
- package/dist/types/eval.d.ts +71 -0
- package/package.json +74 -14
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* T2.2 step 4a/N — Compression decision logic (ADR D440).
|
|
3
|
+
*
|
|
4
|
+
* Pure function that determines whether the agent-loop should attempt
|
|
5
|
+
* context-window compression on a given error. Isolates the decision
|
|
6
|
+
* matrix from the loop.ts hot path so it's independently testable.
|
|
7
|
+
*
|
|
8
|
+
* @internal
|
|
9
|
+
*/
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compression helpers (T2.3, ADR D92).
|
|
3
|
+
*
|
|
4
|
+
* Scaffold for future compression LLM integration:
|
|
5
|
+
* - `selectCompressionWindow` — splits messages into compress/preserve halves
|
|
6
|
+
* - `assertCompressionReduced` — 10% reduction floor to detect "compression placebo"
|
|
7
|
+
*
|
|
8
|
+
* The compression LLM call itself is out of scope for this plan (requires
|
|
9
|
+
* an auxiliary-model ADR). These helpers are used by `Agent.send` when a
|
|
10
|
+
* future iteration adds compression.
|
|
11
|
+
*
|
|
12
|
+
* @internal
|
|
13
|
+
*/
|
|
14
|
+
export interface CompressionCheck {
|
|
15
|
+
reduced: boolean;
|
|
16
|
+
reductionPct: number;
|
|
17
|
+
reason?: string;
|
|
18
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* T2.2 — Provider-agnostic compression-model registry (ADR D440).
|
|
3
|
+
*
|
|
4
|
+
* Resolves a cheaper-tier summarization model in the SAME vendor family
|
|
5
|
+
* as the agent's main model. Provider-agnostic by design: a consumer
|
|
6
|
+
* running on Anthropic-only / Ollama-only / Bedrock-only never needs
|
|
7
|
+
* to provision a second vendor's key for the compression aux-LLM.
|
|
8
|
+
*
|
|
9
|
+
* Resolution algorithm:
|
|
10
|
+
*
|
|
11
|
+
* 1. Exact match in `EXACT_REGISTRY` → cheaper-tier id (most cases).
|
|
12
|
+
* 2. Wildcard match in `WILDCARD_REGISTRY` (`*` suffix in key) →
|
|
13
|
+
* swap matched suffix (Bedrock region-prefixed variants).
|
|
14
|
+
* 3. Provider in `NO_AUTH_PROVIDERS` (Ollama / LM Studio / llama.cpp)
|
|
15
|
+
* → return SAME model id (local — cost N/A; running the same
|
|
16
|
+
* model for summarization costs only the round-trip latency,
|
|
17
|
+
* acceptable in dev/local mode).
|
|
18
|
+
* 4. No match → throw `CompressionModelUnresolvedError` with the
|
|
19
|
+
* actionable message naming the model + override path + the
|
|
20
|
+
* registry-PR remediation hint.
|
|
21
|
+
*
|
|
22
|
+
* Step 1 of T2.2 (compression-helpers wire). Step 2 wires this into
|
|
23
|
+
* `compression-config.ts`. Step 3 builds the OTel-instrumented aux
|
|
24
|
+
* client. Step 4 wires into `loop.ts` ContextWindowExceededError catch.
|
|
25
|
+
*
|
|
26
|
+
* @internal
|
|
27
|
+
*/
|
|
28
|
+
/**
|
|
29
|
+
* T2.2 — Typed error thrown when `resolveCompressionModel` cannot
|
|
30
|
+
* find a same-family-cheaper-tier mapping for `agentModel`. Surfaces
|
|
31
|
+
* the offending model id so operators can either (a) provide
|
|
32
|
+
* `Agent.create({compression: {model: ...}})` explicitly or (b) open
|
|
33
|
+
* a registry-PR adding the missing entry.
|
|
34
|
+
*
|
|
35
|
+
* @public
|
|
36
|
+
*/
|
|
37
|
+
export declare class CompressionModelUnresolvedError extends Error {
|
|
38
|
+
readonly name = "CompressionModelUnresolvedError";
|
|
39
|
+
readonly agentModel: string;
|
|
40
|
+
constructor(agentModel: string);
|
|
41
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* T2.2 step 3/N — Compression summarizer (ADR D440).
|
|
3
|
+
*
|
|
4
|
+
* Takes a conversation window (messages to compress) + a resolved
|
|
5
|
+
* compression model + an injected LLM caller, and returns a single
|
|
6
|
+
* system-role summary message that replaces the compressed window.
|
|
7
|
+
*
|
|
8
|
+
* The `callLlm` parameter is dependency-injected so:
|
|
9
|
+
* - Unit tests pass a deterministic fake (no real-LLM cost)
|
|
10
|
+
* - The agent-loop passes a real LLM client bound to the resolved
|
|
11
|
+
* compression config (step 4 wire)
|
|
12
|
+
*
|
|
13
|
+
* Failure mode per ADR D440: if the LLM call fails, throws
|
|
14
|
+
* `CompressionFailedError` — the caller (loop.ts) catches this,
|
|
15
|
+
* logs WARN with redacted metadata, and returns the ORIGINAL
|
|
16
|
+
* conversation unchanged (counter incremented toward cap 3).
|
|
17
|
+
*
|
|
18
|
+
* @internal
|
|
19
|
+
*/
|
|
20
|
+
/**
|
|
21
|
+
* Typed error thrown when the compression LLM call fails or returns
|
|
22
|
+
* an empty/ineffective summary. The caller catches and handles per
|
|
23
|
+
* ADR D440 failure mode (WARN + original conversation + counter).
|
|
24
|
+
*
|
|
25
|
+
* @public
|
|
26
|
+
*/
|
|
27
|
+
export declare class CompressionFailedError extends Error {
|
|
28
|
+
readonly name = "CompressionFailedError";
|
|
29
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/** How discovered instruction files are reduced to a single `content` string. */
|
|
2
|
+
export type ProjectInstructionScope = "nearest" | "merged";
|
|
3
|
+
/** One discovered project-instruction file. */
|
|
4
|
+
export interface ProjectInstructionFile {
|
|
5
|
+
/** Absolute path to the file. */
|
|
6
|
+
path: string;
|
|
7
|
+
/** Full file content (never truncated — the caller bounds it). */
|
|
8
|
+
content: string;
|
|
9
|
+
}
|
|
10
|
+
/** Result of {@link readProjectInstructions}. */
|
|
11
|
+
export interface ProjectInstructions {
|
|
12
|
+
/** Found files, nearest-first (innermost directory first). Empty if none. */
|
|
13
|
+
files: ProjectInstructionFile[];
|
|
14
|
+
/**
|
|
15
|
+
* The `scope`-selected reduction: `nearest` → the innermost file's content;
|
|
16
|
+
* `merged` → all files joined root-first (nearest content last). `undefined`
|
|
17
|
+
* when no file was found.
|
|
18
|
+
*/
|
|
19
|
+
content: string | undefined;
|
|
20
|
+
}
|
|
21
|
+
/** Options for {@link readProjectInstructions}. */
|
|
22
|
+
export interface ReadProjectInstructionsOptions {
|
|
23
|
+
/** Instruction filename to discover. Default `"THEO.md"`. */
|
|
24
|
+
filename?: string;
|
|
25
|
+
/** How to reduce the found files to `content`. Default `"nearest"`. */
|
|
26
|
+
scope?: ProjectInstructionScope;
|
|
27
|
+
/** Stop the upward walk at this directory (inclusive). Default: filesystem root. */
|
|
28
|
+
stopDir?: string;
|
|
29
|
+
}
|
|
30
|
+
/** Options for {@link writeProjectInstructions}. */
|
|
31
|
+
export interface WriteProjectInstructionsOptions {
|
|
32
|
+
/** Instruction filename to write. Default `"THEO.md"`. */
|
|
33
|
+
filename?: string;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Read hierarchical project instructions by walking up from `cwd`.
|
|
37
|
+
*
|
|
38
|
+
* Discovers every `<dir>/<filename>` from `cwd` up to the filesystem root (or
|
|
39
|
+
* `stopDir`), reads each, and returns them nearest-first in `files` plus a
|
|
40
|
+
* `content` reduction chosen by `scope`. Composes the hardened internal
|
|
41
|
+
* `walkUpForFile` (64-level cap, realpath dedup, FS-race tolerant).
|
|
42
|
+
*
|
|
43
|
+
* NEVER throws: a missing/unreadable directory or a path that exists but is not
|
|
44
|
+
* a readable file is skipped; no instruction file → `{ files: [], content: undefined }`.
|
|
45
|
+
*
|
|
46
|
+
* Public via `@theokit/sdk/project`.
|
|
47
|
+
*
|
|
48
|
+
* @public
|
|
49
|
+
*/
|
|
50
|
+
export declare function readProjectInstructions(cwd: string, options?: ReadProjectInstructionsOptions): Promise<ProjectInstructions>;
|
|
51
|
+
/**
|
|
52
|
+
* Write project instructions to `<cwd>/<filename>` atomically (temp + fsync +
|
|
53
|
+
* rename, via the shipped `replaceFileAtomic`).
|
|
54
|
+
*
|
|
55
|
+
* Unlike the reader, this FAILS LOUD: an unsafe `filename` (path traversal,
|
|
56
|
+
* separators, absolute) is rejected with `ConfigurationError`
|
|
57
|
+
* (`code: "unsafe_filename"`) — symmetric with the reader, whose `filename`
|
|
58
|
+
* flows through the same `isSafePattern` guard — and a write error (e.g. the
|
|
59
|
+
* parent directory does not exist) propagates to the caller. A failed mutation
|
|
60
|
+
* is a real error, never silently swallowed.
|
|
61
|
+
*
|
|
62
|
+
* Public via `@theokit/sdk/project`.
|
|
63
|
+
*
|
|
64
|
+
* @public
|
|
65
|
+
*/
|
|
66
|
+
export declare function writeProjectInstructions(cwd: string, content: string, options?: WriteProjectInstructionsOptions): Promise<void>;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stateless continuation-history rebuild (M1-3 — plan m1-continuation-history).
|
|
3
|
+
*
|
|
4
|
+
* `buildReplayHistory` serializes `SDKMessage[]` stream events into a bounded
|
|
5
|
+
* `StoredMessage[]` replay history for the STATELESS continuation path: a server
|
|
6
|
+
* (or serverless handler) that re-runs an agent on a fresh request reconstructs
|
|
7
|
+
* the working memory from persisted events rather than a live session. The
|
|
8
|
+
* replayed history is the ONLY working memory the continued model has, so it
|
|
9
|
+
* MUST carry tool-result content and be bounded against the context window.
|
|
10
|
+
*
|
|
11
|
+
* Complements M1 Phase 3 `runToCompletion` (the STATEFUL path, where the session
|
|
12
|
+
* preserves history). Pure, sync, dependency-free; reuses the SDK's own
|
|
13
|
+
* `truncateWithMarker` for per-item caps (Rule 9). Design: blueprint
|
|
14
|
+
* `m1-continuation-history` ADRs D1-D5; first-party baseline
|
|
15
|
+
* `theocode/server/lib/continuation-history.ts`.
|
|
16
|
+
*
|
|
17
|
+
* @public
|
|
18
|
+
*/
|
|
19
|
+
import type { StoredMessage } from "../../../types/conversation-storage.js";
|
|
20
|
+
import type { SDKMessage } from "../../../types/messages.js";
|
|
21
|
+
/**
|
|
22
|
+
* Options for {@link buildReplayHistory}.
|
|
23
|
+
*
|
|
24
|
+
* @public
|
|
25
|
+
*/
|
|
26
|
+
export interface ReplayHistoryOptions {
|
|
27
|
+
/** The continued model's context window, in tokens. Drives the char budget. */
|
|
28
|
+
contextWindowTokens: number;
|
|
29
|
+
/** Tokens held back for system + continuation prompt + reply. Default 8000. */
|
|
30
|
+
reserveTokens?: number;
|
|
31
|
+
/**
|
|
32
|
+
* Max characters for a single oversized turn before it is truncated (never
|
|
33
|
+
* dropped). Default `floor(budgetChars / 2)`. Guarded to ≥ 0.
|
|
34
|
+
*/
|
|
35
|
+
perItemCap?: number;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Rebuild a bounded replay history from `base` (prior durable turns) plus the
|
|
39
|
+
* `events` of the latest round. Returns a NEW array; never mutates inputs.
|
|
40
|
+
*
|
|
41
|
+
* @public
|
|
42
|
+
*/
|
|
43
|
+
export declare function buildReplayHistory(base: readonly StoredMessage[], events: readonly SDKMessage[], options: ReplayHistoryOptions): StoredMessage[];
|
|
@@ -11,11 +11,11 @@
|
|
|
11
11
|
export declare const HOOK_EVENTS: readonly ["preRun", "postRun", "preToolUse", "postToolUse", "stop"];
|
|
12
12
|
export declare const HookFrontmatterSchema: z.ZodObject<{
|
|
13
13
|
event: z.ZodEnum<{
|
|
14
|
-
stop: "stop";
|
|
15
14
|
preRun: "preRun";
|
|
16
15
|
postRun: "postRun";
|
|
17
16
|
preToolUse: "preToolUse";
|
|
18
17
|
postToolUse: "postToolUse";
|
|
18
|
+
stop: "stop";
|
|
19
19
|
}>;
|
|
20
20
|
matcher: z.ZodString;
|
|
21
21
|
command: z.ZodString;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A discovered skill's metadata. The skill BODY is never included — only the
|
|
3
|
+
* strict frontmatter fields plus the resolved `source` path.
|
|
4
|
+
*
|
|
5
|
+
* Public via `@theokit/sdk/skills`.
|
|
6
|
+
*
|
|
7
|
+
* @public
|
|
8
|
+
*/
|
|
9
|
+
export interface Skill {
|
|
10
|
+
name: string;
|
|
11
|
+
description: string;
|
|
12
|
+
/** Absolute path to the discovered `SKILL.md`. */
|
|
13
|
+
source: string;
|
|
14
|
+
category?: string;
|
|
15
|
+
dependencies?: string[];
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Information passed to `onInvalidSkill` when a `SKILL.md` is present but its
|
|
19
|
+
* frontmatter is malformed (missing required field or invalid YAML).
|
|
20
|
+
*
|
|
21
|
+
* @public
|
|
22
|
+
*/
|
|
23
|
+
export interface InvalidSkillInfo {
|
|
24
|
+
/** The skill directory name (used as the fallback skill name). */
|
|
25
|
+
name: string;
|
|
26
|
+
/** Absolute path to the offending `SKILL.md`. */
|
|
27
|
+
source: string;
|
|
28
|
+
/** Typed reason: `missing_frontmatter` or `schema_invalid`. */
|
|
29
|
+
code: string;
|
|
30
|
+
message: string;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Options for {@link discoverSkills}.
|
|
34
|
+
*
|
|
35
|
+
* @public
|
|
36
|
+
*/
|
|
37
|
+
export interface DiscoverSkillsOptions {
|
|
38
|
+
/**
|
|
39
|
+
* Called once per directory that contains a `SKILL.md` with malformed
|
|
40
|
+
* frontmatter. The skill is excluded from the result; discovery continues
|
|
41
|
+
* (strict-frontmatter ADR / EC-5). A directory WITHOUT a `SKILL.md` is NOT a
|
|
42
|
+
* malformed skill and does not trigger this callback.
|
|
43
|
+
*
|
|
44
|
+
* Default: no-op (a library primitive must not write to the consumer's
|
|
45
|
+
* stderr by default).
|
|
46
|
+
*/
|
|
47
|
+
onInvalidSkill?: (info: InvalidSkillInfo) => void;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Discover `SKILL.md` skills under an arbitrary directory.
|
|
51
|
+
*
|
|
52
|
+
* For each immediate subdirectory `<dir>/<name>/` containing a `SKILL.md`, the
|
|
53
|
+
* file's strict YAML frontmatter is parsed (`name`/`description` required;
|
|
54
|
+
* `category`/`dependencies` optional). Malformed skills are skipped (optionally
|
|
55
|
+
* reported via {@link DiscoverSkillsOptions.onInvalidSkill}); a subdirectory
|
|
56
|
+
* whose realpath escapes `dir` (via symlink) is skipped (symlink-escape guard,
|
|
57
|
+
* reusing `@theokit/sdk/path-safety`).
|
|
58
|
+
*
|
|
59
|
+
* NEVER throws: a missing, unreadable, or non-directory `dir` yields `[]`.
|
|
60
|
+
*
|
|
61
|
+
* Discovery order follows the filesystem `readdir` order (OS-dependent). Sort
|
|
62
|
+
* the result before {@link buildSkillsBlock} if a stable block order matters.
|
|
63
|
+
*
|
|
64
|
+
* Public via `@theokit/sdk/skills`.
|
|
65
|
+
*
|
|
66
|
+
* @public
|
|
67
|
+
*/
|
|
68
|
+
export declare function discoverSkills(dir: string, options?: DiscoverSkillsOptions): Promise<Skill[]>;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Render the `<skills>` system-prompt block from a skill list.
|
|
3
|
+
*
|
|
4
|
+
* Input is the structural subset `{ name, description }` — the skill BODY is
|
|
5
|
+
* NOT in the type, so it cannot leak into the prompt. Both fields are passed
|
|
6
|
+
* through `escapeBlockBody` to neutralise prompt-injection vectors hidden in
|
|
7
|
+
* user-controlled SKILL.md frontmatter (injection-escape ADR).
|
|
8
|
+
*
|
|
9
|
+
* Returns `undefined` for an empty list so the caller can omit the block.
|
|
10
|
+
*
|
|
11
|
+
* Public via `@theokit/sdk/skills`.
|
|
12
|
+
*
|
|
13
|
+
* @public
|
|
14
|
+
*/
|
|
15
|
+
export declare function buildSkillsBlock(skills: ReadonlyArray<{
|
|
16
|
+
name: string;
|
|
17
|
+
description: string;
|
|
18
|
+
}>): string | undefined;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { AgentDefinition } from "../../../types/agent.js";
|
|
2
|
+
/**
|
|
3
|
+
* Resolve a sub-agent's tool whitelist from its {@link AgentDefinition.tools}
|
|
4
|
+
* (M4-6). Returns a `Set` of allowed tool names when `tools` is a non-empty
|
|
5
|
+
* array, else `undefined` (unscoped — the sub-agent inherits the parent's full
|
|
6
|
+
* toolset). The `Set` is the exact shape `withToolWhitelist` /
|
|
7
|
+
* `ForkOptions.allowedTools` consume.
|
|
8
|
+
*
|
|
9
|
+
* @public
|
|
10
|
+
*/
|
|
11
|
+
export declare function subagentToolWhitelist(definition: AgentDefinition): Set<string> | undefined;
|
|
12
|
+
/**
|
|
13
|
+
* Run `fn` under the sub-agent's tool whitelist (M4-6). When the definition
|
|
14
|
+
* declares `tools`, the run executes inside `withToolWhitelist(set, fn)` — so
|
|
15
|
+
* every tool call the sub-agent makes is vetoed at dispatch (`checkToolWhitelist`,
|
|
16
|
+
* the same enforcement forks use) unless its canonical name is whitelisted: a
|
|
17
|
+
* `tools: ["read_file"]` sub-agent provably cannot call `write_file`/`shell_exec`.
|
|
18
|
+
* Enforcement is `withToolWhitelist`, NOT `PermissionEngine`.
|
|
19
|
+
*
|
|
20
|
+
* An unscoped definition (no/empty `tools`) runs `fn` directly — the parent's
|
|
21
|
+
* full toolset is preserved.
|
|
22
|
+
*
|
|
23
|
+
* @public
|
|
24
|
+
*/
|
|
25
|
+
export declare function withSubagentToolScope<T>(definition: AgentDefinition, fn: () => Promise<T>): Promise<T>;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// src/messages.ts
|
|
4
|
+
function assistantText(msg) {
|
|
5
|
+
if (msg.type !== "assistant") {
|
|
6
|
+
return "";
|
|
7
|
+
}
|
|
8
|
+
return msg.message.content.filter((block) => block.type === "text").map((block) => block.text).join("");
|
|
9
|
+
}
|
|
10
|
+
function extractToolUses(msg) {
|
|
11
|
+
if (msg.type !== "assistant") {
|
|
12
|
+
return [];
|
|
13
|
+
}
|
|
14
|
+
return msg.message.content.filter((block) => block.type === "tool_use");
|
|
15
|
+
}
|
|
16
|
+
function costAmountUsd(cost) {
|
|
17
|
+
return cost?.amountUsd;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
exports.assistantText = assistantText;
|
|
21
|
+
exports.costAmountUsd = costAmountUsd;
|
|
22
|
+
exports.extractToolUses = extractToolUses;
|
|
23
|
+
//# sourceMappingURL=messages.cjs.map
|
|
24
|
+
//# sourceMappingURL=messages.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/messages.ts"],"names":[],"mappings":";;;AAmBO,SAAS,cAAc,GAAA,EAAyB;AACrD,EAAA,IAAI,GAAA,CAAI,SAAS,WAAA,EAAa;AAC5B,IAAA,OAAO,EAAA;AAAA,EACT;AACA,EAAA,OAAO,IAAI,OAAA,CAAQ,OAAA,CAChB,MAAA,CAAO,CAAC,UAA4D,KAAA,CAAM,IAAA,KAAS,MAAM,CAAA,CACzF,IAAI,CAAC,KAAA,KAAU,MAAM,IAAI,CAAA,CACzB,KAAK,EAAE,CAAA;AACZ;AASO,SAAS,gBAAgB,GAAA,EAAiC;AAC/D,EAAA,IAAI,GAAA,CAAI,SAAS,WAAA,EAAa;AAC5B,IAAA,OAAO,EAAC;AAAA,EACV;AACA,EAAA,OAAO,GAAA,CAAI,QAAQ,OAAA,CAAQ,MAAA,CAAO,CAAC,KAAA,KAAiC,KAAA,CAAM,SAAS,UAAU,CAAA;AAC/F;AAQO,SAAS,cAAc,IAAA,EAAqD;AACjF,EAAA,OAAO,IAAA,EAAM,SAAA;AACf","file":"messages.cjs","sourcesContent":["/**\n * Pure readers over the `SDKMessage` stream (M1-5).\n *\n * Promotes the proven first-party hand-roll (`../theocode/server/lib/sdk-mappers.ts`)\n * onto the SDK's own types so consumers stop re-implementing a wire-event mapper.\n * Every reader is pure: no I/O, no mutation of its input, deterministic.\n *\n * Public from the `@theokit/sdk/messages` sub-path. See `docs.md → Message readers`.\n */\n\nimport type { SDKMessage, ToolUseBlock } from \"./types/messages.js\";\nimport type { CostBreakdown } from \"./types/usage.js\";\n\n/**\n * Concatenate the text of an assistant message's `TextBlock`s.\n *\n * Returns `\"\"` for any non-assistant message (or an assistant with no text\n * blocks). `tool_use` blocks are ignored — only `text` blocks contribute.\n */\nexport function assistantText(msg: SDKMessage): string {\n if (msg.type !== \"assistant\") {\n return \"\";\n }\n return msg.message.content\n .filter((block): block is Extract<typeof block, { type: \"text\" }> => block.type === \"text\")\n .map((block) => block.text)\n .join(\"\");\n}\n\n/**\n * Extract the `ToolUseBlock`s from an assistant message's content.\n *\n * Returns `[]` for any non-assistant message. This reads the assistant\n * message's content blocks — NOT the separate `SDKToolUseMessage`\n * (`type:\"tool_call\"`) lifecycle event, which is a different stream (ADR D2).\n */\nexport function extractToolUses(msg: SDKMessage): ToolUseBlock[] {\n if (msg.type !== \"assistant\") {\n return [];\n }\n return msg.message.content.filter((block): block is ToolUseBlock => block.type === \"tool_use\");\n}\n\n/**\n * Read the cost amount from a `CostBreakdown`, preserving the honesty contract\n * (repo ADR `D377-cost-status-closed-enum.md`): `amountUsd` is `number | undefined`\n * where `undefined` means \"cost unknown\" — distinct from a real `$0` (e.g. a\n * subscription-included route). NEVER coerced to 0.\n */\nexport function costAmountUsd(cost: CostBreakdown | undefined): number | undefined {\n return cost?.amountUsd;\n}\n"]}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure readers over the `SDKMessage` stream (M1-5).
|
|
3
|
+
*
|
|
4
|
+
* Promotes the proven first-party hand-roll (`../theocode/server/lib/sdk-mappers.ts`)
|
|
5
|
+
* onto the SDK's own types so consumers stop re-implementing a wire-event mapper.
|
|
6
|
+
* Every reader is pure: no I/O, no mutation of its input, deterministic.
|
|
7
|
+
*
|
|
8
|
+
* Public from the `@theokit/sdk/messages` sub-path. See `docs.md → Message readers`.
|
|
9
|
+
*/
|
|
10
|
+
import type { SDKMessage, ToolUseBlock } from "./types/messages.js";
|
|
11
|
+
import type { CostBreakdown } from "./types/usage.js";
|
|
12
|
+
/**
|
|
13
|
+
* Concatenate the text of an assistant message's `TextBlock`s.
|
|
14
|
+
*
|
|
15
|
+
* Returns `""` for any non-assistant message (or an assistant with no text
|
|
16
|
+
* blocks). `tool_use` blocks are ignored — only `text` blocks contribute.
|
|
17
|
+
*/
|
|
18
|
+
export declare function assistantText(msg: SDKMessage): string;
|
|
19
|
+
/**
|
|
20
|
+
* Extract the `ToolUseBlock`s from an assistant message's content.
|
|
21
|
+
*
|
|
22
|
+
* Returns `[]` for any non-assistant message. This reads the assistant
|
|
23
|
+
* message's content blocks — NOT the separate `SDKToolUseMessage`
|
|
24
|
+
* (`type:"tool_call"`) lifecycle event, which is a different stream (ADR D2).
|
|
25
|
+
*/
|
|
26
|
+
export declare function extractToolUses(msg: SDKMessage): ToolUseBlock[];
|
|
27
|
+
/**
|
|
28
|
+
* Read the cost amount from a `CostBreakdown`, preserving the honesty contract
|
|
29
|
+
* (repo ADR `D377-cost-status-closed-enum.md`): `amountUsd` is `number | undefined`
|
|
30
|
+
* where `undefined` means "cost unknown" — distinct from a real `$0` (e.g. a
|
|
31
|
+
* subscription-included route). NEVER coerced to 0.
|
|
32
|
+
*/
|
|
33
|
+
export declare function costAmountUsd(cost: CostBreakdown | undefined): number | undefined;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure readers over the `SDKMessage` stream (M1-5).
|
|
3
|
+
*
|
|
4
|
+
* Promotes the proven first-party hand-roll (`../theocode/server/lib/sdk-mappers.ts`)
|
|
5
|
+
* onto the SDK's own types so consumers stop re-implementing a wire-event mapper.
|
|
6
|
+
* Every reader is pure: no I/O, no mutation of its input, deterministic.
|
|
7
|
+
*
|
|
8
|
+
* Public from the `@theokit/sdk/messages` sub-path. See `docs.md → Message readers`.
|
|
9
|
+
*/
|
|
10
|
+
import type { SDKMessage, ToolUseBlock } from "./types/messages.js";
|
|
11
|
+
import type { CostBreakdown } from "./types/usage.js";
|
|
12
|
+
/**
|
|
13
|
+
* Concatenate the text of an assistant message's `TextBlock`s.
|
|
14
|
+
*
|
|
15
|
+
* Returns `""` for any non-assistant message (or an assistant with no text
|
|
16
|
+
* blocks). `tool_use` blocks are ignored — only `text` blocks contribute.
|
|
17
|
+
*/
|
|
18
|
+
export declare function assistantText(msg: SDKMessage): string;
|
|
19
|
+
/**
|
|
20
|
+
* Extract the `ToolUseBlock`s from an assistant message's content.
|
|
21
|
+
*
|
|
22
|
+
* Returns `[]` for any non-assistant message. This reads the assistant
|
|
23
|
+
* message's content blocks — NOT the separate `SDKToolUseMessage`
|
|
24
|
+
* (`type:"tool_call"`) lifecycle event, which is a different stream (ADR D2).
|
|
25
|
+
*/
|
|
26
|
+
export declare function extractToolUses(msg: SDKMessage): ToolUseBlock[];
|
|
27
|
+
/**
|
|
28
|
+
* Read the cost amount from a `CostBreakdown`, preserving the honesty contract
|
|
29
|
+
* (repo ADR `D377-cost-status-closed-enum.md`): `amountUsd` is `number | undefined`
|
|
30
|
+
* where `undefined` means "cost unknown" — distinct from a real `$0` (e.g. a
|
|
31
|
+
* subscription-included route). NEVER coerced to 0.
|
|
32
|
+
*/
|
|
33
|
+
export declare function costAmountUsd(cost: CostBreakdown | undefined): number | undefined;
|
package/dist/messages.js
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// src/messages.ts
|
|
2
|
+
function assistantText(msg) {
|
|
3
|
+
if (msg.type !== "assistant") {
|
|
4
|
+
return "";
|
|
5
|
+
}
|
|
6
|
+
return msg.message.content.filter((block) => block.type === "text").map((block) => block.text).join("");
|
|
7
|
+
}
|
|
8
|
+
function extractToolUses(msg) {
|
|
9
|
+
if (msg.type !== "assistant") {
|
|
10
|
+
return [];
|
|
11
|
+
}
|
|
12
|
+
return msg.message.content.filter((block) => block.type === "tool_use");
|
|
13
|
+
}
|
|
14
|
+
function costAmountUsd(cost) {
|
|
15
|
+
return cost?.amountUsd;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export { assistantText, costAmountUsd, extractToolUses };
|
|
19
|
+
//# sourceMappingURL=messages.js.map
|
|
20
|
+
//# sourceMappingURL=messages.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/messages.ts"],"names":[],"mappings":";AAmBO,SAAS,cAAc,GAAA,EAAyB;AACrD,EAAA,IAAI,GAAA,CAAI,SAAS,WAAA,EAAa;AAC5B,IAAA,OAAO,EAAA;AAAA,EACT;AACA,EAAA,OAAO,IAAI,OAAA,CAAQ,OAAA,CAChB,MAAA,CAAO,CAAC,UAA4D,KAAA,CAAM,IAAA,KAAS,MAAM,CAAA,CACzF,IAAI,CAAC,KAAA,KAAU,MAAM,IAAI,CAAA,CACzB,KAAK,EAAE,CAAA;AACZ;AASO,SAAS,gBAAgB,GAAA,EAAiC;AAC/D,EAAA,IAAI,GAAA,CAAI,SAAS,WAAA,EAAa;AAC5B,IAAA,OAAO,EAAC;AAAA,EACV;AACA,EAAA,OAAO,GAAA,CAAI,QAAQ,OAAA,CAAQ,MAAA,CAAO,CAAC,KAAA,KAAiC,KAAA,CAAM,SAAS,UAAU,CAAA;AAC/F;AAQO,SAAS,cAAc,IAAA,EAAqD;AACjF,EAAA,OAAO,IAAA,EAAM,SAAA;AACf","file":"messages.js","sourcesContent":["/**\n * Pure readers over the `SDKMessage` stream (M1-5).\n *\n * Promotes the proven first-party hand-roll (`../theocode/server/lib/sdk-mappers.ts`)\n * onto the SDK's own types so consumers stop re-implementing a wire-event mapper.\n * Every reader is pure: no I/O, no mutation of its input, deterministic.\n *\n * Public from the `@theokit/sdk/messages` sub-path. See `docs.md → Message readers`.\n */\n\nimport type { SDKMessage, ToolUseBlock } from \"./types/messages.js\";\nimport type { CostBreakdown } from \"./types/usage.js\";\n\n/**\n * Concatenate the text of an assistant message's `TextBlock`s.\n *\n * Returns `\"\"` for any non-assistant message (or an assistant with no text\n * blocks). `tool_use` blocks are ignored — only `text` blocks contribute.\n */\nexport function assistantText(msg: SDKMessage): string {\n if (msg.type !== \"assistant\") {\n return \"\";\n }\n return msg.message.content\n .filter((block): block is Extract<typeof block, { type: \"text\" }> => block.type === \"text\")\n .map((block) => block.text)\n .join(\"\");\n}\n\n/**\n * Extract the `ToolUseBlock`s from an assistant message's content.\n *\n * Returns `[]` for any non-assistant message. This reads the assistant\n * message's content blocks — NOT the separate `SDKToolUseMessage`\n * (`type:\"tool_call\"`) lifecycle event, which is a different stream (ADR D2).\n */\nexport function extractToolUses(msg: SDKMessage): ToolUseBlock[] {\n if (msg.type !== \"assistant\") {\n return [];\n }\n return msg.message.content.filter((block): block is ToolUseBlock => block.type === \"tool_use\");\n}\n\n/**\n * Read the cost amount from a `CostBreakdown`, preserving the honesty contract\n * (repo ADR `D377-cost-status-closed-enum.md`): `amountUsd` is `number | undefined`\n * where `undefined` means \"cost unknown\" — distinct from a real `$0` (e.g. a\n * subscription-included route). NEVER coerced to 0.\n */\nexport function costAmountUsd(cost: CostBreakdown | undefined): number | undefined {\n return cost?.amountUsd;\n}\n"]}
|