@runtypelabs/sdk 4.15.0 → 4.17.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/dist/index.cjs +742 -137
- package/dist/index.d.cts +1294 -34
- package/dist/index.d.ts +1294 -34
- package/dist/index.mjs +730 -137
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1094,20 +1094,20 @@ var FlowBuilder = class {
|
|
|
1094
1094
|
*/
|
|
1095
1095
|
build() {
|
|
1096
1096
|
const flow = this.existingFlowId ? { id: this.existingFlowId } : { name: this.flowConfig.name, steps: this.steps };
|
|
1097
|
-
const
|
|
1097
|
+
const request6 = { flow };
|
|
1098
1098
|
if (this.recordConfig) {
|
|
1099
|
-
|
|
1099
|
+
request6.record = this.recordConfig;
|
|
1100
1100
|
}
|
|
1101
1101
|
if (this.messagesConfig) {
|
|
1102
|
-
|
|
1102
|
+
request6.messages = this.messagesConfig;
|
|
1103
1103
|
}
|
|
1104
1104
|
if (this.inputsConfig) {
|
|
1105
|
-
|
|
1105
|
+
request6.inputs = this.inputsConfig;
|
|
1106
1106
|
}
|
|
1107
1107
|
if (Object.keys(this.optionsConfig).length > 0) {
|
|
1108
|
-
|
|
1108
|
+
request6.options = this.optionsConfig;
|
|
1109
1109
|
}
|
|
1110
|
-
return
|
|
1110
|
+
return request6;
|
|
1111
1111
|
}
|
|
1112
1112
|
/**
|
|
1113
1113
|
* Validate this prospective flow against the public validation endpoint
|
|
@@ -2501,15 +2501,15 @@ var RuntypeFlowBuilder = class {
|
|
|
2501
2501
|
build() {
|
|
2502
2502
|
const flowMode = this.mode === "existing" ? "existing" : this.mode;
|
|
2503
2503
|
const flow = this.existingFlowId ? { id: this.existingFlowId } : { name: this.flowConfig.name, steps: this.steps };
|
|
2504
|
-
const
|
|
2504
|
+
const request6 = { flow };
|
|
2505
2505
|
if (this.recordConfig) {
|
|
2506
|
-
|
|
2506
|
+
request6.record = this.recordConfig;
|
|
2507
2507
|
}
|
|
2508
2508
|
if (this.messagesConfig) {
|
|
2509
|
-
|
|
2509
|
+
request6.messages = this.messagesConfig;
|
|
2510
2510
|
}
|
|
2511
2511
|
if (this.inputsConfig) {
|
|
2512
|
-
|
|
2512
|
+
request6.inputs = this.inputsConfig;
|
|
2513
2513
|
}
|
|
2514
2514
|
const options = {
|
|
2515
2515
|
flowMode,
|
|
@@ -2527,8 +2527,8 @@ var RuntypeFlowBuilder = class {
|
|
|
2527
2527
|
if (this.mode === "upsert" && Object.keys(this.upsertOptions).length > 0) {
|
|
2528
2528
|
options.upsertOptions = this.upsertOptions;
|
|
2529
2529
|
}
|
|
2530
|
-
|
|
2531
|
-
return
|
|
2530
|
+
request6.options = options;
|
|
2531
|
+
return request6;
|
|
2532
2532
|
}
|
|
2533
2533
|
/**
|
|
2534
2534
|
* Validate this prospective flow against the public validation endpoint
|
|
@@ -3122,6 +3122,192 @@ var PromptsNamespace = class {
|
|
|
3122
3122
|
}
|
|
3123
3123
|
};
|
|
3124
3124
|
|
|
3125
|
+
// src/skills-ensure.ts
|
|
3126
|
+
function isPlainObject2(value) {
|
|
3127
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
3128
|
+
}
|
|
3129
|
+
function normalizeValue(value) {
|
|
3130
|
+
if (Array.isArray(value)) {
|
|
3131
|
+
return value.map((item) => normalizeValue(item));
|
|
3132
|
+
}
|
|
3133
|
+
if (isPlainObject2(value)) {
|
|
3134
|
+
const normalized = {};
|
|
3135
|
+
for (const key of Object.keys(value).sort()) {
|
|
3136
|
+
const entry = value[key];
|
|
3137
|
+
if (entry === void 0 || entry === null) continue;
|
|
3138
|
+
normalized[key] = normalizeValue(entry);
|
|
3139
|
+
}
|
|
3140
|
+
return normalized;
|
|
3141
|
+
}
|
|
3142
|
+
return value;
|
|
3143
|
+
}
|
|
3144
|
+
function normalizeSkillDefinition(definition) {
|
|
3145
|
+
const manifest = isPlainObject2(definition.manifest) ? definition.manifest : {};
|
|
3146
|
+
const rawFrontmatter = isPlainObject2(manifest.frontmatter) ? manifest.frontmatter : {};
|
|
3147
|
+
const frontmatterWithoutName = {};
|
|
3148
|
+
for (const key of Object.keys(rawFrontmatter)) {
|
|
3149
|
+
if (key === "name") continue;
|
|
3150
|
+
frontmatterWithoutName[key] = rawFrontmatter[key];
|
|
3151
|
+
}
|
|
3152
|
+
const frontmatter = normalizeValue(frontmatterWithoutName);
|
|
3153
|
+
const runtype = isPlainObject2(manifest.runtype) ? normalizeValue(manifest.runtype) : {};
|
|
3154
|
+
const body = typeof manifest.body === "string" ? manifest.body : "";
|
|
3155
|
+
return { frontmatter, runtype, body };
|
|
3156
|
+
}
|
|
3157
|
+
async function computeSkillContentHash(definition) {
|
|
3158
|
+
const serialized = JSON.stringify(normalizeSkillDefinition(definition));
|
|
3159
|
+
const encoded = new TextEncoder().encode(serialized);
|
|
3160
|
+
const hashBuffer = await crypto.subtle.digest("SHA-256", encoded);
|
|
3161
|
+
return Array.from(new Uint8Array(hashBuffer)).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
3162
|
+
}
|
|
3163
|
+
var DEFINE_SKILL_TOP_LEVEL_KEYS = /* @__PURE__ */ new Set(["name", "manifest"]);
|
|
3164
|
+
function defineSkill(input) {
|
|
3165
|
+
if (!input || typeof input !== "object") {
|
|
3166
|
+
throw new Error("defineSkill requires a definition object");
|
|
3167
|
+
}
|
|
3168
|
+
if (typeof input.name !== "string" || input.name.length === 0) {
|
|
3169
|
+
throw new Error('defineSkill requires a non-empty string "name"');
|
|
3170
|
+
}
|
|
3171
|
+
if (!isPlainObject2(input.manifest)) {
|
|
3172
|
+
throw new Error('defineSkill requires a "manifest" object ({ frontmatter, runtype, body })');
|
|
3173
|
+
}
|
|
3174
|
+
const unknownKeys = Object.keys(input).filter((key) => !DEFINE_SKILL_TOP_LEVEL_KEYS.has(key));
|
|
3175
|
+
if (unknownKeys.length > 0) {
|
|
3176
|
+
throw new Error(
|
|
3177
|
+
`defineSkill: unknown field(s): ${unknownKeys.join(", ")}. Allowed fields are name and manifest.`
|
|
3178
|
+
);
|
|
3179
|
+
}
|
|
3180
|
+
const frontmatter = input.manifest.frontmatter;
|
|
3181
|
+
if (!isPlainObject2(frontmatter) || typeof frontmatter.name !== "string") {
|
|
3182
|
+
throw new Error("defineSkill: manifest.frontmatter.name is required");
|
|
3183
|
+
}
|
|
3184
|
+
if (frontmatter.name !== input.name) {
|
|
3185
|
+
throw new Error(
|
|
3186
|
+
`defineSkill: manifest.frontmatter.name ("${frontmatter.name}") must match the identity name ("${input.name}").`
|
|
3187
|
+
);
|
|
3188
|
+
}
|
|
3189
|
+
return { name: input.name, manifest: input.manifest };
|
|
3190
|
+
}
|
|
3191
|
+
var SkillEnsureConflictError = class extends Error {
|
|
3192
|
+
constructor(body) {
|
|
3193
|
+
super(body.error ?? `Skill ensure conflict: ${body.code}`);
|
|
3194
|
+
this.name = "SkillEnsureConflictError";
|
|
3195
|
+
this.code = body.code;
|
|
3196
|
+
this.lastModifiedSource = body.lastModifiedSource;
|
|
3197
|
+
this.modifiedAt = body.modifiedAt;
|
|
3198
|
+
this.currentHash = body.currentHash;
|
|
3199
|
+
}
|
|
3200
|
+
};
|
|
3201
|
+
var SkillDriftError = class extends Error {
|
|
3202
|
+
constructor(plan) {
|
|
3203
|
+
super(
|
|
3204
|
+
`Skill "${plan.skillId ?? "definition"}" drifted: plan is '${plan.changes}' (changed: ${plan.changedKeys.join(", ") || "n/a"}). Run client.skills.pull(name) to absorb the remote edit into your repo, or re-run ensure to converge.`
|
|
3205
|
+
);
|
|
3206
|
+
this.name = "SkillDriftError";
|
|
3207
|
+
this.plan = plan;
|
|
3208
|
+
}
|
|
3209
|
+
};
|
|
3210
|
+
function parseRequestError2(err) {
|
|
3211
|
+
if (!(err instanceof Error)) return { status: null, body: null };
|
|
3212
|
+
const match = err.message.match(/^API request failed: (\d{3}) .*? - ([\s\S]*)$/);
|
|
3213
|
+
if (!match) return { status: null, body: null };
|
|
3214
|
+
try {
|
|
3215
|
+
return { status: Number(match[1]), body: JSON.parse(match[2]) };
|
|
3216
|
+
} catch {
|
|
3217
|
+
return { status: Number(match[1]), body: null };
|
|
3218
|
+
}
|
|
3219
|
+
}
|
|
3220
|
+
function toConflictError2(err) {
|
|
3221
|
+
const { status, body } = parseRequestError2(err);
|
|
3222
|
+
if (status !== 409 || !isPlainObject2(body)) return null;
|
|
3223
|
+
const code = body.code;
|
|
3224
|
+
if (code !== "external_modification" && code !== "remote_changed") return null;
|
|
3225
|
+
return new SkillEnsureConflictError(
|
|
3226
|
+
body
|
|
3227
|
+
);
|
|
3228
|
+
}
|
|
3229
|
+
var serverHashMemo2 = /* @__PURE__ */ new WeakMap();
|
|
3230
|
+
function memoFor2(client) {
|
|
3231
|
+
let memo = serverHashMemo2.get(client);
|
|
3232
|
+
if (!memo) {
|
|
3233
|
+
memo = /* @__PURE__ */ new Map();
|
|
3234
|
+
serverHashMemo2.set(client, memo);
|
|
3235
|
+
}
|
|
3236
|
+
return memo;
|
|
3237
|
+
}
|
|
3238
|
+
function memoize2(memo, memoKey, result) {
|
|
3239
|
+
if (result.result !== "plan") memo.set(memoKey, result.contentHash);
|
|
3240
|
+
}
|
|
3241
|
+
async function request2(client, body) {
|
|
3242
|
+
try {
|
|
3243
|
+
return await client.post(
|
|
3244
|
+
"/skills/ensure",
|
|
3245
|
+
body
|
|
3246
|
+
);
|
|
3247
|
+
} catch (err) {
|
|
3248
|
+
const conflict = toConflictError2(err);
|
|
3249
|
+
if (conflict) throw conflict;
|
|
3250
|
+
throw err;
|
|
3251
|
+
}
|
|
3252
|
+
}
|
|
3253
|
+
async function ensureSkill(client, definition, options = {}) {
|
|
3254
|
+
const { dryRun, onConflict, release, expectedRemoteHash, expectNoChanges } = options;
|
|
3255
|
+
const passthrough = {
|
|
3256
|
+
...onConflict ? { onConflict } : {},
|
|
3257
|
+
...release ? { release } : {},
|
|
3258
|
+
...expectedRemoteHash ? { expectedRemoteHash } : {}
|
|
3259
|
+
};
|
|
3260
|
+
if (dryRun || expectNoChanges) {
|
|
3261
|
+
const plan = await request2(client, {
|
|
3262
|
+
name: definition.name,
|
|
3263
|
+
definition: manifestToWire(definition),
|
|
3264
|
+
dryRun: true,
|
|
3265
|
+
...passthrough
|
|
3266
|
+
});
|
|
3267
|
+
if (plan.result !== "plan") {
|
|
3268
|
+
throw new Error(`Expected a plan result from dryRun, got '${plan.result}'`);
|
|
3269
|
+
}
|
|
3270
|
+
if (expectNoChanges && plan.changes !== "none") {
|
|
3271
|
+
throw new SkillDriftError(plan);
|
|
3272
|
+
}
|
|
3273
|
+
return plan;
|
|
3274
|
+
}
|
|
3275
|
+
const memo = memoFor2(client);
|
|
3276
|
+
const localHash = await computeSkillContentHash(definition);
|
|
3277
|
+
const memoKey = `${definition.name} ${localHash}`;
|
|
3278
|
+
const contentHash = memo.get(memoKey) ?? localHash;
|
|
3279
|
+
const probe = await request2(client, {
|
|
3280
|
+
name: definition.name,
|
|
3281
|
+
contentHash,
|
|
3282
|
+
...passthrough
|
|
3283
|
+
});
|
|
3284
|
+
if (probe.result !== "definitionRequired") {
|
|
3285
|
+
memoize2(memo, memoKey, probe);
|
|
3286
|
+
return probe;
|
|
3287
|
+
}
|
|
3288
|
+
const converged = await request2(client, {
|
|
3289
|
+
name: definition.name,
|
|
3290
|
+
definition: manifestToWire(definition),
|
|
3291
|
+
...passthrough
|
|
3292
|
+
});
|
|
3293
|
+
if (converged.result === "definitionRequired") {
|
|
3294
|
+
throw new Error("Server reported definitionRequired for a full-definition request");
|
|
3295
|
+
}
|
|
3296
|
+
memoize2(memo, memoKey, converged);
|
|
3297
|
+
return converged;
|
|
3298
|
+
}
|
|
3299
|
+
function manifestToWire(definition) {
|
|
3300
|
+
const manifest = definition.manifest;
|
|
3301
|
+
const frontmatter = { ...manifest.frontmatter };
|
|
3302
|
+
if (manifest.runtype && Object.keys(manifest.runtype).length > 0) {
|
|
3303
|
+
frontmatter.runtype = manifest.runtype;
|
|
3304
|
+
}
|
|
3305
|
+
return { frontmatter, body: manifest.body ?? "" };
|
|
3306
|
+
}
|
|
3307
|
+
async function pullSkill(client, name) {
|
|
3308
|
+
return client.get("/skills/pull", { name });
|
|
3309
|
+
}
|
|
3310
|
+
|
|
3125
3311
|
// src/skills-namespace.ts
|
|
3126
3312
|
var SkillProposalsNamespace = class {
|
|
3127
3313
|
constructor(getClient) {
|
|
@@ -3262,6 +3448,22 @@ var SkillsNamespace = class {
|
|
|
3262
3448
|
const client = this.getClient();
|
|
3263
3449
|
await client.post(`/skills/${skillId}/versions/${versionId}/publish`);
|
|
3264
3450
|
}
|
|
3451
|
+
/**
|
|
3452
|
+
* Statically scan a SKILL.md document for malicious patterns and return a
|
|
3453
|
+
* two-tier verdict — `warning` when a skill appears suspicious (low–medium
|
|
3454
|
+
* confidence), `error` when high-confidence malicious. Does not persist or
|
|
3455
|
+
* gate; use it as a "scan before save" affordance.
|
|
3456
|
+
*
|
|
3457
|
+
* @example
|
|
3458
|
+
* ```typescript
|
|
3459
|
+
* const { verdict } = await Runtype.skills.scan(skillMarkdown)
|
|
3460
|
+
* if (verdict.tier === 'error') console.warn(verdict.summary)
|
|
3461
|
+
* ```
|
|
3462
|
+
*/
|
|
3463
|
+
async scan(markdown) {
|
|
3464
|
+
const client = this.getClient();
|
|
3465
|
+
return client.post("/skills/scan", { markdown });
|
|
3466
|
+
}
|
|
3265
3467
|
/**
|
|
3266
3468
|
* Import a single SKILL.md document. The imported skill lands with
|
|
3267
3469
|
* `trustLevel: 'imported'` and a draft version.
|
|
@@ -3304,6 +3506,40 @@ var SkillsNamespace = class {
|
|
|
3304
3506
|
const res = await client.get("/skills/bindings", { agentId });
|
|
3305
3507
|
return res.data;
|
|
3306
3508
|
}
|
|
3509
|
+
/**
|
|
3510
|
+
* Idempotently converge a `defineSkill` definition onto the platform.
|
|
3511
|
+
* Hash-first: the steady state is one tiny probe request. Creates or appends a
|
|
3512
|
+
* new version; never deletes. Identity is name + account scope. Pass
|
|
3513
|
+
* `release: 'publish'` to publish the converged version.
|
|
3514
|
+
*
|
|
3515
|
+
* @example
|
|
3516
|
+
* ```typescript
|
|
3517
|
+
* const reviewer = defineSkill({
|
|
3518
|
+
* name: 'code_reviewer',
|
|
3519
|
+
* manifest: {
|
|
3520
|
+
* frontmatter: { name: 'code_reviewer', description: 'Reviews pull requests' },
|
|
3521
|
+
* runtype: { trustLevel: 'org' },
|
|
3522
|
+
* body: '# Code Reviewer\n\nReview the diff...',
|
|
3523
|
+
* },
|
|
3524
|
+
* })
|
|
3525
|
+
*
|
|
3526
|
+
* // Converge + publish (CI/deploy).
|
|
3527
|
+
* const result = await Runtype.skills.ensure(reviewer, { release: 'publish' })
|
|
3528
|
+
*
|
|
3529
|
+
* // PR drift gate.
|
|
3530
|
+
* await Runtype.skills.ensure(reviewer, { expectNoChanges: true })
|
|
3531
|
+
* ```
|
|
3532
|
+
*/
|
|
3533
|
+
async ensure(definition, options = {}) {
|
|
3534
|
+
return ensureSkill(this.getClient(), definition, options);
|
|
3535
|
+
}
|
|
3536
|
+
/**
|
|
3537
|
+
* Pull the canonical definition + provenance for a skill by name — the
|
|
3538
|
+
* absorb-drift direction of the ensure protocol.
|
|
3539
|
+
*/
|
|
3540
|
+
async pull(name) {
|
|
3541
|
+
return pullSkill(this.getClient(), name);
|
|
3542
|
+
}
|
|
3307
3543
|
};
|
|
3308
3544
|
|
|
3309
3545
|
// src/agents-namespace.ts
|
|
@@ -3329,19 +3565,19 @@ var AGENT_CONFIG_KEYS = [
|
|
|
3329
3565
|
"memory"
|
|
3330
3566
|
];
|
|
3331
3567
|
var AGENT_CONFIG_KEY_LIST = [...AGENT_CONFIG_KEYS].sort();
|
|
3332
|
-
function
|
|
3568
|
+
function isPlainObject3(value) {
|
|
3333
3569
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
3334
3570
|
}
|
|
3335
|
-
function
|
|
3571
|
+
function normalizeValue2(value) {
|
|
3336
3572
|
if (Array.isArray(value)) {
|
|
3337
|
-
return value.map((item) =>
|
|
3573
|
+
return value.map((item) => normalizeValue2(item));
|
|
3338
3574
|
}
|
|
3339
|
-
if (
|
|
3575
|
+
if (isPlainObject3(value)) {
|
|
3340
3576
|
const normalized = {};
|
|
3341
3577
|
for (const key of Object.keys(value).sort()) {
|
|
3342
3578
|
const entry = value[key];
|
|
3343
3579
|
if (entry === void 0 || entry === null) continue;
|
|
3344
|
-
normalized[key] =
|
|
3580
|
+
normalized[key] = normalizeValue2(entry);
|
|
3345
3581
|
}
|
|
3346
3582
|
return normalized;
|
|
3347
3583
|
}
|
|
@@ -3349,11 +3585,11 @@ function normalizeValue(value) {
|
|
|
3349
3585
|
}
|
|
3350
3586
|
function normalizeAgentDefinition(definition) {
|
|
3351
3587
|
const config = {};
|
|
3352
|
-
const rawConfig =
|
|
3588
|
+
const rawConfig = isPlainObject3(definition.config) ? definition.config : {};
|
|
3353
3589
|
for (const key of AGENT_CONFIG_KEY_LIST) {
|
|
3354
3590
|
const value = rawConfig[key];
|
|
3355
3591
|
if (value === void 0 || value === null) continue;
|
|
3356
|
-
config[key] =
|
|
3592
|
+
config[key] = normalizeValue2(value);
|
|
3357
3593
|
}
|
|
3358
3594
|
return {
|
|
3359
3595
|
name: definition.name,
|
|
@@ -3371,7 +3607,7 @@ async function computeAgentContentHash(definition) {
|
|
|
3371
3607
|
var DEFINE_TOP_LEVEL_KEYS = /* @__PURE__ */ new Set(["name", "description", "icon", ...AGENT_CONFIG_KEYS]);
|
|
3372
3608
|
function collectNonPortableToolRefs(config) {
|
|
3373
3609
|
const tools = config.tools;
|
|
3374
|
-
if (!
|
|
3610
|
+
if (!isPlainObject3(tools)) return [];
|
|
3375
3611
|
const found = [];
|
|
3376
3612
|
const isAccountScoped = (ref) => typeof ref === "string" && ref.startsWith("tool_");
|
|
3377
3613
|
const scanArray = (value, path) => {
|
|
@@ -3381,7 +3617,7 @@ function collectNonPortableToolRefs(config) {
|
|
|
3381
3617
|
});
|
|
3382
3618
|
};
|
|
3383
3619
|
const scanKeys = (value, path) => {
|
|
3384
|
-
if (!
|
|
3620
|
+
if (!isPlainObject3(value)) return;
|
|
3385
3621
|
for (const key of Object.keys(value)) {
|
|
3386
3622
|
if (isAccountScoped(key)) found.push(`${path}.${key}`);
|
|
3387
3623
|
}
|
|
@@ -3389,16 +3625,16 @@ function collectNonPortableToolRefs(config) {
|
|
|
3389
3625
|
scanArray(tools.toolIds, "tools.toolIds");
|
|
3390
3626
|
scanKeys(tools.toolConfigs, "tools.toolConfigs");
|
|
3391
3627
|
scanKeys(tools.perToolLimits, "tools.perToolLimits");
|
|
3392
|
-
if (
|
|
3393
|
-
if (
|
|
3628
|
+
if (isPlainObject3(tools.approval)) scanArray(tools.approval.require, "tools.approval.require");
|
|
3629
|
+
if (isPlainObject3(tools.subagentConfig)) {
|
|
3394
3630
|
scanArray(tools.subagentConfig.toolPool, "tools.subagentConfig.toolPool");
|
|
3395
3631
|
}
|
|
3396
|
-
if (
|
|
3632
|
+
if (isPlainObject3(tools.codeModeConfig)) {
|
|
3397
3633
|
scanArray(tools.codeModeConfig.toolPool, "tools.codeModeConfig.toolPool");
|
|
3398
3634
|
}
|
|
3399
3635
|
if (Array.isArray(tools.runtimeTools)) {
|
|
3400
3636
|
tools.runtimeTools.forEach((runtimeTool, i) => {
|
|
3401
|
-
if (!
|
|
3637
|
+
if (!isPlainObject3(runtimeTool) || !isPlainObject3(runtimeTool.config)) return;
|
|
3402
3638
|
const base = `tools.runtimeTools[${i}].config`;
|
|
3403
3639
|
const rtConfig = runtimeTool.config;
|
|
3404
3640
|
if (runtimeTool.toolType === "subagent" && typeof rtConfig.agentId === "string" && rtConfig.agentId.startsWith("agent_")) {
|
|
@@ -3460,7 +3696,7 @@ var AgentDriftError = class extends Error {
|
|
|
3460
3696
|
this.plan = plan;
|
|
3461
3697
|
}
|
|
3462
3698
|
};
|
|
3463
|
-
function
|
|
3699
|
+
function parseRequestError3(err) {
|
|
3464
3700
|
if (!(err instanceof Error)) return { status: null, body: null };
|
|
3465
3701
|
const match = err.message.match(/^API request failed: (\d{3}) .*? - ([\s\S]*)$/);
|
|
3466
3702
|
if (!match) return { status: null, body: null };
|
|
@@ -3470,21 +3706,21 @@ function parseRequestError2(err) {
|
|
|
3470
3706
|
return { status: Number(match[1]), body: null };
|
|
3471
3707
|
}
|
|
3472
3708
|
}
|
|
3473
|
-
function
|
|
3474
|
-
const { status, body } =
|
|
3475
|
-
if (status !== 409 || !
|
|
3709
|
+
function toConflictError3(err) {
|
|
3710
|
+
const { status, body } = parseRequestError3(err);
|
|
3711
|
+
if (status !== 409 || !isPlainObject3(body)) return null;
|
|
3476
3712
|
const code = body.code;
|
|
3477
3713
|
if (code !== "external_modification" && code !== "remote_changed") return null;
|
|
3478
3714
|
return new AgentEnsureConflictError(
|
|
3479
3715
|
body
|
|
3480
3716
|
);
|
|
3481
3717
|
}
|
|
3482
|
-
var
|
|
3483
|
-
function
|
|
3484
|
-
let memo =
|
|
3718
|
+
var serverHashMemo3 = /* @__PURE__ */ new WeakMap();
|
|
3719
|
+
function memoFor3(client) {
|
|
3720
|
+
let memo = serverHashMemo3.get(client);
|
|
3485
3721
|
if (!memo) {
|
|
3486
3722
|
memo = /* @__PURE__ */ new Map();
|
|
3487
|
-
|
|
3723
|
+
serverHashMemo3.set(client, memo);
|
|
3488
3724
|
}
|
|
3489
3725
|
return memo;
|
|
3490
3726
|
}
|
|
@@ -3521,7 +3757,7 @@ var AgentsNamespace = class {
|
|
|
3521
3757
|
}
|
|
3522
3758
|
return plan;
|
|
3523
3759
|
}
|
|
3524
|
-
const memo =
|
|
3760
|
+
const memo = memoFor3(client);
|
|
3525
3761
|
const localHash = await computeAgentContentHash({
|
|
3526
3762
|
...definition,
|
|
3527
3763
|
config: definition.config
|
|
@@ -3566,7 +3802,7 @@ var AgentsNamespace = class {
|
|
|
3566
3802
|
body
|
|
3567
3803
|
);
|
|
3568
3804
|
} catch (err) {
|
|
3569
|
-
const conflict =
|
|
3805
|
+
const conflict = toConflictError3(err);
|
|
3570
3806
|
if (conflict) throw conflict;
|
|
3571
3807
|
throw err;
|
|
3572
3808
|
}
|
|
@@ -3574,27 +3810,27 @@ var AgentsNamespace = class {
|
|
|
3574
3810
|
};
|
|
3575
3811
|
|
|
3576
3812
|
// src/tools-ensure.ts
|
|
3577
|
-
function
|
|
3813
|
+
function isPlainObject4(value) {
|
|
3578
3814
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
3579
3815
|
}
|
|
3580
|
-
function
|
|
3816
|
+
function normalizeValue3(value) {
|
|
3581
3817
|
if (Array.isArray(value)) {
|
|
3582
|
-
return value.map((item) =>
|
|
3818
|
+
return value.map((item) => normalizeValue3(item));
|
|
3583
3819
|
}
|
|
3584
|
-
if (
|
|
3820
|
+
if (isPlainObject4(value)) {
|
|
3585
3821
|
const normalized = {};
|
|
3586
3822
|
for (const key of Object.keys(value).sort()) {
|
|
3587
3823
|
const entry = value[key];
|
|
3588
3824
|
if (entry === void 0 || entry === null) continue;
|
|
3589
|
-
normalized[key] =
|
|
3825
|
+
normalized[key] = normalizeValue3(entry);
|
|
3590
3826
|
}
|
|
3591
3827
|
return normalized;
|
|
3592
3828
|
}
|
|
3593
3829
|
return value;
|
|
3594
3830
|
}
|
|
3595
3831
|
function normalizeToolDefinition(definition) {
|
|
3596
|
-
const parametersSchema =
|
|
3597
|
-
const config =
|
|
3832
|
+
const parametersSchema = isPlainObject4(definition.parametersSchema) ? normalizeValue3(definition.parametersSchema) : {};
|
|
3833
|
+
const config = isPlainObject4(definition.config) ? normalizeValue3(definition.config) : {};
|
|
3598
3834
|
return {
|
|
3599
3835
|
toolType: definition.toolType,
|
|
3600
3836
|
...definition.description ? { description: definition.description } : {},
|
|
@@ -3639,10 +3875,10 @@ function defineTool(input) {
|
|
|
3639
3875
|
`defineTool requires "toolType" to be one of: ${[...TOOL_DEFINITION_TYPES].join(", ")}`
|
|
3640
3876
|
);
|
|
3641
3877
|
}
|
|
3642
|
-
if (!
|
|
3878
|
+
if (!isPlainObject4(input.parametersSchema)) {
|
|
3643
3879
|
throw new Error('defineTool requires a "parametersSchema" object (a JSON Schema)');
|
|
3644
3880
|
}
|
|
3645
|
-
if (!
|
|
3881
|
+
if (!isPlainObject4(input.config)) {
|
|
3646
3882
|
throw new Error('defineTool requires a "config" object');
|
|
3647
3883
|
}
|
|
3648
3884
|
const unknownKeys = Object.keys(input).filter((key) => !DEFINE_TOOL_TOP_LEVEL_KEYS.has(key));
|
|
@@ -3678,7 +3914,7 @@ var ToolDriftError = class extends Error {
|
|
|
3678
3914
|
this.plan = plan;
|
|
3679
3915
|
}
|
|
3680
3916
|
};
|
|
3681
|
-
function
|
|
3917
|
+
function parseRequestError4(err) {
|
|
3682
3918
|
if (!(err instanceof Error)) return { status: null, body: null };
|
|
3683
3919
|
const match = err.message.match(/^API request failed: (\d{3}) .*? - ([\s\S]*)$/);
|
|
3684
3920
|
if (!match) return { status: null, body: null };
|
|
@@ -3688,35 +3924,35 @@ function parseRequestError3(err) {
|
|
|
3688
3924
|
return { status: Number(match[1]), body: null };
|
|
3689
3925
|
}
|
|
3690
3926
|
}
|
|
3691
|
-
function
|
|
3692
|
-
const { status, body } =
|
|
3693
|
-
if (status !== 409 || !
|
|
3927
|
+
function toConflictError4(err) {
|
|
3928
|
+
const { status, body } = parseRequestError4(err);
|
|
3929
|
+
if (status !== 409 || !isPlainObject4(body)) return null;
|
|
3694
3930
|
const code = body.code;
|
|
3695
3931
|
if (code !== "external_modification" && code !== "remote_changed") return null;
|
|
3696
3932
|
return new ToolEnsureConflictError(
|
|
3697
3933
|
body
|
|
3698
3934
|
);
|
|
3699
3935
|
}
|
|
3700
|
-
var
|
|
3701
|
-
function
|
|
3702
|
-
let memo =
|
|
3936
|
+
var serverHashMemo4 = /* @__PURE__ */ new WeakMap();
|
|
3937
|
+
function memoFor4(client) {
|
|
3938
|
+
let memo = serverHashMemo4.get(client);
|
|
3703
3939
|
if (!memo) {
|
|
3704
3940
|
memo = /* @__PURE__ */ new Map();
|
|
3705
|
-
|
|
3941
|
+
serverHashMemo4.set(client, memo);
|
|
3706
3942
|
}
|
|
3707
3943
|
return memo;
|
|
3708
3944
|
}
|
|
3709
|
-
function
|
|
3945
|
+
function memoize3(memo, memoKey, result) {
|
|
3710
3946
|
if (result.result !== "plan") memo.set(memoKey, result.contentHash);
|
|
3711
3947
|
}
|
|
3712
|
-
async function
|
|
3948
|
+
async function request3(client, body) {
|
|
3713
3949
|
try {
|
|
3714
3950
|
return await client.post(
|
|
3715
3951
|
"/tools/ensure",
|
|
3716
3952
|
body
|
|
3717
3953
|
);
|
|
3718
3954
|
} catch (err) {
|
|
3719
|
-
const conflict =
|
|
3955
|
+
const conflict = toConflictError4(err);
|
|
3720
3956
|
if (conflict) throw conflict;
|
|
3721
3957
|
throw err;
|
|
3722
3958
|
}
|
|
@@ -3728,7 +3964,7 @@ async function ensureTool(client, definition, options = {}) {
|
|
|
3728
3964
|
...expectedRemoteHash ? { expectedRemoteHash } : {}
|
|
3729
3965
|
};
|
|
3730
3966
|
if (dryRun || expectNoChanges) {
|
|
3731
|
-
const plan = await
|
|
3967
|
+
const plan = await request3(client, {
|
|
3732
3968
|
name: definition.name,
|
|
3733
3969
|
definition,
|
|
3734
3970
|
dryRun: true,
|
|
@@ -3742,20 +3978,20 @@ async function ensureTool(client, definition, options = {}) {
|
|
|
3742
3978
|
}
|
|
3743
3979
|
return plan;
|
|
3744
3980
|
}
|
|
3745
|
-
const memo =
|
|
3981
|
+
const memo = memoFor4(client);
|
|
3746
3982
|
const localHash = await computeToolContentHash(definition);
|
|
3747
3983
|
const memoKey = `${definition.name} ${localHash}`;
|
|
3748
3984
|
const contentHash = memo.get(memoKey) ?? localHash;
|
|
3749
|
-
const probe = await
|
|
3985
|
+
const probe = await request3(client, {
|
|
3750
3986
|
name: definition.name,
|
|
3751
3987
|
contentHash,
|
|
3752
3988
|
...passthrough
|
|
3753
3989
|
});
|
|
3754
3990
|
if (probe.result !== "definitionRequired") {
|
|
3755
|
-
|
|
3991
|
+
memoize3(memo, memoKey, probe);
|
|
3756
3992
|
return probe;
|
|
3757
3993
|
}
|
|
3758
|
-
const converged = await
|
|
3994
|
+
const converged = await request3(client, {
|
|
3759
3995
|
name: definition.name,
|
|
3760
3996
|
definition,
|
|
3761
3997
|
...passthrough
|
|
@@ -3763,7 +3999,7 @@ async function ensureTool(client, definition, options = {}) {
|
|
|
3763
3999
|
if (converged.result === "definitionRequired") {
|
|
3764
4000
|
throw new Error("Server reported definitionRequired for a full-definition request");
|
|
3765
4001
|
}
|
|
3766
|
-
|
|
4002
|
+
memoize3(memo, memoKey, converged);
|
|
3767
4003
|
return converged;
|
|
3768
4004
|
}
|
|
3769
4005
|
async function pullTool(client, name) {
|
|
@@ -3810,26 +4046,26 @@ var ToolsNamespace = class {
|
|
|
3810
4046
|
};
|
|
3811
4047
|
|
|
3812
4048
|
// src/products-ensure.ts
|
|
3813
|
-
function
|
|
4049
|
+
function isPlainObject5(value) {
|
|
3814
4050
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
3815
4051
|
}
|
|
3816
|
-
function
|
|
4052
|
+
function normalizeValue4(value) {
|
|
3817
4053
|
if (Array.isArray(value)) {
|
|
3818
|
-
return value.map((item) =>
|
|
4054
|
+
return value.map((item) => normalizeValue4(item));
|
|
3819
4055
|
}
|
|
3820
|
-
if (
|
|
4056
|
+
if (isPlainObject5(value)) {
|
|
3821
4057
|
const normalized = {};
|
|
3822
4058
|
for (const key of Object.keys(value).sort()) {
|
|
3823
4059
|
const entry = value[key];
|
|
3824
4060
|
if (entry === void 0 || entry === null) continue;
|
|
3825
|
-
normalized[key] =
|
|
4061
|
+
normalized[key] = normalizeValue4(entry);
|
|
3826
4062
|
}
|
|
3827
4063
|
return normalized;
|
|
3828
4064
|
}
|
|
3829
4065
|
return value;
|
|
3830
4066
|
}
|
|
3831
4067
|
function normalizeProductDefinition(definition) {
|
|
3832
|
-
const spec =
|
|
4068
|
+
const spec = isPlainObject5(definition.spec) ? normalizeValue4(definition.spec) : {};
|
|
3833
4069
|
return {
|
|
3834
4070
|
...definition.description ? { description: definition.description } : {},
|
|
3835
4071
|
...definition.icon ? { icon: definition.icon } : {},
|
|
@@ -3856,7 +4092,7 @@ function defineProduct(input) {
|
|
|
3856
4092
|
if (input.icon != null && typeof input.icon !== "string") {
|
|
3857
4093
|
throw new Error('defineProduct "icon" must be a string when provided');
|
|
3858
4094
|
}
|
|
3859
|
-
if (input.spec != null && !
|
|
4095
|
+
if (input.spec != null && !isPlainObject5(input.spec)) {
|
|
3860
4096
|
throw new Error('defineProduct "spec" must be an object when provided');
|
|
3861
4097
|
}
|
|
3862
4098
|
const unknownKeys = Object.keys(input).filter((key) => !DEFINE_PRODUCT_TOP_LEVEL_KEYS.has(key));
|
|
@@ -3891,7 +4127,7 @@ var ProductDriftError = class extends Error {
|
|
|
3891
4127
|
this.plan = plan;
|
|
3892
4128
|
}
|
|
3893
4129
|
};
|
|
3894
|
-
function
|
|
4130
|
+
function parseRequestError5(err) {
|
|
3895
4131
|
if (!(err instanceof Error)) return { status: null, body: null };
|
|
3896
4132
|
const match = err.message.match(/^API request failed: (\d{3}) .*? - ([\s\S]*)$/);
|
|
3897
4133
|
if (!match) return { status: null, body: null };
|
|
@@ -3901,35 +4137,35 @@ function parseRequestError4(err) {
|
|
|
3901
4137
|
return { status: Number(match[1]), body: null };
|
|
3902
4138
|
}
|
|
3903
4139
|
}
|
|
3904
|
-
function
|
|
3905
|
-
const { status, body } =
|
|
3906
|
-
if (status !== 409 || !
|
|
4140
|
+
function toConflictError5(err) {
|
|
4141
|
+
const { status, body } = parseRequestError5(err);
|
|
4142
|
+
if (status !== 409 || !isPlainObject5(body)) return null;
|
|
3907
4143
|
const code = body.code;
|
|
3908
4144
|
if (code !== "external_modification" && code !== "remote_changed") return null;
|
|
3909
4145
|
return new ProductEnsureConflictError(
|
|
3910
4146
|
body
|
|
3911
4147
|
);
|
|
3912
4148
|
}
|
|
3913
|
-
var
|
|
3914
|
-
function
|
|
3915
|
-
let memo =
|
|
4149
|
+
var serverHashMemo5 = /* @__PURE__ */ new WeakMap();
|
|
4150
|
+
function memoFor5(client) {
|
|
4151
|
+
let memo = serverHashMemo5.get(client);
|
|
3916
4152
|
if (!memo) {
|
|
3917
4153
|
memo = /* @__PURE__ */ new Map();
|
|
3918
|
-
|
|
4154
|
+
serverHashMemo5.set(client, memo);
|
|
3919
4155
|
}
|
|
3920
4156
|
return memo;
|
|
3921
4157
|
}
|
|
3922
|
-
function
|
|
4158
|
+
function memoize4(memo, memoKey, result) {
|
|
3923
4159
|
if (result.result !== "plan") memo.set(memoKey, result.contentHash);
|
|
3924
4160
|
}
|
|
3925
|
-
async function
|
|
4161
|
+
async function request4(client, body) {
|
|
3926
4162
|
try {
|
|
3927
4163
|
return await client.post(
|
|
3928
4164
|
"/products/ensure",
|
|
3929
4165
|
body
|
|
3930
4166
|
);
|
|
3931
4167
|
} catch (err) {
|
|
3932
|
-
const conflict =
|
|
4168
|
+
const conflict = toConflictError5(err);
|
|
3933
4169
|
if (conflict) throw conflict;
|
|
3934
4170
|
throw err;
|
|
3935
4171
|
}
|
|
@@ -3941,7 +4177,7 @@ async function ensureProduct(client, definition, options = {}) {
|
|
|
3941
4177
|
...expectedRemoteHash ? { expectedRemoteHash } : {}
|
|
3942
4178
|
};
|
|
3943
4179
|
if (dryRun || expectNoChanges) {
|
|
3944
|
-
const plan = await
|
|
4180
|
+
const plan = await request4(client, {
|
|
3945
4181
|
name: definition.name,
|
|
3946
4182
|
definition,
|
|
3947
4183
|
dryRun: true,
|
|
@@ -3955,20 +4191,20 @@ async function ensureProduct(client, definition, options = {}) {
|
|
|
3955
4191
|
}
|
|
3956
4192
|
return plan;
|
|
3957
4193
|
}
|
|
3958
|
-
const memo =
|
|
4194
|
+
const memo = memoFor5(client);
|
|
3959
4195
|
const localHash = await computeProductContentHash(definition);
|
|
3960
4196
|
const memoKey = `${definition.name} ${localHash}`;
|
|
3961
4197
|
const contentHash = memo.get(memoKey) ?? localHash;
|
|
3962
|
-
const probe = await
|
|
4198
|
+
const probe = await request4(client, {
|
|
3963
4199
|
name: definition.name,
|
|
3964
4200
|
contentHash,
|
|
3965
4201
|
...passthrough
|
|
3966
4202
|
});
|
|
3967
4203
|
if (probe.result !== "definitionRequired") {
|
|
3968
|
-
|
|
4204
|
+
memoize4(memo, memoKey, probe);
|
|
3969
4205
|
return probe;
|
|
3970
4206
|
}
|
|
3971
|
-
const converged = await
|
|
4207
|
+
const converged = await request4(client, {
|
|
3972
4208
|
name: definition.name,
|
|
3973
4209
|
definition,
|
|
3974
4210
|
...passthrough
|
|
@@ -3976,7 +4212,7 @@ async function ensureProduct(client, definition, options = {}) {
|
|
|
3976
4212
|
if (converged.result === "definitionRequired") {
|
|
3977
4213
|
throw new Error("Server reported definitionRequired for a full-definition request");
|
|
3978
4214
|
}
|
|
3979
|
-
|
|
4215
|
+
memoize4(memo, memoKey, converged);
|
|
3980
4216
|
return converged;
|
|
3981
4217
|
}
|
|
3982
4218
|
async function pullProduct(client, name) {
|
|
@@ -4022,6 +4258,262 @@ var ProductsNamespace = class {
|
|
|
4022
4258
|
}
|
|
4023
4259
|
};
|
|
4024
4260
|
|
|
4261
|
+
// src/surfaces-ensure.ts
|
|
4262
|
+
function isPlainObject6(value) {
|
|
4263
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
4264
|
+
}
|
|
4265
|
+
function normalizeValue5(value) {
|
|
4266
|
+
if (Array.isArray(value)) {
|
|
4267
|
+
return value.map((item) => normalizeValue5(item));
|
|
4268
|
+
}
|
|
4269
|
+
if (isPlainObject6(value)) {
|
|
4270
|
+
const normalized = {};
|
|
4271
|
+
for (const key of Object.keys(value).sort()) {
|
|
4272
|
+
const entry = value[key];
|
|
4273
|
+
if (entry === void 0 || entry === null) continue;
|
|
4274
|
+
normalized[key] = normalizeValue5(entry);
|
|
4275
|
+
}
|
|
4276
|
+
return normalized;
|
|
4277
|
+
}
|
|
4278
|
+
return value;
|
|
4279
|
+
}
|
|
4280
|
+
function normalizeSurfaceDefinition(definition) {
|
|
4281
|
+
const behavior = isPlainObject6(definition.behavior) ? normalizeValue5(definition.behavior) : { type: definition.type };
|
|
4282
|
+
return {
|
|
4283
|
+
type: definition.type,
|
|
4284
|
+
behavior,
|
|
4285
|
+
status: definition.status || "draft",
|
|
4286
|
+
environment: definition.environment || "development"
|
|
4287
|
+
};
|
|
4288
|
+
}
|
|
4289
|
+
async function computeSurfaceContentHash(definition) {
|
|
4290
|
+
const serialized = JSON.stringify(normalizeSurfaceDefinition(definition));
|
|
4291
|
+
const encoded = new TextEncoder().encode(serialized);
|
|
4292
|
+
const hashBuffer = await crypto.subtle.digest("SHA-256", encoded);
|
|
4293
|
+
return Array.from(new Uint8Array(hashBuffer)).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
4294
|
+
}
|
|
4295
|
+
var DEFINE_SURFACE_TOP_LEVEL_KEYS = /* @__PURE__ */ new Set([
|
|
4296
|
+
"name",
|
|
4297
|
+
"type",
|
|
4298
|
+
"behavior",
|
|
4299
|
+
"inbound",
|
|
4300
|
+
"outbound",
|
|
4301
|
+
"status",
|
|
4302
|
+
"environment"
|
|
4303
|
+
]);
|
|
4304
|
+
var SURFACE_DEFINITION_TYPES = /* @__PURE__ */ new Set([
|
|
4305
|
+
"chat",
|
|
4306
|
+
"mcp",
|
|
4307
|
+
"mcp_code",
|
|
4308
|
+
"api",
|
|
4309
|
+
"webhook",
|
|
4310
|
+
"schedule",
|
|
4311
|
+
"a2a",
|
|
4312
|
+
"email",
|
|
4313
|
+
"slack",
|
|
4314
|
+
"sms",
|
|
4315
|
+
"imessage",
|
|
4316
|
+
"discord",
|
|
4317
|
+
"whatsapp",
|
|
4318
|
+
"telegram",
|
|
4319
|
+
"hosted-page",
|
|
4320
|
+
"chrome_extension"
|
|
4321
|
+
]);
|
|
4322
|
+
function defineSurface(input) {
|
|
4323
|
+
if (!input || typeof input !== "object") {
|
|
4324
|
+
throw new Error("defineSurface requires a definition object");
|
|
4325
|
+
}
|
|
4326
|
+
if (typeof input.name !== "string" || input.name.length === 0) {
|
|
4327
|
+
throw new Error('defineSurface requires a non-empty string "name"');
|
|
4328
|
+
}
|
|
4329
|
+
if (typeof input.type !== "string" || !SURFACE_DEFINITION_TYPES.has(input.type)) {
|
|
4330
|
+
throw new Error(
|
|
4331
|
+
`defineSurface requires "type" to be one of: ${[...SURFACE_DEFINITION_TYPES].join(", ")}`
|
|
4332
|
+
);
|
|
4333
|
+
}
|
|
4334
|
+
if (input.behavior !== void 0 && !isPlainObject6(input.behavior)) {
|
|
4335
|
+
throw new Error('defineSurface "behavior" must be an object when provided');
|
|
4336
|
+
}
|
|
4337
|
+
if (input.inbound !== void 0 && !isPlainObject6(input.inbound)) {
|
|
4338
|
+
throw new Error('defineSurface "inbound" must be an object when provided');
|
|
4339
|
+
}
|
|
4340
|
+
if (input.outbound !== void 0 && !isPlainObject6(input.outbound)) {
|
|
4341
|
+
throw new Error('defineSurface "outbound" must be an object when provided');
|
|
4342
|
+
}
|
|
4343
|
+
if (input.status !== void 0 && !["draft", "active", "paused"].includes(input.status)) {
|
|
4344
|
+
throw new Error('defineSurface "status" must be one of: draft, active, paused');
|
|
4345
|
+
}
|
|
4346
|
+
if (input.environment !== void 0 && !["production", "development"].includes(input.environment)) {
|
|
4347
|
+
throw new Error('defineSurface "environment" must be one of: production, development');
|
|
4348
|
+
}
|
|
4349
|
+
const unknownKeys = Object.keys(input).filter((key) => !DEFINE_SURFACE_TOP_LEVEL_KEYS.has(key));
|
|
4350
|
+
if (unknownKeys.length > 0) {
|
|
4351
|
+
throw new Error(
|
|
4352
|
+
`defineSurface: unknown field(s): ${unknownKeys.join(", ")}. Allowed fields are name, type, behavior, inbound, outbound, status, environment.`
|
|
4353
|
+
);
|
|
4354
|
+
}
|
|
4355
|
+
return {
|
|
4356
|
+
name: input.name,
|
|
4357
|
+
type: input.type,
|
|
4358
|
+
...input.behavior !== void 0 ? { behavior: input.behavior } : {},
|
|
4359
|
+
...input.inbound !== void 0 ? { inbound: input.inbound } : {},
|
|
4360
|
+
...input.outbound !== void 0 ? { outbound: input.outbound } : {},
|
|
4361
|
+
...input.status !== void 0 ? { status: input.status } : {},
|
|
4362
|
+
...input.environment !== void 0 ? { environment: input.environment } : {}
|
|
4363
|
+
};
|
|
4364
|
+
}
|
|
4365
|
+
var SurfaceEnsureConflictError = class extends Error {
|
|
4366
|
+
constructor(body) {
|
|
4367
|
+
super(body.error ?? `Surface ensure conflict: ${body.code}`);
|
|
4368
|
+
this.name = "SurfaceEnsureConflictError";
|
|
4369
|
+
this.code = body.code;
|
|
4370
|
+
this.lastModifiedSource = body.lastModifiedSource;
|
|
4371
|
+
this.modifiedAt = body.modifiedAt;
|
|
4372
|
+
this.currentHash = body.currentHash;
|
|
4373
|
+
}
|
|
4374
|
+
};
|
|
4375
|
+
var SurfaceDriftError = class extends Error {
|
|
4376
|
+
constructor(plan) {
|
|
4377
|
+
super(
|
|
4378
|
+
`Surface "${plan.surfaceId ?? "definition"}" drifted: plan is '${plan.changes}' (changed: ${plan.changedKeys.join(", ") || "n/a"}). Run client.surfaces.pull(productId, name) to absorb the remote edit into your repo, or re-run ensure to converge.`
|
|
4379
|
+
);
|
|
4380
|
+
this.name = "SurfaceDriftError";
|
|
4381
|
+
this.plan = plan;
|
|
4382
|
+
}
|
|
4383
|
+
};
|
|
4384
|
+
function parseRequestError6(err) {
|
|
4385
|
+
if (!(err instanceof Error)) return { status: null, body: null };
|
|
4386
|
+
const match = err.message.match(/^API request failed: (\d{3}) .*? - ([\s\S]*)$/);
|
|
4387
|
+
if (!match) return { status: null, body: null };
|
|
4388
|
+
try {
|
|
4389
|
+
return { status: Number(match[1]), body: JSON.parse(match[2]) };
|
|
4390
|
+
} catch {
|
|
4391
|
+
return { status: Number(match[1]), body: null };
|
|
4392
|
+
}
|
|
4393
|
+
}
|
|
4394
|
+
function toConflictError6(err) {
|
|
4395
|
+
const { status, body } = parseRequestError6(err);
|
|
4396
|
+
if (status !== 409 || !isPlainObject6(body)) return null;
|
|
4397
|
+
const code = body.code;
|
|
4398
|
+
if (code !== "external_modification" && code !== "remote_changed") return null;
|
|
4399
|
+
return new SurfaceEnsureConflictError(
|
|
4400
|
+
body
|
|
4401
|
+
);
|
|
4402
|
+
}
|
|
4403
|
+
var serverHashMemo6 = /* @__PURE__ */ new WeakMap();
|
|
4404
|
+
function memoFor6(client) {
|
|
4405
|
+
let memo = serverHashMemo6.get(client);
|
|
4406
|
+
if (!memo) {
|
|
4407
|
+
memo = /* @__PURE__ */ new Map();
|
|
4408
|
+
serverHashMemo6.set(client, memo);
|
|
4409
|
+
}
|
|
4410
|
+
return memo;
|
|
4411
|
+
}
|
|
4412
|
+
function memoize5(memo, memoKey, result) {
|
|
4413
|
+
if (result.result !== "plan") memo.set(memoKey, result.contentHash);
|
|
4414
|
+
}
|
|
4415
|
+
async function request5(client, productId, body) {
|
|
4416
|
+
try {
|
|
4417
|
+
return await client.post(
|
|
4418
|
+
`/products/${encodeURIComponent(productId)}/surfaces/ensure`,
|
|
4419
|
+
body
|
|
4420
|
+
);
|
|
4421
|
+
} catch (err) {
|
|
4422
|
+
const conflict = toConflictError6(err);
|
|
4423
|
+
if (conflict) throw conflict;
|
|
4424
|
+
throw err;
|
|
4425
|
+
}
|
|
4426
|
+
}
|
|
4427
|
+
async function ensureSurface(client, productId, definition, options = {}) {
|
|
4428
|
+
const { dryRun, onConflict, expectedRemoteHash, expectNoChanges } = options;
|
|
4429
|
+
const passthrough = {
|
|
4430
|
+
...onConflict ? { onConflict } : {},
|
|
4431
|
+
...expectedRemoteHash ? { expectedRemoteHash } : {}
|
|
4432
|
+
};
|
|
4433
|
+
if (dryRun || expectNoChanges) {
|
|
4434
|
+
const plan = await request5(client, productId, {
|
|
4435
|
+
name: definition.name,
|
|
4436
|
+
definition,
|
|
4437
|
+
dryRun: true,
|
|
4438
|
+
...passthrough
|
|
4439
|
+
});
|
|
4440
|
+
if (plan.result !== "plan") {
|
|
4441
|
+
throw new Error(`Expected a plan result from dryRun, got '${plan.result}'`);
|
|
4442
|
+
}
|
|
4443
|
+
if (expectNoChanges && plan.changes !== "none") {
|
|
4444
|
+
throw new SurfaceDriftError(plan);
|
|
4445
|
+
}
|
|
4446
|
+
return plan;
|
|
4447
|
+
}
|
|
4448
|
+
const memo = memoFor6(client);
|
|
4449
|
+
const localHash = await computeSurfaceContentHash(definition);
|
|
4450
|
+
const memoKey = `${productId} ${definition.name} ${localHash}`;
|
|
4451
|
+
const contentHash = memo.get(memoKey) ?? localHash;
|
|
4452
|
+
const probe = await request5(client, productId, {
|
|
4453
|
+
name: definition.name,
|
|
4454
|
+
contentHash,
|
|
4455
|
+
...passthrough
|
|
4456
|
+
});
|
|
4457
|
+
if (probe.result !== "definitionRequired") {
|
|
4458
|
+
memoize5(memo, memoKey, probe);
|
|
4459
|
+
return probe;
|
|
4460
|
+
}
|
|
4461
|
+
const converged = await request5(client, productId, {
|
|
4462
|
+
name: definition.name,
|
|
4463
|
+
definition,
|
|
4464
|
+
...passthrough
|
|
4465
|
+
});
|
|
4466
|
+
if (converged.result === "definitionRequired") {
|
|
4467
|
+
throw new Error("Server reported definitionRequired for a full-definition request");
|
|
4468
|
+
}
|
|
4469
|
+
memoize5(memo, memoKey, converged);
|
|
4470
|
+
return converged;
|
|
4471
|
+
}
|
|
4472
|
+
async function pullSurface(client, productId, name) {
|
|
4473
|
+
return client.get(
|
|
4474
|
+
`/products/${encodeURIComponent(productId)}/surfaces/pull`,
|
|
4475
|
+
{ name }
|
|
4476
|
+
);
|
|
4477
|
+
}
|
|
4478
|
+
|
|
4479
|
+
// src/surfaces-namespace.ts
|
|
4480
|
+
var SurfacesNamespace = class {
|
|
4481
|
+
constructor(getClient) {
|
|
4482
|
+
this.getClient = getClient;
|
|
4483
|
+
}
|
|
4484
|
+
/**
|
|
4485
|
+
* Idempotently converge a `defineSurface` definition onto a product.
|
|
4486
|
+
* Hash-first: the steady state is one tiny probe request. Creates or updates
|
|
4487
|
+
* the surface; never deletes. Identity is name + product.
|
|
4488
|
+
*
|
|
4489
|
+
* @example
|
|
4490
|
+
* ```typescript
|
|
4491
|
+
* const chat = defineSurface({
|
|
4492
|
+
* name: 'Support Chat',
|
|
4493
|
+
* type: 'chat',
|
|
4494
|
+
* behavior: { type: 'chat', greeting: 'Hi there!' },
|
|
4495
|
+
* status: 'active',
|
|
4496
|
+
* })
|
|
4497
|
+
*
|
|
4498
|
+
* // Converge (CI/deploy).
|
|
4499
|
+
* const result = await Runtype.surfaces.ensure('product_abc', chat)
|
|
4500
|
+
*
|
|
4501
|
+
* // PR drift gate.
|
|
4502
|
+
* await Runtype.surfaces.ensure('product_abc', chat, { expectNoChanges: true })
|
|
4503
|
+
* ```
|
|
4504
|
+
*/
|
|
4505
|
+
async ensure(productId, definition, options = {}) {
|
|
4506
|
+
return ensureSurface(this.getClient(), productId, definition, options);
|
|
4507
|
+
}
|
|
4508
|
+
/**
|
|
4509
|
+
* Pull the canonical definition + provenance for a surface by name within a
|
|
4510
|
+
* product — the absorb-drift direction of the ensure protocol.
|
|
4511
|
+
*/
|
|
4512
|
+
async pull(productId, name) {
|
|
4513
|
+
return pullSurface(this.getClient(), productId, name);
|
|
4514
|
+
}
|
|
4515
|
+
};
|
|
4516
|
+
|
|
4025
4517
|
// src/transform.ts
|
|
4026
4518
|
function transformResponse(data) {
|
|
4027
4519
|
return data;
|
|
@@ -4469,6 +4961,35 @@ var Runtype = class {
|
|
|
4469
4961
|
static get products() {
|
|
4470
4962
|
return new ProductsNamespace(() => this.getClient());
|
|
4471
4963
|
}
|
|
4964
|
+
/**
|
|
4965
|
+
* Config-as-code operations for product surfaces. `surfaces.ensure` is the
|
|
4966
|
+
* deploy-time, non-executing converge (create-or-update a surface by name
|
|
4967
|
+
* within a product); `surfaces.pull` is the absorb-drift direction.
|
|
4968
|
+
*
|
|
4969
|
+
* @example
|
|
4970
|
+
* ```typescript
|
|
4971
|
+
* import { Runtype, defineSurface } from '@runtypelabs/sdk'
|
|
4972
|
+
*
|
|
4973
|
+
* const chat = defineSurface({
|
|
4974
|
+
* name: 'Support Chat',
|
|
4975
|
+
* type: 'chat',
|
|
4976
|
+
* behavior: { type: 'chat', greeting: 'Hi there!' },
|
|
4977
|
+
* status: 'active',
|
|
4978
|
+
* })
|
|
4979
|
+
*
|
|
4980
|
+
* // Converge at deploy time (idempotent; one tiny probe in steady state)
|
|
4981
|
+
* await Runtype.surfaces.ensure('product_abc', chat)
|
|
4982
|
+
*
|
|
4983
|
+
* // CI drift gate
|
|
4984
|
+
* await Runtype.surfaces.ensure('product_abc', chat, { expectNoChanges: true })
|
|
4985
|
+
*
|
|
4986
|
+
* // Absorb a dashboard edit back into the repo
|
|
4987
|
+
* const { definition } = await Runtype.surfaces.pull('product_abc', 'Support Chat')
|
|
4988
|
+
* ```
|
|
4989
|
+
*/
|
|
4990
|
+
static get surfaces() {
|
|
4991
|
+
return new SurfacesNamespace(() => this.getClient());
|
|
4992
|
+
}
|
|
4472
4993
|
};
|
|
4473
4994
|
|
|
4474
4995
|
// src/generated-tool-gate.ts
|
|
@@ -4691,8 +5212,8 @@ function buildGeneratedRuntimeToolGateOutput(proposal, options = {}) {
|
|
|
4691
5212
|
...decision.tool ? { tool: decision.tool } : {}
|
|
4692
5213
|
};
|
|
4693
5214
|
}
|
|
4694
|
-
function attachRuntimeToolsToDispatchRequest(
|
|
4695
|
-
const stepList =
|
|
5215
|
+
function attachRuntimeToolsToDispatchRequest(request6, runtimeTools, options = {}) {
|
|
5216
|
+
const stepList = request6.flow.steps;
|
|
4696
5217
|
if (!stepList || !Array.isArray(stepList) || stepList.length === 0) {
|
|
4697
5218
|
throw new Error("Cannot attach runtime tools: dispatch request must include flow.steps");
|
|
4698
5219
|
}
|
|
@@ -4735,9 +5256,9 @@ function attachRuntimeToolsToDispatchRequest(request4, runtimeTools, options = {
|
|
|
4735
5256
|
}
|
|
4736
5257
|
};
|
|
4737
5258
|
return {
|
|
4738
|
-
...
|
|
5259
|
+
...request6,
|
|
4739
5260
|
flow: {
|
|
4740
|
-
...
|
|
5261
|
+
...request6.flow,
|
|
4741
5262
|
// `clonedSteps` is a structural clone of `request.flow.steps` (already
|
|
4742
5263
|
// `FlowStepDefinition[]`); only the prompt step's `config.tools` was
|
|
4743
5264
|
// merged, so every step's `type` discriminant is preserved. The clone is
|
|
@@ -4747,12 +5268,12 @@ function attachRuntimeToolsToDispatchRequest(request4, runtimeTools, options = {
|
|
|
4747
5268
|
}
|
|
4748
5269
|
};
|
|
4749
5270
|
}
|
|
4750
|
-
function applyGeneratedRuntimeToolProposalToDispatchRequest(
|
|
5271
|
+
function applyGeneratedRuntimeToolProposalToDispatchRequest(request6, proposal, options = {}) {
|
|
4751
5272
|
const decision = evaluateGeneratedRuntimeToolProposal(proposal, options.gate);
|
|
4752
5273
|
if (!decision.approved || !decision.tool) {
|
|
4753
|
-
return { decision, request:
|
|
5274
|
+
return { decision, request: request6 };
|
|
4754
5275
|
}
|
|
4755
|
-
const nextRequest = attachRuntimeToolsToDispatchRequest(
|
|
5276
|
+
const nextRequest = attachRuntimeToolsToDispatchRequest(request6, [decision.tool], options.attach);
|
|
4756
5277
|
return {
|
|
4757
5278
|
decision,
|
|
4758
5279
|
request: nextRequest
|
|
@@ -7002,15 +7523,15 @@ var DispatchEndpoint = class {
|
|
|
7002
7523
|
* Attach approved runtime tools to a prompt step in a redispatch request.
|
|
7003
7524
|
* Returns a new request object and does not mutate the original.
|
|
7004
7525
|
*/
|
|
7005
|
-
attachApprovedRuntimeTools(
|
|
7006
|
-
return attachRuntimeToolsToDispatchRequest(
|
|
7526
|
+
attachApprovedRuntimeTools(request6, runtimeTools, options) {
|
|
7527
|
+
return attachRuntimeToolsToDispatchRequest(request6, runtimeTools, options);
|
|
7007
7528
|
}
|
|
7008
7529
|
/**
|
|
7009
7530
|
* Validate a generated runtime tool proposal and attach it to the redispatch
|
|
7010
7531
|
* request if approved, in one call.
|
|
7011
7532
|
*/
|
|
7012
|
-
applyGeneratedRuntimeToolProposal(
|
|
7013
|
-
return applyGeneratedRuntimeToolProposalToDispatchRequest(
|
|
7533
|
+
applyGeneratedRuntimeToolProposal(request6, proposal, options) {
|
|
7534
|
+
return applyGeneratedRuntimeToolProposalToDispatchRequest(request6, proposal, options);
|
|
7014
7535
|
}
|
|
7015
7536
|
};
|
|
7016
7537
|
var ChatEndpoint = class {
|
|
@@ -7562,8 +8083,8 @@ var GENERATED_RUNTIME_TOOL_PROPOSAL_SCHEMA = {
|
|
|
7562
8083
|
},
|
|
7563
8084
|
required: ["name", "description", "toolType", "parametersSchema", "config"]
|
|
7564
8085
|
};
|
|
7565
|
-
function appendRuntimeToolsToAgentRequest(
|
|
7566
|
-
const existing =
|
|
8086
|
+
function appendRuntimeToolsToAgentRequest(request6, runtimeTools) {
|
|
8087
|
+
const existing = request6.tools?.runtimeTools || [];
|
|
7567
8088
|
const existingNames = new Set(existing.map((tool) => tool.name));
|
|
7568
8089
|
const converted = runtimeTools.filter((tool) => !existingNames.has(tool.name)).map((tool) => ({
|
|
7569
8090
|
name: tool.name,
|
|
@@ -7573,9 +8094,9 @@ function appendRuntimeToolsToAgentRequest(request4, runtimeTools) {
|
|
|
7573
8094
|
...tool.config ? { config: tool.config } : {}
|
|
7574
8095
|
}));
|
|
7575
8096
|
return {
|
|
7576
|
-
...
|
|
8097
|
+
...request6,
|
|
7577
8098
|
tools: {
|
|
7578
|
-
...
|
|
8099
|
+
...request6.tools,
|
|
7579
8100
|
runtimeTools: [...existing, ...converted]
|
|
7580
8101
|
}
|
|
7581
8102
|
};
|
|
@@ -7651,21 +8172,21 @@ var _AgentsEndpoint = class _AgentsEndpoint {
|
|
|
7651
8172
|
* Attach approved runtime tools to an agent execute request.
|
|
7652
8173
|
* Returns a new request object and does not mutate the original.
|
|
7653
8174
|
*/
|
|
7654
|
-
attachApprovedRuntimeTools(
|
|
7655
|
-
return appendRuntimeToolsToAgentRequest(
|
|
8175
|
+
attachApprovedRuntimeTools(request6, runtimeTools) {
|
|
8176
|
+
return appendRuntimeToolsToAgentRequest(request6, runtimeTools);
|
|
7656
8177
|
}
|
|
7657
8178
|
/**
|
|
7658
8179
|
* Validate a generated runtime tool proposal and append it to an agent execute
|
|
7659
8180
|
* request if approved, in one call.
|
|
7660
8181
|
*/
|
|
7661
|
-
applyGeneratedRuntimeToolProposal(
|
|
8182
|
+
applyGeneratedRuntimeToolProposal(request6, proposal, options) {
|
|
7662
8183
|
const decision = evaluateGeneratedRuntimeToolProposal(proposal, options);
|
|
7663
8184
|
if (!decision.approved || !decision.tool) {
|
|
7664
|
-
return { decision, request:
|
|
8185
|
+
return { decision, request: request6 };
|
|
7665
8186
|
}
|
|
7666
8187
|
return {
|
|
7667
8188
|
decision,
|
|
7668
|
-
request: appendRuntimeToolsToAgentRequest(
|
|
8189
|
+
request: appendRuntimeToolsToAgentRequest(request6, [decision.tool])
|
|
7669
8190
|
};
|
|
7670
8191
|
}
|
|
7671
8192
|
/**
|
|
@@ -10766,6 +11287,29 @@ var BillingEndpoint = class {
|
|
|
10766
11287
|
return this.client.get("/billing/spend-analytics", params);
|
|
10767
11288
|
}
|
|
10768
11289
|
};
|
|
11290
|
+
var ToolApprovalGrantsEndpoint = class {
|
|
11291
|
+
constructor(client) {
|
|
11292
|
+
this.client = client;
|
|
11293
|
+
}
|
|
11294
|
+
/**
|
|
11295
|
+
* List active remembered tool-approval grants for the authenticated owner,
|
|
11296
|
+
* optionally filtered to a single agent.
|
|
11297
|
+
*/
|
|
11298
|
+
async list(agentId) {
|
|
11299
|
+
const query = agentId ? `?agentId=${encodeURIComponent(agentId)}` : "";
|
|
11300
|
+
const response = await this.client.get(
|
|
11301
|
+
`/tool-approval-grants${query}`
|
|
11302
|
+
);
|
|
11303
|
+
return response.data;
|
|
11304
|
+
}
|
|
11305
|
+
/**
|
|
11306
|
+
* Revoke (soft-delete) a remembered grant so the tool prompts for approval
|
|
11307
|
+
* again on future dispatches.
|
|
11308
|
+
*/
|
|
11309
|
+
async revoke(id) {
|
|
11310
|
+
return this.client.delete(`/tool-approval-grants/${id}`);
|
|
11311
|
+
}
|
|
11312
|
+
};
|
|
10769
11313
|
var AppsEndpoint = class {
|
|
10770
11314
|
constructor(client) {
|
|
10771
11315
|
this.client = client;
|
|
@@ -10863,6 +11407,7 @@ var RuntypeClient2 = class {
|
|
|
10863
11407
|
this.flowVersions = new FlowVersionsEndpoint(this);
|
|
10864
11408
|
this.integrations = new IntegrationsEndpoint(this);
|
|
10865
11409
|
this.billing = new BillingEndpoint(this);
|
|
11410
|
+
this.toolApprovalGrants = new ToolApprovalGrantsEndpoint(this);
|
|
10866
11411
|
}
|
|
10867
11412
|
/**
|
|
10868
11413
|
* Set the API key for authentication
|
|
@@ -10901,7 +11446,7 @@ var RuntypeClient2 = class {
|
|
|
10901
11446
|
clearApiKey() {
|
|
10902
11447
|
delete this.headers.Authorization;
|
|
10903
11448
|
}
|
|
10904
|
-
async runWithLocalTools(
|
|
11449
|
+
async runWithLocalTools(request6, localTools, arg3, arg4) {
|
|
10905
11450
|
const isOptionsObject = (val) => typeof val === "object" && val !== null && "scope" in val;
|
|
10906
11451
|
const callbacks = isOptionsObject(arg3) ? void 0 : arg3;
|
|
10907
11452
|
const options = (isOptionsObject(arg3) ? arg3 : arg4) ?? {};
|
|
@@ -10915,12 +11460,12 @@ var RuntypeClient2 = class {
|
|
|
10915
11460
|
...entry.pageOrigin ? { pageOrigin: entry.pageOrigin } : {}
|
|
10916
11461
|
})) : [];
|
|
10917
11462
|
const modifiedRequest = {
|
|
10918
|
-
...
|
|
11463
|
+
...request6,
|
|
10919
11464
|
...derivedClientTools.length > 0 ? {
|
|
10920
|
-
clientTools: [...
|
|
11465
|
+
clientTools: [...request6.clientTools ?? [], ...derivedClientTools]
|
|
10921
11466
|
} : {},
|
|
10922
11467
|
options: {
|
|
10923
|
-
...
|
|
11468
|
+
...request6.options || {},
|
|
10924
11469
|
streamResponse: isStreaming
|
|
10925
11470
|
}
|
|
10926
11471
|
};
|
|
@@ -11080,6 +11625,30 @@ var RuntypeClient2 = class {
|
|
|
11080
11625
|
});
|
|
11081
11626
|
return transformResponse(response);
|
|
11082
11627
|
}
|
|
11628
|
+
/**
|
|
11629
|
+
* Conditional GET (`ETag` / `If-None-Match`).
|
|
11630
|
+
*
|
|
11631
|
+
* Unlike {@link get}, this does NOT throw on `304` — it surfaces the not-modified
|
|
11632
|
+
* outcome so callers can keep their cached copy. Used by the dashboard's primary
|
|
11633
|
+
* lists to revalidate the canonical first page in a single round trip on both
|
|
11634
|
+
* the changed and unchanged paths. The `304` path returns no body; the `200`
|
|
11635
|
+
* path returns the parsed body plus the server's fresh `ETag`.
|
|
11636
|
+
*/
|
|
11637
|
+
async getConditional(path, params, ifNoneMatch) {
|
|
11638
|
+
const url = this.buildUrl(path, params);
|
|
11639
|
+
const headers = { ...this.headers };
|
|
11640
|
+
if (ifNoneMatch) headers["If-None-Match"] = ifNoneMatch;
|
|
11641
|
+
const response = await this.fetchWithTimeout(url, { method: "GET", headers });
|
|
11642
|
+
const etag = response.headers.get("ETag");
|
|
11643
|
+
if (response.status === 304) {
|
|
11644
|
+
return { notModified: true, etag };
|
|
11645
|
+
}
|
|
11646
|
+
if (!response.ok) {
|
|
11647
|
+
throw await this.createApiError(response);
|
|
11648
|
+
}
|
|
11649
|
+
const data = transformResponse(await response.json());
|
|
11650
|
+
return { notModified: false, etag, data };
|
|
11651
|
+
}
|
|
11083
11652
|
/**
|
|
11084
11653
|
* Generic POST request
|
|
11085
11654
|
*/
|
|
@@ -11198,7 +11767,15 @@ var RuntypeClient2 = class {
|
|
|
11198
11767
|
/**
|
|
11199
11768
|
* Make HTTP request with timeout and error handling
|
|
11200
11769
|
*/
|
|
11201
|
-
|
|
11770
|
+
/**
|
|
11771
|
+
* Run a fetch under the client timeout and return the raw `Response`. Maps a
|
|
11772
|
+
* timeout-driven `AbortError` to a descriptive timeout `Error`; does NOT inspect
|
|
11773
|
+
* status, so callers decide how to treat non-2xx (throw, intercept `304`, etc.).
|
|
11774
|
+
*
|
|
11775
|
+
* `makeRawRequest` keeps its own variant: it additionally composes a
|
|
11776
|
+
* caller-supplied `signal` (user-initiated stream aborts) with the timeout.
|
|
11777
|
+
*/
|
|
11778
|
+
async fetchWithTimeout(url, options) {
|
|
11202
11779
|
const controller = this.timeout === null ? null : new AbortController();
|
|
11203
11780
|
const timeoutId = controller && this.timeout !== null ? setTimeout(() => controller.abort(), this.timeout) : null;
|
|
11204
11781
|
try {
|
|
@@ -11207,17 +11784,7 @@ var RuntypeClient2 = class {
|
|
|
11207
11784
|
...controller ? { signal: controller.signal } : {}
|
|
11208
11785
|
});
|
|
11209
11786
|
if (timeoutId) clearTimeout(timeoutId);
|
|
11210
|
-
|
|
11211
|
-
throw await this.createApiError(response);
|
|
11212
|
-
}
|
|
11213
|
-
if (response.status === 204) {
|
|
11214
|
-
return null;
|
|
11215
|
-
}
|
|
11216
|
-
const contentType = response.headers.get("content-type");
|
|
11217
|
-
if (contentType?.includes("application/json")) {
|
|
11218
|
-
return response.json();
|
|
11219
|
-
}
|
|
11220
|
-
return response.text();
|
|
11787
|
+
return response;
|
|
11221
11788
|
} catch (error) {
|
|
11222
11789
|
if (timeoutId) clearTimeout(timeoutId);
|
|
11223
11790
|
if (timeoutId && error instanceof Error && error.name === "AbortError") {
|
|
@@ -11226,6 +11793,20 @@ var RuntypeClient2 = class {
|
|
|
11226
11793
|
throw error;
|
|
11227
11794
|
}
|
|
11228
11795
|
}
|
|
11796
|
+
async makeRequest(url, options) {
|
|
11797
|
+
const response = await this.fetchWithTimeout(url, options);
|
|
11798
|
+
if (!response.ok) {
|
|
11799
|
+
throw await this.createApiError(response);
|
|
11800
|
+
}
|
|
11801
|
+
if (response.status === 204) {
|
|
11802
|
+
return null;
|
|
11803
|
+
}
|
|
11804
|
+
const contentType = response.headers.get("content-type");
|
|
11805
|
+
if (contentType?.includes("application/json")) {
|
|
11806
|
+
return response.json();
|
|
11807
|
+
}
|
|
11808
|
+
return response.text();
|
|
11809
|
+
}
|
|
11229
11810
|
/**
|
|
11230
11811
|
* Make HTTP request that returns raw Response (for streaming)
|
|
11231
11812
|
*/
|
|
@@ -11358,20 +11939,20 @@ var BatchBuilder = class {
|
|
|
11358
11939
|
if (!this.recordType) {
|
|
11359
11940
|
throw new Error("BatchBuilder: recordType is required. Call .forRecordType(type) first.");
|
|
11360
11941
|
}
|
|
11361
|
-
const
|
|
11942
|
+
const request6 = {
|
|
11362
11943
|
flowId: this.flowId,
|
|
11363
11944
|
recordType: this.recordType
|
|
11364
11945
|
};
|
|
11365
11946
|
if (Object.keys(this.batchOptions).length > 0) {
|
|
11366
|
-
|
|
11947
|
+
request6.options = this.batchOptions;
|
|
11367
11948
|
}
|
|
11368
11949
|
if (this.filterConfig) {
|
|
11369
|
-
|
|
11950
|
+
request6.filter = this.filterConfig;
|
|
11370
11951
|
}
|
|
11371
11952
|
if (this.limitConfig !== void 0) {
|
|
11372
|
-
|
|
11953
|
+
request6.limit = this.limitConfig;
|
|
11373
11954
|
}
|
|
11374
|
-
return
|
|
11955
|
+
return request6;
|
|
11375
11956
|
}
|
|
11376
11957
|
/**
|
|
11377
11958
|
* Execute the batch operation
|
|
@@ -11528,32 +12109,32 @@ var EvalBuilder = class {
|
|
|
11528
12109
|
"EvalBuilder: records are required. Call .forRecordType(type) or .withRecords([...]) first."
|
|
11529
12110
|
);
|
|
11530
12111
|
}
|
|
11531
|
-
const
|
|
12112
|
+
const request6 = {};
|
|
11532
12113
|
if (this.flowId) {
|
|
11533
|
-
|
|
12114
|
+
request6.flowId = this.flowId;
|
|
11534
12115
|
} else if (this.virtualFlow) {
|
|
11535
|
-
|
|
12116
|
+
request6.flow = this.virtualFlow;
|
|
11536
12117
|
}
|
|
11537
12118
|
if (this.recordType) {
|
|
11538
|
-
|
|
12119
|
+
request6.recordType = this.recordType;
|
|
11539
12120
|
} else if (this.inlineRecords) {
|
|
11540
|
-
|
|
12121
|
+
request6.records = this.inlineRecords;
|
|
11541
12122
|
}
|
|
11542
12123
|
if (this.modelOverrides) {
|
|
11543
|
-
|
|
12124
|
+
request6.modelOverrides = this.modelOverrides;
|
|
11544
12125
|
} else if (this.modelConfigs) {
|
|
11545
|
-
|
|
12126
|
+
request6.modelConfigs = this.modelConfigs;
|
|
11546
12127
|
}
|
|
11547
12128
|
if (Object.keys(this.evalOptions).length > 0) {
|
|
11548
|
-
|
|
12129
|
+
request6.options = this.evalOptions;
|
|
11549
12130
|
}
|
|
11550
12131
|
if (this.filterConfig) {
|
|
11551
|
-
|
|
12132
|
+
request6.filter = this.filterConfig;
|
|
11552
12133
|
}
|
|
11553
12134
|
if (this.limitConfig !== void 0) {
|
|
11554
|
-
|
|
12135
|
+
request6.limit = this.limitConfig;
|
|
11555
12136
|
}
|
|
11556
|
-
return
|
|
12137
|
+
return request6;
|
|
11557
12138
|
}
|
|
11558
12139
|
/**
|
|
11559
12140
|
* Execute the evaluation
|
|
@@ -12072,9 +12653,15 @@ export {
|
|
|
12072
12653
|
STEP_TYPE_TO_METHOD,
|
|
12073
12654
|
SchedulesEndpoint,
|
|
12074
12655
|
SecretsEndpoint,
|
|
12656
|
+
SkillDriftError,
|
|
12657
|
+
SkillEnsureConflictError,
|
|
12075
12658
|
SkillProposalsNamespace,
|
|
12076
12659
|
SkillsNamespace,
|
|
12660
|
+
SurfaceDriftError,
|
|
12661
|
+
SurfaceEnsureConflictError,
|
|
12077
12662
|
SurfacesEndpoint,
|
|
12663
|
+
SurfacesNamespace,
|
|
12664
|
+
ToolApprovalGrantsEndpoint,
|
|
12078
12665
|
ToolDriftError,
|
|
12079
12666
|
ToolEnsureConflictError,
|
|
12080
12667
|
ToolsEndpoint,
|
|
@@ -12091,6 +12678,8 @@ export {
|
|
|
12091
12678
|
computeAgentContentHash,
|
|
12092
12679
|
computeFlowContentHash,
|
|
12093
12680
|
computeProductContentHash,
|
|
12681
|
+
computeSkillContentHash,
|
|
12682
|
+
computeSurfaceContentHash,
|
|
12094
12683
|
computeToolContentHash,
|
|
12095
12684
|
createClient,
|
|
12096
12685
|
createExternalTool,
|
|
@@ -12100,6 +12689,8 @@ export {
|
|
|
12100
12689
|
defineFlow,
|
|
12101
12690
|
definePlaybook,
|
|
12102
12691
|
defineProduct,
|
|
12692
|
+
defineSkill,
|
|
12693
|
+
defineSurface,
|
|
12103
12694
|
defineTool,
|
|
12104
12695
|
deployWorkflow,
|
|
12105
12696
|
ensureDefaultWorkflowHooks,
|
|
@@ -12117,6 +12708,8 @@ export {
|
|
|
12117
12708
|
normalizeAgentDefinition,
|
|
12118
12709
|
normalizeCandidatePath,
|
|
12119
12710
|
normalizeProductDefinition,
|
|
12711
|
+
normalizeSkillDefinition,
|
|
12712
|
+
normalizeSurfaceDefinition,
|
|
12120
12713
|
normalizeToolDefinition,
|
|
12121
12714
|
parseFinalBuffer,
|
|
12122
12715
|
parseLedgerArtifactRelativePath,
|