@theokit/sdk 3.1.1 → 3.2.2
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 +36 -0
- package/dist/a2a/index.cjs +188 -49
- package/dist/a2a/index.cjs.map +1 -1
- package/dist/a2a/index.js +188 -49
- package/dist/a2a/index.js.map +1 -1
- package/dist/{cron-C2jWAvlQ.d.cts → cron-4u1UdmgC.d.cts} +1 -1
- package/dist/{cron-BLRe166v.d.ts → cron-DuhVPer6.d.ts} +1 -1
- package/dist/cron.cjs +188 -49
- package/dist/cron.cjs.map +1 -1
- package/dist/cron.d.cts +2 -2
- package/dist/cron.d.ts +2 -2
- package/dist/cron.js +188 -49
- package/dist/cron.js.map +1 -1
- package/dist/{errors-D_Bfo30u.d.ts → errors-_fPS0X80.d.ts} +1 -1
- package/dist/{errors-DZpCGlYv.d.cts → errors-jxK4yfp5.d.cts} +1 -1
- package/dist/errors.d.cts +2 -2
- package/dist/eval.cjs +188 -64
- package/dist/eval.cjs.map +1 -1
- package/dist/eval.js +188 -64
- package/dist/eval.js.map +1 -1
- package/dist/index.cjs +197 -50
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +6 -6
- package/dist/index.d.ts +6 -6
- package/dist/index.js +197 -50
- package/dist/index.js.map +1 -1
- package/dist/internal/runtime/context/context-discovery.d.ts +1 -1
- package/dist/internal/runtime/context/context-glob.d.ts +1 -0
- package/dist/internal/runtime/context/context-manager.d.ts +18 -1
- package/dist/internal/runtime/context/context-mdc-parser.d.ts +7 -6
- package/dist/internal/runtime/context/context-rules-frontmatter.d.ts +30 -0
- package/dist/internal/runtime/context/context-yaml-lite.d.ts +26 -0
- package/dist/project.cjs.map +1 -1
- package/dist/project.js.map +1 -1
- package/dist/{run-CLXKMRgq.d.cts → run-CrHz9BAP.d.cts} +9 -0
- package/dist/{run-CLXKMRgq.d.ts → run-CrHz9BAP.d.ts} +9 -0
- package/dist/sandbox/index.cjs +8 -9
- package/dist/sandbox/index.cjs.map +1 -1
- package/dist/sandbox/index.js +8 -9
- package/dist/sandbox/index.js.map +1 -1
- package/dist/sandbox/types.d.cts +0 -1
- package/dist/sandbox/types.d.ts +0 -1
- package/dist/types/run.d.ts +9 -0
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,41 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 3.2.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 7f57c5a: Security (#55) — a delegated subagent now inherits the parent's code-registered plugins (e.g. `PermissionPlugin`), so its inner tool calls run under the SAME argument-level permission gate. Previously the child `Agent.create` received only apiKey/model/tools, so a parent that denied `shell` with a matching-arg rule did not stop a subagent it granted `shell` to — arg-level gating silently stopped at the delegation boundary.
|
|
8
|
+
- f81ac79: Fix (#58) — a run cancelled between tool iterations now reports `RunStatus: "cancelled"` instead of `"finished"`, so a caller can distinguish a cancellation from a clean completion. Previously the between-iteration abort break left the default `"finished"` status.
|
|
9
|
+
- 57cfcc8: Fix (#58) — `JobQueue.cancel()` on a running job that ignores its `AbortSignal` (never settles) previously leaked its concurrency slot, deadlocking a `maxConcurrency`-bounded queue. Cancel now frees the slot immediately; `#release` is idempotent so the job's eventual settle is a no-op (no double-free).
|
|
10
|
+
- bd06140: Fix (#65) — the `transform_llm_output` plugin hook now rewrites the FINAL user-visible / streamed assistant text, and fires on text-only terminal turns. Previously it ran only in the tool-call branch and folded only into internal message history, so a plugin could not scrub what the caller actually received. The transform is now applied once, up front, and flows into the emitted step, `finalText`/`result`, and message history alike.
|
|
11
|
+
|
|
12
|
+
## 3.2.1
|
|
13
|
+
|
|
14
|
+
### Patch Changes
|
|
15
|
+
|
|
16
|
+
- a283dd4: Security (#54) — harden child-process env scrubbing.
|
|
17
|
+
|
|
18
|
+
- The `inherit-scrubbed` denylist now also drops the highest-signal VALUE-embedded-secret conventions: connection strings that carry `user:password@` (`DATABASE_URL`, `REDIS_URL`, `MONGODB_URI`, `DB_URL`, …), plus `DSN`, `WEBHOOK`, `COOKIE`, and `CONNECTION_STRING`. Generic non-secret URLs (`PUBLIC_BASE_URL`, `API_URL`, `PGHOST`) are deliberately preserved. A denylist still cannot catch every value-embedded secret — policy `core` (allowlist) remains the fail-closed mode for untrusted children.
|
|
19
|
+
- Removed dead `validateCommand` / `SHELL_METACHARACTERS` from the sandbox base — a never-invoked "guard" that provided a false sense of protection.
|
|
20
|
+
- Added an end-to-end test proving `LocalSandbox.execute` scrubs secret-like host env vars from the real child process.
|
|
21
|
+
|
|
22
|
+
- 826bca0: Security (#56) — close two residual cross-tenant active-recall cache leaks found by adversarial review.
|
|
23
|
+
|
|
24
|
+
- `@theokit/sdk-memory` (publishable) called `cache.get`/`cache.set` with no tenant context, so two callers with the same query text but different identity shared a cached recall — a cross-tenant leak for every consumer of the package. The cache read/write are now keyed by the `{namespace, userId, scope}` tenant tuple (the primitive already supported it).
|
|
25
|
+
- In `@theokit/sdk` the production caller hardcoded `namespace: "default"` and dropped `memoryContext.tenantId`, so two tenants sharing a `userId` collided on one cache entry. The caller now threads `memoryContext.tenantId` into the tenant partition (`namespace`). `sessionId` is intentionally not a key dimension — recall is cross-session by design.
|
|
26
|
+
|
|
27
|
+
- 7bcc872: Security/correctness (#59) — the HTTP MCP body read (`response.json()`) was outside the abort try/catch, so a server that returned headers then stalled the body surfaced a raw `DOMException(TimeoutError)` instead of the typed `NetworkError{code:"mcp_timeout"}`. The request was still bounded (no hang), but the typed-timeout contract now holds across both the header and body phases.
|
|
28
|
+
|
|
29
|
+
## 3.2.0
|
|
30
|
+
|
|
31
|
+
### Minor Changes
|
|
32
|
+
|
|
33
|
+
- bf66122: Add `.theokit/rules/*.md` — theokit-native path-scoped rule files, mirroring Claude Code's `.claude/rules/`.
|
|
34
|
+
|
|
35
|
+
Each rule file carries frontmatter with `paths:` (Claude Code parity) and/or `globs:` (Cursor-compatible alias) — both are glob-pattern arrays — plus `alwaysApply` and `enabled`. Rules with `alwaysApply: true` load into the agent's context every send; path-scoped rules activate only when an in-scope file matches, declared per-send via the new `SendOptions.contextPaths`. The same in-scope signal also unblocks conditional activation for `.cursor/rules/*.mdc` globs. No new dependency — glob matching and the YAML-subset parser are shared across both rule formats.
|
|
36
|
+
|
|
37
|
+
Also fixes the shared glob compiler so `dir/**/*.ext` correctly matches a top-level file directly under `dir/` (e.g. `src/**/*.ts` now matches `src/foo.ts`, not just `src/a/b/foo.ts`) — the semantics Cursor and Claude Code document. This improves `.cursor/rules/*.mdc` glob activation as well. `*` and `?` no longer cross a `/` separator.
|
|
38
|
+
|
|
3
39
|
## 3.1.1
|
|
4
40
|
|
|
5
41
|
### Patch Changes
|
package/dist/a2a/index.cjs
CHANGED
|
@@ -962,10 +962,10 @@ function buildToolPrompt(prompt) {
|
|
|
962
962
|
Respond by calling the \`output\` tool with the structured answer that matches the schema.`;
|
|
963
963
|
}
|
|
964
964
|
function setupStructuredOutput(schema, maxRetries) {
|
|
965
|
-
const
|
|
965
|
+
const z8 = requireZod();
|
|
966
966
|
const jsonSchema = toJsonSchema(schema, { unrepresentable: "any" });
|
|
967
967
|
return {
|
|
968
|
-
z:
|
|
968
|
+
z: z8,
|
|
969
969
|
jsonSchema,
|
|
970
970
|
maxRetries: maxRetries ?? 1,
|
|
971
971
|
initialUsage: { inputTokens: 0, outputTokens: 0 }
|
|
@@ -4743,7 +4743,14 @@ var init_env_policy = __esm({
|
|
|
4743
4743
|
/[_-]PWD/i,
|
|
4744
4744
|
/CREDENTIAL/i,
|
|
4745
4745
|
/PRIVATE/i,
|
|
4746
|
-
/_AUTH/i
|
|
4746
|
+
/_AUTH/i,
|
|
4747
|
+
// #54-a — value-embedded-secret conventions (no generic `*_URL` — see keep-list test).
|
|
4748
|
+
/DSN/i,
|
|
4749
|
+
/WEBHOOK/i,
|
|
4750
|
+
/COOKIE/i,
|
|
4751
|
+
/CONNECTION[_-]?STRING/i,
|
|
4752
|
+
// Known DB / message-broker connection-string vars (carry `user:pass@`).
|
|
4753
|
+
/(?:^|[_-])(?:DATABASE|DB|REDIS|MONGO(?:DB)?|POSTGRES(?:QL)?|MYSQL|MARIADB|AMQP|RABBITMQ|CLICKHOUSE|ELASTIC(?:SEARCH)?|CASSANDRA|COUCHDB|MEMCACHED|NATS|KAFKA)[_-]?(?:URL|URI|DSN|CONNECTION)/i
|
|
4747
4754
|
];
|
|
4748
4755
|
CORE_VARS = [
|
|
4749
4756
|
"PATH",
|
|
@@ -6041,7 +6048,7 @@ async function buildSystemPromptContext(inputs, userText, memoryFacts, manager =
|
|
|
6041
6048
|
memory: memoryFacts.map((fact) => ({ text: fact.text }))
|
|
6042
6049
|
};
|
|
6043
6050
|
}
|
|
6044
|
-
async function buildAssemblyContext(inputs, userText, baseSystemPrompt, memoryFacts, activeMemorySummary) {
|
|
6051
|
+
async function buildAssemblyContext(inputs, userText, baseSystemPrompt, memoryFacts, activeMemorySummary, contextPaths) {
|
|
6045
6052
|
const resolved = await resolveSendSkills(inputs, userText, memoryFacts);
|
|
6046
6053
|
const baseCtx = await buildSystemPromptContext(inputs, userText, memoryFacts, resolved.manager);
|
|
6047
6054
|
const assemblyCtx = {
|
|
@@ -6054,19 +6061,21 @@ async function buildAssemblyContext(inputs, userText, baseSystemPrompt, memoryFa
|
|
|
6054
6061
|
assemblyCtx.activeMemorySummary = activeMemorySummary;
|
|
6055
6062
|
}
|
|
6056
6063
|
if (inputs.context !== void 0) {
|
|
6064
|
+
await inputs.context.applyScope(contextPaths);
|
|
6057
6065
|
const internal = inputs.context.internalAssemblySnapshot();
|
|
6058
6066
|
assemblyCtx.contextSnapshot = { sources: internal.sources };
|
|
6059
6067
|
if (internal.maxTokens !== void 0) assemblyCtx.contextMaxTokens = internal.maxTokens;
|
|
6060
6068
|
}
|
|
6061
6069
|
return assemblyCtx;
|
|
6062
6070
|
}
|
|
6063
|
-
async function assembleSystemPromptForSend(inputs, userText, baseSystemPrompt, memoryFacts, activeMemorySummary) {
|
|
6071
|
+
async function assembleSystemPromptForSend(inputs, userText, baseSystemPrompt, memoryFacts, activeMemorySummary, contextPaths) {
|
|
6064
6072
|
const ctx = await buildAssemblyContext(
|
|
6065
6073
|
inputs,
|
|
6066
6074
|
userText,
|
|
6067
6075
|
baseSystemPrompt,
|
|
6068
6076
|
memoryFacts,
|
|
6069
|
-
activeMemorySummary
|
|
6077
|
+
activeMemorySummary,
|
|
6078
|
+
contextPaths
|
|
6070
6079
|
);
|
|
6071
6080
|
return inputs.systemPromptPipeline.assemble(ctx);
|
|
6072
6081
|
}
|
|
@@ -6773,6 +6782,14 @@ var init_context_discovery = __esm({
|
|
|
6773
6782
|
followImports: false,
|
|
6774
6783
|
priority: 40
|
|
6775
6784
|
},
|
|
6785
|
+
{
|
|
6786
|
+
id: "theokit-rules",
|
|
6787
|
+
pattern: ".theokit/rules/*.md",
|
|
6788
|
+
scope: "globbed",
|
|
6789
|
+
parser: "rules-frontmatter",
|
|
6790
|
+
followImports: false,
|
|
6791
|
+
priority: 45
|
|
6792
|
+
},
|
|
6776
6793
|
{
|
|
6777
6794
|
id: "theokit-context",
|
|
6778
6795
|
pattern: ".theokit/context/*.md",
|
|
@@ -6856,32 +6873,27 @@ var init_context_import_resolver = __esm({
|
|
|
6856
6873
|
MAX_HOPS = 5;
|
|
6857
6874
|
}
|
|
6858
6875
|
});
|
|
6859
|
-
|
|
6860
|
-
|
|
6861
|
-
|
|
6862
|
-
|
|
6863
|
-
}
|
|
6864
|
-
const yamlBody = m[1] ?? "";
|
|
6865
|
-
const body = m[2] ?? "";
|
|
6866
|
-
try {
|
|
6867
|
-
const parsed = parseSimpleYaml2(yamlBody);
|
|
6868
|
-
const validated = McdFrontmatterSchema.safeParse(parsed);
|
|
6869
|
-
if (!validated.success) return void 0;
|
|
6870
|
-
return { frontmatter: validated.data, body };
|
|
6871
|
-
} catch {
|
|
6872
|
-
return void 0;
|
|
6873
|
-
}
|
|
6876
|
+
|
|
6877
|
+
// src/internal/runtime/context/context-glob.ts
|
|
6878
|
+
function globToRegex(glob) {
|
|
6879
|
+
const compiled = glob.replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*\*\//g, "::GLOBSTAR_SLASH::").replace(/\*\*/g, "::GLOBSTAR::").replace(/\*/g, "[^/]*").replace(/\?/g, "[^/]").replace(/::GLOBSTAR_SLASH::/g, "(?:.*/)?").replace(/::GLOBSTAR::/g, ".*");
|
|
6880
|
+
return new RegExp(`^${compiled}$`);
|
|
6874
6881
|
}
|
|
6875
|
-
function
|
|
6876
|
-
if (
|
|
6877
|
-
|
|
6878
|
-
|
|
6879
|
-
const globRes = fm.globs.map(globToRegex);
|
|
6880
|
-
return touchedFiles.some((file) => globRes.some((re) => re.test(file)));
|
|
6882
|
+
function anyGlobMatches(patterns, paths) {
|
|
6883
|
+
if (patterns.length === 0 || paths.length === 0) return false;
|
|
6884
|
+
const res = patterns.map(globToRegex);
|
|
6885
|
+
return paths.some((p) => res.some((re) => re.test(p)));
|
|
6881
6886
|
}
|
|
6882
|
-
|
|
6883
|
-
|
|
6884
|
-
|
|
6887
|
+
var init_context_glob = __esm({
|
|
6888
|
+
"src/internal/runtime/context/context-glob.ts"() {
|
|
6889
|
+
}
|
|
6890
|
+
});
|
|
6891
|
+
|
|
6892
|
+
// src/internal/runtime/context/context-yaml-lite.ts
|
|
6893
|
+
function splitFrontmatter3(content) {
|
|
6894
|
+
const m = FRONTMATTER_RE.exec(content);
|
|
6895
|
+
if (m === null) return { yaml: void 0, body: content };
|
|
6896
|
+
return { yaml: m[1] ?? "", body: m[2] ?? "" };
|
|
6885
6897
|
}
|
|
6886
6898
|
function parseSimpleYaml2(yaml) {
|
|
6887
6899
|
const out = {};
|
|
@@ -6928,15 +6940,76 @@ function parseScalar(s) {
|
|
|
6928
6940
|
if (/^-?\d+$/.test(s)) return parseInt(s, 10);
|
|
6929
6941
|
return s.replace(/^["']|["']$/g, "");
|
|
6930
6942
|
}
|
|
6931
|
-
var
|
|
6943
|
+
var FRONTMATTER_RE;
|
|
6944
|
+
var init_context_yaml_lite = __esm({
|
|
6945
|
+
"src/internal/runtime/context/context-yaml-lite.ts"() {
|
|
6946
|
+
FRONTMATTER_RE = /^---\s*\n([\s\S]*?)\n---\s*\n([\s\S]*)$/;
|
|
6947
|
+
}
|
|
6948
|
+
});
|
|
6949
|
+
function parseMdc(content) {
|
|
6950
|
+
const { yaml, body } = splitFrontmatter3(content);
|
|
6951
|
+
if (yaml === void 0) {
|
|
6952
|
+
return { frontmatter: { alwaysApply: true }, body: content };
|
|
6953
|
+
}
|
|
6954
|
+
try {
|
|
6955
|
+
const parsed = parseSimpleYaml2(yaml);
|
|
6956
|
+
const validated = McdFrontmatterSchema.safeParse(parsed);
|
|
6957
|
+
if (!validated.success) return void 0;
|
|
6958
|
+
return { frontmatter: validated.data, body };
|
|
6959
|
+
} catch {
|
|
6960
|
+
return void 0;
|
|
6961
|
+
}
|
|
6962
|
+
}
|
|
6963
|
+
function shouldActivate(fm, touchedFiles) {
|
|
6964
|
+
if (fm.alwaysApply === true) return true;
|
|
6965
|
+
if (fm.globs === void 0 || fm.globs.length === 0) return false;
|
|
6966
|
+
return anyGlobMatches(fm.globs, touchedFiles);
|
|
6967
|
+
}
|
|
6968
|
+
var McdFrontmatterSchema;
|
|
6932
6969
|
var init_context_mdc_parser = __esm({
|
|
6933
6970
|
"src/internal/runtime/context/context-mdc-parser.ts"() {
|
|
6971
|
+
init_context_glob();
|
|
6972
|
+
init_context_yaml_lite();
|
|
6934
6973
|
McdFrontmatterSchema = zod.z.object({
|
|
6935
6974
|
description: zod.z.string().optional(),
|
|
6936
6975
|
globs: zod.z.array(zod.z.string()).optional(),
|
|
6937
6976
|
alwaysApply: zod.z.boolean().optional()
|
|
6938
6977
|
});
|
|
6939
|
-
|
|
6978
|
+
}
|
|
6979
|
+
});
|
|
6980
|
+
function parseRules(content) {
|
|
6981
|
+
const { yaml, body } = splitFrontmatter3(content);
|
|
6982
|
+
if (yaml === void 0) {
|
|
6983
|
+
return { frontmatter: { alwaysApply: true }, body: content };
|
|
6984
|
+
}
|
|
6985
|
+
try {
|
|
6986
|
+
const parsed = parseSimpleYaml2(yaml);
|
|
6987
|
+
const validated = RulesFrontmatterSchema.safeParse(parsed);
|
|
6988
|
+
if (!validated.success) return void 0;
|
|
6989
|
+
return { frontmatter: validated.data, body };
|
|
6990
|
+
} catch {
|
|
6991
|
+
return void 0;
|
|
6992
|
+
}
|
|
6993
|
+
}
|
|
6994
|
+
function shouldActivateRule(fm, inScopePaths) {
|
|
6995
|
+
if (fm.enabled === false) return false;
|
|
6996
|
+
if (fm.alwaysApply === true) return true;
|
|
6997
|
+
const patterns = [...fm.paths ?? [], ...fm.globs ?? []];
|
|
6998
|
+
if (patterns.length === 0) return false;
|
|
6999
|
+
return anyGlobMatches(patterns, inScopePaths);
|
|
7000
|
+
}
|
|
7001
|
+
var RulesFrontmatterSchema;
|
|
7002
|
+
var init_context_rules_frontmatter = __esm({
|
|
7003
|
+
"src/internal/runtime/context/context-rules-frontmatter.ts"() {
|
|
7004
|
+
init_context_glob();
|
|
7005
|
+
init_context_yaml_lite();
|
|
7006
|
+
RulesFrontmatterSchema = zod.z.object({
|
|
7007
|
+
description: zod.z.string().optional(),
|
|
7008
|
+
paths: zod.z.array(zod.z.string()).optional(),
|
|
7009
|
+
globs: zod.z.array(zod.z.string()).optional(),
|
|
7010
|
+
alwaysApply: zod.z.boolean().optional(),
|
|
7011
|
+
enabled: zod.z.boolean().optional()
|
|
7012
|
+
});
|
|
6940
7013
|
}
|
|
6941
7014
|
});
|
|
6942
7015
|
async function runDiscovery(opts) {
|
|
@@ -6972,6 +7045,9 @@ async function loadOneSource(spec, path$1, opts, gitRoot) {
|
|
|
6972
7045
|
if (spec.parser === "mdc") {
|
|
6973
7046
|
return loadMdcSource(spec, path$1, id, opts);
|
|
6974
7047
|
}
|
|
7048
|
+
if (spec.parser === "rules-frontmatter") {
|
|
7049
|
+
return loadRulesSource(spec, path$1, id, opts);
|
|
7050
|
+
}
|
|
6975
7051
|
if (spec.parser === "frontmatter-zod") {
|
|
6976
7052
|
return void 0;
|
|
6977
7053
|
}
|
|
@@ -6995,6 +7071,24 @@ async function loadMdcSource(spec, path, id, opts) {
|
|
|
6995
7071
|
truncated: false
|
|
6996
7072
|
};
|
|
6997
7073
|
}
|
|
7074
|
+
async function loadRulesSource(spec, path, id, opts) {
|
|
7075
|
+
let raw;
|
|
7076
|
+
try {
|
|
7077
|
+
raw = await promises.readFile(path, "utf8");
|
|
7078
|
+
} catch {
|
|
7079
|
+
return void 0;
|
|
7080
|
+
}
|
|
7081
|
+
const parsed = parseRules(raw);
|
|
7082
|
+
if (parsed === void 0) return void 0;
|
|
7083
|
+
if (!shouldActivateRule(parsed.frontmatter, opts.touchedFiles ?? [])) return void 0;
|
|
7084
|
+
return {
|
|
7085
|
+
id,
|
|
7086
|
+
source: path,
|
|
7087
|
+
content: parsed.body,
|
|
7088
|
+
priority: spec.priority,
|
|
7089
|
+
truncated: false
|
|
7090
|
+
};
|
|
7091
|
+
}
|
|
6998
7092
|
async function loadPlainMarkdownSource(spec, path, id, opts) {
|
|
6999
7093
|
const loaded = await loadPlainMarkdown(path, { maxBytesPerFile: opts.maxBytesPerFile });
|
|
7000
7094
|
if (loaded === void 0) return void 0;
|
|
@@ -7020,6 +7114,7 @@ var init_context_discovery_runner = __esm({
|
|
|
7020
7114
|
init_context_import_resolver();
|
|
7021
7115
|
init_context_loaders();
|
|
7022
7116
|
init_context_mdc_parser();
|
|
7117
|
+
init_context_rules_frontmatter();
|
|
7023
7118
|
}
|
|
7024
7119
|
});
|
|
7025
7120
|
var ContextSourceFrontmatterSchema;
|
|
@@ -7155,6 +7250,10 @@ function matchesGlob(pattern, path) {
|
|
|
7155
7250
|
function tokenizeContent(content) {
|
|
7156
7251
|
return content.split(/\s+/).filter((token) => token.length > 0);
|
|
7157
7252
|
}
|
|
7253
|
+
function sameScope(a, b) {
|
|
7254
|
+
if (a.length !== b.length) return false;
|
|
7255
|
+
return a.every((v, i) => v === b[i]);
|
|
7256
|
+
}
|
|
7158
7257
|
var FileContextManager;
|
|
7159
7258
|
var init_context_manager = __esm({
|
|
7160
7259
|
"src/internal/runtime/context/context-manager.ts"() {
|
|
@@ -7175,6 +7274,13 @@ var init_context_manager = __esm({
|
|
|
7175
7274
|
settings;
|
|
7176
7275
|
settingSourcesIncludeProject;
|
|
7177
7276
|
state;
|
|
7277
|
+
/**
|
|
7278
|
+
* The in-scope file set used by the most recent `refresh`. Tracked so
|
|
7279
|
+
* `applyScope` only touches state when the scope actually changes — a
|
|
7280
|
+
* caller that never scopes (the common case) keeps the create-time
|
|
7281
|
+
* snapshot untouched, at zero per-send cost.
|
|
7282
|
+
*/
|
|
7283
|
+
lastScope = [];
|
|
7178
7284
|
async initialize() {
|
|
7179
7285
|
if (!this.settingSourcesIncludeProject && this.settings.manager !== "file") {
|
|
7180
7286
|
this.state = { config: { sources: [] }, loadedSources: [] };
|
|
@@ -7182,14 +7288,31 @@ var init_context_manager = __esm({
|
|
|
7182
7288
|
}
|
|
7183
7289
|
await this.refresh();
|
|
7184
7290
|
}
|
|
7185
|
-
|
|
7291
|
+
/**
|
|
7292
|
+
* Re-run discovery for a specific per-send in-scope file set (T3). Path-scoped
|
|
7293
|
+
* rules (`.theokit/rules/*.md`, `.cursor/rules/*.mdc` globs) activate iff a
|
|
7294
|
+
* pattern matches one of `contextPaths`. Idempotent: unchanged scope is a
|
|
7295
|
+
* no-op, and `undefined` scope while never previously scoped never touches
|
|
7296
|
+
* state (preserves the create-time snapshot for non-users).
|
|
7297
|
+
*/
|
|
7298
|
+
async applyScope(contextPaths) {
|
|
7299
|
+
const scope = contextPaths ?? [];
|
|
7300
|
+
if (scope.length === 0 && this.lastScope.length === 0) return;
|
|
7301
|
+
if (sameScope(scope, this.lastScope)) return;
|
|
7302
|
+
await this.refresh({ touchedFiles: scope });
|
|
7303
|
+
}
|
|
7304
|
+
async refresh(opts) {
|
|
7305
|
+
const touchedFiles = opts?.touchedFiles ?? [];
|
|
7306
|
+
this.lastScope = [...touchedFiles];
|
|
7186
7307
|
const config = await loadContextConfig(this.cwd);
|
|
7187
7308
|
const legacy = await loadSources(config, this.cwd);
|
|
7188
7309
|
const maxBytesPerFile = this.settings.maxBytesPerFile ?? DEFAULT_MAX_BYTES_PER_FILE;
|
|
7189
7310
|
const maxBytesTotal = this.settings.maxBytesTotal ?? DEFAULT_MAX_BYTES_TOTAL;
|
|
7190
7311
|
const discovered = await runDiscovery({
|
|
7191
7312
|
cwd: this.cwd,
|
|
7192
|
-
maxBytesPerFile
|
|
7313
|
+
maxBytesPerFile,
|
|
7314
|
+
touchedFiles
|
|
7315
|
+
});
|
|
7193
7316
|
const legacyAsAggregator = legacy.map((src) => ({
|
|
7194
7317
|
id: src.name,
|
|
7195
7318
|
source: src.path,
|
|
@@ -9382,7 +9505,10 @@ async function runAgentLoop(inputs) {
|
|
|
9382
9505
|
}
|
|
9383
9506
|
budget.consume();
|
|
9384
9507
|
inputs.budgetTracker?.nextIteration?.();
|
|
9385
|
-
if (inputs.signal?.aborted === true)
|
|
9508
|
+
if (inputs.signal?.aborted === true) {
|
|
9509
|
+
ctx.finalStatus = "cancelled";
|
|
9510
|
+
break;
|
|
9511
|
+
}
|
|
9386
9512
|
}
|
|
9387
9513
|
if (lastTurnDecision === "continue" && budget.shouldContinue() === false) {
|
|
9388
9514
|
ctx.stoppedAtIterationLimit = true;
|
|
@@ -9567,15 +9693,15 @@ async function guardAndTransformToolResults(inputs, raw, ctx) {
|
|
|
9567
9693
|
}
|
|
9568
9694
|
async function continueOrTerminate(inputs, ctx, llmOutput) {
|
|
9569
9695
|
if (llmOutput.errored) return "error";
|
|
9570
|
-
|
|
9571
|
-
|
|
9696
|
+
const tCtx = { agentId: inputs.agentId, runId: inputs.runId };
|
|
9697
|
+
const text = llmOutput.text.length > 0 ? await transformLlmOutputText(inputs, llmOutput.text, tCtx) : llmOutput.text;
|
|
9698
|
+
if (text.length > 0) {
|
|
9699
|
+
await emitAssistantTextStep(inputs, ctx, text);
|
|
9572
9700
|
}
|
|
9573
9701
|
if (llmOutput.stopReason !== "tool_use" || llmOutput.toolCalls.length === 0) {
|
|
9574
9702
|
return finishOrReflect(inputs, ctx, llmOutput);
|
|
9575
9703
|
}
|
|
9576
|
-
|
|
9577
|
-
const outText = await transformLlmOutputText(inputs, llmOutput.text, tCtx);
|
|
9578
|
-
ctx.messages.push(buildAssistantTurn(outText, llmOutput.toolCalls));
|
|
9704
|
+
ctx.messages.push(buildAssistantTurn(text, llmOutput.toolCalls));
|
|
9579
9705
|
const rawResults = await dispatchTools(
|
|
9580
9706
|
// SE12 — forward a read-only text projection of the transcript-so-far to tool
|
|
9581
9707
|
// handlers via `ctx.messages` (consumed by defineSubAgent's messageFilter).
|
|
@@ -12899,7 +13025,12 @@ var init_client = __esm({
|
|
|
12899
13025
|
code: "mcp_http_error"
|
|
12900
13026
|
});
|
|
12901
13027
|
}
|
|
12902
|
-
|
|
13028
|
+
try {
|
|
13029
|
+
return await response.json();
|
|
13030
|
+
} catch (cause) {
|
|
13031
|
+
if (isAbortLike(cause)) throw mcpTimeoutError(this.name, timeoutMs);
|
|
13032
|
+
throw cause;
|
|
13033
|
+
}
|
|
12903
13034
|
}
|
|
12904
13035
|
};
|
|
12905
13036
|
}
|
|
@@ -13139,9 +13270,11 @@ function declarativeSubagentTools(agentOptions, parentTools) {
|
|
|
13139
13270
|
return subAgentToolsFromDefinitions(agents2, parentTools);
|
|
13140
13271
|
}
|
|
13141
13272
|
function bindParentCredentials(tools, agentOptions) {
|
|
13273
|
+
const parentPlugins = Array.isArray(agentOptions.plugins) ? agentOptions.plugins : void 0;
|
|
13142
13274
|
const credentials = {
|
|
13143
13275
|
...agentOptions.apiKey !== void 0 ? { apiKey: agentOptions.apiKey } : {},
|
|
13144
|
-
...typeof agentOptions.model === "object" ? { model: agentOptions.model } : {}
|
|
13276
|
+
...typeof agentOptions.model === "object" ? { model: agentOptions.model } : {},
|
|
13277
|
+
...parentPlugins !== void 0 ? { plugins: parentPlugins } : {}
|
|
13145
13278
|
};
|
|
13146
13279
|
for (const tool of tools) inheritSubAgentCredentials(tool, credentials);
|
|
13147
13280
|
}
|
|
@@ -15666,10 +15799,11 @@ var init_local_agent_memory = __esm({
|
|
|
15666
15799
|
}
|
|
15667
15800
|
buildTelemetryRecallArgs(telemetry) {
|
|
15668
15801
|
const userId = typeof this.options.memoryContext?.userId === "string" ? this.options.memoryContext.userId : void 0;
|
|
15802
|
+
const tenantId = typeof this.options.memoryContext?.tenantId === "string" ? this.options.memoryContext.tenantId : void 0;
|
|
15669
15803
|
return {
|
|
15670
15804
|
...telemetry !== void 0 ? { telemetry } : {},
|
|
15671
15805
|
...userId !== void 0 ? { userId } : {},
|
|
15672
|
-
namespace: "default",
|
|
15806
|
+
namespace: tenantId ?? "default",
|
|
15673
15807
|
scope: "session"
|
|
15674
15808
|
};
|
|
15675
15809
|
}
|
|
@@ -16966,7 +17100,8 @@ async function executeSendLocked(inputs, message, options) {
|
|
|
16966
17100
|
userText,
|
|
16967
17101
|
baseSystemPrompt,
|
|
16968
17102
|
memoryFacts,
|
|
16969
|
-
activeMemorySummary
|
|
17103
|
+
activeMemorySummary,
|
|
17104
|
+
options.contextPaths
|
|
16970
17105
|
);
|
|
16971
17106
|
const projectedSystemPrompt = await projectCurrentObjective(
|
|
16972
17107
|
inputs.storageHandle,
|
|
@@ -17854,7 +17989,7 @@ var init_local_agent = __esm({
|
|
|
17854
17989
|
runPreHook: (ut) => this.runPreHook(ut),
|
|
17855
17990
|
// biome-ignore format: G8 budget — callbacks wire to private methods.
|
|
17856
17991
|
resolveSystemPromptForSend: (ut, o, mf) => this.resolveSystemPrompt(ut, o, mf),
|
|
17857
|
-
assembleSystemPromptForSend: (ut, bp, mf, ams) => assembleSystemPromptForSend(this.assemblyInputs(), ut, bp, mf, ams),
|
|
17992
|
+
assembleSystemPromptForSend: (ut, bp, mf, ams, cp) => assembleSystemPromptForSend(this.assemblyInputs(), ut, bp, mf, ams, cp),
|
|
17858
17993
|
dispatchRun: (msg, o, sp, mf, pm, mt, mp) => this.dispatchRun(msg, o, sp, mf, pm, mt, mp)
|
|
17859
17994
|
},
|
|
17860
17995
|
message,
|
|
@@ -19002,15 +19137,19 @@ async function collectChildToolResults(run) {
|
|
|
19002
19137
|
${lines.join("\n")}
|
|
19003
19138
|
</subagent-tool-results>`;
|
|
19004
19139
|
}
|
|
19005
|
-
|
|
19006
|
-
const { Agent: Agent2 } = await Promise.resolve().then(() => (init_agent(), agent_exports));
|
|
19140
|
+
function buildChildCreateOptions(spec, inherited) {
|
|
19007
19141
|
const model = spec.model ? { id: spec.model } : inherited?.model;
|
|
19008
|
-
|
|
19142
|
+
return {
|
|
19009
19143
|
...inherited?.apiKey !== void 0 ? { apiKey: inherited.apiKey } : {},
|
|
19010
19144
|
...model !== void 0 ? { model } : {},
|
|
19145
|
+
...inherited?.plugins !== void 0 ? { plugins: inherited.plugins } : {},
|
|
19011
19146
|
systemPrompt: spec.instructions,
|
|
19012
19147
|
tools: spec.tools ?? []
|
|
19013
|
-
}
|
|
19148
|
+
};
|
|
19149
|
+
}
|
|
19150
|
+
async function runChildAgent(spec, input, signal, maxSteps, inherited) {
|
|
19151
|
+
const { Agent: Agent2 } = await Promise.resolve().then(() => (init_agent(), agent_exports));
|
|
19152
|
+
const agent = await Agent2.create(buildChildCreateOptions(spec, inherited));
|
|
19014
19153
|
try {
|
|
19015
19154
|
const sendOptions = {
|
|
19016
19155
|
...signal !== void 0 ? { signal } : {},
|