@ifc-lite/ids-agent 0.0.0-stage → 0.2.2

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.
Files changed (123) hide show
  1. package/LICENSE +373 -0
  2. package/README.md +144 -2
  3. package/dist/bridges.d.ts +163 -0
  4. package/dist/bridges.d.ts.map +1 -0
  5. package/dist/bridges.js +6 -0
  6. package/dist/bridges.js.map +1 -0
  7. package/dist/index.d.ts +23 -0
  8. package/dist/index.d.ts.map +1 -0
  9. package/dist/index.js +26 -0
  10. package/dist/index.js.map +1 -0
  11. package/dist/modes.d.ts +30 -0
  12. package/dist/modes.d.ts.map +1 -0
  13. package/dist/modes.js +34 -0
  14. package/dist/modes.js.map +1 -0
  15. package/dist/prompts/system-v1.d.ts +19 -0
  16. package/dist/prompts/system-v1.d.ts.map +1 -0
  17. package/dist/prompts/system-v1.js +43 -0
  18. package/dist/prompts/system-v1.js.map +1 -0
  19. package/dist/proposal/proposal.d.ts +72 -0
  20. package/dist/proposal/proposal.d.ts.map +1 -0
  21. package/dist/proposal/proposal.js +60 -0
  22. package/dist/proposal/proposal.js.map +1 -0
  23. package/dist/proposal/view-model.d.ts +66 -0
  24. package/dist/proposal/view-model.d.ts.map +1 -0
  25. package/dist/proposal/view-model.js +94 -0
  26. package/dist/proposal/view-model.js.map +1 -0
  27. package/dist/providers/anthropic.d.ts +45 -0
  28. package/dist/providers/anthropic.d.ts.map +1 -0
  29. package/dist/providers/anthropic.js +107 -0
  30. package/dist/providers/anthropic.js.map +1 -0
  31. package/dist/providers/openai.d.ts +60 -0
  32. package/dist/providers/openai.d.ts.map +1 -0
  33. package/dist/providers/openai.js +92 -0
  34. package/dist/providers/openai.js.map +1 -0
  35. package/dist/runner/context.d.ts +21 -0
  36. package/dist/runner/context.d.ts.map +1 -0
  37. package/dist/runner/context.js +25 -0
  38. package/dist/runner/context.js.map +1 -0
  39. package/dist/runner/loop.d.ts +96 -0
  40. package/dist/runner/loop.d.ts.map +1 -0
  41. package/dist/runner/loop.js +194 -0
  42. package/dist/runner/loop.js.map +1 -0
  43. package/dist/runner/privacy.d.ts +71 -0
  44. package/dist/runner/privacy.d.ts.map +1 -0
  45. package/dist/runner/privacy.js +72 -0
  46. package/dist/runner/privacy.js.map +1 -0
  47. package/dist/runner/receipt.d.ts +48 -0
  48. package/dist/runner/receipt.d.ts.map +1 -0
  49. package/dist/runner/receipt.js +29 -0
  50. package/dist/runner/receipt.js.map +1 -0
  51. package/dist/sandbox/handles.d.ts +22 -0
  52. package/dist/sandbox/handles.d.ts.map +1 -0
  53. package/dist/sandbox/handles.js +67 -0
  54. package/dist/sandbox/handles.js.map +1 -0
  55. package/dist/sandbox/nodes.d.ts +11 -0
  56. package/dist/sandbox/nodes.d.ts.map +1 -0
  57. package/dist/sandbox/nodes.js +38 -0
  58. package/dist/sandbox/nodes.js.map +1 -0
  59. package/dist/sandbox/sandbox.d.ts +110 -0
  60. package/dist/sandbox/sandbox.d.ts.map +1 -0
  61. package/dist/sandbox/sandbox.js +125 -0
  62. package/dist/sandbox/sandbox.js.map +1 -0
  63. package/dist/testing/doubles.d.ts +20 -0
  64. package/dist/testing/doubles.d.ts.map +1 -0
  65. package/dist/testing/doubles.js +105 -0
  66. package/dist/testing/doubles.js.map +1 -0
  67. package/dist/testing/index.d.ts +8 -0
  68. package/dist/testing/index.d.ts.map +1 -0
  69. package/dist/testing/index.js +11 -0
  70. package/dist/testing/index.js.map +1 -0
  71. package/dist/testing/transports.d.ts +48 -0
  72. package/dist/testing/transports.d.ts.map +1 -0
  73. package/dist/testing/transports.js +70 -0
  74. package/dist/testing/transports.js.map +1 -0
  75. package/dist/tools/act-tools.d.ts +13 -0
  76. package/dist/tools/act-tools.d.ts.map +1 -0
  77. package/dist/tools/act-tools.js +115 -0
  78. package/dist/tools/act-tools.js.map +1 -0
  79. package/dist/tools/ask-user.d.ts +3 -0
  80. package/dist/tools/ask-user.d.ts.map +1 -0
  81. package/dist/tools/ask-user.js +62 -0
  82. package/dist/tools/ask-user.js.map +1 -0
  83. package/dist/tools/bsdd-tools.d.ts +8 -0
  84. package/dist/tools/bsdd-tools.d.ts.map +1 -0
  85. package/dist/tools/bsdd-tools.js +64 -0
  86. package/dist/tools/bsdd-tools.js.map +1 -0
  87. package/dist/tools/context.d.ts +27 -0
  88. package/dist/tools/context.d.ts.map +1 -0
  89. package/dist/tools/context.js +21 -0
  90. package/dist/tools/context.js.map +1 -0
  91. package/dist/tools/ids-read.d.ts +26 -0
  92. package/dist/tools/ids-read.d.ts.map +1 -0
  93. package/dist/tools/ids-read.js +74 -0
  94. package/dist/tools/ids-read.js.map +1 -0
  95. package/dist/tools/index.d.ts +11 -0
  96. package/dist/tools/index.d.ts.map +1 -0
  97. package/dist/tools/index.js +22 -0
  98. package/dist/tools/index.js.map +1 -0
  99. package/dist/tools/model-tools.d.ts +3 -0
  100. package/dist/tools/model-tools.d.ts.map +1 -0
  101. package/dist/tools/model-tools.js +100 -0
  102. package/dist/tools/model-tools.js.map +1 -0
  103. package/dist/tools/op-schema.d.ts +23 -0
  104. package/dist/tools/op-schema.d.ts.map +1 -0
  105. package/dist/tools/op-schema.js +57 -0
  106. package/dist/tools/op-schema.js.map +1 -0
  107. package/dist/tools/rank.d.ts +3 -0
  108. package/dist/tools/rank.d.ts.map +1 -0
  109. package/dist/tools/rank.js +66 -0
  110. package/dist/tools/rank.js.map +1 -0
  111. package/dist/tools/registry.d.ts +59 -0
  112. package/dist/tools/registry.d.ts.map +1 -0
  113. package/dist/tools/registry.js +61 -0
  114. package/dist/tools/registry.js.map +1 -0
  115. package/dist/tools/schema-tools.d.ts +3 -0
  116. package/dist/tools/schema-tools.d.ts.map +1 -0
  117. package/dist/tools/schema-tools.js +127 -0
  118. package/dist/tools/schema-tools.js.map +1 -0
  119. package/dist/worker-bridge.d.ts +47 -0
  120. package/dist/worker-bridge.d.ts.map +1 -0
  121. package/dist/worker-bridge.js +97 -0
  122. package/dist/worker-bridge.js.map +1 -0
  123. package/package.json +79 -3
@@ -0,0 +1,125 @@
1
+ /* This Source Code Form is subject to the terms of the Mozilla Public
2
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
3
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
+ /**
5
+ * The sandbox fork an agent run works on (ADR-008).
6
+ *
7
+ * It starts from a copy of the user's document and changes ONLY through the
8
+ * op vocabulary: every batch passes the grounding gate (`checkOps`) before
9
+ * the reducer applies it (`commit`), all or nothing. A rejected batch leaves
10
+ * the fork untouched and returns the gate issues, with ranked candidates,
11
+ * for the model to correct. After each applied batch the linter re-runs and
12
+ * the diagnostics delta is reported back.
13
+ *
14
+ * Every applied batch is recorded with its rationale and sources: those
15
+ * records ARE the proposal the user reviews. The live document is never
16
+ * touched here; `acceptProposal` replays chosen batches through the gate
17
+ * again against the live document.
18
+ */
19
+ import { checkOps, commit, createLinter, createStudioState, undo as undoState, } from '@ifc-lite/ids-authoring';
20
+ import { createHandleTable } from './handles.js';
21
+ import { diagnosticId, specIdsFor } from './nodes.js';
22
+ /** Op kinds the reducer emits as exact inverses; an agent never authors them. */
23
+ export const FIDELITY_KINDS = new Set(['spec.restore', 'spec.patch', 'facet.restore', 'facet.patch']);
24
+ export function brief(d) {
25
+ return {
26
+ diagnosticId: diagnosticId(d), code: d.code, severity: d.severity, message: d.message,
27
+ ...(d.specId ? { specId: d.specId } : {}), fixes: (d.fixes ?? []).map((f) => f.label),
28
+ };
29
+ }
30
+ function refusalOf(issue) {
31
+ return {
32
+ code: issue.code, path: issue.path, message: issue.message,
33
+ candidates: issue.candidates.slice(0, 5).map((c) => c.value),
34
+ ...(issue.value !== undefined ? { value: issue.value } : {}),
35
+ };
36
+ }
37
+ function guardOps(ops, guard) {
38
+ if (!guard)
39
+ return null;
40
+ for (const [index, op] of ops.entries()) {
41
+ const record = typeof op === 'object' && op !== null ? op : {};
42
+ const reason = guard({ kind: String(record.kind), payload: record.payload });
43
+ if (reason)
44
+ return { code: 'AGENT-MODE-001', path: `ops[${index}]`, message: reason, candidates: [] };
45
+ }
46
+ return null;
47
+ }
48
+ export function createSandbox(options) {
49
+ const { gate, runId, model } = options;
50
+ const base = options.doc;
51
+ let state = createStudioState(base);
52
+ const linter = createLinter(options.lint);
53
+ let current = linter.lint(base).diagnostics;
54
+ const batches = [];
55
+ const unresolved = [];
56
+ const handles = createHandleTable(runId);
57
+ let batchCounter = 0;
58
+ let unresolvedCounter = 0;
59
+ return {
60
+ base,
61
+ get doc() { return state.doc; },
62
+ get batches() { return batches; },
63
+ get unresolved() { return unresolved; },
64
+ handles,
65
+ diagnostics: () => current,
66
+ apply(rawOps, meta) {
67
+ const fidelity = rawOps.findIndex((op) => typeof op === 'object' && op !== null && FIDELITY_KINDS.has(String(op.kind)));
68
+ if (fidelity >= 0) {
69
+ return { applied: false, refusals: [{ code: 'AGENT-OP-001', path: `ops[${fidelity}].kind`, candidates: [],
70
+ message: 'restore/patch ops are emitted by undo only; use the authoring ops (spec.add, facet.add, value.set, …).' }] };
71
+ }
72
+ const guarded = guardOps(rawOps, options.opGuard);
73
+ if (guarded)
74
+ return { applied: false, refusals: [guarded] };
75
+ const ops = handles.resolve(rawOps);
76
+ const gateResult = checkOps(ops, state.doc, gate);
77
+ if (!gateResult.ok)
78
+ return { applied: false, refusals: gateResult.issues.map(refusalOf) };
79
+ const before = state.doc;
80
+ let touched;
81
+ try {
82
+ // The gate passed `ops`, so they are well-formed `StudioOp`s.
83
+ const committed = commit(state, ops, { source: { by: 'ai', runId, model } });
84
+ state = committed.state;
85
+ touched = committed.result.touched;
86
+ }
87
+ catch (error) {
88
+ const message = error instanceof Error ? error.message : String(error);
89
+ return { applied: false, refusals: [{ code: 'AGENT-APPLY-001', path: 'ops', message, candidates: [] }] };
90
+ }
91
+ const previous = new Set(current.map(diagnosticId));
92
+ const next = linter.lint(state.doc, { touched }).diagnostics;
93
+ const nextIds = new Set(next.map(diagnosticId));
94
+ const added = next.filter((d) => !previous.has(diagnosticId(d))).map(brief);
95
+ const resolved = [...previous].filter((id) => !nextIds.has(id)).length;
96
+ current = next;
97
+ const batch = {
98
+ id: `b${++batchCounter}`, origin: meta.origin, ops: ops,
99
+ ...(meta.rationale ? { rationale: meta.rationale } : {}),
100
+ sources: meta.sources ?? [], specIds: specIdsFor(touched, before, state.doc),
101
+ ...(meta.fix ? { fix: meta.fix } : {}),
102
+ };
103
+ batches.push(batch);
104
+ const used = Object.fromEntries([...handles.handles].filter(([handle]) => JSON.stringify(rawOps).includes(`"${handle}"`)));
105
+ return { applied: true, batch, added, resolved, handles: used };
106
+ },
107
+ undo(steps) {
108
+ let undone = 0;
109
+ while (undone < steps && batches.length > 0) {
110
+ state = undoState(state);
111
+ batches.pop();
112
+ undone += 1;
113
+ }
114
+ if (undone > 0)
115
+ current = linter.lint(state.doc).diagnostics;
116
+ return undone;
117
+ },
118
+ markUnresolved(entry) {
119
+ const item = { id: `u${++unresolvedCounter}`, ...entry };
120
+ unresolved.push(item);
121
+ return item;
122
+ },
123
+ };
124
+ }
125
+ //# sourceMappingURL=sandbox.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sandbox.js","sourceRoot":"","sources":["../../src/sandbox/sandbox.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ import type { BsddClassCard, BsddClient, BsddPropertyCard, ModelBridge } from '../bridges.js';
2
+ export interface FakeElement {
3
+ /** PascalCase class. */
4
+ entity: string;
5
+ /** `Pset.Property` → value. */
6
+ properties?: Record<string, string>;
7
+ }
8
+ /** A `ModelBridge` over a list of fake elements, recording every call. */
9
+ export declare function createFakeModelBridge(elements: readonly FakeElement[], schema?: string): ModelBridge & {
10
+ calls: string[];
11
+ };
12
+ export interface FakeBsddRecord {
13
+ card: BsddClassCard;
14
+ properties: BsddPropertyCard[];
15
+ }
16
+ /** A `BsddClient` answering from recorded class records, recording every request. */
17
+ export declare function createFakeBsddClient(records: readonly FakeBsddRecord[]): BsddClient & {
18
+ requests: string[];
19
+ };
20
+ //# sourceMappingURL=doubles.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doubles.d.ts","sourceRoot":"","sources":["../../src/testing/doubles.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EACV,aAAa,EACb,UAAU,EACV,gBAAgB,EAMhB,WAAW,EAEZ,MAAM,eAAe,CAAC;AAEvB,MAAM,WAAW,WAAW;IAC1B,wBAAwB;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,+BAA+B;IAC/B,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACrC;AAiBD,0EAA0E;AAC1E,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,SAAS,WAAW,EAAE,EAAE,MAAM,SAAS,GAAG,WAAW,GAAG;IAAE,KAAK,EAAE,MAAM,EAAE,CAAA;CAAE,CAsD1H;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,aAAa,CAAC;IACpB,UAAU,EAAE,gBAAgB,EAAE,CAAC;CAChC;AAED,qFAAqF;AACrF,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,SAAS,cAAc,EAAE,GAAG,UAAU,GAAG;IAAE,QAAQ,EAAE,MAAM,EAAE,CAAA;CAAE,CAwB5G"}
@@ -0,0 +1,105 @@
1
+ /* This Source Code Form is subject to the terms of the Mozilla Public
2
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
3
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
+ function literal(constraint) {
5
+ const c = constraint;
6
+ return c?.type === 'simpleValue' && typeof c.value === 'string' ? c.value : undefined;
7
+ }
8
+ /** A crude facet matcher over fake elements: entity names and literal property names only. */
9
+ function matches(element, facet) {
10
+ if (facet.type === 'entity')
11
+ return literal(facet.name)?.toUpperCase() === element.entity.toUpperCase();
12
+ if (facet.type === 'property') {
13
+ const key = `${literal(facet.propertySet)}.${literal(facet.baseName)}`;
14
+ return element.properties?.[key] !== undefined;
15
+ }
16
+ return true;
17
+ }
18
+ /** A `ModelBridge` over a list of fake elements, recording every call. */
19
+ export function createFakeModelBridge(elements, schema = 'IFC4') {
20
+ const calls = [];
21
+ const classes = () => {
22
+ const counts = new Map();
23
+ for (const e of elements)
24
+ counts.set(e.entity, (counts.get(e.entity) ?? 0) + 1);
25
+ return [...counts].map(([name, count]) => ({ name, count })).sort((a, b) => b.count - a.count || a.name.localeCompare(b.name));
26
+ };
27
+ return {
28
+ calls,
29
+ async stats() {
30
+ calls.push('stats');
31
+ return [{ id: 'model-1', schema, elementCount: elements.length, classes: classes(), lengthUnit: 'METRE' }];
32
+ },
33
+ async count(query) {
34
+ calls.push('count');
35
+ let set = [...elements];
36
+ const stages = [{ facetIndex: -1, count: set.length }];
37
+ query.applicability.forEach((f, i) => { set = set.filter((e) => matches(e, f)); stages.push({ facetIndex: i, count: set.length }); });
38
+ const passing = query.requirements ? set.filter((e) => query.requirements?.every((f) => matches(e, f))).length : undefined;
39
+ return { stages, applicable: set.length, ...(passing !== undefined ? { passing, failing: set.length - passing } : {}) };
40
+ },
41
+ async distinctValues(query) {
42
+ calls.push('distinctValues');
43
+ const counts = new Map();
44
+ for (const e of elements) {
45
+ if (query.entity && e.entity.toUpperCase() !== query.entity.toUpperCase())
46
+ continue;
47
+ const v = e.properties?.[`${query.propertySet}.${query.property}`];
48
+ if (v !== undefined)
49
+ counts.set(v, (counts.get(v) ?? 0) + 1);
50
+ }
51
+ const values = [...counts].map(([value, count]) => ({ value, count })).sort((a, b) => b.count - a.count);
52
+ return { values: values.slice(0, query.limit), truncated: values.length > query.limit };
53
+ },
54
+ async infer(query) {
55
+ calls.push('infer');
56
+ const examples = elements.filter((e) => !query.entity || e.entity.toUpperCase() === query.entity.toUpperCase());
57
+ const keys = new Set(examples.flatMap((e) => Object.keys(e.properties ?? {})));
58
+ return {
59
+ sampled: false,
60
+ candidates: [...keys].map((key) => {
61
+ const [pset, prop] = key.split('.');
62
+ const matched = examples.filter((e) => e.properties?.[key] !== undefined).length;
63
+ return { section: 'requirements', positives: { matched, total: examples.length },
64
+ facet: { type: 'property', propertySet: { type: 'simpleValue', value: pset }, baseName: { type: 'simpleValue', value: prop } } };
65
+ }).filter((c) => c.positives.matched / Math.max(1, c.positives.total) >= query.threshold),
66
+ };
67
+ },
68
+ async coverage(query) {
69
+ calls.push('coverage');
70
+ const governed = (e) => query.applicabilities.some((facets) => facets.length > 0 && facets.every((f) => matches(e, f)));
71
+ const counts = new Map();
72
+ for (const e of elements)
73
+ if (!governed(e))
74
+ counts.set(e.entity, (counts.get(e.entity) ?? 0) + 1);
75
+ return [...counts].map(([name, count]) => ({ name, count })).sort((a, b) => b.count - a.count);
76
+ },
77
+ };
78
+ }
79
+ /** A `BsddClient` answering from recorded class records, recording every request. */
80
+ export function createFakeBsddClient(records) {
81
+ const requests = [];
82
+ const byUri = new Map(records.map((r) => [r.card.uri, r]));
83
+ return {
84
+ requests,
85
+ async search(query) {
86
+ requests.push(`search:${query.text}`);
87
+ const text = query.text.toLowerCase();
88
+ return records
89
+ .filter((r) => (r.card.name.toLowerCase().includes(text) || r.card.code.toLowerCase().includes(text))
90
+ && (!query.dictionaryUri || r.card.dictionaryUri === query.dictionaryUri)
91
+ && (!query.relatedIfcEntity || (r.card.relatedIfcEntities ?? []).includes(query.relatedIfcEntity)))
92
+ .slice(0, query.limit)
93
+ .map(({ card }) => ({ uri: card.uri, code: card.code, name: card.name, dictionaryUri: card.dictionaryUri,
94
+ ...(card.relatedIfcEntities ? { relatedIfcEntities: card.relatedIfcEntities } : {}) }));
95
+ },
96
+ async getClass(uri) { requests.push(`class:${uri}`); return byUri.get(uri)?.card ?? null; },
97
+ async classProperties(uri) { requests.push(`properties:${uri}`); return byUri.get(uri)?.properties ?? []; },
98
+ async resolveUri(uri) {
99
+ requests.push(`resolve:${uri}`);
100
+ const record = byUri.get(uri);
101
+ return record ? { kind: 'class', card: record.card } : { kind: 'unknown', uri };
102
+ },
103
+ };
104
+ }
105
+ //# sourceMappingURL=doubles.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doubles.js","sourceRoot":"","sources":["../../src/testing/doubles.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * `@ifc-lite/ids-agent/testing`: fake models, recorded transcripts and bridge
3
+ * doubles. Used by this package's tests and by the P-08 eval runner, which
4
+ * replays recorded transcripts in CI (no key, no network).
5
+ */
6
+ export { scriptedTransport, recordingTransport, replayTransport, parseTranscript, toolCall, turn, lastResults, type ScriptStep, type ScriptedTransport, type RecordedTranscript, } from './transports.js';
7
+ export { createFakeModelBridge, createFakeBsddClient, type FakeElement, type FakeBsddRecord } from './doubles.js';
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/testing/index.ts"],"names":[],"mappings":"AAIA;;;;GAIG;AAEH,OAAO,EACL,iBAAiB,EACjB,kBAAkB,EAClB,eAAe,EACf,eAAe,EACf,QAAQ,EACR,IAAI,EACJ,WAAW,EACX,KAAK,UAAU,EACf,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,GACxB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,KAAK,WAAW,EAAE,KAAK,cAAc,EAAE,MAAM,cAAc,CAAC"}
@@ -0,0 +1,11 @@
1
+ /* This Source Code Form is subject to the terms of the Mozilla Public
2
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
3
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
+ /**
5
+ * `@ifc-lite/ids-agent/testing`: fake models, recorded transcripts and bridge
6
+ * doubles. Used by this package's tests and by the P-08 eval runner, which
7
+ * replays recorded transcripts in CI (no key, no network).
8
+ */
9
+ export { scriptedTransport, recordingTransport, replayTransport, parseTranscript, toolCall, turn, lastResults, } from './transports.js';
10
+ export { createFakeModelBridge, createFakeBsddClient } from './doubles.js';
11
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/testing/index.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAE/D;;;;GAIG;AAEH,OAAO,EACL,iBAAiB,EACjB,kBAAkB,EAClB,eAAe,EACf,eAAe,EACf,QAAQ,EACR,IAAI,EACJ,WAAW,GAIZ,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,qBAAqB,EAAE,oBAAoB,EAAyC,MAAM,cAAc,CAAC"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Model doubles for tests and for the P-08 eval runner: nothing here calls a
3
+ * provider.
4
+ *
5
+ * - `scriptedTransport`: plays turns written in the test, each a fixed turn
6
+ * or a function of what the agent sent (so a script can react to a gate
7
+ * rejection, as a real model would).
8
+ * - `recordingTransport` wraps a live transport and captures every turn as
9
+ * a `RecordedTranscript` (JSON, no credentials, no request bodies).
10
+ * - `replayTransport` plays a recorded transcript back deterministically, so
11
+ * CI replays orchestration without a key (`06-ai-agent.md` §9 harness).
12
+ */
13
+ import type { ContentBlock, ToolTurn, ToolTurnCall, ToolTurnStopReason, ToolTurnTransport } from '@ifc-lite/ai';
14
+ export type ScriptStep = ToolTurn | ((call: ToolTurnCall, index: number) => ToolTurn);
15
+ export interface ScriptedTransport {
16
+ transport: ToolTurnTransport;
17
+ /** Every call the agent made, in order. */
18
+ calls: ToolTurnCall[];
19
+ }
20
+ export declare function scriptedTransport(steps: readonly ScriptStep[]): ScriptedTransport;
21
+ /** A tool call block. */
22
+ export declare function toolCall(name: string, input: unknown, id?: string): ContentBlock;
23
+ /** A turn; the stop reason defaults to `tool_use` when it calls a tool, else `end_turn`. */
24
+ export declare function turn(content: readonly ContentBlock[], stopReason?: ToolTurnStopReason, usage?: {
25
+ inputTokens: number;
26
+ outputTokens: number;
27
+ }): ToolTurn;
28
+ /** The tool results the agent sent in the latest message of a call. */
29
+ export declare function lastResults(call: ToolTurnCall): {
30
+ callId: string;
31
+ isError: boolean;
32
+ data: unknown;
33
+ }[];
34
+ export interface RecordedTranscript {
35
+ format: 'ids-agent-transcript';
36
+ version: 1;
37
+ /** The model the turns came from. */
38
+ model: string;
39
+ turns: ToolTurn[];
40
+ }
41
+ export declare function recordingTransport(inner: ToolTurnTransport): {
42
+ transport: ToolTurnTransport;
43
+ transcript(model: string): RecordedTranscript;
44
+ };
45
+ /** Validate a parsed transcript file. */
46
+ export declare function parseTranscript(value: unknown): RecordedTranscript;
47
+ export declare function replayTransport(transcript: RecordedTranscript): ToolTurnTransport;
48
+ //# sourceMappingURL=transports.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transports.d.ts","sourceRoot":"","sources":["../../src/testing/transports.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,YAAY,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAEhH,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,CAAC,CAAC,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,KAAK,QAAQ,CAAC,CAAC;AAEtF,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,iBAAiB,CAAC;IAC7B,2CAA2C;IAC3C,KAAK,EAAE,YAAY,EAAE,CAAC;CACvB;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,SAAS,UAAU,EAAE,GAAG,iBAAiB,CAcjF;AAID,yBAAyB;AACzB,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,SAA0B,GAAG,YAAY,CAEjG;AAED,4FAA4F;AAC5F,wBAAgB,IAAI,CAAC,OAAO,EAAE,SAAS,YAAY,EAAE,EAAE,UAAU,CAAC,EAAE,kBAAkB,EAAE,KAAK;;;CAAyC,GAAG,QAAQ,CAEhJ;AAED,uEAAuE;AACvE,wBAAgB,WAAW,CAAC,IAAI,EAAE,YAAY,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,OAAO,CAAA;CAAE,EAAE,CAIrG;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,sBAAsB,CAAC;IAC/B,OAAO,EAAE,CAAC,CAAC;IACX,qCAAqC;IACrC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,QAAQ,EAAE,CAAC;CACnB;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,iBAAiB,GAAG;IAAE,SAAS,EAAE,iBAAiB,CAAC;IAAC,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,kBAAkB,CAAA;CAAE,CAU5I;AAED,yCAAyC;AACzC,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,kBAAkB,CAMlE;AAED,wBAAgB,eAAe,CAAC,UAAU,EAAE,kBAAkB,GAAG,iBAAiB,CASjF"}
@@ -0,0 +1,70 @@
1
+ /* This Source Code Form is subject to the terms of the Mozilla Public
2
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
3
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
+ export function scriptedTransport(steps) {
5
+ const calls = [];
6
+ return {
7
+ calls,
8
+ transport: async (call) => {
9
+ const index = calls.length;
10
+ calls.push(call);
11
+ const step = steps[index];
12
+ if (!step)
13
+ throw new Error(`script exhausted after ${steps.length} turns`);
14
+ const turn = typeof step === 'function' ? step(call, index) : step;
15
+ for (const block of turn.content)
16
+ if (block.type === 'text')
17
+ call.onText(block.text);
18
+ return turn;
19
+ },
20
+ };
21
+ }
22
+ let callCounter = 0;
23
+ /** A tool call block. */
24
+ export function toolCall(name, input, id = `call-${++callCounter}`) {
25
+ return { type: 'tool_call', id, name, input };
26
+ }
27
+ /** A turn; the stop reason defaults to `tool_use` when it calls a tool, else `end_turn`. */
28
+ export function turn(content, stopReason, usage = { inputTokens: 100, outputTokens: 50 }) {
29
+ return { content, stopReason: stopReason ?? (content.some((b) => b.type === 'tool_call') ? 'tool_use' : 'end_turn'), usage };
30
+ }
31
+ /** The tool results the agent sent in the latest message of a call. */
32
+ export function lastResults(call) {
33
+ const last = call.messages[call.messages.length - 1];
34
+ if (!last || last.role !== 'tool')
35
+ return [];
36
+ return last.results.map((r) => ({ callId: r.callId, isError: r.isError, data: JSON.parse(r.content) }));
37
+ }
38
+ export function recordingTransport(inner) {
39
+ const turns = [];
40
+ return {
41
+ transport: async (call) => {
42
+ const result = await inner(call);
43
+ turns.push(structuredClone(result));
44
+ return result;
45
+ },
46
+ transcript: (model) => ({ format: 'ids-agent-transcript', version: 1, model, turns: structuredClone(turns) }),
47
+ };
48
+ }
49
+ /** Validate a parsed transcript file. */
50
+ export function parseTranscript(value) {
51
+ const v = value;
52
+ if (!v || v.format !== 'ids-agent-transcript' || v.version !== 1 || !Array.isArray(v.turns) || typeof v.model !== 'string') {
53
+ throw new Error('Not an ids-agent transcript (format "ids-agent-transcript", version 1).');
54
+ }
55
+ return v;
56
+ }
57
+ export function replayTransport(transcript) {
58
+ let index = 0;
59
+ return async (call) => {
60
+ const recorded = transcript.turns[index++];
61
+ if (!recorded)
62
+ throw new Error(`transcript exhausted after ${transcript.turns.length} turns`);
63
+ const result = structuredClone(recorded);
64
+ for (const block of result.content)
65
+ if (block.type === 'text')
66
+ call.onText(block.text);
67
+ return result;
68
+ };
69
+ }
70
+ //# sourceMappingURL=transports.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transports.js","sourceRoot":"","sources":["../../src/testing/transports.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Act tools (`06-ai-agent.md` §5). `ids_apply_ops` is the ONLY way the agent
3
+ * changes the document, and it goes through the sandbox: grounding gate,
4
+ * then reducer, then lint. `ids_apply_fix` and an `ids_ask_user` answer
5
+ * reuse the same path, so there is no second write path to audit.
6
+ */
7
+ import type { ApplyOutcome } from '../sandbox/sandbox.js';
8
+ import { type IdsAgentTool } from './context.js';
9
+ import { type ToolOutcome } from './registry.js';
10
+ /** Turn a sandbox outcome into the tool result the model reads. */
11
+ export declare function applyResult(outcome: ApplyOutcome, what: string): ToolOutcome;
12
+ export declare const ACT_TOOLS: readonly IdsAgentTool[];
13
+ //# sourceMappingURL=act-tools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"act-tools.d.ts","sourceRoot":"","sources":["../../src/tools/act-tools.ts"],"names":[],"mappings":"AAIA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAmC,MAAM,uBAAuB,CAAC;AAG3F,OAAO,EAAuC,KAAK,YAAY,EAAE,MAAM,cAAc,CAAC;AAEtF,OAAO,EAAgC,KAAK,WAAW,EAAE,MAAM,eAAe,CAAC;AAU/E,mEAAmE;AACnE,wBAAgB,WAAW,CAAC,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,GAAG,WAAW,CAa5E;AA0FD,eAAO,MAAM,SAAS,EAAE,SAAS,YAAY,EAAqD,CAAC"}
@@ -0,0 +1,115 @@
1
+ /* This Source Code Form is subject to the terms of the Mozilla Public
2
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
3
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
+ import { brief } from '../sandbox/sandbox.js';
5
+ import { diagnosticId } from '../sandbox/nodes.js';
6
+ import { objectSchema } from './context.js';
7
+ import { agentOpSchema } from './op-schema.js';
8
+ import { defineTool, failure, success } from './registry.js';
9
+ const sourceSchema = objectSchema({
10
+ opIndex: { type: 'integer', minimum: 0, description: 'The op of this batch the quote supports; omit for the whole batch.' },
11
+ docRef: { type: 'string' },
12
+ quote: { type: 'string', minLength: 1, description: 'The source sentence or cell, verbatim.' },
13
+ page: { type: 'integer', minimum: 1 },
14
+ }, ['quote']);
15
+ /** Turn a sandbox outcome into the tool result the model reads. */
16
+ export function applyResult(outcome, what) {
17
+ if (!outcome.applied) {
18
+ return failure(`${what}: refused (${outcome.refusals.map((r) => r.code).join(', ')})`, {
19
+ applied: false,
20
+ error: 'The batch was not applied; nothing changed. Fix every issue and send the whole batch again. Pick names from "candidates" or look them up with the schema_ tools.',
21
+ issues: outcome.refusals,
22
+ }, outcome.refusals.map((r) => `${r.code}:${r.value ?? r.path}`));
23
+ }
24
+ return success(`${what}: applied ${outcome.batch.ops.length} ops as ${outcome.batch.id}`, {
25
+ applied: true, batchId: outcome.batch.id, specIds: outcome.batch.specIds,
26
+ ...(Object.keys(outcome.handles).length ? { handles: outcome.handles } : {}),
27
+ diagnostics: { added: outcome.added.slice(0, 20), addedCount: outcome.added.length, resolvedCount: outcome.resolved },
28
+ });
29
+ }
30
+ const applyOps = defineTool({
31
+ name: 'ids_apply_ops', group: 'ids', strict: false, readOnly: false,
32
+ description: [
33
+ 'Apply a batch of IDS operations to the working document. The batch is checked by the grounding gate first and applied all or nothing.',
34
+ 'Every IFC entity, predefined type, attribute, property set, property, data type and enumeration value must come from a schema_ or bsdd_ lookup in this run.',
35
+ 'A rejected batch returns issues with ranked candidates; nothing is applied.',
36
+ 'Name nodes you create with handles such as "@doors" (specId, facetId) and reuse the handle in later ops; opId may be omitted.',
37
+ 'Prefer one batch per specification. Attach the source sentence for each requirement in "sources".',
38
+ ].join(' '),
39
+ inputSchema: {
40
+ type: 'object',
41
+ properties: {
42
+ ops: { type: 'array', items: agentOpSchema().op, minItems: 1 },
43
+ rationale: { type: 'string', description: 'Why, and any assumption made.' },
44
+ sources: { type: 'array', items: sourceSchema },
45
+ },
46
+ required: ['ops'],
47
+ additionalProperties: false,
48
+ },
49
+ defs: agentOpSchema().defs,
50
+ run(input, ctx) {
51
+ const outcome = ctx.sandbox.apply(input.ops, {
52
+ origin: 'apply_ops', ...(input.rationale ? { rationale: input.rationale } : {}), sources: input.sources ?? [],
53
+ });
54
+ return applyResult(outcome, 'apply_ops');
55
+ },
56
+ });
57
+ const undo = defineTool({
58
+ name: 'ids_undo', group: 'ids', strict: true, readOnly: false,
59
+ description: 'Undo the latest applied batches of this run (each batch is one step).',
60
+ inputSchema: objectSchema({ steps: { type: 'integer', minimum: 1 } }, ['steps']),
61
+ run(input, ctx) {
62
+ const undone = ctx.sandbox.undo(input.steps);
63
+ return success(`undid ${undone} batches`, { undone, remainingBatches: ctx.sandbox.batches.length });
64
+ },
65
+ });
66
+ const lint = defineTool({
67
+ name: 'ids_lint', group: 'ids', strict: true, readOnly: true,
68
+ description: 'Lint the working document. Returns diagnostics with a stable diagnosticId and the labels of the quick fixes each offers (apply one with ids_apply_fix).',
69
+ inputSchema: objectSchema({ specIds: { type: 'array', items: { type: 'string' } } }, []),
70
+ run(input, ctx) {
71
+ const wanted = input.specIds && input.specIds.length > 0 ? new Set(input.specIds) : null;
72
+ const all = ctx.sandbox.diagnostics().filter((d) => !wanted || (d.specId !== undefined && wanted.has(d.specId)));
73
+ const order = { error: 0, warning: 1, info: 2 };
74
+ const sorted = [...all].sort((a, b) => order[a.severity] - order[b.severity]);
75
+ return success(`${all.length} diagnostics`, {
76
+ count: all.length,
77
+ errors: all.filter((d) => d.severity === 'error').length,
78
+ diagnostics: sorted.slice(0, 40).map(brief),
79
+ });
80
+ },
81
+ });
82
+ const applyFix = defineTool({
83
+ name: 'ids_apply_fix', group: 'ids', strict: true, readOnly: false,
84
+ description: 'Apply one quick fix of a current diagnostic (diagnosticId from ids_lint or an apply result; fixIndex 0 is the first fix). Goes through the gate like ids_apply_ops.',
85
+ inputSchema: objectSchema({ diagnosticId: { type: 'string', minLength: 1 }, fixIndex: { type: 'integer', minimum: 0 } }, ['diagnosticId', 'fixIndex']),
86
+ run(input, ctx) {
87
+ const d = ctx.sandbox.diagnostics().find((x) => diagnosticId(x) === input.diagnosticId);
88
+ if (!d)
89
+ return failure('unknown diagnostic', { error: `No current diagnostic has id "${input.diagnosticId}". Call ids_lint.` }, [`FIX:${input.diagnosticId}`]);
90
+ const fix = d.fixes?.[input.fixIndex];
91
+ if (!fix)
92
+ return failure('no such fix', { error: `${d.code} offers ${d.fixes?.length ?? 0} fixes.` }, [`FIX:${input.diagnosticId}:${input.fixIndex}`]);
93
+ const outcome = ctx.sandbox.apply(fix.ops, { origin: 'apply_fix', rationale: fix.label, sources: [], fix: { code: d.code, diagnosticId: input.diagnosticId } });
94
+ return applyResult(outcome, `fix ${d.code}`);
95
+ },
96
+ });
97
+ const CATEGORIES = ['geometry', 'relationship', 'rules-engine', 'manual', 'ambiguous', 'out-of-scope'];
98
+ const markUnresolved = defineTool({
99
+ name: 'ids_mark_unresolved', group: 'ids', strict: true, readOnly: false,
100
+ description: 'Record a requirement statement the IDS cannot express (geometry, relationships, counts or uniqueness belong to a rules engine), or that stays ambiguous, with the reason. Every statement must end up as ops or as unresolved.',
101
+ inputSchema: objectSchema({
102
+ statement: { type: 'string', minLength: 1 },
103
+ category: { enum: CATEGORIES },
104
+ reason: { type: 'string', minLength: 1 },
105
+ source: sourceSchema,
106
+ }, ['statement', 'category', 'reason']),
107
+ run(input, ctx) {
108
+ const item = ctx.sandbox.markUnresolved({
109
+ statement: input.statement, category: input.category, reason: input.reason, ...(input.source ? { source: input.source } : {}),
110
+ });
111
+ return success(`unresolved ${item.id} (${item.category})`, { id: item.id, unresolvedCount: ctx.sandbox.unresolved.length });
112
+ },
113
+ });
114
+ export const ACT_TOOLS = [applyOps, undo, lint, applyFix, markUnresolved];
115
+ //# sourceMappingURL=act-tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"act-tools.js","sourceRoot":"","sources":["../../src/tools/act-tools.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { type IdsAgentTool } from './context.js';
2
+ export declare const ASK_USER_TOOLS: readonly IdsAgentTool[];
3
+ //# sourceMappingURL=ask-user.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ask-user.d.ts","sourceRoot":"","sources":["../../src/tools/ask-user.ts"],"names":[],"mappings":"AAcA,OAAO,EAAuC,KAAK,YAAY,EAAE,MAAM,cAAc,CAAC;AAmDtF,eAAO,MAAM,cAAc,EAAE,SAAS,YAAY,EAAc,CAAC"}