@felspar/sdk 0.2.0 → 0.3.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 +29 -65
- package/dist/chunks/{chunk-IY6A2423.js → chunk-2RV7RPXW.js} +354 -189
- package/dist/chunks/{chunk-HACK7D24.js → chunk-3YVYBD4H.js} +151 -25
- package/dist/chunks/{chunk-247XZ6IY.js → chunk-7HN5KUTJ.js} +4 -5
- package/dist/draft-action-gate-claude.js +5 -5
- package/dist/draft-action-gate-eve.js +3 -3
- package/dist/draft-action-gate-openai.js +5 -5
- package/dist/draft-action-gate.js +2 -2
- package/dist/draft-hosted-client.js +1 -1
- package/dist/eve.js +3 -3
- package/dist/types/draft-action-gate-cases.d.ts +1 -0
- package/dist/types/draft-action-gate-decisions.d.ts +33 -3
- package/dist/types/draft-action-gate-describe.d.ts +39 -1
- package/dist/types/draft-action-gate-subject.d.ts +33 -0
- package/dist/types/draft-action-gate.d.ts +5 -3
- package/dist/types/draft-hosted-client.d.ts +152 -31
- package/package.json +1 -1
- package/skills/felspar/SKILL.md +16 -9
|
@@ -535,8 +535,14 @@ function calendarDay(value) {
|
|
|
535
535
|
// ../schemas/src/draft-evidence-scope.ts
|
|
536
536
|
import { z as z3 } from "zod";
|
|
537
537
|
var identifier = z3.string().min(1).max(256).regex(/^[a-zA-Z0-9][a-zA-Z0-9._:/@-]*$/u);
|
|
538
|
+
var draftSourceIdLimit = 2048;
|
|
539
|
+
var draftSourceIdPattern = /^[a-zA-Z0-9](?:[a-zA-Z0-9\-._~:/?#[\]@!$&'()*+,;=]|%[0-9a-fA-F]{2})*$/u;
|
|
540
|
+
function isDraftSourceId(value) {
|
|
541
|
+
return value.length <= draftSourceIdLimit && draftSourceIdPattern.test(value);
|
|
542
|
+
}
|
|
543
|
+
var sourceId = z3.string().min(1).max(draftSourceIdLimit).regex(draftSourceIdPattern);
|
|
538
544
|
var reference2 = z3.strictObject({
|
|
539
|
-
sourceId
|
|
545
|
+
sourceId,
|
|
540
546
|
revision: identifier,
|
|
541
547
|
locator: z3.string().min(1).max(4096).regex(/\S/u),
|
|
542
548
|
contentDigest: z3.string().regex(/^sha256:[a-f0-9]{64}$/u)
|
|
@@ -2357,7 +2363,7 @@ var DraftEvaluatorContractSchema = z24.strictObject({
|
|
|
2357
2363
|
evaluator,
|
|
2358
2364
|
calibration: z24.strictObject({ id: identifier13, version: identifier13, contentDigest: digest9 }),
|
|
2359
2365
|
minimumSelectedProbability: z24.number().gt(0).max(1),
|
|
2360
|
-
inputContextContract: z24.
|
|
2366
|
+
inputContextContract: z24.enum(["job-entity-time/v1", "job-only/v2"]).optional(),
|
|
2361
2367
|
probabilityContract: z24.enum([
|
|
2362
2368
|
"closed-distribution-unique-maximum/v1",
|
|
2363
2369
|
"closed-distribution-with-abstention/v1"
|
|
@@ -2367,6 +2373,7 @@ var judgment = z24.discriminatedUnion("status", [
|
|
|
2367
2373
|
z24.strictObject({
|
|
2368
2374
|
status: z24.literal("evaluated"),
|
|
2369
2375
|
abstentionProbability: z24.number().min(0).max(1).optional(),
|
|
2376
|
+
promptInjectionProbability: z24.number().min(0).max(1).optional(),
|
|
2370
2377
|
probabilities: z24.array(z24.strictObject({
|
|
2371
2378
|
value: z24.string().min(1).max(200),
|
|
2372
2379
|
probability: z24.number().min(0).max(1)
|
|
@@ -2403,11 +2410,14 @@ var DraftNormalizedEvidenceSchema = z24.strictObject({
|
|
|
2403
2410
|
evaluatorContractDigest: digest9,
|
|
2404
2411
|
evaluator,
|
|
2405
2412
|
calibrationDigest: digest9,
|
|
2406
|
-
inputScope: z24.
|
|
2407
|
-
|
|
2408
|
-
|
|
2409
|
-
|
|
2410
|
-
|
|
2413
|
+
inputScope: z24.union([
|
|
2414
|
+
z24.strictObject({
|
|
2415
|
+
job: DraftEvidenceValidationSchema.shape.job,
|
|
2416
|
+
entityId: identifier13,
|
|
2417
|
+
evaluationTime: DraftEvidenceValidationSchema.shape.observationChecks.shape.evaluationTime
|
|
2418
|
+
}),
|
|
2419
|
+
z24.strictObject({ job: DraftEvidenceValidationSchema.shape.job })
|
|
2420
|
+
]).optional(),
|
|
2411
2421
|
judgment
|
|
2412
2422
|
})).max(64)
|
|
2413
2423
|
});
|
|
@@ -2590,11 +2600,11 @@ function readObservation(input, ref) {
|
|
|
2590
2600
|
if (ref.kind === "interpreter") {
|
|
2591
2601
|
return { path: `${path3}.interpretation`, value: observation2.interpretation };
|
|
2592
2602
|
}
|
|
2593
|
-
const { sourceId, revision, locator: locator2 } = observation2.evidence;
|
|
2603
|
+
const { sourceId: sourceId2, revision, locator: locator2 } = observation2.evidence;
|
|
2594
2604
|
return {
|
|
2595
2605
|
path: ref.kind === "evidence" ? `${path3}.evidence` : path3,
|
|
2596
2606
|
value: ref.kind === "evidence" ? observation2.evidence : observation2,
|
|
2597
|
-
source: { sourceId, revision, locator: locator2 }
|
|
2607
|
+
source: { sourceId: sourceId2, revision, locator: locator2 }
|
|
2598
2608
|
};
|
|
2599
2609
|
}
|
|
2600
2610
|
function readReference(input, ref) {
|
|
@@ -3702,6 +3712,73 @@ var DraftApplicationReleaseSchema = z43.strictObject({
|
|
|
3702
3712
|
// ../schemas/src/draft-hosted-application.ts
|
|
3703
3713
|
import { z as z50 } from "zod";
|
|
3704
3714
|
|
|
3715
|
+
// ../schemas/src/draft-source-instant.ts
|
|
3716
|
+
var localPattern = /^(\d{4})-(\d{2})-(\d{2})[Tt](\d{2}):(\d{2})(?::(\d{2})(?:\.(\d{1,9}))?)?([^.\d].*)$/u;
|
|
3717
|
+
var offsetPattern = /^(?:[Zz]|([+-])(\d{2}):?(\d{2}))$/u;
|
|
3718
|
+
var utcYear = /^\d{4}-/u;
|
|
3719
|
+
var sourceInstantMaxLength = 64;
|
|
3720
|
+
function daysIn(year, month) {
|
|
3721
|
+
const date = /* @__PURE__ */ new Date(0);
|
|
3722
|
+
date.setUTCFullYear(year, month, 0);
|
|
3723
|
+
return date.getUTCDate();
|
|
3724
|
+
}
|
|
3725
|
+
function isCalendarValue(local) {
|
|
3726
|
+
const { year, month, day } = local;
|
|
3727
|
+
const isDate = month >= 1 && month <= 12 && day >= 1 && day <= daysIn(year, month);
|
|
3728
|
+
return isDate && local.hour <= 23 && local.minute <= 59 && local.second <= 59;
|
|
3729
|
+
}
|
|
3730
|
+
function offsetMinutes(suffix) {
|
|
3731
|
+
const match = offsetPattern.exec(suffix);
|
|
3732
|
+
if (match === null) {
|
|
3733
|
+
return null;
|
|
3734
|
+
}
|
|
3735
|
+
const [, sign, hours, minutes] = match;
|
|
3736
|
+
if (sign === void 0) {
|
|
3737
|
+
return 0;
|
|
3738
|
+
}
|
|
3739
|
+
const h = Number(hours);
|
|
3740
|
+
const m = Number(minutes);
|
|
3741
|
+
if (h > 23 || m > 59) {
|
|
3742
|
+
return null;
|
|
3743
|
+
}
|
|
3744
|
+
return (sign === "-" ? -1 : 1) * (h * 60 + m);
|
|
3745
|
+
}
|
|
3746
|
+
function utcOf(local, offset) {
|
|
3747
|
+
const date = /* @__PURE__ */ new Date(0);
|
|
3748
|
+
date.setUTCFullYear(local.year, local.month - 1, local.day);
|
|
3749
|
+
date.setUTCHours(local.hour, local.minute - offset, local.second, 0);
|
|
3750
|
+
const utc = date.toISOString();
|
|
3751
|
+
return utcYear.test(utc) ? utc.slice(0, 19) : null;
|
|
3752
|
+
}
|
|
3753
|
+
function normalizedSourceInstant(value) {
|
|
3754
|
+
if (value.length > sourceInstantMaxLength) {
|
|
3755
|
+
return null;
|
|
3756
|
+
}
|
|
3757
|
+
const match = localPattern.exec(value);
|
|
3758
|
+
if (match === null) {
|
|
3759
|
+
return null;
|
|
3760
|
+
}
|
|
3761
|
+
const [, year, month, day, hour, minute, second, fraction, suffix] = match;
|
|
3762
|
+
const local = {
|
|
3763
|
+
year: Number(year),
|
|
3764
|
+
month: Number(month),
|
|
3765
|
+
day: Number(day),
|
|
3766
|
+
hour: Number(hour),
|
|
3767
|
+
minute: Number(minute),
|
|
3768
|
+
second: Number(second ?? "0")
|
|
3769
|
+
};
|
|
3770
|
+
const offset = offsetMinutes(suffix ?? "");
|
|
3771
|
+
if (offset === null || !isCalendarValue(local)) {
|
|
3772
|
+
return null;
|
|
3773
|
+
}
|
|
3774
|
+
const utc = utcOf(local, offset);
|
|
3775
|
+
if (utc === null) {
|
|
3776
|
+
return null;
|
|
3777
|
+
}
|
|
3778
|
+
const digits = fraction === void 0 ? "" : `.${fraction.slice(0, 3)}`;
|
|
3779
|
+
return `${utc}${digits}Z`;
|
|
3780
|
+
}
|
|
3781
|
+
|
|
3705
3782
|
// ../schemas/src/draft-hosted-output-checks.ts
|
|
3706
3783
|
import { z as z49 } from "zod";
|
|
3707
3784
|
|
|
@@ -3852,11 +3929,11 @@ var recipe = DraftClaimEvaluationRecipeSchema.shape;
|
|
|
3852
3929
|
var recipeQuestion = recipe.questions.element.shape;
|
|
3853
3930
|
var { judgment: judgment4 } = DraftNormalizedEvidenceSchema.shape.normalizations.element.shape;
|
|
3854
3931
|
var artifactSemanticLimits = {
|
|
3855
|
-
maxQuestions:
|
|
3932
|
+
maxQuestions: 24,
|
|
3856
3933
|
maxUnits: 64,
|
|
3857
|
-
maxEvaluations:
|
|
3934
|
+
maxEvaluations: 24 * 64,
|
|
3858
3935
|
maxRequestBytes: 32768,
|
|
3859
|
-
maxTotalBytes:
|
|
3936
|
+
maxTotalBytes: 16777216
|
|
3860
3937
|
};
|
|
3861
3938
|
var ArtifactSemanticQuestionSchema = z46.strictObject({
|
|
3862
3939
|
id: id3,
|
|
@@ -4354,12 +4431,14 @@ var hostedFactsLimits = {
|
|
|
4354
4431
|
maxFactsBytes: 524288,
|
|
4355
4432
|
maxQuestions: 64
|
|
4356
4433
|
};
|
|
4434
|
+
var factSourceId = z50.string().refine(isDraftSourceId, "source_id_invalid").describe(`The source's own ID or address, such as its page URL with any query: RFC 3986 characters, starting with a letter or digit, at most ${draftSourceIdLimit} characters.`);
|
|
4435
|
+
var observedAt = z50.string().refine((value) => normalizedSourceInstant(value) !== null, "observed_at_invalid").transform((value) => normalizedSourceInstant(value) ?? value).describe(`When the source was read: an RFC 3339 date and time with Z or an offset, such as 2026-10-21T10:00:00Z or 2026-10-21T12:00+02:00, at most ${sourceInstantMaxLength} characters. Stored in UTC.`);
|
|
4357
4436
|
var factSource = z50.strictObject({
|
|
4358
4437
|
class: id6,
|
|
4359
|
-
id:
|
|
4438
|
+
id: factSourceId,
|
|
4360
4439
|
revision: id6.optional(),
|
|
4361
4440
|
locator: z50.string().min(1).max(4096).optional(),
|
|
4362
|
-
observedAt
|
|
4441
|
+
observedAt,
|
|
4363
4442
|
sensitivity: id6.optional()
|
|
4364
4443
|
});
|
|
4365
4444
|
var excerptText = z50.string().min(1).refine((text7) => text7.length <= hostedFactsLimits.maxExcerptCharacters, "text_too_long");
|
|
@@ -4448,8 +4527,10 @@ var HostedJobResultSchema = z50.object({
|
|
|
4448
4527
|
|
|
4449
4528
|
// ../schemas/src/draft-hosted-refusals.ts
|
|
4450
4529
|
var limits = hostedFactsLimits;
|
|
4451
|
-
var formatFix = "The request does not match the facts request format at this path; follow input.
|
|
4530
|
+
var formatFix = "The request does not match the facts request format at this path; follow input.example from get_job_requirements (input.jsonSchema in the REST brief).";
|
|
4452
4531
|
var fixes = {
|
|
4532
|
+
observed_at_invalid: "Send observedAt as the date and time the source was read, with Z or an offset: for example 2026-10-21T10:00:00Z or 2026-10-21T12:00+02:00. A date alone, a time with no offset or words such as yesterday are not accepted.",
|
|
4533
|
+
source_id_invalid: `Send source.id as the source's own ID or address, such as the page URL with its query: at most ${draftSourceIdLimit} characters, starting with a letter or digit, using URL characters only (percent-encode spaces and non-ASCII characters).`,
|
|
4453
4534
|
unknown_question: "This question is not in the released job. Use the question keys from describe.",
|
|
4454
4535
|
source_class_not_accepted: "This question does not accept this source class. Send an excerpt from a source class the question's evidence policy in describe lists.",
|
|
4455
4536
|
value_not_in_excerpt: "The quoted words do not state this value. Quote the exact words that state it, or send the text without a typed value.",
|
|
@@ -4483,6 +4564,7 @@ var fixes = {
|
|
|
4483
4564
|
rate_limited: "This caller or workspace sent more decision requests in the last minute than its plan allows. Wait retryAfterSeconds, then resend the same request with the same execution ID. Send every question you have evidence for in one facts request per entity instead of one request per question, and spread a large run over time; for runs of thousands of entities, ask Felspar about batch scoring.",
|
|
4484
4565
|
execution_id_reused: "This execution ID was already used for a different request. Use a new execution ID, or resend the original request unchanged.",
|
|
4485
4566
|
invalid_body: "The body must be JSON or content parts within the size limit.",
|
|
4567
|
+
context_graph_invalid: "Felspar would block every decision of this pack because of the context issues listed. Build the pack again from its draft with check_pack until it is clean, then propose it again; a pack with these issues can't be proposed, approved or released.",
|
|
4486
4568
|
forbidden: "This caller may not run this job on this release, or the release is not available. Check the release ID and the caller's access.",
|
|
4487
4569
|
source_read_failed: "Felspar couldn't read the document's current version with your own connection. If access is not_connected or reconnect, connect or reconnect Google Drive on the Felspar Sources page; if no_access, ask the document's owner to share it with you; otherwise try again later.",
|
|
4488
4570
|
source_text_not_allowed: "An MCP client can't submit text as a source. To use a document's newest text, call add_current_version with its sourceObjectId from list_sources.",
|
|
@@ -5060,6 +5142,35 @@ var HostedOutputCheckReplySchema = z56.object({
|
|
|
5060
5142
|
decision: z56.object({ executionId: z56.string(), receiptDigest: digestText }),
|
|
5061
5143
|
actionAuthorized: z56.literal(false)
|
|
5062
5144
|
}).loose();
|
|
5145
|
+
var quotedWords = z56.object({ text: z56.string() }).loose();
|
|
5146
|
+
var FelsparCaseSchema = z56.object({ id: z56.string().min(1).max(200), mode: z56.enum(identityModes) });
|
|
5147
|
+
var FelsparRelatedSchema = z56.object({
|
|
5148
|
+
relationship: z56.string(),
|
|
5149
|
+
subject: z56.string(),
|
|
5150
|
+
id: z56.string(),
|
|
5151
|
+
questions: z56.array(z56.string())
|
|
5152
|
+
});
|
|
5153
|
+
var FelsparResultSubjectSchema = z56.object({
|
|
5154
|
+
type: z56.string(),
|
|
5155
|
+
id: z56.string(),
|
|
5156
|
+
related: z56.array(FelsparRelatedSchema)
|
|
5157
|
+
});
|
|
5158
|
+
var FelsparEscalationSchema = z56.object({
|
|
5159
|
+
id: z56.string().min(1).max(200),
|
|
5160
|
+
trigger: z56.enum(escalationTriggers),
|
|
5161
|
+
why: quotedWords
|
|
5162
|
+
});
|
|
5163
|
+
var FelsparJobResultSchema = HostedJobResultSchema.extend({
|
|
5164
|
+
result: HostedJobResultSchema.shape.result.unwrap().extend({
|
|
5165
|
+
case: FelsparCaseSchema.optional(),
|
|
5166
|
+
subject: FelsparResultSubjectSchema.optional(),
|
|
5167
|
+
escalation: FelsparEscalationSchema.optional(),
|
|
5168
|
+
missing: z56.array(z56.string()).optional()
|
|
5169
|
+
}).nullable()
|
|
5170
|
+
});
|
|
5171
|
+
var FelsparJobListSchema = z56.object({
|
|
5172
|
+
jobs: z56.array(z56.object({ id: z56.string().min(1).max(200) })).max(256)
|
|
5173
|
+
});
|
|
5063
5174
|
var hostedPartsContentType = "application/x.felspar-content-parts";
|
|
5064
5175
|
async function partsBody(value) {
|
|
5065
5176
|
const packed = await packContentParts(value);
|
|
@@ -5067,10 +5178,10 @@ async function partsBody(value) {
|
|
|
5067
5178
|
}
|
|
5068
5179
|
async function factsRequest(value, describeRelease) {
|
|
5069
5180
|
if (typeof value.expectedReleaseDigest === "string") {
|
|
5070
|
-
return
|
|
5181
|
+
return HostedFactsRequestSchema.parse({ mode: "facts", ...value });
|
|
5071
5182
|
}
|
|
5072
5183
|
const described = await describeRelease(HostedObjectSchema.shape.id.parse(value.jobId));
|
|
5073
|
-
return
|
|
5184
|
+
return HostedFactsRequestSchema.parse({
|
|
5074
5185
|
mode: "facts",
|
|
5075
5186
|
...value,
|
|
5076
5187
|
expectedReleaseDigest: described.release.releaseDigest
|
|
@@ -5112,16 +5223,24 @@ ${jobId}`;
|
|
|
5112
5223
|
}
|
|
5113
5224
|
var refusalCode = z56.string().regex(/^[a-z][a-z_]{2,63}$/u);
|
|
5114
5225
|
var fieldPath = z56.array(z56.string().max(256)).max(32);
|
|
5226
|
+
var refusalEscalationSchema = z56.object({
|
|
5227
|
+
id: z56.string().regex(/^[a-zA-Z0-9][a-zA-Z0-9._:/@-]{0,199}$/u),
|
|
5228
|
+
trigger: z56.enum(escalationTriggers),
|
|
5229
|
+
why: z56.object({ text: z56.string().max(2e4) })
|
|
5230
|
+
});
|
|
5115
5231
|
var refusalSchema = z56.object({
|
|
5116
5232
|
error: refusalCode,
|
|
5117
5233
|
path: fieldPath.optional(),
|
|
5118
5234
|
currentReleaseDigest: z56.string().regex(/^sha256:[a-f0-9]{64}$/u).optional(),
|
|
5119
5235
|
retryAfterSeconds: z56.number().int().min(1).max(3600).optional(),
|
|
5236
|
+
escalation: z56.unknown().optional(),
|
|
5120
5237
|
issues: z56.array(z56.object({ code: refusalCode, path: fieldPath })).max(64).optional()
|
|
5121
|
-
}).transform((value) => {
|
|
5238
|
+
}).transform(({ escalation: named, ...value }) => {
|
|
5122
5239
|
const fix = hostedRefusalFix(value.error);
|
|
5240
|
+
const escalation = refusalEscalationSchema.safeParse(named).data;
|
|
5123
5241
|
return {
|
|
5124
5242
|
...value,
|
|
5243
|
+
...escalation !== void 0 && { escalation },
|
|
5125
5244
|
...fix !== null && { fix },
|
|
5126
5245
|
...value.issues && {
|
|
5127
5246
|
issues: value.issues.map((issue) => {
|
|
@@ -5172,6 +5291,18 @@ function outputCheckCalls(call) {
|
|
|
5172
5291
|
readOutputCheck: async (job, checkId) => await call(`${checksOf(job)}/${encodeURIComponent(objectId.parse(checkId))}`, HostedOutputCheckReplySchema)
|
|
5173
5292
|
};
|
|
5174
5293
|
}
|
|
5294
|
+
function agentCalls(call) {
|
|
5295
|
+
const objectId = HostedObjectSchema.shape.id;
|
|
5296
|
+
return {
|
|
5297
|
+
listJobs: async () => await call("/v0/jobs", FelsparJobListSchema),
|
|
5298
|
+
resolveJob: async (id12, value) => {
|
|
5299
|
+
const input = HostedSuppliedJobInputSchema.parse(value);
|
|
5300
|
+
const releaseId = objectId.parse(id12);
|
|
5301
|
+
const path3 = `/v0/releases/${encodeURIComponent(releaseId)}/jobs`;
|
|
5302
|
+
return pinnedResult(await call(path3, FelsparJobResultSchema, input), releaseId, input);
|
|
5303
|
+
}
|
|
5304
|
+
};
|
|
5305
|
+
}
|
|
5175
5306
|
function createHostedFelsparClient(configuration) {
|
|
5176
5307
|
const origin = new URL(configuration.origin);
|
|
5177
5308
|
const invalid = [
|
|
@@ -5218,17 +5349,12 @@ function createHostedFelsparClient(configuration) {
|
|
|
5218
5349
|
verifyReceipt: async (executionObjectId, value) => await call(`/v0/executions/${encodeURIComponent(objectId.parse(executionObjectId))}/verify`, HostedReceiptVerificationSchema, HostedReceiptVerificationInputSchema.parse(value)),
|
|
5219
5350
|
...outputCheckCalls(call),
|
|
5220
5351
|
executeJob: async (id12, value) => await call(`/v0/releases/${encodeURIComponent(objectId.parse(id12))}/jobs`, HostedJobResultSchema, HostedJobInputSchema.parse(value)),
|
|
5352
|
+
...agentCalls(call),
|
|
5221
5353
|
resolveFacts: async (id12, value) => {
|
|
5222
5354
|
const releaseId = objectId.parse(id12);
|
|
5223
5355
|
const input = await factsRequest(value, async (jobId) => await describe(releaseId, jobId));
|
|
5224
5356
|
const path3 = `/v0/releases/${encodeURIComponent(releaseId)}/jobs`;
|
|
5225
|
-
return pinnedResult(await call(path3,
|
|
5226
|
-
},
|
|
5227
|
-
resolveJob: async (id12, value) => {
|
|
5228
|
-
const input = HostedSuppliedJobInputSchema.parse(value);
|
|
5229
|
-
const releaseId = objectId.parse(id12);
|
|
5230
|
-
const response = await call(`/v0/releases/${encodeURIComponent(releaseId)}/jobs`, HostedJobResultSchema, input);
|
|
5231
|
-
return pinnedResult(response, releaseId, input);
|
|
5357
|
+
return pinnedResult(await call(path3, FelsparJobResultSchema, input), releaseId, input);
|
|
5232
5358
|
}
|
|
5233
5359
|
};
|
|
5234
5360
|
}
|
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
denialText,
|
|
3
3
|
entityIdOf,
|
|
4
4
|
jobOf
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-2RV7RPXW.js";
|
|
6
6
|
|
|
7
7
|
// src/draft-action-gate-eve.ts
|
|
8
8
|
function felsparGate(gate) {
|
|
@@ -22,11 +22,10 @@ function felsparDecisionEvents(gate) {
|
|
|
22
22
|
return;
|
|
23
23
|
}
|
|
24
24
|
for (const action of actions) {
|
|
25
|
-
const entity = entityIdOf(action.input);
|
|
26
|
-
if (entity !== void 0 && gate.isDecisionTool(action.toolName ?? "")) {
|
|
27
|
-
gate.decisions.noteRequest(action.callId, entity);
|
|
28
|
-
}
|
|
29
25
|
const job = jobOf(action.input);
|
|
26
|
+
if (gate.isDecisionTool(action.toolName ?? "")) {
|
|
27
|
+
gate.decisions.noteRequest(action.callId, { entity: entityIdOf(action.input), job });
|
|
28
|
+
}
|
|
30
29
|
if (job !== void 0 && gate.isOutputCheckTool(action.toolName ?? "")) {
|
|
31
30
|
checks.set(action.callId, job);
|
|
32
31
|
}
|
|
@@ -2,8 +2,8 @@ import {
|
|
|
2
2
|
denialText,
|
|
3
3
|
entityIdOf,
|
|
4
4
|
jobOf
|
|
5
|
-
} from "./chunks/chunk-
|
|
6
|
-
import "./chunks/chunk-
|
|
5
|
+
} from "./chunks/chunk-2RV7RPXW.js";
|
|
6
|
+
import "./chunks/chunk-3YVYBD4H.js";
|
|
7
7
|
|
|
8
8
|
// src/draft-action-gate-claude.ts
|
|
9
9
|
function felsparPreToolUse(gate) {
|
|
@@ -31,9 +31,9 @@ function felsparPostToolUse(gate) {
|
|
|
31
31
|
if (job !== void 0 && input.hook_event_name === "PostToolUse" && gate.isOutputCheckTool(input.tool_name ?? "")) {
|
|
32
32
|
gate.decisions.recordOutputCheck(input.session_id, job, input.tool_response);
|
|
33
33
|
}
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
gate.decisions.record(input.session_id, entity, input.tool_response);
|
|
34
|
+
if (input.hook_event_name === "PostToolUse" && gate.isDecisionTool(input.tool_name ?? "")) {
|
|
35
|
+
const entity = entityIdOf(input.tool_input);
|
|
36
|
+
gate.decisions.record(input.session_id, { entity, job }, input.tool_response);
|
|
37
37
|
}
|
|
38
38
|
return {};
|
|
39
39
|
};
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
felsparDecisionEvents,
|
|
3
3
|
felsparGate
|
|
4
|
-
} from "./chunks/chunk-
|
|
5
|
-
import "./chunks/chunk-
|
|
6
|
-
import "./chunks/chunk-
|
|
4
|
+
} from "./chunks/chunk-7HN5KUTJ.js";
|
|
5
|
+
import "./chunks/chunk-2RV7RPXW.js";
|
|
6
|
+
import "./chunks/chunk-3YVYBD4H.js";
|
|
7
7
|
export {
|
|
8
8
|
felsparDecisionEvents,
|
|
9
9
|
felsparGate
|
|
@@ -2,8 +2,8 @@ import {
|
|
|
2
2
|
denialText,
|
|
3
3
|
entityIdOf,
|
|
4
4
|
jobOf
|
|
5
|
-
} from "./chunks/chunk-
|
|
6
|
-
import "./chunks/chunk-
|
|
5
|
+
} from "./chunks/chunk-2RV7RPXW.js";
|
|
6
|
+
import "./chunks/chunk-3YVYBD4H.js";
|
|
7
7
|
|
|
8
8
|
// src/draft-action-gate-openai.ts
|
|
9
9
|
function argumentsOf(text) {
|
|
@@ -47,9 +47,9 @@ function felsparDecisionOutputGuardrail(gate, options) {
|
|
|
47
47
|
if (job !== void 0 && gate.isOutputCheckTool(data.toolCall.name)) {
|
|
48
48
|
gate.decisions.recordOutputCheck(options.sessionOf(data.context), job, data.output);
|
|
49
49
|
}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
gate.decisions.record(
|
|
50
|
+
if (gate.isDecisionTool(data.toolCall.name)) {
|
|
51
|
+
const session = options.sessionOf(data.context);
|
|
52
|
+
gate.decisions.record(session, { entity: entityIdOf(input), job }, data.output);
|
|
53
53
|
}
|
|
54
54
|
return { behavior: { type: "allow" } };
|
|
55
55
|
}
|
|
@@ -16,8 +16,8 @@ import {
|
|
|
16
16
|
outputCheckFromResult,
|
|
17
17
|
outputTextDigest,
|
|
18
18
|
sharedDomains
|
|
19
|
-
} from "./chunks/chunk-
|
|
20
|
-
import "./chunks/chunk-
|
|
19
|
+
} from "./chunks/chunk-2RV7RPXW.js";
|
|
20
|
+
import "./chunks/chunk-3YVYBD4H.js";
|
|
21
21
|
export {
|
|
22
22
|
checkAction,
|
|
23
23
|
createActionGate,
|
package/dist/eve.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
felsparDecisionEvents,
|
|
3
3
|
felsparGate
|
|
4
|
-
} from "./chunks/chunk-
|
|
5
|
-
import "./chunks/chunk-
|
|
6
|
-
import "./chunks/chunk-
|
|
4
|
+
} from "./chunks/chunk-7HN5KUTJ.js";
|
|
5
|
+
import "./chunks/chunk-2RV7RPXW.js";
|
|
6
|
+
import "./chunks/chunk-3YVYBD4H.js";
|
|
7
7
|
|
|
8
8
|
// src/eve.ts
|
|
9
9
|
var felsparMcpUrl = "https://mcp.felspar.ai/mcp";
|
|
@@ -26,5 +26,6 @@ export interface Found {
|
|
|
26
26
|
export declare const foldCase: (text: string) => string;
|
|
27
27
|
export declare const caseKeyOf: (rule: CaseRule) => (text: string) => string;
|
|
28
28
|
export declare const sameField: (names: readonly string[]) => (field: string) => boolean;
|
|
29
|
+
export declare function testListProblem(scope: Pick<CaseScope, "rules" | "rule">, input: Input): string | null;
|
|
29
30
|
export declare function caseFor(scope: CaseScope, input: Input): Found;
|
|
30
31
|
export {};
|
|
@@ -1,6 +1,23 @@
|
|
|
1
1
|
import type { FelsparOutputCheck } from "./draft-action-gate-outputs.js";
|
|
2
|
+
declare const identityModes: readonly ["provided", "fields", "content", "issued"];
|
|
3
|
+
export type IdentityMode = (typeof identityModes)[number];
|
|
4
|
+
declare const escalationTriggers: readonly ["outcome", "unresolved", "attempt_limit"];
|
|
5
|
+
export type EscalationTrigger = (typeof escalationTriggers)[number];
|
|
6
|
+
export interface FelsparCase {
|
|
7
|
+
id: string;
|
|
8
|
+
mode: IdentityMode;
|
|
9
|
+
}
|
|
10
|
+
export interface FelsparEscalation {
|
|
11
|
+
id: string;
|
|
12
|
+
trigger: EscalationTrigger;
|
|
13
|
+
why: string;
|
|
14
|
+
}
|
|
2
15
|
export interface FelsparDecision {
|
|
3
16
|
entity: string;
|
|
17
|
+
case?: FelsparCase | undefined;
|
|
18
|
+
job?: string | undefined;
|
|
19
|
+
releaseId?: string | undefined;
|
|
20
|
+
escalation?: FelsparEscalation | undefined;
|
|
4
21
|
outcome: string;
|
|
5
22
|
executionObjectId: string;
|
|
6
23
|
receipt: {
|
|
@@ -14,16 +31,28 @@ export interface VerifiedDecision {
|
|
|
14
31
|
entityId: string;
|
|
15
32
|
releaseId?: string;
|
|
16
33
|
outcome: string | null;
|
|
34
|
+
case?: {
|
|
35
|
+
id: string;
|
|
36
|
+
mode: string;
|
|
37
|
+
} | undefined;
|
|
38
|
+
escalation?: {
|
|
39
|
+
id: string;
|
|
40
|
+
trigger: string;
|
|
41
|
+
} | undefined;
|
|
17
42
|
}
|
|
18
43
|
export type ReceiptVerifier = (decision: FelsparDecision) => Promise<VerifiedDecision | null>;
|
|
19
44
|
export declare function jobOf(input: unknown): string | undefined;
|
|
20
45
|
export declare function entityIdOf(input: unknown): string | undefined;
|
|
21
|
-
export
|
|
46
|
+
export type DecisionRequest = string | {
|
|
47
|
+
entity?: string | undefined;
|
|
48
|
+
job?: string | undefined;
|
|
49
|
+
};
|
|
50
|
+
export declare function decisionFromResult(request: DecisionRequest, output: unknown): FelsparDecision | null;
|
|
22
51
|
export interface DecisionRecorder {
|
|
23
52
|
recordOutputCheck: (sessionId: string, jobId: string, output: unknown) => FelsparOutputCheck | null;
|
|
24
53
|
outputChecksIn: (sessionId: string) => readonly FelsparOutputCheck[];
|
|
25
|
-
record: (sessionId: string,
|
|
26
|
-
noteRequest: (callId: string,
|
|
54
|
+
record: (sessionId: string, request: DecisionRequest, output: unknown) => FelsparDecision | null;
|
|
55
|
+
noteRequest: (callId: string, request: DecisionRequest) => void;
|
|
27
56
|
noteResult: (sessionId: string, callId: string, output: unknown) => FelsparDecision | null;
|
|
28
57
|
decisionsIn: (sessionId: string) => readonly FelsparDecision[];
|
|
29
58
|
forget: (sessionId: string) => void;
|
|
@@ -34,3 +63,4 @@ export interface DecisionRecorderLimits {
|
|
|
34
63
|
pendingRequests?: number;
|
|
35
64
|
}
|
|
36
65
|
export declare function createDecisionRecorder(limits?: DecisionRecorderLimits): DecisionRecorder;
|
|
66
|
+
export {};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { EscalationTrigger, IdentityMode } from "./draft-action-gate-decisions.js";
|
|
1
2
|
interface Quoted {
|
|
2
3
|
text: string;
|
|
3
4
|
}
|
|
@@ -6,13 +7,28 @@ export interface GateJobDescription {
|
|
|
6
7
|
release: {
|
|
7
8
|
releaseId: string;
|
|
8
9
|
};
|
|
10
|
+
subject?: {
|
|
11
|
+
type: string;
|
|
12
|
+
match: "exact" | "case-insensitive";
|
|
13
|
+
} | undefined;
|
|
14
|
+
identity?: {
|
|
15
|
+
mode: IdentityMode;
|
|
16
|
+
} | undefined;
|
|
9
17
|
outcomes: readonly {
|
|
10
18
|
id: string;
|
|
11
19
|
nextStep?: Quoted | null | undefined;
|
|
12
20
|
outputs?: readonly {
|
|
13
21
|
id: string;
|
|
14
22
|
}[] | undefined;
|
|
23
|
+
escalate?: string | undefined;
|
|
15
24
|
}[];
|
|
25
|
+
escalations?: {
|
|
26
|
+
routes: readonly {
|
|
27
|
+
id: string;
|
|
28
|
+
quote: Quoted;
|
|
29
|
+
}[];
|
|
30
|
+
unresolved: string | null;
|
|
31
|
+
} | undefined;
|
|
16
32
|
whenUnresolved?: Quoted | null | undefined;
|
|
17
33
|
}
|
|
18
34
|
export type JobDescriber = (releaseId: string, jobId: string) => Promise<GateJobDescription>;
|
|
@@ -28,6 +44,16 @@ export declare function writesProblem(describe: JobDescriber | undefined, decide
|
|
|
28
44
|
outcome: string;
|
|
29
45
|
output: string;
|
|
30
46
|
}): Promise<string | null>;
|
|
47
|
+
export declare function subjectOf(describe: JobDescriber, releaseId: string, jobId: string): Promise<{
|
|
48
|
+
type: string;
|
|
49
|
+
match: "exact" | "case-insensitive";
|
|
50
|
+
mode: "provided" | "fields" | "content" | "issued";
|
|
51
|
+
} | null>;
|
|
52
|
+
export interface GateEscalation {
|
|
53
|
+
id: string;
|
|
54
|
+
trigger: EscalationTrigger;
|
|
55
|
+
why: string | null;
|
|
56
|
+
}
|
|
31
57
|
export type EscalationStep = {
|
|
32
58
|
kind: "unresolved";
|
|
33
59
|
releaseId: string | undefined;
|
|
@@ -35,9 +61,21 @@ export type EscalationStep = {
|
|
|
35
61
|
kind: "outcome";
|
|
36
62
|
releaseId: string | undefined;
|
|
37
63
|
outcome: string;
|
|
64
|
+
replayed?: {
|
|
65
|
+
id: string;
|
|
66
|
+
trigger: string;
|
|
67
|
+
} | undefined;
|
|
68
|
+
recorded?: {
|
|
69
|
+
id: string;
|
|
70
|
+
why: string;
|
|
71
|
+
} | undefined;
|
|
38
72
|
} | {
|
|
39
73
|
kind: "output-check";
|
|
40
74
|
};
|
|
41
75
|
export declare const fixOutputCheck = "Fix what check_output flagged, check it again, then retry.";
|
|
42
|
-
export
|
|
76
|
+
export interface Escalated {
|
|
77
|
+
escalate?: string;
|
|
78
|
+
escalation?: GateEscalation;
|
|
79
|
+
}
|
|
80
|
+
export declare function escalationFor(step: EscalationStep | undefined, describe: JobDescriber | undefined, jobId: string): Promise<Escalated>;
|
|
43
81
|
export {};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { CaseRule, CaseRules } from "./draft-action-gate-cases.js";
|
|
2
|
+
import type { FelsparCase, FelsparDecision } from "./draft-action-gate-decisions.js";
|
|
3
|
+
import type { JobDescriber } from "./draft-action-gate-describe.js";
|
|
4
|
+
export interface GateSubject {
|
|
5
|
+
type: string;
|
|
6
|
+
match: "exact" | "case-insensitive";
|
|
7
|
+
mode: FelsparCase["mode"];
|
|
8
|
+
}
|
|
9
|
+
export interface CaseKeying {
|
|
10
|
+
key: (id: string) => string;
|
|
11
|
+
decisionKey: (decision: FelsparDecision) => string;
|
|
12
|
+
}
|
|
13
|
+
export type Selected = {
|
|
14
|
+
company: string;
|
|
15
|
+
decision: FelsparDecision;
|
|
16
|
+
keying: CaseKeying;
|
|
17
|
+
} | {
|
|
18
|
+
company?: undefined;
|
|
19
|
+
reason: string;
|
|
20
|
+
missing?: true;
|
|
21
|
+
};
|
|
22
|
+
interface SelectScope {
|
|
23
|
+
rules: CaseRules & {
|
|
24
|
+
job: string;
|
|
25
|
+
sharedDomains?: readonly string[];
|
|
26
|
+
};
|
|
27
|
+
rule: CaseRule;
|
|
28
|
+
decisions: readonly FelsparDecision[];
|
|
29
|
+
describe?: JobDescriber | undefined;
|
|
30
|
+
}
|
|
31
|
+
type Input = Record<string, unknown>;
|
|
32
|
+
export declare function selectCase(scope: SelectScope, input: Input): Promise<Selected>;
|
|
33
|
+
export {};
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import type { JobDescriber } from "./draft-action-gate-describe.js";
|
|
1
|
+
import type { GateEscalation, JobDescriber } from "./draft-action-gate-describe.js";
|
|
2
2
|
import type { FelsparOutputCheck, OutputCheckVerifier } from "./draft-action-gate-outputs.js";
|
|
3
3
|
import type { ActionRule } from "./draft-action-gate-rules.js";
|
|
4
4
|
import type { DecisionRecorder, FelsparDecision, ReceiptVerifier } from "./draft-action-gate-decisions.js";
|
|
5
5
|
export { emailRecipientFields, emailSubjectFields } from "./draft-action-gate-cases.js";
|
|
6
6
|
export { createDecisionRecorder, decisionFromResult, entityIdOf, jobOf, } from "./draft-action-gate-decisions.js";
|
|
7
|
-
export type { DecisionRecorder, DecisionRecorderLimits, FelsparDecision, ReceiptVerifier, VerifiedDecision, } from "./draft-action-gate-decisions.js";
|
|
7
|
+
export type { DecisionRecorder, DecisionRecorderLimits, DecisionRequest, EscalationTrigger, FelsparCase, FelsparDecision, FelsparEscalation, IdentityMode, ReceiptVerifier, VerifiedDecision, } from "./draft-action-gate-decisions.js";
|
|
8
8
|
export { felsparJobDescriber } from "./draft-action-gate-describe.js";
|
|
9
|
-
export type { GateJobDescription, JobDescriber } from "./draft-action-gate-describe.js";
|
|
9
|
+
export type { GateEscalation, GateJobDescription, JobDescriber, } from "./draft-action-gate-describe.js";
|
|
10
10
|
export { isCompanyDomain, sharedDomains } from "./draft-action-gate-domains.js";
|
|
11
11
|
export type { ActionRule } from "./draft-action-gate-rules.js";
|
|
12
12
|
export { felsparVerifier } from "./draft-action-gate-verifier.js";
|
|
@@ -30,10 +30,12 @@ export type ActionVerdict = {
|
|
|
30
30
|
allow: false;
|
|
31
31
|
reason: string;
|
|
32
32
|
escalate?: string;
|
|
33
|
+
escalation?: GateEscalation;
|
|
33
34
|
};
|
|
34
35
|
export declare function denialText(verdict: {
|
|
35
36
|
reason: string;
|
|
36
37
|
escalate?: string;
|
|
38
|
+
escalation?: GateEscalation;
|
|
37
39
|
}): string;
|
|
38
40
|
export declare function gatedRule(rules: ActionGateRules, toolName: string): ActionRule | undefined;
|
|
39
41
|
export interface CheckActionRequest {
|