@framers/agentos 0.1.229 → 0.1.230

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.
@@ -0,0 +1,67 @@
1
+ /**
2
+ * @fileoverview Classify forge-rejection `errorReason` strings into a
3
+ * small set of actionable categories.
4
+ * @module @framers/agentos/emergent/ForgeRejectionClassifier
5
+ *
6
+ * Without categorization, the only way to answer "why are forges failing"
7
+ * is to grep logs. With classification, an aggregator can emit a live
8
+ * histogram of failure modes (schema-extra-field vs shape-check vs judge
9
+ * correctness vs parse error) so operators see the failure-mode
10
+ * distribution without log access.
11
+ *
12
+ * Categories are deliberately narrow. They split out the patterns that
13
+ * appear in real production rejection text; anything unrecognized falls
14
+ * into `other`. A growing `other` bucket is the signal to read raw
15
+ * reasons and extend the pattern set.
16
+ */
17
+ /**
18
+ * Rejection-reason category produced by {@link classifyForgeRejection}.
19
+ */
20
+ export type ForgeRejectionCategory =
21
+ /**
22
+ * Implementation returned output fields not declared in outputSchema
23
+ * (violates `additionalProperties: false`). The most common forge
24
+ * failure mode under a strict schema contract.
25
+ */
26
+ 'schema_extra_field'
27
+ /**
28
+ * Pre-judge shape validator caught a malformed request (empty schema
29
+ * properties, empty testCases, empty-input testCases).
30
+ */
31
+ | 'shape_check'
32
+ /**
33
+ * Judge LLM returned malformed JSON the engine could not parse.
34
+ */
35
+ | 'parse_error'
36
+ /**
37
+ * Judge flagged logic / correctness / safety concerns in the code
38
+ * itself (division bugs, threshold inversions, unbounded outputs,
39
+ * non-deterministic behavior).
40
+ */
41
+ | 'judge_correctness'
42
+ /**
43
+ * Everything else. A non-zero `other` bucket is a signal to inspect
44
+ * the raw reasons and consider adding a new category.
45
+ */
46
+ | 'other';
47
+ /**
48
+ * Classify a rejection reason string into a {@link ForgeRejectionCategory}.
49
+ *
50
+ * Case-insensitive substring match against pattern lists, evaluated in
51
+ * order: schema_extra_field first (most common and most actionable),
52
+ * then shape_check (local pre-validator), then parse_error, then
53
+ * judge_correctness, then `other`.
54
+ *
55
+ * Order matters: "violates the declared output schema by returning an
56
+ * additional field due to a logic error" matches BOTH schema_extra_field
57
+ * and judge_correctness; the former wins because it is the more specific
58
+ * and more actionable signal.
59
+ *
60
+ * @param errorReason Raw rejection reason text, typically the judge's
61
+ * verdict reasoning or the local shape-validator's joined error list.
62
+ * May be `undefined` when no reason was captured.
63
+ * @returns One of the five category labels. Empty / `undefined` input
64
+ * returns `'other'`.
65
+ */
66
+ export declare function classifyForgeRejection(errorReason: string | undefined): ForgeRejectionCategory;
67
+ //# sourceMappingURL=ForgeRejectionClassifier.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ForgeRejectionClassifier.d.ts","sourceRoot":"","sources":["../../src/emergent/ForgeRejectionClassifier.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH;;GAEG;AACH,MAAM,MAAM,sBAAsB;AAChC;;;;GAIG;AACD,oBAAoB;AACtB;;;GAGG;GACD,aAAa;AACf;;GAEG;GACD,aAAa;AACf;;;;GAIG;GACD,mBAAmB;AACrB;;;GAGG;GACD,OAAO,CAAC;AAuEZ;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,sBAAsB,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,GAAG,sBAAsB,CAoB9F"}
@@ -0,0 +1,126 @@
1
+ /**
2
+ * @fileoverview Classify forge-rejection `errorReason` strings into a
3
+ * small set of actionable categories.
4
+ * @module @framers/agentos/emergent/ForgeRejectionClassifier
5
+ *
6
+ * Without categorization, the only way to answer "why are forges failing"
7
+ * is to grep logs. With classification, an aggregator can emit a live
8
+ * histogram of failure modes (schema-extra-field vs shape-check vs judge
9
+ * correctness vs parse error) so operators see the failure-mode
10
+ * distribution without log access.
11
+ *
12
+ * Categories are deliberately narrow. They split out the patterns that
13
+ * appear in real production rejection text; anything unrecognized falls
14
+ * into `other`. A growing `other` bucket is the signal to read raw
15
+ * reasons and extend the pattern set.
16
+ */
17
+ const SCHEMA_EXTRA_FIELD_PATTERNS = [
18
+ 'additional properties',
19
+ 'additional property',
20
+ 'additionalproperties',
21
+ 'extra field',
22
+ 'extra fields',
23
+ 'extra property',
24
+ 'extra properties',
25
+ 'undeclared extra field',
26
+ 'undeclared field',
27
+ 'emits an additional',
28
+ 'emits extra',
29
+ 'returning an additional',
30
+ 'returning extra',
31
+ 'returns an additional',
32
+ 'returns extra',
33
+ 'returns additional',
34
+ 'returning an undeclared',
35
+ ];
36
+ /**
37
+ * Regex-based patterns for "extra <modifier> field" phrasings that
38
+ * substring matching misses. Example: "extra recommendations field"
39
+ * is clearly a schema-extra-field rejection but the contiguous string
40
+ * "extra field" is absent. These regexes catch the general form.
41
+ */
42
+ const SCHEMA_EXTRA_FIELD_REGEXES = [
43
+ /\bextra\s+\w+\s+field\b/,
44
+ /\badditional\s+\w+\s+field\b/,
45
+ /\bextra\s+\w+\s+property\b/,
46
+ /\badditional\s+\w+\s+property\b/,
47
+ ];
48
+ const SHAPE_CHECK_PATTERNS = [
49
+ 'shape check failed',
50
+ 'inputschema has no declared properties',
51
+ 'outputschema has no declared properties',
52
+ 'testcases use empty input',
53
+ 'testcase use empty input',
54
+ 'need at least 2 testcases',
55
+ 'every test needs real field values',
56
+ ];
57
+ const PARSE_ERROR_PATTERNS = [
58
+ 'failed to parse llm response',
59
+ 'could not parse judge response',
60
+ 'judge response was not valid json',
61
+ ];
62
+ const JUDGE_CORRECTNESS_PATTERNS = [
63
+ 'logic error',
64
+ 'threshold ordering',
65
+ 'clamped',
66
+ 'unclamped',
67
+ 'inconsistent risk grading',
68
+ 'division by zero',
69
+ 'unbounded output',
70
+ 'unbounded',
71
+ 'returns nan',
72
+ 'returns infinity',
73
+ 'infinite loop',
74
+ 'not deterministic',
75
+ 'nondeterministic',
76
+ 'correctness is questionable',
77
+ 'correctness concern',
78
+ 'fails safety',
79
+ 'safety concern',
80
+ ];
81
+ /**
82
+ * Classify a rejection reason string into a {@link ForgeRejectionCategory}.
83
+ *
84
+ * Case-insensitive substring match against pattern lists, evaluated in
85
+ * order: schema_extra_field first (most common and most actionable),
86
+ * then shape_check (local pre-validator), then parse_error, then
87
+ * judge_correctness, then `other`.
88
+ *
89
+ * Order matters: "violates the declared output schema by returning an
90
+ * additional field due to a logic error" matches BOTH schema_extra_field
91
+ * and judge_correctness; the former wins because it is the more specific
92
+ * and more actionable signal.
93
+ *
94
+ * @param errorReason Raw rejection reason text, typically the judge's
95
+ * verdict reasoning or the local shape-validator's joined error list.
96
+ * May be `undefined` when no reason was captured.
97
+ * @returns One of the five category labels. Empty / `undefined` input
98
+ * returns `'other'`.
99
+ */
100
+ export function classifyForgeRejection(errorReason) {
101
+ if (!errorReason)
102
+ return 'other';
103
+ const lower = errorReason.toLowerCase();
104
+ for (const p of SCHEMA_EXTRA_FIELD_PATTERNS) {
105
+ if (lower.includes(p))
106
+ return 'schema_extra_field';
107
+ }
108
+ for (const rx of SCHEMA_EXTRA_FIELD_REGEXES) {
109
+ if (rx.test(lower))
110
+ return 'schema_extra_field';
111
+ }
112
+ for (const p of SHAPE_CHECK_PATTERNS) {
113
+ if (lower.includes(p))
114
+ return 'shape_check';
115
+ }
116
+ for (const p of PARSE_ERROR_PATTERNS) {
117
+ if (lower.includes(p))
118
+ return 'parse_error';
119
+ }
120
+ for (const p of JUDGE_CORRECTNESS_PATTERNS) {
121
+ if (lower.includes(p))
122
+ return 'judge_correctness';
123
+ }
124
+ return 'other';
125
+ }
126
+ //# sourceMappingURL=ForgeRejectionClassifier.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ForgeRejectionClassifier.js","sourceRoot":"","sources":["../../src/emergent/ForgeRejectionClassifier.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAiCH,MAAM,2BAA2B,GAAG;IAClC,uBAAuB;IACvB,qBAAqB;IACrB,sBAAsB;IACtB,aAAa;IACb,cAAc;IACd,gBAAgB;IAChB,kBAAkB;IAClB,wBAAwB;IACxB,kBAAkB;IAClB,qBAAqB;IACrB,aAAa;IACb,yBAAyB;IACzB,iBAAiB;IACjB,uBAAuB;IACvB,eAAe;IACf,oBAAoB;IACpB,yBAAyB;CAC1B,CAAC;AAEF;;;;;GAKG;AACH,MAAM,0BAA0B,GAAa;IAC3C,yBAAyB;IACzB,8BAA8B;IAC9B,4BAA4B;IAC5B,iCAAiC;CAClC,CAAC;AAEF,MAAM,oBAAoB,GAAG;IAC3B,oBAAoB;IACpB,wCAAwC;IACxC,yCAAyC;IACzC,2BAA2B;IAC3B,0BAA0B;IAC1B,2BAA2B;IAC3B,oCAAoC;CACrC,CAAC;AAEF,MAAM,oBAAoB,GAAG;IAC3B,8BAA8B;IAC9B,gCAAgC;IAChC,mCAAmC;CACpC,CAAC;AAEF,MAAM,0BAA0B,GAAG;IACjC,aAAa;IACb,oBAAoB;IACpB,SAAS;IACT,WAAW;IACX,2BAA2B;IAC3B,kBAAkB;IAClB,kBAAkB;IAClB,WAAW;IACX,aAAa;IACb,kBAAkB;IAClB,eAAe;IACf,mBAAmB;IACnB,kBAAkB;IAClB,6BAA6B;IAC7B,qBAAqB;IACrB,cAAc;IACd,gBAAgB;CACjB,CAAC;AAEF;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,sBAAsB,CAAC,WAA+B;IACpE,IAAI,CAAC,WAAW;QAAE,OAAO,OAAO,CAAC;IACjC,MAAM,KAAK,GAAG,WAAW,CAAC,WAAW,EAAE,CAAC;IAExC,KAAK,MAAM,CAAC,IAAI,2BAA2B,EAAE,CAAC;QAC5C,IAAI,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC;YAAE,OAAO,oBAAoB,CAAC;IACrD,CAAC;IACD,KAAK,MAAM,EAAE,IAAI,0BAA0B,EAAE,CAAC;QAC5C,IAAI,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC;YAAE,OAAO,oBAAoB,CAAC;IAClD,CAAC;IACD,KAAK,MAAM,CAAC,IAAI,oBAAoB,EAAE,CAAC;QACrC,IAAI,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC;YAAE,OAAO,aAAa,CAAC;IAC9C,CAAC;IACD,KAAK,MAAM,CAAC,IAAI,oBAAoB,EAAE,CAAC;QACrC,IAAI,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC;YAAE,OAAO,aAAa,CAAC;IAC9C,CAAC;IACD,KAAK,MAAM,CAAC,IAAI,0BAA0B,EAAE,CAAC;QAC3C,IAAI,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC;YAAE,OAAO,mBAAmB,CAAC;IACpD,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -0,0 +1,39 @@
1
+ /**
2
+ * @fileoverview Synthesize missing forge input/output schema properties
3
+ * from testCase values.
4
+ * @module @framers/agentos/emergent/ForgeSchemaInference
5
+ *
6
+ * Problem: LLMs routinely emit concrete testCases with real field values
7
+ * but forget to declare `inputSchema.properties` / `outputSchema.properties`.
8
+ * The shape validator then rejects every such forge even though the
9
+ * intent is clearly legitimate.
10
+ *
11
+ * Solution: when a schema lacks declared properties but the testCases
12
+ * carry field values, synthesize properties from the testCase data so
13
+ * the shape check passes. This is NOT a relaxation of schema discipline
14
+ * — the tool code still has to handle whatever inputs come in. It is a
15
+ * correction of a common LLM oversight (examples without formalization).
16
+ *
17
+ * Pure function, mutates the request in place. No dependencies.
18
+ */
19
+ /** Request fragment carrying the three fields we may mutate. */
20
+ export interface ForgeSchemaInferenceRequest {
21
+ inputSchema?: unknown;
22
+ outputSchema?: unknown;
23
+ testCases?: unknown;
24
+ }
25
+ /**
26
+ * Populate missing inputSchema / outputSchema properties from testCase
27
+ * data. Mutates `req` in place. Fields are scanned as a union across
28
+ * every testCase so a single incomplete case does not narrow the
29
+ * inferred schema.
30
+ *
31
+ * A schema that already has declared properties is left alone. Only
32
+ * the missing-properties case is upgraded. `additionalProperties: false`
33
+ * is added to the synthesized schema so the strict-schema discipline is
34
+ * preserved for the generated shape.
35
+ *
36
+ * @param req Forge request fragment. Mutated in place.
37
+ */
38
+ export declare function inferSchemaFromTestCases(req: ForgeSchemaInferenceRequest): void;
39
+ //# sourceMappingURL=ForgeSchemaInference.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ForgeSchemaInference.d.ts","sourceRoot":"","sources":["../../src/emergent/ForgeSchemaInference.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,gEAAgE;AAChE,MAAM,WAAW,2BAA2B;IAC1C,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAiBD;;;;;;;;;;;;GAYG;AACH,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,2BAA2B,GAAG,IAAI,CAiD/E"}
@@ -0,0 +1,92 @@
1
+ /**
2
+ * @fileoverview Synthesize missing forge input/output schema properties
3
+ * from testCase values.
4
+ * @module @framers/agentos/emergent/ForgeSchemaInference
5
+ *
6
+ * Problem: LLMs routinely emit concrete testCases with real field values
7
+ * but forget to declare `inputSchema.properties` / `outputSchema.properties`.
8
+ * The shape validator then rejects every such forge even though the
9
+ * intent is clearly legitimate.
10
+ *
11
+ * Solution: when a schema lacks declared properties but the testCases
12
+ * carry field values, synthesize properties from the testCase data so
13
+ * the shape check passes. This is NOT a relaxation of schema discipline
14
+ * — the tool code still has to handle whatever inputs come in. It is a
15
+ * correction of a common LLM oversight (examples without formalization).
16
+ *
17
+ * Pure function, mutates the request in place. No dependencies.
18
+ */
19
+ /**
20
+ * Derive a JSON-Schema primitive type from a concrete testCase value.
21
+ * Handles the types the sandbox forge returns: number, string, boolean,
22
+ * object, array. Falls back to `'string'` for anything else so the
23
+ * schema stays well-formed.
24
+ */
25
+ function inferTypeFromValue(v) {
26
+ if (typeof v === 'number')
27
+ return 'number';
28
+ if (typeof v === 'boolean')
29
+ return 'boolean';
30
+ if (typeof v === 'string')
31
+ return 'string';
32
+ if (Array.isArray(v))
33
+ return 'array';
34
+ if (v !== null && typeof v === 'object')
35
+ return 'object';
36
+ return 'string';
37
+ }
38
+ /**
39
+ * Populate missing inputSchema / outputSchema properties from testCase
40
+ * data. Mutates `req` in place. Fields are scanned as a union across
41
+ * every testCase so a single incomplete case does not narrow the
42
+ * inferred schema.
43
+ *
44
+ * A schema that already has declared properties is left alone. Only
45
+ * the missing-properties case is upgraded. `additionalProperties: false`
46
+ * is added to the synthesized schema so the strict-schema discipline is
47
+ * preserved for the generated shape.
48
+ *
49
+ * @param req Forge request fragment. Mutated in place.
50
+ */
51
+ export function inferSchemaFromTestCases(req) {
52
+ const tcArr = Array.isArray(req.testCases)
53
+ ? req.testCases
54
+ : [];
55
+ if (tcArr.length === 0)
56
+ return;
57
+ const inferProperties = (key) => {
58
+ const props = {};
59
+ for (const tc of tcArr) {
60
+ const data = tc?.[key];
61
+ if (!data || typeof data !== 'object' || Array.isArray(data))
62
+ continue;
63
+ for (const [field, value] of Object.entries(data)) {
64
+ if (props[field])
65
+ continue;
66
+ props[field] = { type: inferTypeFromValue(value) };
67
+ }
68
+ }
69
+ return props;
70
+ };
71
+ const maybeUpgrade = (schemaKey, testCaseKey) => {
72
+ const schema = req[schemaKey];
73
+ const current = (schema && typeof schema === 'object' ? schema : {});
74
+ const hasProps = current.properties &&
75
+ typeof current.properties === 'object' &&
76
+ Object.keys(current.properties).length > 0;
77
+ if (hasProps)
78
+ return;
79
+ const inferred = inferProperties(testCaseKey);
80
+ if (Object.keys(inferred).length === 0)
81
+ return;
82
+ req[schemaKey] = {
83
+ type: 'object',
84
+ properties: inferred,
85
+ required: Object.keys(inferred),
86
+ additionalProperties: false,
87
+ };
88
+ };
89
+ maybeUpgrade('inputSchema', 'input');
90
+ maybeUpgrade('outputSchema', 'expectedOutput');
91
+ }
92
+ //# sourceMappingURL=ForgeSchemaInference.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ForgeSchemaInference.js","sourceRoot":"","sources":["../../src/emergent/ForgeSchemaInference.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AASH;;;;;GAKG;AACH,SAAS,kBAAkB,CAAC,CAAU;IACpC,IAAI,OAAO,CAAC,KAAK,QAAQ;QAAE,OAAO,QAAQ,CAAC;IAC3C,IAAI,OAAO,CAAC,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IAC7C,IAAI,OAAO,CAAC,KAAK,QAAQ;QAAE,OAAO,QAAQ,CAAC;IAC3C,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;QAAE,OAAO,OAAO,CAAC;IACrC,IAAI,CAAC,KAAK,IAAI,IAAI,OAAO,CAAC,KAAK,QAAQ;QAAE,OAAO,QAAQ,CAAC;IACzD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,wBAAwB,CAAC,GAAgC;IACvE,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC;QACxC,CAAC,CAAE,GAAG,CAAC,SAAkE;QACzE,CAAC,CAAC,EAAE,CAAC;IACP,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO;IAE/B,MAAM,eAAe,GAAG,CAAC,GAA+B,EAAE,EAAE;QAC1D,MAAM,KAAK,GAAqC,EAAE,CAAC;QACnD,KAAK,MAAM,EAAE,IAAI,KAAK,EAAE,CAAC;YACvB,MAAM,IAAI,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC;YACvB,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC;gBAAE,SAAS;YACvE,KAAK,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAA+B,CAAC,EAAE,CAAC;gBAC7E,IAAI,KAAK,CAAC,KAAK,CAAC;oBAAE,SAAS;gBAC3B,KAAK,CAAC,KAAK,CAAC,GAAG,EAAE,IAAI,EAAE,kBAAkB,CAAC,KAAK,CAAC,EAAE,CAAC;YACrD,CAAC;QACH,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC,CAAC;IAEF,MAAM,YAAY,GAAG,CACnB,SAAyC,EACzC,WAAuC,EACvC,EAAE;QACF,MAAM,MAAM,GAAG,GAAG,CAAC,SAAS,CAAC,CAAC;QAC9B,MAAM,OAAO,GAAG,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAKlE,CAAC;QACF,MAAM,QAAQ,GACZ,OAAO,CAAC,UAAU;YAClB,OAAO,OAAO,CAAC,UAAU,KAAK,QAAQ;YACtC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;QAC7C,IAAI,QAAQ;YAAE,OAAO;QAErB,MAAM,QAAQ,GAAG,eAAe,CAAC,WAAW,CAAC,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QAE/C,GAAG,CAAC,SAAS,CAAC,GAAG;YACf,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE,QAAQ;YACpB,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC;YAC/B,oBAAoB,EAAE,KAAK;SAC5B,CAAC;IACJ,CAAC,CAAC;IAEF,YAAY,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;IACrC,YAAY,CAAC,cAAc,EAAE,gBAAgB,CAAC,CAAC;AACjD,CAAC"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * @fileoverview Pre-judge shape validator for forge requests.
3
+ * @module @framers/agentos/emergent/ForgeShapeValidator
4
+ *
5
+ * Catches the failure modes that dominate cheap-tier forge rejections
6
+ * (empty schema properties, too-few testCases, empty-input testCases)
7
+ * BEFORE the judge LLM sees the request. Every shape-check rejection
8
+ * saves one judge invocation plus the sandbox round-trip that would
9
+ * have followed it.
10
+ *
11
+ * Pure function, no dependencies.
12
+ */
13
+ /**
14
+ * Minimal forge request shape the validator needs. Accepts `unknown`
15
+ * for the schema fields so callers can pass raw LLM output without
16
+ * pre-shaping.
17
+ */
18
+ export interface ForgeShapeRequest {
19
+ inputSchema?: unknown;
20
+ outputSchema?: unknown;
21
+ testCases?: unknown;
22
+ }
23
+ /**
24
+ * Validate a forge request's shape against the rules that dominate
25
+ * cheap-tier failures. Every violation is reported at once (no
26
+ * short-circuit) so the caller can build one comprehensive error
27
+ * message to show the LLM.
28
+ *
29
+ * Rules enforced:
30
+ * - `inputSchema.properties` must declare at least one field.
31
+ * - `outputSchema.properties` must declare at least one field.
32
+ * - `testCases` must have at least 2 entries.
33
+ * - Every testCase must have a non-empty `input` object.
34
+ *
35
+ * @param req Request fragment. Only the three fields are inspected;
36
+ * other fields on the forge request are ignored.
37
+ * @returns Array of human-readable error strings. Empty means the
38
+ * request's shape is well-formed enough to forward to the judge.
39
+ */
40
+ export declare function validateForgeShape(req: ForgeShapeRequest): string[];
41
+ //# sourceMappingURL=ForgeShapeValidator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ForgeShapeValidator.d.ts","sourceRoot":"","sources":["../../src/emergent/ForgeShapeValidator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH;;;;GAIG;AACH,MAAM,WAAW,iBAAiB;IAChC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,iBAAiB,GAAG,MAAM,EAAE,CA8BnE"}
@@ -0,0 +1,57 @@
1
+ /**
2
+ * @fileoverview Pre-judge shape validator for forge requests.
3
+ * @module @framers/agentos/emergent/ForgeShapeValidator
4
+ *
5
+ * Catches the failure modes that dominate cheap-tier forge rejections
6
+ * (empty schema properties, too-few testCases, empty-input testCases)
7
+ * BEFORE the judge LLM sees the request. Every shape-check rejection
8
+ * saves one judge invocation plus the sandbox round-trip that would
9
+ * have followed it.
10
+ *
11
+ * Pure function, no dependencies.
12
+ */
13
+ /**
14
+ * Validate a forge request's shape against the rules that dominate
15
+ * cheap-tier failures. Every violation is reported at once (no
16
+ * short-circuit) so the caller can build one comprehensive error
17
+ * message to show the LLM.
18
+ *
19
+ * Rules enforced:
20
+ * - `inputSchema.properties` must declare at least one field.
21
+ * - `outputSchema.properties` must declare at least one field.
22
+ * - `testCases` must have at least 2 entries.
23
+ * - Every testCase must have a non-empty `input` object.
24
+ *
25
+ * @param req Request fragment. Only the three fields are inspected;
26
+ * other fields on the forge request are ignored.
27
+ * @returns Array of human-readable error strings. Empty means the
28
+ * request's shape is well-formed enough to forward to the judge.
29
+ */
30
+ export function validateForgeShape(req) {
31
+ const errors = [];
32
+ const inputSchema = req.inputSchema;
33
+ const outputSchema = req.outputSchema;
34
+ const inputProps = inputSchema && typeof inputSchema.properties === 'object' ? inputSchema.properties : null;
35
+ const outputProps = outputSchema && typeof outputSchema.properties === 'object' ? outputSchema.properties : null;
36
+ if (!inputProps || Object.keys(inputProps).length === 0) {
37
+ errors.push('inputSchema has no declared properties; add at least two typed fields');
38
+ }
39
+ if (!outputProps || Object.keys(outputProps).length === 0) {
40
+ errors.push('outputSchema has no declared properties; add at least one typed output field');
41
+ }
42
+ const tcArr = Array.isArray(req.testCases)
43
+ ? req.testCases
44
+ : [];
45
+ if (tcArr.length < 2) {
46
+ errors.push(`need at least 2 testCases, got ${tcArr.length}`);
47
+ }
48
+ const emptyInputs = tcArr.filter(tc => {
49
+ const inp = tc?.input;
50
+ return !inp || typeof inp !== 'object' || Object.keys(inp).length === 0;
51
+ }).length;
52
+ if (emptyInputs > 0) {
53
+ errors.push(`${emptyInputs} testCase${emptyInputs === 1 ? '' : 's'} use empty input; every test needs real field values`);
54
+ }
55
+ return errors;
56
+ }
57
+ //# sourceMappingURL=ForgeShapeValidator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ForgeShapeValidator.js","sourceRoot":"","sources":["../../src/emergent/ForgeShapeValidator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAaH;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,kBAAkB,CAAC,GAAsB;IACvD,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,MAAM,WAAW,GAAG,GAAG,CAAC,WAA8D,CAAC;IACvF,MAAM,YAAY,GAAG,GAAG,CAAC,YAA+D,CAAC;IACzF,MAAM,UAAU,GACd,WAAW,IAAI,OAAO,WAAW,CAAC,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC;IAC5F,MAAM,WAAW,GACf,YAAY,IAAI,OAAO,YAAY,CAAC,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC;IAC/F,IAAI,CAAC,UAAU,IAAI,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxD,MAAM,CAAC,IAAI,CAAC,uEAAuE,CAAC,CAAC;IACvF,CAAC;IACD,IAAI,CAAC,WAAW,IAAI,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1D,MAAM,CAAC,IAAI,CAAC,8EAA8E,CAAC,CAAC;IAC9F,CAAC;IACD,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC;QACxC,CAAC,CAAE,GAAG,CAAC,SAAkE;QACzE,CAAC,CAAC,EAAE,CAAC;IACP,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACrB,MAAM,CAAC,IAAI,CAAC,kCAAkC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;IAChE,CAAC;IACD,MAAM,WAAW,GAAG,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE;QACpC,MAAM,GAAG,GAAG,EAAE,EAAE,KAAK,CAAC;QACtB,OAAO,CAAC,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,MAAM,CAAC,IAAI,CAAC,GAA8B,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC;IACrG,CAAC,CAAC,CAAC,MAAM,CAAC;IACV,IAAI,WAAW,GAAG,CAAC,EAAE,CAAC;QACpB,MAAM,CAAC,IAAI,CACT,GAAG,WAAW,YAAY,WAAW,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,sDAAsD,CAC7G,CAAC;IACJ,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,94 @@
1
+ /**
2
+ * @fileoverview Standalone per-run aggregator for forge reliability
3
+ * telemetry. Composes with any cost/usage tracker the consumer already
4
+ * has.
5
+ * @module @framers/agentos/emergent/ForgeStatsAggregator
6
+ *
7
+ * Pinned shape: the {@link ForgeStats} snapshot must stay stable. It
8
+ * ships through consumer telemetry endpoints that downstream dashboards
9
+ * parse; renaming fields is a breaking change. Fold in new dimensions
10
+ * by adding fields, not renaming existing ones.
11
+ */
12
+ import { type ForgeRejectionCategory } from './ForgeRejectionClassifier.js';
13
+ /** Per-run forge reliability rollup snapshot. */
14
+ export interface ForgeStats {
15
+ /** Total forge attempts (approved + rejected combined). */
16
+ attempts: number;
17
+ /** Attempts the judge approved. */
18
+ approved: number;
19
+ /** Attempts the judge or shape validator rejected. */
20
+ rejected: number;
21
+ /** Sum of confidence across approved attempts. Divide by `approved` for avg. */
22
+ approvedConfidenceSum: number;
23
+ /**
24
+ * Count of unique tool names seen this run (union of approved + rejected).
25
+ * A tool rejected then re-forged under the same name counts once.
26
+ */
27
+ uniqueNames: number;
28
+ /** Count of unique tool names that landed approved at least once this run. */
29
+ uniqueApproved: number;
30
+ /**
31
+ * Count of unique tool names that were ONLY rejected (never approved)
32
+ * this run. The retry loop did not recover these. Actionable signal
33
+ * for "real quality failures" vs retry churn.
34
+ */
35
+ uniqueTerminalRejections: number;
36
+ /**
37
+ * Histogram of rejection reasons, classified via
38
+ * {@link classifyForgeRejection}. Keys match {@link ForgeRejectionCategory}.
39
+ */
40
+ rejectionReasons: Record<ForgeRejectionCategory, number>;
41
+ }
42
+ /**
43
+ * Create a fresh, zeroed {@link ForgeStats} snapshot. Exposed for consumers
44
+ * that want to seed their own state or compare against a baseline.
45
+ */
46
+ export declare function emptyForgeStats(): ForgeStats;
47
+ /**
48
+ * Aggregator for forge outcomes across a single run. No dependency on
49
+ * the cost tracker or any consumer-specific types — consumers compose
50
+ * it into whatever telemetry layer they already have.
51
+ *
52
+ * Typical wiring: the consumer's forge capture callback calls
53
+ * {@link recordAttempt} with the outcome fields, then embeds
54
+ * {@link snapshot} under a `forgeStats` key in whatever payload the
55
+ * consumer ships to clients.
56
+ */
57
+ export declare class ForgeStatsAggregator {
58
+ private stats;
59
+ private readonly approvedNames;
60
+ private readonly rejectedNames;
61
+ /**
62
+ * Record one forge attempt's outcome.
63
+ *
64
+ * @param approved `true` when the judge approved; `false` for shape-check
65
+ * or judge rejections.
66
+ * @param confidence Judge's confidence score for approved tools. Summed
67
+ * into `approvedConfidenceSum` (skipped for rejections so rejection
68
+ * confidence does not dilute the average).
69
+ * @param toolName Optional tool name. When provided, tracks unique-tool
70
+ * metrics (eventually-approved vs terminally-rejected) rather than
71
+ * raw attempt counts.
72
+ * @param errorReason Optional rejection-reason string. On a rejected
73
+ * attempt, passed through {@link classifyForgeRejection} and binned
74
+ * into `rejectionReasons`.
75
+ */
76
+ recordAttempt(approved: boolean, confidence: number, toolName?: string, errorReason?: string): void;
77
+ /**
78
+ * Build a plain-object snapshot of current stats. Safe to JSON-serialize
79
+ * and ship to clients. Returns a shallow copy so callers can mutate
80
+ * without affecting the aggregator's internal state.
81
+ */
82
+ snapshot(): ForgeStats;
83
+ /**
84
+ * Clear all accumulated state. Useful when the aggregator is reused
85
+ * across multiple runs in one process.
86
+ */
87
+ reset(): void;
88
+ /**
89
+ * Recompute the three unique-tool counters from the name sets. Called
90
+ * after every attempt so `snapshot()` never has to do the math itself.
91
+ */
92
+ private refreshUniqueCounts;
93
+ }
94
+ //# sourceMappingURL=ForgeStatsAggregator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ForgeStatsAggregator.d.ts","sourceRoot":"","sources":["../../src/emergent/ForgeStatsAggregator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAEL,KAAK,sBAAsB,EAC5B,MAAM,+BAA+B,CAAC;AAEvC,iDAAiD;AACjD,MAAM,WAAW,UAAU;IACzB,2DAA2D;IAC3D,QAAQ,EAAE,MAAM,CAAC;IACjB,mCAAmC;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,sDAAsD;IACtD,QAAQ,EAAE,MAAM,CAAC;IACjB,gFAAgF;IAChF,qBAAqB,EAAE,MAAM,CAAC;IAC9B;;;OAGG;IACH,WAAW,EAAE,MAAM,CAAC;IACpB,8EAA8E;IAC9E,cAAc,EAAE,MAAM,CAAC;IACvB;;;;OAIG;IACH,wBAAwB,EAAE,MAAM,CAAC;IACjC;;;OAGG;IACH,gBAAgB,EAAE,MAAM,CAAC,sBAAsB,EAAE,MAAM,CAAC,CAAC;CAC1D;AAED;;;GAGG;AACH,wBAAgB,eAAe,IAAI,UAAU,CAiB5C;AAED;;;;;;;;;GASG;AACH,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,KAAK,CAAiC;IAC9C,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAqB;IACnD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAqB;IAEnD;;;;;;;;;;;;;;OAcG;IACH,aAAa,CACX,QAAQ,EAAE,OAAO,EACjB,UAAU,EAAE,MAAM,EAClB,QAAQ,CAAC,EAAE,MAAM,EACjB,WAAW,CAAC,EAAE,MAAM,GACnB,IAAI;IAeP;;;;OAIG;IACH,QAAQ,IAAI,UAAU;IAOtB;;;OAGG;IACH,KAAK,IAAI,IAAI;IAMb;;;OAGG;IACH,OAAO,CAAC,mBAAmB;CAY5B"}
@@ -0,0 +1,123 @@
1
+ /**
2
+ * @fileoverview Standalone per-run aggregator for forge reliability
3
+ * telemetry. Composes with any cost/usage tracker the consumer already
4
+ * has.
5
+ * @module @framers/agentos/emergent/ForgeStatsAggregator
6
+ *
7
+ * Pinned shape: the {@link ForgeStats} snapshot must stay stable. It
8
+ * ships through consumer telemetry endpoints that downstream dashboards
9
+ * parse; renaming fields is a breaking change. Fold in new dimensions
10
+ * by adding fields, not renaming existing ones.
11
+ */
12
+ import { classifyForgeRejection, } from './ForgeRejectionClassifier.js';
13
+ /**
14
+ * Create a fresh, zeroed {@link ForgeStats} snapshot. Exposed for consumers
15
+ * that want to seed their own state or compare against a baseline.
16
+ */
17
+ export function emptyForgeStats() {
18
+ return {
19
+ attempts: 0,
20
+ approved: 0,
21
+ rejected: 0,
22
+ approvedConfidenceSum: 0,
23
+ uniqueNames: 0,
24
+ uniqueApproved: 0,
25
+ uniqueTerminalRejections: 0,
26
+ rejectionReasons: {
27
+ schema_extra_field: 0,
28
+ shape_check: 0,
29
+ parse_error: 0,
30
+ judge_correctness: 0,
31
+ other: 0,
32
+ },
33
+ };
34
+ }
35
+ /**
36
+ * Aggregator for forge outcomes across a single run. No dependency on
37
+ * the cost tracker or any consumer-specific types — consumers compose
38
+ * it into whatever telemetry layer they already have.
39
+ *
40
+ * Typical wiring: the consumer's forge capture callback calls
41
+ * {@link recordAttempt} with the outcome fields, then embeds
42
+ * {@link snapshot} under a `forgeStats` key in whatever payload the
43
+ * consumer ships to clients.
44
+ */
45
+ export class ForgeStatsAggregator {
46
+ constructor() {
47
+ this.stats = emptyForgeStats();
48
+ this.approvedNames = new Set();
49
+ this.rejectedNames = new Set();
50
+ }
51
+ /**
52
+ * Record one forge attempt's outcome.
53
+ *
54
+ * @param approved `true` when the judge approved; `false` for shape-check
55
+ * or judge rejections.
56
+ * @param confidence Judge's confidence score for approved tools. Summed
57
+ * into `approvedConfidenceSum` (skipped for rejections so rejection
58
+ * confidence does not dilute the average).
59
+ * @param toolName Optional tool name. When provided, tracks unique-tool
60
+ * metrics (eventually-approved vs terminally-rejected) rather than
61
+ * raw attempt counts.
62
+ * @param errorReason Optional rejection-reason string. On a rejected
63
+ * attempt, passed through {@link classifyForgeRejection} and binned
64
+ * into `rejectionReasons`.
65
+ */
66
+ recordAttempt(approved, confidence, toolName, errorReason) {
67
+ this.stats.attempts += 1;
68
+ if (approved) {
69
+ this.stats.approved += 1;
70
+ this.stats.approvedConfidenceSum += confidence;
71
+ if (toolName)
72
+ this.approvedNames.add(toolName);
73
+ }
74
+ else {
75
+ this.stats.rejected += 1;
76
+ if (toolName)
77
+ this.rejectedNames.add(toolName);
78
+ const category = classifyForgeRejection(errorReason);
79
+ this.stats.rejectionReasons[category] += 1;
80
+ }
81
+ this.refreshUniqueCounts();
82
+ }
83
+ /**
84
+ * Build a plain-object snapshot of current stats. Safe to JSON-serialize
85
+ * and ship to clients. Returns a shallow copy so callers can mutate
86
+ * without affecting the aggregator's internal state.
87
+ */
88
+ snapshot() {
89
+ return {
90
+ ...this.stats,
91
+ rejectionReasons: { ...this.stats.rejectionReasons },
92
+ };
93
+ }
94
+ /**
95
+ * Clear all accumulated state. Useful when the aggregator is reused
96
+ * across multiple runs in one process.
97
+ */
98
+ reset() {
99
+ this.stats = emptyForgeStats();
100
+ this.approvedNames.clear();
101
+ this.rejectedNames.clear();
102
+ }
103
+ /**
104
+ * Recompute the three unique-tool counters from the name sets. Called
105
+ * after every attempt so `snapshot()` never has to do the math itself.
106
+ */
107
+ refreshUniqueCounts() {
108
+ this.stats.uniqueApproved = this.approvedNames.size;
109
+ let terminal = 0;
110
+ for (const n of this.rejectedNames) {
111
+ if (!this.approvedNames.has(n))
112
+ terminal += 1;
113
+ }
114
+ this.stats.uniqueTerminalRejections = terminal;
115
+ const union = new Set();
116
+ for (const n of this.approvedNames)
117
+ union.add(n);
118
+ for (const n of this.rejectedNames)
119
+ union.add(n);
120
+ this.stats.uniqueNames = union.size;
121
+ }
122
+ }
123
+ //# sourceMappingURL=ForgeStatsAggregator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ForgeStatsAggregator.js","sourceRoot":"","sources":["../../src/emergent/ForgeStatsAggregator.ts"],"names":[],"mappings":"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"}
@@ -33,4 +33,9 @@ export { SelfEvaluateTool } from './SelfEvaluateTool.js';
33
33
  export { PersonalityMutationStore } from './PersonalityMutationStore.js';
34
34
  export type { PersonalityMutation, RecordMutationInput, DecayResult } from './PersonalityMutationStore.js';
35
35
  export type { SelfImprovementToolDeps } from './EmergentCapabilityEngine.js';
36
+ export { classifyForgeRejection, type ForgeRejectionCategory, } from './ForgeRejectionClassifier.js';
37
+ export { validateForgeShape, type ForgeShapeRequest, } from './ForgeShapeValidator.js';
38
+ export { inferSchemaFromTestCases, type ForgeSchemaInferenceRequest, } from './ForgeSchemaInference.js';
39
+ export { wrapForgeTool, type CapturedForge, type ForgeLogEvent, type WrapForgeToolOptions, } from './wrapForgeTool.js';
40
+ export { ForgeStatsAggregator, emptyForgeStats, type ForgeStats, } from './ForgeStatsAggregator.js';
36
41
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/emergent/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,KAAK,qBAAqB,EAAE,+BAA+B,EAAE,MAAM,4BAA4B,CAAC;AACzG,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACnE,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,YAAY,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AACxE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,YAAY,EACV,eAAe,IAAI,8BAA8B,EACjD,UAAU,GACX,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACL,oCAAoC,EACpC,wBAAwB,EACxB,4BAA4B,EAC5B,wBAAwB,EACxB,kCAAkC,GACnC,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EACV,6BAA6B,EAC7B,0BAA0B,EAC1B,2BAA2B,EAC3B,+BAA+B,EAC/B,yCAAyC,GAC1C,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,YAAY,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAC7E,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AACzE,YAAY,EAAE,4BAA4B,EAAE,MAAM,+BAA+B,CAAC;AAClF,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,YAAY,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,cAAc,EACd,qBAAqB,GACtB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AACzE,YAAY,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AAC3G,YAAY,EAAE,uBAAuB,EAAE,MAAM,+BAA+B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/emergent/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,KAAK,qBAAqB,EAAE,+BAA+B,EAAE,MAAM,4BAA4B,CAAC;AACzG,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACnE,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,YAAY,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AACxE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,YAAY,EACV,eAAe,IAAI,8BAA8B,EACjD,UAAU,GACX,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACL,oCAAoC,EACpC,wBAAwB,EACxB,4BAA4B,EAC5B,wBAAwB,EACxB,kCAAkC,GACnC,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EACV,6BAA6B,EAC7B,0BAA0B,EAC1B,2BAA2B,EAC3B,+BAA+B,EAC/B,yCAAyC,GAC1C,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,YAAY,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAC7E,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AACzE,YAAY,EAAE,4BAA4B,EAAE,MAAM,+BAA+B,CAAC;AAClF,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,YAAY,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,cAAc,EACd,qBAAqB,GACtB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AACzE,YAAY,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AAC3G,YAAY,EAAE,uBAAuB,EAAE,MAAM,+BAA+B,CAAC;AAM7E,OAAO,EACL,sBAAsB,EACtB,KAAK,sBAAsB,GAC5B,MAAM,+BAA+B,CAAC;AACvC,OAAO,EACL,kBAAkB,EAClB,KAAK,iBAAiB,GACvB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,wBAAwB,EACxB,KAAK,2BAA2B,GACjC,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACL,aAAa,EACb,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,KAAK,oBAAoB,GAC1B,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,oBAAoB,EACpB,eAAe,EACf,KAAK,UAAU,GAChB,MAAM,2BAA2B,CAAC"}
@@ -25,4 +25,13 @@ export { ManageSkillsTool } from './ManageSkillsTool.js';
25
25
  export { CreateWorkflowTool } from './CreateWorkflowTool.js';
26
26
  export { SelfEvaluateTool } from './SelfEvaluateTool.js';
27
27
  export { PersonalityMutationStore } from './PersonalityMutationStore.js';
28
+ // Forge observability — instrumentation for consumers that want live
29
+ // visibility into forge health (rejection-reason histogram, shape-check
30
+ // pre-validator, schema inference from testCases, capture wrapper,
31
+ // aggregator).
32
+ export { classifyForgeRejection, } from './ForgeRejectionClassifier.js';
33
+ export { validateForgeShape, } from './ForgeShapeValidator.js';
34
+ export { inferSchemaFromTestCases, } from './ForgeSchemaInference.js';
35
+ export { wrapForgeTool, } from './wrapForgeTool.js';
36
+ export { ForgeStatsAggregator, emptyForgeStats, } from './ForgeStatsAggregator.js';
28
37
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/emergent/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,cAAc,YAAY,CAAC;AAC3B,OAAO,EAA8B,+BAA+B,EAAE,MAAM,4BAA4B,CAAC;AACzG,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACnE,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAE7D,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAKjE,OAAO,EACL,oCAAoC,EACpC,wBAAwB,EACxB,4BAA4B,EAC5B,wBAAwB,EACxB,kCAAkC,GACnC,MAAM,kBAAkB,CAAC;AAQ1B,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEnD,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AAEzE,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAE3D,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,cAAc,EACd,qBAAqB,GACtB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/emergent/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,cAAc,YAAY,CAAC;AAC3B,OAAO,EAA8B,+BAA+B,EAAE,MAAM,4BAA4B,CAAC;AACzG,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACnE,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAE7D,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAKjE,OAAO,EACL,oCAAoC,EACpC,wBAAwB,EACxB,4BAA4B,EAC5B,wBAAwB,EACxB,kCAAkC,GACnC,MAAM,kBAAkB,CAAC;AAQ1B,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEnD,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AAEzE,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAE3D,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,cAAc,EACd,qBAAqB,GACtB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AAIzE,qEAAqE;AACrE,wEAAwE;AACxE,mEAAmE;AACnE,eAAe;AACf,OAAO,EACL,sBAAsB,GAEvB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EACL,kBAAkB,GAEnB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,wBAAwB,GAEzB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACL,aAAa,GAId,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,oBAAoB,EACpB,eAAe,GAEhB,MAAM,2BAA2B,CAAC"}
@@ -0,0 +1,114 @@
1
+ /**
2
+ * @fileoverview Wrapper around ForgeToolMetaTool that normalizes LLM
3
+ * output, runs a pre-judge shape check, captures every attempt, and
4
+ * surfaces outcomes as structured log events.
5
+ * @module @framers/agentos/emergent/wrapForgeTool
6
+ *
7
+ * LLMs emit wide variety in forge_tool args (stringified JSON, wrong
8
+ * mode spellings, missing allowlists, no code body). This wrapper fixes
9
+ * them up so the engine never crashes deep in sandbox validation, and
10
+ * every attempt gets recorded to the caller's capture sink regardless
11
+ * of outcome. That gives consumers an attempt-level ground truth that
12
+ * does not depend on the LLM self-reporting its forge calls.
13
+ *
14
+ * Pure wrapper over ForgeToolMetaTool + ForgeShapeValidator +
15
+ * ForgeSchemaInference. No stdout dependency — log events route
16
+ * through the optional `log` callback.
17
+ */
18
+ import type { ITool } from '../core/tools/ITool.js';
19
+ import { ForgeToolMetaTool } from './ForgeToolMetaTool.js';
20
+ /**
21
+ * Captured forge event — ground-truth record of an actual forge call,
22
+ * independent of whether the LLM self-reported it.
23
+ */
24
+ export interface CapturedForge {
25
+ /** Tool name (`fixed.name || 'unnamed'`). */
26
+ name: string;
27
+ /** Tool description (`fixed.description || name`). */
28
+ description: string;
29
+ /** `'sandbox'` or `'compose'` after normalization. */
30
+ mode: string;
31
+ /** Forge request's declared input schema post-normalization. */
32
+ inputSchema: unknown;
33
+ /** Forge request's declared output schema post-normalization. */
34
+ outputSchema: unknown;
35
+ /** Did the judge approve? */
36
+ approved: boolean;
37
+ /** Judge confidence for approved tools; 0 on rejection. */
38
+ confidence: number;
39
+ /** Judge verdict payload or shape-check context. */
40
+ output: unknown;
41
+ /** Populated on rejection or error. Truncated to 240 chars. */
42
+ errorReason?: string;
43
+ /**
44
+ * Optional free-form scope label (e.g. a department name, a chat
45
+ * agent id, or any grouping the caller wants propagated onto every
46
+ * capture record). Left undefined when the caller does not group.
47
+ */
48
+ scope?: string;
49
+ /** Wall-clock ms so captures can be attributed to surrounding events. */
50
+ timestamp: number;
51
+ }
52
+ /**
53
+ * Structured log event emitted at each forge lifecycle step. Consumers
54
+ * who care about stdout visibility can pass a `log` callback that
55
+ * renders this into console.log / pm2 / whatever. AgentOS emits
56
+ * nothing by default so the wrapper is safe to use in quiet contexts.
57
+ */
58
+ export type ForgeLogEvent = {
59
+ kind: 'start';
60
+ scope?: string;
61
+ toolName: string;
62
+ mode: string;
63
+ } | {
64
+ kind: 'approved';
65
+ scope?: string;
66
+ toolName: string;
67
+ confidence: number;
68
+ } | {
69
+ kind: 'rejected';
70
+ scope?: string;
71
+ toolName: string;
72
+ reason: string;
73
+ } | {
74
+ kind: 'error';
75
+ scope?: string;
76
+ toolName: string;
77
+ error: string;
78
+ };
79
+ /** Options for {@link wrapForgeTool}. */
80
+ export interface WrapForgeToolOptions {
81
+ /** The raw ForgeToolMetaTool instance from EmergentCapabilityEngine. */
82
+ raw: ForgeToolMetaTool;
83
+ /** GMI / agent id patched onto the tool execution context. */
84
+ agentId: string;
85
+ /** Session id patched onto the tool execution context under sessionData. */
86
+ sessionId: string;
87
+ /** Required capture sink. Every attempt (valid or not) is recorded. */
88
+ capture: (record: CapturedForge) => void;
89
+ /**
90
+ * Optional scope label propagated onto every CapturedForge. Use for
91
+ * semantic grouping when multiple callers share a wrapper (dept
92
+ * name, channel id, agent role, etc.).
93
+ */
94
+ scope?: string;
95
+ /**
96
+ * Optional log callback for lifecycle visibility. When undefined,
97
+ * no log events are emitted (quiet mode).
98
+ */
99
+ log?: (event: ForgeLogEvent) => void;
100
+ }
101
+ /**
102
+ * Wrap the raw ForgeToolMetaTool so each forge attempt gets normalized,
103
+ * pre-validated, captured, and logged.
104
+ *
105
+ * Normalization fixes: stringified-JSON fields, mode synonyms (`code`,
106
+ * `javascript`, `js` → `sandbox`; `composed`, `composition`, `chain`,
107
+ * `pipeline` → `compose`), missing allowlist / code body / steps /
108
+ * schemas / testCases. After normalization, the shape validator runs;
109
+ * on failure the judge is skipped and a rejection record is captured
110
+ * immediately. On success, the raw meta-tool executes and the result's
111
+ * verdict is folded into a capture record.
112
+ */
113
+ export declare function wrapForgeTool(options: WrapForgeToolOptions): ITool;
114
+ //# sourceMappingURL=wrapForgeTool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wrapForgeTool.d.ts","sourceRoot":"","sources":["../../src/emergent/wrapForgeTool.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAwB,MAAM,wBAAwB,CAAC;AAC1E,OAAO,EAAE,iBAAiB,EAAuB,MAAM,wBAAwB,CAAC;AAIhF;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,6CAA6C;IAC7C,IAAI,EAAE,MAAM,CAAC;IACb,sDAAsD;IACtD,WAAW,EAAE,MAAM,CAAC;IACpB,sDAAsD;IACtD,IAAI,EAAE,MAAM,CAAC;IACb,gEAAgE;IAChE,WAAW,EAAE,OAAO,CAAC;IACrB,iEAAiE;IACjE,YAAY,EAAE,OAAO,CAAC;IACtB,6BAA6B;IAC7B,QAAQ,EAAE,OAAO,CAAC;IAClB,2DAA2D;IAC3D,UAAU,EAAE,MAAM,CAAC;IACnB,oDAAoD;IACpD,MAAM,EAAE,OAAO,CAAC;IAChB,+DAA+D;IAC/D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,yEAAyE;IACzE,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;;GAKG;AACH,MAAM,MAAM,aAAa,GACrB;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACjE;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GAC1E;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACtE;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAEvE,yCAAyC;AACzC,MAAM,WAAW,oBAAoB;IACnC,wEAAwE;IACxE,GAAG,EAAE,iBAAiB,CAAC;IACvB,8DAA8D;IAC9D,OAAO,EAAE,MAAM,CAAC;IAChB,4EAA4E;IAC5E,SAAS,EAAE,MAAM,CAAC;IAClB,uEAAuE;IACvE,OAAO,EAAE,CAAC,MAAM,EAAE,aAAa,KAAK,IAAI,CAAC;IACzC;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;CACtC;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,oBAAoB,GAAG,KAAK,CA2LlE"}
@@ -0,0 +1,219 @@
1
+ /**
2
+ * @fileoverview Wrapper around ForgeToolMetaTool that normalizes LLM
3
+ * output, runs a pre-judge shape check, captures every attempt, and
4
+ * surfaces outcomes as structured log events.
5
+ * @module @framers/agentos/emergent/wrapForgeTool
6
+ *
7
+ * LLMs emit wide variety in forge_tool args (stringified JSON, wrong
8
+ * mode spellings, missing allowlists, no code body). This wrapper fixes
9
+ * them up so the engine never crashes deep in sandbox validation, and
10
+ * every attempt gets recorded to the caller's capture sink regardless
11
+ * of outcome. That gives consumers an attempt-level ground truth that
12
+ * does not depend on the LLM self-reporting its forge calls.
13
+ *
14
+ * Pure wrapper over ForgeToolMetaTool + ForgeShapeValidator +
15
+ * ForgeSchemaInference. No stdout dependency — log events route
16
+ * through the optional `log` callback.
17
+ */
18
+ import { validateForgeShape } from './ForgeShapeValidator.js';
19
+ import { inferSchemaFromTestCases } from './ForgeSchemaInference.js';
20
+ /**
21
+ * Wrap the raw ForgeToolMetaTool so each forge attempt gets normalized,
22
+ * pre-validated, captured, and logged.
23
+ *
24
+ * Normalization fixes: stringified-JSON fields, mode synonyms (`code`,
25
+ * `javascript`, `js` → `sandbox`; `composed`, `composition`, `chain`,
26
+ * `pipeline` → `compose`), missing allowlist / code body / steps /
27
+ * schemas / testCases. After normalization, the shape validator runs;
28
+ * on failure the judge is skipped and a rejection record is captured
29
+ * immediately. On success, the raw meta-tool executes and the result's
30
+ * verdict is folded into a capture record.
31
+ */
32
+ export function wrapForgeTool(options) {
33
+ const { raw, agentId, sessionId, capture, scope, log } = options;
34
+ return {
35
+ ...raw,
36
+ async execute(args, ctx) {
37
+ const fixed = { ...args };
38
+ for (const k of ['implementation', 'inputSchema', 'outputSchema', 'testCases']) {
39
+ if (typeof fixed[k] === 'string') {
40
+ try {
41
+ fixed[k] = JSON.parse(fixed[k]);
42
+ }
43
+ catch {
44
+ // Leave as-is; downstream normalization backstops most failures.
45
+ }
46
+ }
47
+ }
48
+ // Normalize implementation. Strict `mode === 'compose'` check in
49
+ // the engine means anything else falls into the sandbox branch.
50
+ // Unfamiliar mode strings + missing fields can crash deep in
51
+ // SandboxedToolForge.validateCode. Normalize to exactly
52
+ // 'sandbox' or 'compose', infer from field shape when the mode
53
+ // string is unfamiliar, backstop every required field.
54
+ if (fixed.implementation && typeof fixed.implementation === 'object') {
55
+ const impl = fixed.implementation;
56
+ if (impl.mode === 'code' || impl.mode === 'javascript' || impl.mode === 'js') {
57
+ impl.mode = 'sandbox';
58
+ }
59
+ if (impl.mode === 'composed' ||
60
+ impl.mode === 'composition' ||
61
+ impl.mode === 'composable' ||
62
+ impl.mode === 'chain' ||
63
+ impl.mode === 'pipeline') {
64
+ impl.mode = 'compose';
65
+ }
66
+ if (impl.mode !== 'sandbox' && impl.mode !== 'compose') {
67
+ if (Array.isArray(impl.steps))
68
+ impl.mode = 'compose';
69
+ else if (typeof impl.code === 'string')
70
+ impl.mode = 'sandbox';
71
+ else
72
+ impl.mode = 'sandbox';
73
+ }
74
+ if (impl.mode === 'sandbox') {
75
+ if (!Array.isArray(impl.allowlist))
76
+ impl.allowlist = [];
77
+ if (impl.code != null && typeof impl.code !== 'string')
78
+ impl.code = String(impl.code);
79
+ if (!impl.code || typeof impl.code !== 'string') {
80
+ impl.code = 'function execute(input) { return { error: "No code provided in forge request" }; }';
81
+ }
82
+ if (!impl.code.includes('function execute')) {
83
+ impl.code = `function execute(input) {\n${impl.code}\n}`;
84
+ }
85
+ }
86
+ else if (impl.mode === 'compose') {
87
+ if (!Array.isArray(impl.steps))
88
+ impl.steps = [];
89
+ for (const step of impl.steps) {
90
+ if (step && typeof step === 'object') {
91
+ if (typeof step.tool !== 'string')
92
+ step.tool = '';
93
+ if (typeof step.name !== 'string')
94
+ step.name = step.tool || 'step';
95
+ if (!step.inputMapping || typeof step.inputMapping !== 'object') {
96
+ step.inputMapping = {};
97
+ }
98
+ }
99
+ }
100
+ }
101
+ }
102
+ if (!fixed.inputSchema || typeof fixed.inputSchema !== 'object') {
103
+ fixed.inputSchema = { type: 'object', additionalProperties: true };
104
+ }
105
+ if (!fixed.outputSchema || typeof fixed.outputSchema !== 'object') {
106
+ fixed.outputSchema = { type: 'object', additionalProperties: true };
107
+ }
108
+ if (!Array.isArray(fixed.testCases) || fixed.testCases.length === 0) {
109
+ fixed.testCases = [{ input: {}, expectedOutput: {} }];
110
+ }
111
+ for (const tc of fixed.testCases) {
112
+ if (!tc.input || typeof tc.input !== 'object')
113
+ tc.input = {};
114
+ if (tc.expectedOutput === undefined)
115
+ tc.expectedOutput = {};
116
+ }
117
+ // Rescue concrete-testCases-without-formal-schema forges. Still
118
+ // strict: tool code must handle the inferred inputs, but the
119
+ // shape check passes deterministically on intent-clear input.
120
+ inferSchemaFromTestCases(fixed);
121
+ const mode = String(fixed.implementation?.mode ?? '?');
122
+ const toolName = String(fixed.name ?? 'unnamed');
123
+ const toolDescription = String(fixed.description ?? toolName);
124
+ // Pre-judge shape check. On failure, capture + emit a rejection
125
+ // event and short-circuit without invoking the judge LLM.
126
+ const shapeErrors = validateForgeShape(fixed);
127
+ if (shapeErrors.length > 0) {
128
+ const reason = `Shape check failed: ${shapeErrors.join('; ')}`;
129
+ log?.({ kind: 'rejected', scope, toolName, reason });
130
+ capture({
131
+ name: toolName,
132
+ description: toolDescription,
133
+ mode,
134
+ inputSchema: fixed.inputSchema,
135
+ outputSchema: fixed.outputSchema,
136
+ approved: false,
137
+ confidence: 0,
138
+ output: null,
139
+ errorReason: reason.slice(0, 240),
140
+ scope,
141
+ timestamp: Date.now(),
142
+ });
143
+ return {
144
+ success: false,
145
+ error: reason,
146
+ output: { success: false, verdict: { approved: false, confidence: 0, reasoning: reason } },
147
+ };
148
+ }
149
+ log?.({ kind: 'start', scope, toolName, mode });
150
+ const patched = {
151
+ ...ctx,
152
+ gmiId: agentId,
153
+ sessionData: {
154
+ ...(ctx?.sessionData ?? {}),
155
+ sessionId,
156
+ },
157
+ };
158
+ try {
159
+ // Cast is intentional: the wrapper's job is to normalize
160
+ // arbitrary LLM output into something the engine can handle.
161
+ // By this point `fixed` is shape-validated enough to run; TS
162
+ // cannot statically prove it matches every ForgeToolInput
163
+ // field because the source is untyped LLM output.
164
+ const r = await raw.execute(fixed, patched);
165
+ const out = r.output;
166
+ const verdict = out?.verdict ?? {};
167
+ // Judge confidence is the judge's score for whether the tool is
168
+ // safe + correct. When rejected, the judge's confidence is in
169
+ // REJECTING the tool; surfacing that as the tool's own quality
170
+ // score would be misleading. So: approved → judge confidence (or
171
+ // 0.85 fallback); rejected → 0.
172
+ const judgeConfidence = typeof verdict.confidence === 'number' ? verdict.confidence : null;
173
+ const confidence = r.success ? (judgeConfidence ?? 0.85) : 0;
174
+ const errorReason = !r.success
175
+ ? String(r.error ?? verdict.reasoning ?? out?.error ?? '').slice(0, 240)
176
+ : undefined;
177
+ if (r.success) {
178
+ log?.({ kind: 'approved', scope, toolName, confidence });
179
+ }
180
+ else {
181
+ log?.({ kind: 'rejected', scope, toolName, reason: errorReason ?? '' });
182
+ }
183
+ capture({
184
+ name: toolName,
185
+ description: toolDescription,
186
+ mode,
187
+ inputSchema: fixed.inputSchema,
188
+ outputSchema: fixed.outputSchema,
189
+ approved: !!r.success,
190
+ confidence,
191
+ output: out?.testResults ?? out?.result ?? out ?? null,
192
+ errorReason,
193
+ scope,
194
+ timestamp: Date.now(),
195
+ });
196
+ return r;
197
+ }
198
+ catch (err) {
199
+ const message = String(err).slice(0, 240);
200
+ log?.({ kind: 'error', scope, toolName, error: message });
201
+ capture({
202
+ name: toolName,
203
+ description: toolDescription,
204
+ mode,
205
+ inputSchema: fixed.inputSchema,
206
+ outputSchema: fixed.outputSchema,
207
+ approved: false,
208
+ confidence: 0,
209
+ output: null,
210
+ errorReason: message,
211
+ scope,
212
+ timestamp: Date.now(),
213
+ });
214
+ return { success: false, error: String(err) };
215
+ }
216
+ },
217
+ };
218
+ }
219
+ //# sourceMappingURL=wrapForgeTool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wrapForgeTool.js","sourceRoot":"","sources":["../../src/emergent/wrapForgeTool.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAIH,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,EAAE,wBAAwB,EAAE,MAAM,2BAA2B,CAAC;AAsErE;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,aAAa,CAAC,OAA6B;IACzD,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC;IACjE,OAAO;QACL,GAAI,GAAwB;QAC5B,KAAK,CAAC,OAAO,CAAC,IAA6B,EAAE,GAAY;YACvD,MAAM,KAAK,GAAG,EAAE,GAAG,IAAI,EAA6B,CAAC;YACrD,KAAK,MAAM,CAAC,IAAI,CAAC,gBAAgB,EAAE,aAAa,EAAE,cAAc,EAAE,WAAW,CAAC,EAAE,CAAC;gBAC/E,IAAI,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,QAAQ,EAAE,CAAC;oBACjC,IAAI,CAAC;wBACH,KAAK,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAW,CAAC,CAAC;oBAC5C,CAAC;oBAAC,MAAM,CAAC;wBACP,iEAAiE;oBACnE,CAAC;gBACH,CAAC;YACH,CAAC;YACD,iEAAiE;YACjE,gEAAgE;YAChE,6DAA6D;YAC7D,wDAAwD;YACxD,+DAA+D;YAC/D,uDAAuD;YACvD,IAAI,KAAK,CAAC,cAAc,IAAI,OAAO,KAAK,CAAC,cAAc,KAAK,QAAQ,EAAE,CAAC;gBACrE,MAAM,IAAI,GAAG,KAAK,CAAC,cAAyC,CAAC;gBAC7D,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,IAAI,IAAI,CAAC,IAAI,KAAK,YAAY,IAAI,IAAI,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC;oBAC7E,IAAI,CAAC,IAAI,GAAG,SAAS,CAAC;gBACxB,CAAC;gBACD,IACE,IAAI,CAAC,IAAI,KAAK,UAAU;oBACxB,IAAI,CAAC,IAAI,KAAK,aAAa;oBAC3B,IAAI,CAAC,IAAI,KAAK,YAAY;oBAC1B,IAAI,CAAC,IAAI,KAAK,OAAO;oBACrB,IAAI,CAAC,IAAI,KAAK,UAAU,EACxB,CAAC;oBACD,IAAI,CAAC,IAAI,GAAG,SAAS,CAAC;gBACxB,CAAC;gBACD,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;oBACvD,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC;wBAAE,IAAI,CAAC,IAAI,GAAG,SAAS,CAAC;yBAChD,IAAI,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ;wBAAE,IAAI,CAAC,IAAI,GAAG,SAAS,CAAC;;wBACzD,IAAI,CAAC,IAAI,GAAG,SAAS,CAAC;gBAC7B,CAAC;gBACD,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;oBAC5B,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC;wBAAE,IAAI,CAAC,SAAS,GAAG,EAAE,CAAC;oBACxD,IAAI,IAAI,CAAC,IAAI,IAAI,IAAI,IAAI,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ;wBAAE,IAAI,CAAC,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;oBACtF,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;wBAChD,IAAI,CAAC,IAAI,GAAG,oFAAoF,CAAC;oBACnG,CAAC;oBACD,IAAI,CAAE,IAAI,CAAC,IAAe,CAAC,QAAQ,CAAC,kBAAkB,CAAC,EAAE,CAAC;wBACxD,IAAI,CAAC,IAAI,GAAG,8BAA8B,IAAI,CAAC,IAAc,KAAK,CAAC;oBACrE,CAAC;gBACH,CAAC;qBAAM,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;oBACnC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC;wBAAE,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC;oBAChD,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAuC,EAAE,CAAC;wBAChE,IAAI,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;4BACrC,IAAI,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ;gCAAE,IAAI,CAAC,IAAI,GAAG,EAAE,CAAC;4BAClD,IAAI,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ;gCAAE,IAAI,CAAC,IAAI,GAAI,IAAI,CAAC,IAAe,IAAI,MAAM,CAAC;4BAC/E,IAAI,CAAC,IAAI,CAAC,YAAY,IAAI,OAAO,IAAI,CAAC,YAAY,KAAK,QAAQ,EAAE,CAAC;gCAChE,IAAI,CAAC,YAAY,GAAG,EAAE,CAAC;4BACzB,CAAC;wBACH,CAAC;oBACH,CAAC;gBACH,CAAC;YACH,CAAC;YACD,IAAI,CAAC,KAAK,CAAC,WAAW,IAAI,OAAO,KAAK,CAAC,WAAW,KAAK,QAAQ,EAAE,CAAC;gBAChE,KAAK,CAAC,WAAW,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,oBAAoB,EAAE,IAAI,EAAE,CAAC;YACrE,CAAC;YACD,IAAI,CAAC,KAAK,CAAC,YAAY,IAAI,OAAO,KAAK,CAAC,YAAY,KAAK,QAAQ,EAAE,CAAC;gBAClE,KAAK,CAAC,YAAY,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,oBAAoB,EAAE,IAAI,EAAE,CAAC;YACtE,CAAC;YACD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC,IAAK,KAAK,CAAC,SAAuB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACnF,KAAK,CAAC,SAAS,GAAG,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,cAAc,EAAE,EAAE,EAAE,CAAC,CAAC;YACxD,CAAC;YACD,KAAK,MAAM,EAAE,IAAI,KAAK,CAAC,SAA2C,EAAE,CAAC;gBACnE,IAAI,CAAC,EAAE,CAAC,KAAK,IAAI,OAAO,EAAE,CAAC,KAAK,KAAK,QAAQ;oBAAE,EAAE,CAAC,KAAK,GAAG,EAAE,CAAC;gBAC7D,IAAI,EAAE,CAAC,cAAc,KAAK,SAAS;oBAAE,EAAE,CAAC,cAAc,GAAG,EAAE,CAAC;YAC9D,CAAC;YAED,gEAAgE;YAChE,6DAA6D;YAC7D,8DAA8D;YAC9D,wBAAwB,CAAC,KAAK,CAAC,CAAC;YAEhC,MAAM,IAAI,GAAG,MAAM,CAAE,KAAK,CAAC,cAAiD,EAAE,IAAI,IAAI,GAAG,CAAC,CAAC;YAC3F,MAAM,QAAQ,GAAG,MAAM,CAAE,KAA4B,CAAC,IAAI,IAAI,SAAS,CAAC,CAAC;YACzE,MAAM,eAAe,GAAG,MAAM,CAAE,KAAmC,CAAC,WAAW,IAAI,QAAQ,CAAC,CAAC;YAE7F,gEAAgE;YAChE,0DAA0D;YAC1D,MAAM,WAAW,GAAG,kBAAkB,CACpC,KAIC,CACF,CAAC;YACF,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC3B,MAAM,MAAM,GAAG,uBAAuB,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC/D,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC;gBACrD,OAAO,CAAC;oBACN,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,eAAe;oBAC5B,IAAI;oBACJ,WAAW,EAAE,KAAK,CAAC,WAAW;oBAC9B,YAAY,EAAE,KAAK,CAAC,YAAY;oBAChC,QAAQ,EAAE,KAAK;oBACf,UAAU,EAAE,CAAC;oBACb,MAAM,EAAE,IAAI;oBACZ,WAAW,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC;oBACjC,KAAK;oBACL,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;iBACtB,CAAC,CAAC;gBACH,OAAO;oBACL,OAAO,EAAE,KAAK;oBACd,KAAK,EAAE,MAAM;oBACb,MAAM,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE;iBAChF,CAAC;YACf,CAAC;YAED,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;YAChD,MAAM,OAAO,GAAG;gBACd,GAAI,GAA+B;gBACnC,KAAK,EAAE,OAAO;gBACd,WAAW,EAAE;oBACX,GAAG,CAAE,GAAiD,EAAE,WAAW,IAAI,EAAE,CAAC;oBAC1E,SAAS;iBACV;aACF,CAAC;YACF,IAAI,CAAC;gBACH,yDAAyD;gBACzD,6DAA6D;gBAC7D,6DAA6D;gBAC7D,0DAA0D;gBAC1D,kDAAkD;gBAClD,MAAM,CAAC,GAAG,MAAM,GAAG,CAAC,OAAO,CACzB,KAAkC,EAClC,OAA0C,CAC3C,CAAC;gBACF,MAAM,GAAG,GAAG,CAAC,CAAC,MAA6J,CAAC;gBAC5K,MAAM,OAAO,GAAG,GAAG,EAAE,OAAO,IAAI,EAAE,CAAC;gBACnC,gEAAgE;gBAChE,8DAA8D;gBAC9D,+DAA+D;gBAC/D,iEAAiE;gBACjE,gCAAgC;gBAChC,MAAM,eAAe,GAAG,OAAO,OAAO,CAAC,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC;gBAC3F,MAAM,UAAU,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,eAAe,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;gBAC7D,MAAM,WAAW,GAAG,CAAC,CAAC,CAAC,OAAO;oBAC5B,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,IAAI,OAAO,CAAC,SAAS,IAAI,GAAG,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC;oBACxE,CAAC,CAAC,SAAS,CAAC;gBACd,IAAI,CAAC,CAAC,OAAO,EAAE,CAAC;oBACd,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC,CAAC;gBAC3D,CAAC;qBAAM,CAAC;oBACN,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,IAAI,EAAE,EAAE,CAAC,CAAC;gBAC1E,CAAC;gBACD,OAAO,CAAC;oBACN,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,eAAe;oBAC5B,IAAI;oBACJ,WAAW,EAAE,KAAK,CAAC,WAAW;oBAC9B,YAAY,EAAE,KAAK,CAAC,YAAY;oBAChC,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO;oBACrB,UAAU;oBACV,MAAM,EAAE,GAAG,EAAE,WAAW,IAAI,GAAG,EAAE,MAAM,IAAI,GAAG,IAAI,IAAI;oBACtD,WAAW;oBACX,KAAK;oBACL,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;iBACtB,CAAC,CAAC;gBACH,OAAO,CAAC,CAAC;YACX,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;gBAC1C,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;gBAC1D,OAAO,CAAC;oBACN,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,eAAe;oBAC5B,IAAI;oBACJ,WAAW,EAAE,KAAK,CAAC,WAAW;oBAC9B,YAAY,EAAE,KAAK,CAAC,YAAY;oBAChC,QAAQ,EAAE,KAAK;oBACf,UAAU,EAAE,CAAC;oBACb,MAAM,EAAE,IAAI;oBACZ,WAAW,EAAE,OAAO;oBACpB,KAAK;oBACL,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;iBACtB,CAAC,CAAC;gBACH,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;YAChD,CAAC;QACH,CAAC;KACO,CAAC;AACb,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@framers/agentos",
3
- "version": "0.1.229",
3
+ "version": "0.1.230",
4
4
  "description": "Modular AgentOS orchestration library",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",