@aexhq/sdk 0.40.15 → 0.41.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/README.md +25 -25
- package/dist/_contracts/api-key.d.ts +6 -4
- package/dist/_contracts/api-key.js +20 -7
- package/dist/_contracts/asset-upload-helper.d.ts +2 -2
- package/dist/_contracts/asset-upload-helper.js +2 -2
- package/dist/_contracts/connection-ticket.d.ts +5 -5
- package/dist/_contracts/connection-ticket.js +7 -7
- package/dist/_contracts/error-codes.d.ts +1 -1
- package/dist/_contracts/error-codes.js +4 -4
- package/dist/_contracts/error-factory.js +1 -1
- package/dist/_contracts/event-envelope.d.ts +41 -41
- package/dist/_contracts/event-envelope.js +49 -49
- package/dist/_contracts/event-stream-client.d.ts +9 -9
- package/dist/_contracts/event-stream-client.js +5 -5
- package/dist/_contracts/event-view.d.ts +6 -6
- package/dist/_contracts/event-view.js +12 -12
- package/dist/_contracts/http.js +1 -1
- package/dist/_contracts/index.d.ts +10 -10
- package/dist/_contracts/index.js +9 -9
- package/dist/_contracts/models.d.ts +17 -17
- package/dist/_contracts/models.js +14 -14
- package/dist/_contracts/operations.d.ts +79 -82
- package/dist/_contracts/operations.js +233 -243
- package/dist/_contracts/provider-support.d.ts +2 -2
- package/dist/_contracts/runner-event.d.ts +8 -8
- package/dist/_contracts/runner-event.js +9 -9
- package/dist/_contracts/runtime-manifest.d.ts +12 -12
- package/dist/_contracts/runtime-manifest.js +1 -1
- package/dist/_contracts/runtime-sizes.d.ts +12 -12
- package/dist/_contracts/runtime-sizes.js +18 -18
- package/dist/_contracts/runtime-types.d.ts +117 -117
- package/dist/_contracts/runtime-types.js +2 -2
- package/dist/_contracts/sdk-errors.d.ts +3 -3
- package/dist/_contracts/sdk-errors.js +4 -4
- package/dist/_contracts/sdk-secrets.js +10 -10
- package/dist/_contracts/session-artifacts.d.ts +151 -0
- package/dist/_contracts/session-artifacts.js +234 -0
- package/dist/_contracts/{run-config.d.ts → session-config.d.ts} +29 -29
- package/dist/_contracts/{run-config.js → session-config.js} +37 -37
- package/dist/_contracts/session-cost.d.ts +140 -0
- package/dist/_contracts/{run-cost.js → session-cost.js} +94 -94
- package/dist/_contracts/{run-custody.d.ts → session-custody.d.ts} +16 -16
- package/dist/_contracts/{run-custody.js → session-custody.js} +42 -42
- package/dist/_contracts/session-record.d.ts +112 -0
- package/dist/_contracts/{run-record.js → session-record.js} +23 -23
- package/dist/_contracts/session-retention.d.ts +209 -0
- package/dist/_contracts/{run-retention.js → session-retention.js} +116 -116
- package/dist/_contracts/{run-unit.d.ts → session-unit.d.ts} +38 -38
- package/dist/_contracts/{run-unit.js → session-unit.js} +33 -33
- package/dist/_contracts/side-effect-audit.d.ts +14 -14
- package/dist/_contracts/side-effect-audit.js +38 -38
- package/dist/_contracts/sse.d.ts +1 -1
- package/dist/_contracts/sse.js +0 -0
- package/dist/_contracts/stable.d.ts +1 -1
- package/dist/_contracts/stable.js +1 -1
- package/dist/_contracts/status.d.ts +18 -18
- package/dist/_contracts/status.js +19 -19
- package/dist/_contracts/submission.d.ts +101 -99
- package/dist/_contracts/submission.js +96 -96
- package/dist/_contracts/{run-trace.d.ts → turn-trace.d.ts} +1 -1
- package/dist/_contracts/webhook-verify.d.ts +1 -1
- package/dist/_contracts/webhook-verify.js +1 -1
- package/dist/agents-md.d.ts +4 -4
- package/dist/agents-md.js +5 -5
- package/dist/agents-md.js.map +1 -1
- package/dist/bundle.d.ts +1 -1
- package/dist/bundle.js +1 -1
- package/dist/bundle.js.map +1 -1
- package/dist/cli.mjs +580 -623
- package/dist/cli.mjs.sha256 +1 -1
- package/dist/client.d.ts +141 -155
- package/dist/client.js +236 -245
- package/dist/client.js.map +1 -1
- package/dist/fetch-archive.js +3 -3
- package/dist/file.d.ts +7 -7
- package/dist/file.js +8 -8
- package/dist/file.js.map +1 -1
- package/dist/index.d.ts +10 -10
- package/dist/index.js +8 -8
- package/dist/index.js.map +1 -1
- package/dist/mcp-server.d.ts +1 -1
- package/dist/retry.d.ts +1 -1
- package/dist/secret.d.ts +6 -6
- package/dist/secret.js +6 -6
- package/dist/secret.js.map +1 -1
- package/dist/skill.d.ts +2 -2
- package/dist/skill.js +3 -3
- package/dist/skill.js.map +1 -1
- package/dist/tool.js +2 -2
- package/dist/tool.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/version.js.map +1 -1
- package/docs/authentication.md +11 -11
- package/docs/billing.md +3 -3
- package/docs/cleanup.md +5 -5
- package/docs/concepts/agent-tools.md +5 -5
- package/docs/concepts/composition.md +3 -3
- package/docs/concepts/providers-and-runtimes.md +3 -3
- package/docs/concepts/{runs.md → sessions.md} +8 -8
- package/docs/concepts/subagents.md +16 -16
- package/docs/credentials.md +7 -7
- package/docs/defaults.md +14 -14
- package/docs/errors.md +10 -10
- package/docs/events.md +26 -26
- package/docs/files.md +267 -0
- package/docs/limits-and-quotas.md +35 -35
- package/docs/limits.md +6 -6
- package/docs/mcp.md +3 -3
- package/docs/networking.md +24 -24
- package/docs/provider-runtime-capabilities.md +1 -1
- package/docs/public-surface.json +6 -6
- package/docs/quickstart.md +13 -13
- package/docs/release.md +5 -5
- package/docs/retries.md +3 -3
- package/docs/secrets.md +16 -16
- package/docs/session-config.md +58 -0
- package/docs/{run-record.md → session-record.md} +16 -16
- package/docs/skills.md +9 -9
- package/docs/vision-skills.md +7 -7
- package/docs/webhooks.md +11 -11
- package/examples/feature-tour.ts +17 -17
- package/examples/spike-settle-latency.ts +11 -11
- package/package.json +1 -1
- package/dist/_contracts/run-artifacts.d.ts +0 -49
- package/dist/_contracts/run-artifacts.js +0 -102
- package/dist/_contracts/run-cost.d.ts +0 -140
- package/dist/_contracts/run-record.d.ts +0 -116
- package/dist/_contracts/run-retention.d.ts +0 -209
- package/docs/outputs.md +0 -267
- package/docs/run-config.md +0 -58
- /package/dist/_contracts/{run-trace.js → turn-trace.js} +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { SKILL_NAME_PATTERN, SKILL_RESERVED_NAMES, TOOL_NAME_PATTERN, normaliseSkillBundlePath, parseAssetRefFields, parseMcpServerRef } from "./
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { SKILL_NAME_PATTERN, SKILL_RESERVED_NAMES, TOOL_NAME_PATTERN, normaliseSkillBundlePath, parseAssetRefFields, parseMcpServerRef } from "./session-config.js";
|
|
2
|
+
import { parseSessionTimeout, parseRuntimeSize } from "./runtime-sizes.js";
|
|
3
|
+
import { assertModelNameMatchesProvider, parseModelName } from "./models.js";
|
|
4
4
|
import { parseRuntimeSecurityProfile } from "./runtime-security-profile.js";
|
|
5
5
|
/**
|
|
6
6
|
* Reserved prefix for aex-set runtime env vars (`AEX_CLI`,
|
|
@@ -61,12 +61,12 @@ export function packageInstallString(pkg) {
|
|
|
61
61
|
}
|
|
62
62
|
}
|
|
63
63
|
/**
|
|
64
|
-
*
|
|
64
|
+
* SessionRecord-time provider selector. Aex exposes one customer interface
|
|
65
65
|
* for every provider. All new submissions execute through the managed
|
|
66
66
|
* runtime; provider selection only decides which upstream model route
|
|
67
67
|
* the managed provider-proxy uses.
|
|
68
68
|
*/
|
|
69
|
-
export const
|
|
69
|
+
export const PROVIDERS = [
|
|
70
70
|
"anthropic",
|
|
71
71
|
"deepseek",
|
|
72
72
|
"openai",
|
|
@@ -76,7 +76,7 @@ export const RUN_PROVIDERS = [
|
|
|
76
76
|
"doubao",
|
|
77
77
|
"doubao-cn"
|
|
78
78
|
];
|
|
79
|
-
export const
|
|
79
|
+
export const DEFAULT_PROVIDER = "anthropic";
|
|
80
80
|
/**
|
|
81
81
|
* Symbol-style accessors for the closed provider set. Prefer these over raw
|
|
82
82
|
* strings so an invalid token is a compile error, not a runtime 400 — e.g.
|
|
@@ -85,8 +85,8 @@ export const DEFAULT_RUN_PROVIDER = "anthropic";
|
|
|
85
85
|
* submission field; name it explicitly with one of these constants rather than
|
|
86
86
|
* relying on the model alone to determine routing.
|
|
87
87
|
*
|
|
88
|
-
* Every value mirrors {@link
|
|
89
|
-
* `Object.values(Providers)` deep-equals `
|
|
88
|
+
* Every value mirrors {@link PROVIDERS} exactly; a unit test asserts
|
|
89
|
+
* `Object.values(Providers)` deep-equals `PROVIDERS` so the two can never
|
|
90
90
|
* drift.
|
|
91
91
|
*/
|
|
92
92
|
export const Providers = {
|
|
@@ -162,7 +162,7 @@ function parseEnvironment(input) {
|
|
|
162
162
|
* targets.
|
|
163
163
|
* - Bounded: max ENV_VARS_MAX_ENTRIES entries, max
|
|
164
164
|
* ENV_VARS_MAX_VALUE_BYTES per value, max ENV_VARS_MAX_TOTAL_BYTES
|
|
165
|
-
* overall. The caps stop a
|
|
165
|
+
* overall. The caps stop a sessionaway customer from making the
|
|
166
166
|
* mounted RUNTIME files unbounded.
|
|
167
167
|
* - Values are arbitrary UTF-8 strings, EXCEPT NUL bytes are
|
|
168
168
|
* rejected (NUL terminates C-strings and breaks env-var
|
|
@@ -187,7 +187,7 @@ function parseEnvVars(input) {
|
|
|
187
187
|
throw new Error(`submission.environment.envVars.${key} key must match /^[A-Z_][A-Z0-9_]*$/`);
|
|
188
188
|
}
|
|
189
189
|
if (key.startsWith(AEX_RESERVED_ENV_PREFIX)) {
|
|
190
|
-
throw new Error(`submission.environment.envVars.${key} uses reserved prefix "${AEX_RESERVED_ENV_PREFIX}" (set by aex
|
|
190
|
+
throw new Error(`submission.environment.envVars.${key} uses reserved prefix "${AEX_RESERVED_ENV_PREFIX}" (set by aex starttime)`);
|
|
191
191
|
}
|
|
192
192
|
const raw = value[key];
|
|
193
193
|
if (typeof raw !== "string") {
|
|
@@ -318,7 +318,7 @@ export function crossValidateSecretEnvAndValues(secretEnv, envSecrets) {
|
|
|
318
318
|
export function parseInlineSecrets(input) {
|
|
319
319
|
// Absent/null secrets collapse to an empty bundle; the credential-policy gate
|
|
320
320
|
// (enforceCredentialSecretPolicy) decides whether that is admissible for the
|
|
321
|
-
//
|
|
321
|
+
// session's mode (a session inheriting keys server-side may legitimately omit them).
|
|
322
322
|
if (input === undefined || input === null)
|
|
323
323
|
return {};
|
|
324
324
|
const value = requireRecord(input, "secrets");
|
|
@@ -345,7 +345,7 @@ export function parseInlineSecrets(input) {
|
|
|
345
345
|
}
|
|
346
346
|
/**
|
|
347
347
|
* Parse the per-provider BYOK key map. Each key must name a known
|
|
348
|
-
* {@link
|
|
348
|
+
* {@link ProviderName}; each value must be a non-empty string. Returns
|
|
349
349
|
* `undefined` for an absent or empty map so the spread above stays clean.
|
|
350
350
|
*/
|
|
351
351
|
function parseApiKeys(input) {
|
|
@@ -354,8 +354,8 @@ function parseApiKeys(input) {
|
|
|
354
354
|
const value = requireRecord(input, "secrets.apiKeys");
|
|
355
355
|
const out = {};
|
|
356
356
|
for (const [provider, key] of Object.entries(value)) {
|
|
357
|
-
if (!
|
|
358
|
-
throw new Error(`secrets.apiKeys["${provider}"] is not a known provider; permitted: ${
|
|
357
|
+
if (!PROVIDERS.includes(provider)) {
|
|
358
|
+
throw new Error(`secrets.apiKeys["${provider}"] is not a known provider; permitted: ${PROVIDERS.join(", ")}`);
|
|
359
359
|
}
|
|
360
360
|
if (typeof key !== "string" || key.length === 0) {
|
|
361
361
|
throw new Error(`secrets.apiKeys["${provider}"] must be a non-empty string`);
|
|
@@ -522,7 +522,7 @@ function isJsonValue(input) {
|
|
|
522
522
|
}
|
|
523
523
|
return false;
|
|
524
524
|
}
|
|
525
|
-
export function
|
|
525
|
+
export function parseSessionSubmissionRequest(input, options = {}) {
|
|
526
526
|
const value = requireRecord(input, "submission");
|
|
527
527
|
const allowedTopLevelFields = new Set([
|
|
528
528
|
"workspaceId",
|
|
@@ -553,18 +553,18 @@ export function parseRunSubmissionRequest(input, options = {}) {
|
|
|
553
553
|
}
|
|
554
554
|
assertNoSecretBearingFields(fieldValue, [key]);
|
|
555
555
|
}
|
|
556
|
-
const provider =
|
|
556
|
+
const provider = parseProviderName(value.provider);
|
|
557
557
|
const runtimeSize = parseRuntimeSize(value.runtimeSize);
|
|
558
|
-
const timeoutMs =
|
|
559
|
-
const webhook =
|
|
560
|
-
const limits =
|
|
561
|
-
const machine =
|
|
558
|
+
const timeoutMs = parseSessionTimeout(value.timeout);
|
|
559
|
+
const webhook = parseSessionWebhook(value.webhook);
|
|
560
|
+
const limits = parseSessionLimits(value.limits);
|
|
561
|
+
const machine = parseSessionMachine(value.machine);
|
|
562
562
|
const secrets = parseInlineSecrets(value.secrets);
|
|
563
563
|
enforceCredentialSecretPolicy(secrets, provider);
|
|
564
564
|
const submission = parseSubmission(value.submission, {
|
|
565
565
|
trustedReparse: options.trustedReparse === true
|
|
566
566
|
});
|
|
567
|
-
|
|
567
|
+
assertModelNameMatchesProvider(provider, submission.model);
|
|
568
568
|
// Fail-closed streaming: `outputMode:'stream'` on a non-streamable provider is
|
|
569
569
|
// a hard reject at parse time (no silent downgrade).
|
|
570
570
|
assertStreamableOutputMode(submission.outputMode, provider);
|
|
@@ -601,14 +601,14 @@ export function parseRunSubmissionRequest(input, options = {}) {
|
|
|
601
601
|
};
|
|
602
602
|
}
|
|
603
603
|
/**
|
|
604
|
-
* Parse + SSRF-shape-validate the optional per-
|
|
604
|
+
* Parse + SSRF-shape-validate the optional per-session `webhook`. The URL must be
|
|
605
605
|
* https with no userinfo (a `user:pass@host` URL is rejected — credentials must
|
|
606
606
|
* not ride in a callback URL). Unknown subfields are rejected so the strict
|
|
607
607
|
* top-level allow-list extends to the nested object. Returns `undefined` when
|
|
608
608
|
* absent. Delivery-time re-resolution + IP-deny checks live server-side; this
|
|
609
609
|
* is the submit-time shape gate.
|
|
610
610
|
*/
|
|
611
|
-
export function
|
|
611
|
+
export function parseSessionWebhook(input) {
|
|
612
612
|
if (input === undefined) {
|
|
613
613
|
return undefined;
|
|
614
614
|
}
|
|
@@ -636,28 +636,28 @@ export function parseRunWebhook(input) {
|
|
|
636
636
|
return { url };
|
|
637
637
|
}
|
|
638
638
|
/**
|
|
639
|
-
* Parse the optional per-
|
|
639
|
+
* Parse the optional per-session `limits` override. Mirrors {@link parseSessionWebhook}:
|
|
640
640
|
* absent ⇒ `undefined`; a non-object or any unknown subfield is rejected so the
|
|
641
641
|
* strict top-level allow-list extends to the nested object. Each present field
|
|
642
642
|
* is validated as a positive safe integer via {@link optionalPositiveInt}.
|
|
643
643
|
*
|
|
644
644
|
* This is a SHAPE/positivity gate only — it does NOT clamp to the workspace or
|
|
645
|
-
* platform ceilings (that precedence lives in the resolver, `
|
|
645
|
+
* platform ceilings (that precedence lives in the resolver, `resolveSessionLimits`).
|
|
646
646
|
* Only the present fields are returned; an all-absent override (e.g. `{}`)
|
|
647
647
|
* collapses to `undefined` so it carries no signal onto the request.
|
|
648
648
|
*/
|
|
649
|
-
export function
|
|
649
|
+
export function parseSessionLimits(input) {
|
|
650
650
|
if (input === undefined) {
|
|
651
651
|
return undefined;
|
|
652
652
|
}
|
|
653
653
|
const value = requireRecord(input, "limits");
|
|
654
|
-
const allowed = new Set(["
|
|
654
|
+
const allowed = new Set(["maxConcurrentChildSessions", "maxSubagentDepth", "maxSpendUsd", "maxTurns"]);
|
|
655
655
|
for (const key of Object.keys(value)) {
|
|
656
656
|
if (!allowed.has(key)) {
|
|
657
657
|
throw new Error(`limits.${key} is not an allowed field; permitted: ${[...allowed].join(", ")}`);
|
|
658
658
|
}
|
|
659
659
|
}
|
|
660
|
-
const
|
|
660
|
+
const maxConcurrentChildSessions = optionalPositiveInt(value.maxConcurrentChildSessions, "limits.maxConcurrentChildSessions");
|
|
661
661
|
const maxSubagentDepth = optionalPositiveInt(value.maxSubagentDepth, "limits.maxSubagentDepth");
|
|
662
662
|
// maxSpendUsd is a USD amount (may be fractional, e.g. $2.50) so it is a positive
|
|
663
663
|
// NUMBER, not a positive int. Clamping to the workspace/platform ceiling is the
|
|
@@ -667,32 +667,32 @@ export function parseRunLimits(input) {
|
|
|
667
667
|
// is the resolver's job; here we enforce shape + positivity only.
|
|
668
668
|
const maxTurns = optionalPositiveInt(value.maxTurns, "limits.maxTurns");
|
|
669
669
|
// Collapse an all-absent override (e.g. `limits: {}`) to `undefined` so it never
|
|
670
|
-
// lands an empty object on the request — matches sibling parsers (
|
|
670
|
+
// lands an empty object on the request — matches sibling parsers (parseSessionWebhook,
|
|
671
671
|
// parseEnvironment). The resolver supplies platform defaults for absent fields.
|
|
672
|
-
if (
|
|
672
|
+
if (maxConcurrentChildSessions === undefined &&
|
|
673
673
|
maxSubagentDepth === undefined &&
|
|
674
674
|
maxSpendUsd === undefined &&
|
|
675
675
|
maxTurns === undefined) {
|
|
676
676
|
return undefined;
|
|
677
677
|
}
|
|
678
678
|
return {
|
|
679
|
-
...(
|
|
679
|
+
...(maxConcurrentChildSessions !== undefined ? { maxConcurrentChildSessions } : {}),
|
|
680
680
|
...(maxSubagentDepth !== undefined ? { maxSubagentDepth } : {}),
|
|
681
681
|
...(maxSpendUsd !== undefined ? { maxSpendUsd } : {}),
|
|
682
682
|
...(maxTurns !== undefined ? { maxTurns } : {})
|
|
683
683
|
};
|
|
684
684
|
}
|
|
685
685
|
/**
|
|
686
|
-
* Boot-session budget fragment. The public submit surface names a
|
|
686
|
+
* Boot-session budget fragment. The public submit surface names a session's spend
|
|
687
687
|
* cap `limits.maxSpendUsd`; the frozen boot session config the managed runtime
|
|
688
688
|
* folds the loop against names the SAME USD value `budgetUsd` — the field the
|
|
689
|
-
* session planner reads to enforce/terminate a
|
|
689
|
+
* session planner reads to enforce/terminate a session that would out-spend its cap.
|
|
690
690
|
* This is the single source of truth for that wire→boot name mapping so the two
|
|
691
691
|
* layers can never drift.
|
|
692
692
|
*
|
|
693
693
|
* Returns a fragment safe to spread into `sessionConfig.limits`: `{ budgetUsd }`
|
|
694
|
-
* when a cap is set, `{}` when none is (an absent cap stays absent — the
|
|
695
|
-
* unbounded per-
|
|
694
|
+
* when a cap is set, `{}` when none is (an absent cap stays absent — the session is
|
|
695
|
+
* unbounded per-session, subject only to the session timeout + the per-workspace cap).
|
|
696
696
|
* Pure: same input ⇒ same output.
|
|
697
697
|
*/
|
|
698
698
|
export function sessionBudgetLimits(limits) {
|
|
@@ -702,15 +702,15 @@ export function sessionBudgetLimits(limits) {
|
|
|
702
702
|
return { budgetUsd: limits.maxSpendUsd };
|
|
703
703
|
}
|
|
704
704
|
/**
|
|
705
|
-
* Parse the optional per-
|
|
706
|
-
* {@link
|
|
705
|
+
* Parse the optional per-session `machine` capacity intent. Mirrors
|
|
706
|
+
* {@link parseSessionWebhook}: absent ⇒ `undefined`; a non-object or any unknown
|
|
707
707
|
* subfield is rejected so the strict top-level allow-list extends to the nested
|
|
708
708
|
* object. `spot` must be a boolean when present. A no-signal object (e.g.
|
|
709
709
|
* `machine: {}`) collapses to `undefined` so it never lands an empty object on
|
|
710
710
|
* the request. An explicit `spot` (true or false) is preserved verbatim. Only
|
|
711
711
|
* shape is validated here — capacity selection is a runtime concern.
|
|
712
712
|
*/
|
|
713
|
-
export function
|
|
713
|
+
export function parseSessionMachine(input) {
|
|
714
714
|
if (input === undefined) {
|
|
715
715
|
return undefined;
|
|
716
716
|
}
|
|
@@ -729,23 +729,23 @@ export function parseRunMachine(input) {
|
|
|
729
729
|
}
|
|
730
730
|
return { spot: value.spot };
|
|
731
731
|
}
|
|
732
|
-
export function
|
|
732
|
+
export function parseProviderName(input) {
|
|
733
733
|
if (input === undefined) {
|
|
734
|
-
return
|
|
734
|
+
return DEFAULT_PROVIDER;
|
|
735
735
|
}
|
|
736
|
-
if (typeof input !== "string" || !
|
|
737
|
-
throw new Error(`provider must be one of: ${
|
|
736
|
+
if (typeof input !== "string" || !PROVIDERS.includes(input)) {
|
|
737
|
+
throw new Error(`provider must be one of: ${PROVIDERS.join(", ")} (got ${JSON.stringify(input)})`);
|
|
738
738
|
}
|
|
739
739
|
return input;
|
|
740
740
|
}
|
|
741
741
|
/**
|
|
742
742
|
* Cross-check the supplied secrets bundle against the credential mode. BYOK
|
|
743
|
-
* requires `secrets.apiKeys[provider]` (the key for the
|
|
744
|
-
* Additional provider keys are optional (validated for shape only) so the
|
|
743
|
+
* requires `secrets.apiKeys[provider]` (the key for the session's own `provider`).
|
|
744
|
+
* Additional provider keys are optional (validated for shape only) so the session
|
|
745
745
|
* can supply keys for the other providers its subagents may use. MCP / proxy
|
|
746
746
|
* endpoint auth carry across providers and are not checked here.
|
|
747
747
|
*
|
|
748
|
-
* A CHILD
|
|
748
|
+
* A CHILD session (`inheritsFromParent`) is exempt from the own-key requirement: it
|
|
749
749
|
* inherits its provider keys server-side from the parent's vaulted bundle, so
|
|
750
750
|
* it need not carry any of its own. The server still verifies, at admission,
|
|
751
751
|
* that the parent actually holds a key for the child's provider.
|
|
@@ -773,7 +773,7 @@ export function parseSubmission(input, options = {}) {
|
|
|
773
773
|
"environment",
|
|
774
774
|
"securityProfile",
|
|
775
775
|
"metadata",
|
|
776
|
-
"
|
|
776
|
+
"fileCapture",
|
|
777
777
|
"includeBuiltinTools",
|
|
778
778
|
"outputMode",
|
|
779
779
|
"responseFormat",
|
|
@@ -785,7 +785,7 @@ export function parseSubmission(input, options = {}) {
|
|
|
785
785
|
throw new Error(`submission.${key} is not an allowed field; permitted: ${[...allowed].join(", ")}`);
|
|
786
786
|
}
|
|
787
787
|
}
|
|
788
|
-
const model =
|
|
788
|
+
const model = parseModelName(value.model, "submission.model");
|
|
789
789
|
const system = optionalString(value.system, "submission.system");
|
|
790
790
|
const prompt = parsePrompt(value.prompt);
|
|
791
791
|
const { tools, builtinTools } = parseTools(value.tools);
|
|
@@ -798,7 +798,7 @@ export function parseSubmission(input, options = {}) {
|
|
|
798
798
|
const environment = parseEnvironment(value.environment);
|
|
799
799
|
const securityProfile = parseRuntimeSecurityProfile(value.securityProfile);
|
|
800
800
|
const metadata = optionalJsonRecord(value.metadata, "submission.metadata");
|
|
801
|
-
const
|
|
801
|
+
const fileCapture = parseFileCapture(value.fileCapture);
|
|
802
802
|
const includeBuiltinTools = parseIncludeBuiltinTools(value.includeBuiltinTools);
|
|
803
803
|
const outputMode = parseOutputMode(value.outputMode);
|
|
804
804
|
const responseFormat = parseResponseFormat(value.responseFormat);
|
|
@@ -818,7 +818,7 @@ export function parseSubmission(input, options = {}) {
|
|
|
818
818
|
...(environment ? { environment } : {}),
|
|
819
819
|
...(securityProfile ? { securityProfile } : {}),
|
|
820
820
|
...(metadata ? { metadata } : {}),
|
|
821
|
-
...(
|
|
821
|
+
...(fileCapture ? { fileCapture } : {}),
|
|
822
822
|
...(includeBuiltinTools !== undefined ? { includeBuiltinTools } : {}),
|
|
823
823
|
...(builtinTools.length > 0 ? { builtinTools } : {}),
|
|
824
824
|
...(outputMode !== undefined ? { outputMode } : {}),
|
|
@@ -919,7 +919,7 @@ function streamableProviders() {
|
|
|
919
919
|
/**
|
|
920
920
|
* Fail-closed streaming gate: `outputMode:'stream'` on a NON-streamable provider
|
|
921
921
|
* throws (a HARD reject — no silent downgrade to buffered). Called by
|
|
922
|
-
* {@link
|
|
922
|
+
* {@link parseSessionSubmissionRequest} once mode + provider are both known.
|
|
923
923
|
*/
|
|
924
924
|
export function assertStreamableOutputMode(outputMode, provider) {
|
|
925
925
|
if (outputMode === "stream" && !isStreamableProvider(provider)) {
|
|
@@ -1084,21 +1084,21 @@ export const DEFAULT_BUILTIN_TOOLS = BUILTIN_TOOL_NAMES;
|
|
|
1084
1084
|
* Fixed name of the single skills meta-tool. Deliberately NOT a member of
|
|
1085
1085
|
* {@link BUILTIN_TOOL_NAMES} (that closed set is the customer-cherry-pickable
|
|
1086
1086
|
* toggle surface, pinned equal to `HANDS_TOOLS`) — the skills tool is IMPLIED by
|
|
1087
|
-
* a
|
|
1087
|
+
* a session having ≥1 skill, not chosen, and is injected platform-side. Kept in
|
|
1088
1088
|
* lockstep with {@link SKILL_RESERVED_NAMES} so it can never be shadowed by a
|
|
1089
1089
|
* custom tool or skill of the same name.
|
|
1090
1090
|
*/
|
|
1091
1091
|
export const SKILLS_TOOL_NAME = "skills";
|
|
1092
1092
|
/**
|
|
1093
1093
|
* The single default `skills` meta-tool (list/load) the platform injects when a
|
|
1094
|
-
*
|
|
1094
|
+
* session references ≥1 workspace skill. Shared by the platform tool composer and
|
|
1095
1095
|
* kept adjacent to the reserved-name guard so the model-visible contract and the
|
|
1096
1096
|
* name reservation stay in one place. It replaces the former N per-skill no-arg
|
|
1097
1097
|
* load-tools with one arg-taking dispatcher.
|
|
1098
1098
|
*/
|
|
1099
1099
|
export const SKILLS_TOOL_DEFINITION = {
|
|
1100
1100
|
name: "skills",
|
|
1101
|
-
description: "List and load the workspace SKILLS available to this
|
|
1101
|
+
description: "List and load the workspace SKILLS available to this session. Call with {action:'list'} to see each skill's " +
|
|
1102
1102
|
"name + description (cheap; do this first). Call with {action:'load', name:'<skill>'} to read that skill's " +
|
|
1103
1103
|
"full SKILL.md instructions into context before doing work the skill governs. A skill's supporting files are " +
|
|
1104
1104
|
"already on disk under /workspace/skills/<name>/ — load pulls the instructions; read_file/bash read the rest.",
|
|
@@ -1144,43 +1144,43 @@ function parseIncludeBuiltinTools(input) {
|
|
|
1144
1144
|
return input;
|
|
1145
1145
|
}
|
|
1146
1146
|
/**
|
|
1147
|
-
* Maximum number of
|
|
1147
|
+
* Maximum number of file capture entries accepted per list.
|
|
1148
1148
|
*
|
|
1149
1149
|
* 32 is enough room for the typical "one or two capture roots" pattern
|
|
1150
1150
|
* plus a generous margin for legitimate multi-root use cases (per-tool
|
|
1151
|
-
*
|
|
1151
|
+
* file directory + scratch state + logs, repeated across a few
|
|
1152
1152
|
* subdirectories), without inviting abuse of the synthetic-turn path
|
|
1153
1153
|
* the platform capture path drives at session terminal.
|
|
1154
1154
|
*/
|
|
1155
|
-
const
|
|
1155
|
+
const MAX_FILE_CAPTURE_DIRS = 32;
|
|
1156
1156
|
/**
|
|
1157
|
-
* Maximum byte length of a single
|
|
1157
|
+
* Maximum byte length of a single file capture entry (after UTF-8
|
|
1158
1158
|
* encoding). 512 bytes comfortably covers `/very/long/nested/path`
|
|
1159
1159
|
* style entries without letting a misuse smuggle large blobs through
|
|
1160
1160
|
* the field.
|
|
1161
1161
|
*/
|
|
1162
|
-
const
|
|
1163
|
-
const
|
|
1164
|
-
function
|
|
1162
|
+
const MAX_FILE_CAPTURE_DIR_BYTES = 512;
|
|
1163
|
+
const MAX_FILE_CAPTURE_TIMEOUT_MS = 6 * 60 * 60 * 1000;
|
|
1164
|
+
function parseFileCapture(input) {
|
|
1165
1165
|
if (input === undefined || input === null) {
|
|
1166
1166
|
return undefined;
|
|
1167
1167
|
}
|
|
1168
|
-
const value = requireRecord(input, "submission.
|
|
1168
|
+
const value = requireRecord(input, "submission.fileCapture");
|
|
1169
1169
|
const allowed = new Set(["allowedDirs", "deniedDirs", "captureTimeoutMs", "maxFileBytes", "maxTotalBytes", "maxFiles"]);
|
|
1170
1170
|
for (const key of Object.keys(value)) {
|
|
1171
1171
|
if (!allowed.has(key)) {
|
|
1172
|
-
throw new Error(`submission.
|
|
1172
|
+
throw new Error(`submission.fileCapture.${key} is not an allowed field; permitted: ${[...allowed].join(", ")}`);
|
|
1173
1173
|
}
|
|
1174
1174
|
}
|
|
1175
|
-
const allowedDirs =
|
|
1176
|
-
const deniedDirs =
|
|
1177
|
-
const captureTimeoutMs =
|
|
1178
|
-
max:
|
|
1175
|
+
const allowedDirs = parseFileCaptureAllowedDirs(value.allowedDirs);
|
|
1176
|
+
const deniedDirs = parseFileCaptureDeniedDirs(value.deniedDirs);
|
|
1177
|
+
const captureTimeoutMs = parseFileCapturePositiveInteger(value.captureTimeoutMs, "submission.fileCapture.captureTimeoutMs", {
|
|
1178
|
+
max: MAX_FILE_CAPTURE_TIMEOUT_MS,
|
|
1179
1179
|
clamp: true
|
|
1180
1180
|
});
|
|
1181
|
-
const maxFileBytes =
|
|
1182
|
-
const maxTotalBytes =
|
|
1183
|
-
const maxFiles =
|
|
1181
|
+
const maxFileBytes = parseFileCapturePositiveInteger(value.maxFileBytes, "submission.fileCapture.maxFileBytes");
|
|
1182
|
+
const maxTotalBytes = parseFileCapturePositiveInteger(value.maxTotalBytes, "submission.fileCapture.maxTotalBytes");
|
|
1183
|
+
const maxFiles = parseFileCapturePositiveInteger(value.maxFiles, "submission.fileCapture.maxFiles");
|
|
1184
1184
|
if (!allowedDirs && !deniedDirs && captureTimeoutMs === undefined && maxFileBytes === undefined && maxTotalBytes === undefined && maxFiles === undefined) {
|
|
1185
1185
|
return undefined;
|
|
1186
1186
|
}
|
|
@@ -1193,7 +1193,7 @@ function parseOutputs(input) {
|
|
|
1193
1193
|
...(maxFiles !== undefined ? { maxFiles } : {})
|
|
1194
1194
|
};
|
|
1195
1195
|
}
|
|
1196
|
-
function
|
|
1196
|
+
function parseFileCapturePositiveInteger(input, field, options = {}) {
|
|
1197
1197
|
if (input === undefined) {
|
|
1198
1198
|
return undefined;
|
|
1199
1199
|
}
|
|
@@ -1205,47 +1205,47 @@ function parseOutputPositiveInteger(input, field, options = {}) {
|
|
|
1205
1205
|
}
|
|
1206
1206
|
return input;
|
|
1207
1207
|
}
|
|
1208
|
-
function
|
|
1208
|
+
function parseFileCaptureAllowedDirs(input) {
|
|
1209
1209
|
if (input === undefined) {
|
|
1210
1210
|
return undefined;
|
|
1211
1211
|
}
|
|
1212
1212
|
if (!Array.isArray(input)) {
|
|
1213
|
-
throw new Error("submission.
|
|
1213
|
+
throw new Error("submission.fileCapture.allowedDirs must be an array of absolute UNIX paths");
|
|
1214
1214
|
}
|
|
1215
1215
|
if (input.length === 0) {
|
|
1216
1216
|
// Treat an empty array as omission so the idempotency hash matches
|
|
1217
1217
|
// the "no allowedDirs" case.
|
|
1218
1218
|
return undefined;
|
|
1219
1219
|
}
|
|
1220
|
-
if (input.length >
|
|
1221
|
-
throw new Error(`submission.
|
|
1220
|
+
if (input.length > MAX_FILE_CAPTURE_DIRS) {
|
|
1221
|
+
throw new Error(`submission.fileCapture.allowedDirs has ${input.length} entries; max is ${MAX_FILE_CAPTURE_DIRS}`);
|
|
1222
1222
|
}
|
|
1223
1223
|
const seen = new Set();
|
|
1224
1224
|
const normalised = [];
|
|
1225
1225
|
for (let i = 0; i < input.length; i++) {
|
|
1226
1226
|
const item = input[i];
|
|
1227
1227
|
if (typeof item !== "string") {
|
|
1228
|
-
throw new Error(`submission.
|
|
1228
|
+
throw new Error(`submission.fileCapture.allowedDirs[${i}] must be a string`);
|
|
1229
1229
|
}
|
|
1230
1230
|
if (item.length === 0) {
|
|
1231
|
-
throw new Error(`submission.
|
|
1231
|
+
throw new Error(`submission.fileCapture.allowedDirs[${i}] must be a non-empty absolute UNIX path`);
|
|
1232
1232
|
}
|
|
1233
1233
|
const bytes = new TextEncoder().encode(item).length;
|
|
1234
|
-
if (bytes >
|
|
1235
|
-
throw new Error(`submission.
|
|
1234
|
+
if (bytes > MAX_FILE_CAPTURE_DIR_BYTES) {
|
|
1235
|
+
throw new Error(`submission.fileCapture.allowedDirs[${i}] exceeds ${MAX_FILE_CAPTURE_DIR_BYTES} bytes (got ${bytes})`);
|
|
1236
1236
|
}
|
|
1237
1237
|
if (!item.startsWith("/")) {
|
|
1238
|
-
throw new Error(`submission.
|
|
1238
|
+
throw new Error(`submission.fileCapture.allowedDirs[${i}] must be an absolute UNIX path (start with '/')`);
|
|
1239
1239
|
}
|
|
1240
1240
|
if (item.includes("\0")) {
|
|
1241
|
-
throw new Error(`submission.
|
|
1241
|
+
throw new Error(`submission.fileCapture.allowedDirs[${i}] must not contain NUL bytes`);
|
|
1242
1242
|
}
|
|
1243
1243
|
if (item.includes("\n") || item.includes("\r")) {
|
|
1244
|
-
throw new Error(`submission.
|
|
1244
|
+
throw new Error(`submission.fileCapture.allowedDirs[${i}] must not contain newline characters`);
|
|
1245
1245
|
}
|
|
1246
1246
|
const segments = item.split("/");
|
|
1247
1247
|
if (segments.includes("..")) {
|
|
1248
|
-
throw new Error(`submission.
|
|
1248
|
+
throw new Error(`submission.fileCapture.allowedDirs[${i}] must not contain '..' segments`);
|
|
1249
1249
|
}
|
|
1250
1250
|
const collapsed = segments
|
|
1251
1251
|
.filter((seg, idx) => seg.length > 0 || idx === 0)
|
|
@@ -1262,41 +1262,41 @@ function parseOutputAllowedDirs(input) {
|
|
|
1262
1262
|
}
|
|
1263
1263
|
return normalised;
|
|
1264
1264
|
}
|
|
1265
|
-
function
|
|
1265
|
+
function parseFileCaptureDeniedDirs(input) {
|
|
1266
1266
|
if (input === undefined) {
|
|
1267
1267
|
return undefined;
|
|
1268
1268
|
}
|
|
1269
1269
|
if (!Array.isArray(input)) {
|
|
1270
|
-
throw new Error("submission.
|
|
1270
|
+
throw new Error("submission.fileCapture.deniedDirs must be an array of strings");
|
|
1271
1271
|
}
|
|
1272
1272
|
if (input.length === 0) {
|
|
1273
1273
|
return undefined;
|
|
1274
1274
|
}
|
|
1275
|
-
if (input.length >
|
|
1276
|
-
throw new Error(`submission.
|
|
1275
|
+
if (input.length > MAX_FILE_CAPTURE_DIRS) {
|
|
1276
|
+
throw new Error(`submission.fileCapture.deniedDirs has ${input.length} entries; max is ${MAX_FILE_CAPTURE_DIRS}`);
|
|
1277
1277
|
}
|
|
1278
1278
|
const seen = new Set();
|
|
1279
1279
|
const normalised = [];
|
|
1280
1280
|
for (let i = 0; i < input.length; i++) {
|
|
1281
1281
|
const item = input[i];
|
|
1282
1282
|
if (typeof item !== "string") {
|
|
1283
|
-
throw new Error(`submission.
|
|
1283
|
+
throw new Error(`submission.fileCapture.deniedDirs[${i}] must be a string`);
|
|
1284
1284
|
}
|
|
1285
1285
|
if (item.length === 0) {
|
|
1286
|
-
throw new Error(`submission.
|
|
1286
|
+
throw new Error(`submission.fileCapture.deniedDirs[${i}] must be a non-empty pattern`);
|
|
1287
1287
|
}
|
|
1288
1288
|
const bytes = new TextEncoder().encode(item).length;
|
|
1289
|
-
if (bytes >
|
|
1290
|
-
throw new Error(`submission.
|
|
1289
|
+
if (bytes > MAX_FILE_CAPTURE_DIR_BYTES) {
|
|
1290
|
+
throw new Error(`submission.fileCapture.deniedDirs[${i}] exceeds ${MAX_FILE_CAPTURE_DIR_BYTES} bytes (got ${bytes})`);
|
|
1291
1291
|
}
|
|
1292
1292
|
if (item.includes("\0")) {
|
|
1293
|
-
throw new Error(`submission.
|
|
1293
|
+
throw new Error(`submission.fileCapture.deniedDirs[${i}] must not contain NUL bytes`);
|
|
1294
1294
|
}
|
|
1295
1295
|
if (item.includes("\n") || item.includes("\r")) {
|
|
1296
|
-
throw new Error(`submission.
|
|
1296
|
+
throw new Error(`submission.fileCapture.deniedDirs[${i}] must not contain newline characters`);
|
|
1297
1297
|
}
|
|
1298
1298
|
if (item.split("/").includes("..")) {
|
|
1299
|
-
throw new Error(`submission.
|
|
1299
|
+
throw new Error(`submission.fileCapture.deniedDirs[${i}] must not contain '..' segments`);
|
|
1300
1300
|
}
|
|
1301
1301
|
let canonical = item;
|
|
1302
1302
|
if (item.startsWith("/")) {
|
|
@@ -1436,9 +1436,9 @@ function parseTools(input) {
|
|
|
1436
1436
|
return { tools, builtinTools };
|
|
1437
1437
|
}
|
|
1438
1438
|
/**
|
|
1439
|
-
* Upper bound on the number of workspace skills a single
|
|
1440
|
-
* A
|
|
1441
|
-
* generous headroom over any realistic per-
|
|
1439
|
+
* Upper bound on the number of workspace skills a single session may reference.
|
|
1440
|
+
* A session's skill list is a discovery surface, not a bulk-mount channel; 64 is
|
|
1441
|
+
* generous headroom over any realistic per-session set while capping the meta-tool
|
|
1442
1442
|
* `list` payload and the submit-time resolution fan-out.
|
|
1443
1443
|
*/
|
|
1444
1444
|
export const SKILLS_MAX = 64;
|
|
@@ -21,7 +21,7 @@ export interface AssistantTextEntry {
|
|
|
21
21
|
readonly seq?: number;
|
|
22
22
|
readonly recordedAt?: string;
|
|
23
23
|
}
|
|
24
|
-
export interface
|
|
24
|
+
export interface TurnTrace {
|
|
25
25
|
readonly toolCalls: readonly ToolCallTrace[];
|
|
26
26
|
readonly usage: UsageSummary;
|
|
27
27
|
readonly text: readonly AssistantTextEntry[];
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Customer-side verification for aex
|
|
2
|
+
* Customer-side verification for aex start webhooks (Standard Webhooks scheme).
|
|
3
3
|
*
|
|
4
4
|
* aex signs every delivery HMAC-SHA256 over `${webhook-id}.${webhook-timestamp}.${rawBody}`
|
|
5
5
|
* and sends three headers:
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Customer-side verification for aex
|
|
2
|
+
* Customer-side verification for aex start webhooks (Standard Webhooks scheme).
|
|
3
3
|
*
|
|
4
4
|
* aex signs every delivery HMAC-SHA256 over `${webhook-id}.${webhook-timestamp}.${rawBody}`
|
|
5
5
|
* and sends three headers:
|
package/dist/agents-md.d.ts
CHANGED
|
@@ -5,10 +5,10 @@ import type { AgentsMdRef } from "./_contracts/index.js";
|
|
|
5
5
|
* behaviour).
|
|
6
6
|
*
|
|
7
7
|
* const rules = await AgentsMd.fromContent("# Be helpful", { name: "rules" });
|
|
8
|
-
* await client.
|
|
8
|
+
* await client.start({ agentsMd: [rules], message: "..." });
|
|
9
9
|
*
|
|
10
|
-
* `client.
|
|
11
|
-
* before the
|
|
10
|
+
* `client.start` / `openSession` materializes the bytes to the hosted asset store
|
|
11
|
+
* before the session lands. Asset deduplication handles repeated uploads automatically.
|
|
12
12
|
*/
|
|
13
13
|
export declare class AgentsMd {
|
|
14
14
|
#private;
|
|
@@ -33,7 +33,7 @@ export declare class AgentsMd {
|
|
|
33
33
|
}): Promise<AgentsMd>;
|
|
34
34
|
/**
|
|
35
35
|
* Internal: yield the draft's zipped bytes + metadata so
|
|
36
|
-
* `client.
|
|
36
|
+
* `client.start` / `openSession` can upload it as an asset.
|
|
37
37
|
*/
|
|
38
38
|
_takeDraftBundle(): {
|
|
39
39
|
name: string;
|
package/dist/agents-md.js
CHANGED
|
@@ -7,10 +7,10 @@ import { strToU8, zipSync } from "fflate";
|
|
|
7
7
|
* behaviour).
|
|
8
8
|
*
|
|
9
9
|
* const rules = await AgentsMd.fromContent("# Be helpful", { name: "rules" });
|
|
10
|
-
* await client.
|
|
10
|
+
* await client.start({ agentsMd: [rules], message: "..." });
|
|
11
11
|
*
|
|
12
|
-
* `client.
|
|
13
|
-
* before the
|
|
12
|
+
* `client.start` / `openSession` materializes the bytes to the hosted asset store
|
|
13
|
+
* before the session lands. Asset deduplication handles repeated uploads automatically.
|
|
14
14
|
*/
|
|
15
15
|
export class AgentsMd {
|
|
16
16
|
#ref;
|
|
@@ -59,7 +59,7 @@ export class AgentsMd {
|
|
|
59
59
|
}
|
|
60
60
|
/**
|
|
61
61
|
* Internal: yield the draft's zipped bytes + metadata so
|
|
62
|
-
* `client.
|
|
62
|
+
* `client.start` / `openSession` can upload it as an asset.
|
|
63
63
|
*/
|
|
64
64
|
_takeDraftBundle() {
|
|
65
65
|
if (this.#ref.kind !== "draft" || !this.#zipBytes) {
|
|
@@ -74,7 +74,7 @@ export class AgentsMd {
|
|
|
74
74
|
toJSON() {
|
|
75
75
|
if (this.#ref.kind === "draft") {
|
|
76
76
|
throw new Error("AgentsMd: draft AgentsMd cannot be JSON-serialised — it only becomes a wire " +
|
|
77
|
-
"ref when aex.
|
|
77
|
+
"ref when aex.start / openSession uploads the bytes as an asset.");
|
|
78
78
|
}
|
|
79
79
|
return this.#ref;
|
|
80
80
|
}
|
package/dist/agents-md.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agents-md.js","sourceRoot":"","sources":["../src/agents-md.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5C,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAE1C;;;;;;;;;;GAUG;AACH,MAAM,OAAO,QAAQ;IACV,IAAI,CAAiC;IACrC,SAAS,CAAyB;IAC3C,uEAAuE;IACvE,QAAQ,CAAqB;IAE7B,YAAY,GAAmC,EAAE,QAAqB;QACpE,IAAI,CAAC,IAAI,GAAG,GAAG,CAAC;QAChB,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC;IAC5B,CAAC;IAED,IAAI,GAAG;QACL,OAAO,IAAI,CAAC,IAAI,CAAC;IACnB,CAAC;IAED,IAAI,OAAO;QACT,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,OAAO,CAAC;IACpC,CAAC;IAED,oEAAoE;IACpE,IAAI,cAAc;QAChB,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;IAED,uEAAuE;IACvE,cAAc,CAAC,OAAe;QAC5B,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC;IAC1B,CAAC;IAED;;;;OAIG;IACH,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,OAAe,EAAE,IAA+B;QACvE,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACxD,MAAM,IAAI,KAAK,CAAC,0DAA0D,CAAC,CAAC;QAC9E,CAAC;QACD,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YACjF,MAAM,IAAI,KAAK,CAAC,yCAAyC,iBAAiB,CAAC,MAAM,EAAE,CAAC,CAAC;QACvF,CAAC;QACD,MAAM,GAAG,GAAG,OAAO,CAAC,EAAE,WAAW,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;QAC7F,MAAM,WAAW,GAAG,MAAM,eAAe,CAAC,GAAG,CAAC,CAAC;QAC/C,MAAM,GAAG,GAAqB,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,WAAW,EAAE,CAAC;QAC9E,OAAO,IAAI,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IAChC,CAAC;IAED,uEAAuE;IACvE,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAY,EAAE,IAA+B;QACjE,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QAC7C,OAAO,QAAQ,CAAC,WAAW,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IAC7C,CAAC;IAED;;;OAGG;IACH,gBAAgB;QACd,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,OAAO,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;YAClD,OAAO,SAAS,CAAC;QACnB,CAAC;QACD,OAAO;YACL,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI;YACpB,WAAW,EAAE,IAAI,CAAC,IAAI,CAAC,WAAW;YAClC,KAAK,EAAE,IAAI,CAAC,SAAS;SACtB,CAAC;IACJ,CAAC;IAED,MAAM;QACJ,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;YAC/B,MAAM,IAAI,KAAK,CACb,8EAA8E;gBAC5E
|
|
1
|
+
{"version":3,"file":"agents-md.js","sourceRoot":"","sources":["../src/agents-md.ts"],"names":[],"mappings":"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"}
|
package/dist/bundle.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { type BundleSymlink, type ToolInputSchema } from "./_contracts/index.js"
|
|
|
3
3
|
* In-memory skill bundle: a flat path -> bytes map and the
|
|
4
4
|
* deterministically-zipped representation.
|
|
5
5
|
*
|
|
6
|
-
* The SDK
|
|
6
|
+
* The SDK sessions only the cheap, safety-critical checks here
|
|
7
7
|
* (`validateSkillBundleEntry`: no `..`, no absolute paths, no Windows
|
|
8
8
|
* backslashes, depth/length limits). The BFF re-canonicalises and
|
|
9
9
|
* recomputes the canonical hash on receipt — SDK-side hashing is NOT
|
package/dist/bundle.js
CHANGED
|
@@ -65,7 +65,7 @@ export function bundleSkillFiles(files, meta) {
|
|
|
65
65
|
"use AgentsMd.fromPath / File.fromPath instead.");
|
|
66
66
|
}
|
|
67
67
|
// Sort entries and pin every mtime to the epoch so the byte output is
|
|
68
|
-
// identical across machines and re-
|
|
68
|
+
// identical across machines and re-sessions (the BFF re-canonicalises and
|
|
69
69
|
// recomputes the canonical hash, so this is for retry-safety / debug
|
|
70
70
|
// reproducibility rather than a wire-shape contract). The fidelity sidecar,
|
|
71
71
|
// when present, is appended LAST so a metadata-free bundle is byte-identical.
|