@felspar/sdk 0.2.0 → 0.2.1
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 +27 -65
- package/dist/chunks/{chunk-247XZ6IY.js → chunk-B4BWUYQY.js} +4 -5
- package/dist/chunks/{chunk-HACK7D24.js → chunk-XLKRU5RA.js} +54 -10
- package/dist/chunks/{chunk-IY6A2423.js → chunk-Y6KRRIQI.js} +354 -189
- 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 +149 -28
- package/package.json +1 -1
- package/skills/felspar/SKILL.md +5 -4
|
@@ -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-Y6KRRIQI.js";
|
|
6
|
+
import "./chunks/chunk-XLKRU5RA.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-B4BWUYQY.js";
|
|
5
|
+
import "./chunks/chunk-Y6KRRIQI.js";
|
|
6
|
+
import "./chunks/chunk-XLKRU5RA.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-Y6KRRIQI.js";
|
|
6
|
+
import "./chunks/chunk-XLKRU5RA.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-Y6KRRIQI.js";
|
|
20
|
+
import "./chunks/chunk-XLKRU5RA.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-B4BWUYQY.js";
|
|
5
|
+
import "./chunks/chunk-Y6KRRIQI.js";
|
|
6
|
+
import "./chunks/chunk-XLKRU5RA.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 {
|
|
@@ -1,9 +1,143 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
+
declare const FelsparCaseSchema: z.ZodObject<{
|
|
3
|
+
id: z.ZodString;
|
|
4
|
+
mode: z.ZodEnum<{
|
|
5
|
+
provided: "provided";
|
|
6
|
+
fields: "fields";
|
|
7
|
+
content: "content";
|
|
8
|
+
issued: "issued";
|
|
9
|
+
}>;
|
|
10
|
+
}, z.core.$strip>;
|
|
11
|
+
declare const FelsparRelatedSchema: z.ZodObject<{
|
|
12
|
+
relationship: z.ZodString;
|
|
13
|
+
subject: z.ZodString;
|
|
14
|
+
id: z.ZodString;
|
|
15
|
+
questions: z.ZodArray<z.ZodString>;
|
|
16
|
+
}, z.core.$strip>;
|
|
17
|
+
declare const FelsparResultSubjectSchema: z.ZodObject<{
|
|
18
|
+
type: z.ZodString;
|
|
19
|
+
id: z.ZodString;
|
|
20
|
+
related: z.ZodArray<z.ZodObject<{
|
|
21
|
+
relationship: z.ZodString;
|
|
22
|
+
subject: z.ZodString;
|
|
23
|
+
id: z.ZodString;
|
|
24
|
+
questions: z.ZodArray<z.ZodString>;
|
|
25
|
+
}, z.core.$strip>>;
|
|
26
|
+
}, z.core.$strip>;
|
|
27
|
+
declare const FelsparEscalationSchema: z.ZodObject<{
|
|
28
|
+
id: z.ZodString;
|
|
29
|
+
trigger: z.ZodEnum<{
|
|
30
|
+
outcome: "outcome";
|
|
31
|
+
unresolved: "unresolved";
|
|
32
|
+
attempt_limit: "attempt_limit";
|
|
33
|
+
}>;
|
|
34
|
+
why: z.ZodObject<{
|
|
35
|
+
text: z.ZodString;
|
|
36
|
+
}, z.core.$loose>;
|
|
37
|
+
}, z.core.$strip>;
|
|
38
|
+
declare const FelsparJobResultSchema: z.ZodObject<{
|
|
39
|
+
status: z.ZodString;
|
|
40
|
+
reason: z.ZodNullable<z.ZodString>;
|
|
41
|
+
result: z.ZodNullable<z.ZodObject<{
|
|
42
|
+
executionId: z.ZodString;
|
|
43
|
+
releaseId: z.ZodString;
|
|
44
|
+
releaseDigest: z.ZodString;
|
|
45
|
+
outcome: z.ZodNullable<z.ZodString>;
|
|
46
|
+
scoring: z.ZodUnknown;
|
|
47
|
+
context: z.ZodUnknown;
|
|
48
|
+
receipt: z.ZodUnknown;
|
|
49
|
+
case: z.ZodOptional<z.ZodObject<{
|
|
50
|
+
id: z.ZodString;
|
|
51
|
+
mode: z.ZodEnum<{
|
|
52
|
+
provided: "provided";
|
|
53
|
+
fields: "fields";
|
|
54
|
+
content: "content";
|
|
55
|
+
issued: "issued";
|
|
56
|
+
}>;
|
|
57
|
+
}, z.core.$strip>>;
|
|
58
|
+
subject: z.ZodOptional<z.ZodObject<{
|
|
59
|
+
type: z.ZodString;
|
|
60
|
+
id: z.ZodString;
|
|
61
|
+
related: z.ZodArray<z.ZodObject<{
|
|
62
|
+
relationship: z.ZodString;
|
|
63
|
+
subject: z.ZodString;
|
|
64
|
+
id: z.ZodString;
|
|
65
|
+
questions: z.ZodArray<z.ZodString>;
|
|
66
|
+
}, z.core.$strip>>;
|
|
67
|
+
}, z.core.$strip>>;
|
|
68
|
+
escalation: z.ZodOptional<z.ZodObject<{
|
|
69
|
+
id: z.ZodString;
|
|
70
|
+
trigger: z.ZodEnum<{
|
|
71
|
+
outcome: "outcome";
|
|
72
|
+
unresolved: "unresolved";
|
|
73
|
+
attempt_limit: "attempt_limit";
|
|
74
|
+
}>;
|
|
75
|
+
why: z.ZodObject<{
|
|
76
|
+
text: z.ZodString;
|
|
77
|
+
}, z.core.$loose>;
|
|
78
|
+
}, z.core.$strip>>;
|
|
79
|
+
missing: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
80
|
+
}, z.core.$loose>>;
|
|
81
|
+
}, z.core.$strip>;
|
|
82
|
+
export type FelsparJobResult = z.infer<typeof FelsparJobResultSchema>;
|
|
83
|
+
export type FelsparJobCase = z.infer<typeof FelsparCaseSchema>;
|
|
84
|
+
export type FelsparRelatedRecord = z.infer<typeof FelsparRelatedSchema>;
|
|
85
|
+
export type FelsparResultSubject = z.infer<typeof FelsparResultSubjectSchema>;
|
|
86
|
+
export type FelsparJobEscalation = z.infer<typeof FelsparEscalationSchema>;
|
|
87
|
+
interface QuotedWords {
|
|
88
|
+
text: string;
|
|
89
|
+
}
|
|
90
|
+
export interface FelsparJobSubject {
|
|
91
|
+
type: string;
|
|
92
|
+
definition: QuotedWords;
|
|
93
|
+
identifier?: string | undefined;
|
|
94
|
+
example?: string | undefined;
|
|
95
|
+
match: "exact" | "case-insensitive";
|
|
96
|
+
related: readonly {
|
|
97
|
+
relationship: string;
|
|
98
|
+
meaning: QuotedWords;
|
|
99
|
+
cardinality: "one" | "many";
|
|
100
|
+
required: boolean;
|
|
101
|
+
subject: string;
|
|
102
|
+
definition: QuotedWords;
|
|
103
|
+
identifier: string;
|
|
104
|
+
example: string;
|
|
105
|
+
match: "exact" | "case-insensitive";
|
|
106
|
+
}[];
|
|
107
|
+
send: string;
|
|
108
|
+
}
|
|
109
|
+
export interface FelsparJobIdentity {
|
|
110
|
+
mode: FelsparJobCase["mode"];
|
|
111
|
+
send: string;
|
|
112
|
+
fields?: readonly {
|
|
113
|
+
name: string;
|
|
114
|
+
identifier: string;
|
|
115
|
+
example: string;
|
|
116
|
+
match: string;
|
|
117
|
+
}[];
|
|
118
|
+
question?: string | undefined;
|
|
119
|
+
}
|
|
120
|
+
export interface FelsparFactsRequest {
|
|
121
|
+
jobId: string;
|
|
122
|
+
executionId: string;
|
|
123
|
+
expectedReleaseDigest?: string;
|
|
124
|
+
entityId?: string;
|
|
125
|
+
identity?: Record<string, string>;
|
|
126
|
+
related?: Record<string, string | string[]>;
|
|
127
|
+
facts: Record<string, unknown>;
|
|
128
|
+
}
|
|
129
|
+
declare const FelsparJobListSchema: z.ZodObject<{
|
|
130
|
+
jobs: z.ZodArray<z.ZodObject<{
|
|
131
|
+
id: z.ZodString;
|
|
132
|
+
}, z.core.$strip>>;
|
|
133
|
+
}, z.core.$strip>;
|
|
134
|
+
export type FelsparJobList = z.infer<typeof FelsparJobListSchema>;
|
|
2
135
|
declare const refusalSchema: z.ZodPipe<z.ZodObject<{
|
|
3
136
|
error: z.ZodString;
|
|
4
137
|
path: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
5
138
|
currentReleaseDigest: z.ZodOptional<z.ZodString>;
|
|
6
139
|
retryAfterSeconds: z.ZodOptional<z.ZodNumber>;
|
|
140
|
+
escalation: z.ZodOptional<z.ZodUnknown>;
|
|
7
141
|
issues: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
8
142
|
code: z.ZodString;
|
|
9
143
|
path: z.ZodArray<z.ZodString>;
|
|
@@ -14,6 +148,13 @@ declare const refusalSchema: z.ZodPipe<z.ZodObject<{
|
|
|
14
148
|
path: string[];
|
|
15
149
|
}[] | undefined;
|
|
16
150
|
fix?: string;
|
|
151
|
+
escalation?: {
|
|
152
|
+
id: string;
|
|
153
|
+
trigger: "outcome" | "unresolved" | "attempt_limit";
|
|
154
|
+
why: {
|
|
155
|
+
text: string;
|
|
156
|
+
};
|
|
157
|
+
};
|
|
17
158
|
error: string;
|
|
18
159
|
path?: string[] | undefined;
|
|
19
160
|
currentReleaseDigest?: string | undefined;
|
|
@@ -23,6 +164,7 @@ declare const refusalSchema: z.ZodPipe<z.ZodObject<{
|
|
|
23
164
|
path?: string[] | undefined;
|
|
24
165
|
currentReleaseDigest?: string | undefined;
|
|
25
166
|
retryAfterSeconds?: number | undefined;
|
|
167
|
+
escalation?: unknown;
|
|
26
168
|
issues?: {
|
|
27
169
|
code: string;
|
|
28
170
|
path: string[];
|
|
@@ -43,35 +185,14 @@ export declare function createHostedFelsparClient(configuration: {
|
|
|
43
185
|
agentKey?: string;
|
|
44
186
|
fetcher?: typeof fetch;
|
|
45
187
|
}): {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
executionId: string;
|
|
52
|
-
releaseId: string;
|
|
53
|
-
releaseDigest: string;
|
|
54
|
-
outcome: string | null;
|
|
55
|
-
scoring: unknown;
|
|
56
|
-
context: unknown;
|
|
57
|
-
receipt: unknown;
|
|
58
|
-
} | null;
|
|
59
|
-
}>;
|
|
60
|
-
resolveFacts: (id: string, value: Record<string, unknown>) => Promise<{
|
|
61
|
-
status: string;
|
|
62
|
-
reason: string | null;
|
|
63
|
-
result: {
|
|
64
|
-
[x: string]: unknown;
|
|
65
|
-
executionId: string;
|
|
66
|
-
releaseId: string;
|
|
67
|
-
releaseDigest: string;
|
|
68
|
-
outcome: string | null;
|
|
69
|
-
scoring: unknown;
|
|
70
|
-
context: unknown;
|
|
71
|
-
receipt: unknown;
|
|
72
|
-
} | null;
|
|
188
|
+
resolveFacts: (id: string, value: FelsparFactsRequest | Record<string, unknown>) => Promise<FelsparJobResult>;
|
|
189
|
+
listJobs: () => Promise<{
|
|
190
|
+
jobs: {
|
|
191
|
+
id: string;
|
|
192
|
+
}[];
|
|
73
193
|
}>;
|
|
74
|
-
resolveJob: (id: string, value: unknown) => Promise<
|
|
194
|
+
resolveJob: (id: string, value: unknown) => Promise<FelsparJobResult>;
|
|
195
|
+
executeJob: (id: string, value: unknown) => Promise<{
|
|
75
196
|
status: string;
|
|
76
197
|
reason: string | null;
|
|
77
198
|
result: {
|
package/package.json
CHANGED
package/skills/felspar/SKILL.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: felspar
|
|
3
|
-
description: Use this skill when a task involves a Felspar job or a company decision about a case, such as evaluating, classifying or qualifying a company, routing or answering a support ticket, or deciding any other record by the company's approved rules. Load it when choosing which Felspar job fits a task; before gathering evidence or calling list_jobs, get_job_requirements, get_job_decision or check_output; before writing a reply or any other text for a decided case; before an action that follows a decision, such as a draft or a record update; and whenever a Felspar result comes back held, undecided, refused or with an escalation, or Felspar's action gate denies a call.
|
|
3
|
+
description: Use this skill when a task involves a Felspar job or a company decision about a case, such as evaluating, classifying or qualifying a company, routing or answering a support ticket, or deciding any other record by the company's approved rules. Load it when choosing which Felspar job fits a task; before gathering evidence or calling list_jobs, get_job_requirements, get_job_decision or check_output; before writing a reply or any other text for a decided case; before an action that follows a decision, such as a draft or a record update; and whenever a Felspar result comes back held, undecided, refused or with an escalation or a case ID to reuse, or Felspar's action gate denies a call or names an escalation.
|
|
4
4
|
metadata:
|
|
5
|
-
version: "0.2.
|
|
5
|
+
version: "0.2.1"
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
# Working with Felspar
|
|
@@ -94,9 +94,10 @@ Show each output above the answer block: the final text, then one line with its
|
|
|
94
94
|
Actions that follow a decision (an email draft, a ticket reply, a CRM update) may pass Felspar's action gate before they run. The gate checks, in code, that Felspar decided on the case the action is about, that the decided outcome allows the action (or lists the output it writes), that the receipt still verifies and, where required, that Felspar passed exactly the text being sent. So:
|
|
95
95
|
|
|
96
96
|
- Act only on a decided outcome, and only as its next step says. A held or undecided case gets no action.
|
|
97
|
-
- Name the case the way the tool expects. An email about a company goes to people at the company Felspar decided on, one company per email. An action on a record carries the record's ID exactly as you sent it as `entity_id`.
|
|
97
|
+
- Name the case the way the tool expects. An email about a company goes to people at the company Felspar decided on, one company per email. An action on a record carries the case's ID: `result.case.id` exactly when the result names a case (always for an issued, fields or content job), otherwise the record's ID exactly as you sent it as `entity_id`. Never put another case's ID on an action.
|
|
98
|
+
- Work one case at a time: when the tool has no field for the case ID, the gate binds the action to the one case you decided in this conversation.
|
|
98
99
|
- Send exactly the text `check_output` passed, and set only the fields the tool needs; the gate denies anything else.
|
|
99
|
-
- If the gate denies an action, don't retry or rephrase it to get around the gate. Report the reason. When the denial gives a `Next step:` (the company's own, quoted from the policy), do that instead; when it asks you to fix what `check_output` flagged, fix the text, check it again and only then retry; otherwise escalate.
|
|
100
|
+
- If the gate denies an action, don't retry or rephrase it to get around the gate. Report the reason. When the denial gives a `Next step:` (the company's own, quoted from the policy), do that instead; when it names an `Escalation <id>`, report that id exactly with its why and hand the case off; when it asks you to fix what `check_output` flagged, fix the text, check it again and only then retry; otherwise escalate.
|
|
100
101
|
|
|
101
102
|
## 5. Answer
|
|
102
103
|
|