iranti 0.2.51 → 0.3.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.
- package/README.md +30 -17
- package/dist/scripts/api-key-create.js +1 -1
- package/dist/scripts/api-key-list.js +1 -1
- package/dist/scripts/api-key-revoke.js +1 -1
- package/dist/scripts/claude-code-memory-hook.js +116 -30
- package/dist/scripts/codex-setup.js +86 -4
- package/dist/scripts/iranti-cli.js +1359 -57
- package/dist/scripts/iranti-mcp.js +578 -75
- package/dist/scripts/seed.js +11 -6
- package/dist/scripts/setup.js +1 -1
- package/dist/src/api/healthChecks.d.ts +29 -0
- package/dist/src/api/healthChecks.d.ts.map +1 -0
- package/dist/src/api/healthChecks.js +72 -0
- package/dist/src/api/healthChecks.js.map +1 -0
- package/dist/src/api/middleware/validation.d.ts +22 -0
- package/dist/src/api/middleware/validation.d.ts.map +1 -1
- package/dist/src/api/middleware/validation.js +93 -3
- package/dist/src/api/middleware/validation.js.map +1 -1
- package/dist/src/api/routes/knowledge.d.ts.map +1 -1
- package/dist/src/api/routes/knowledge.js +53 -0
- package/dist/src/api/routes/knowledge.js.map +1 -1
- package/dist/src/api/routes/memory.d.ts.map +1 -1
- package/dist/src/api/routes/memory.js +73 -9
- package/dist/src/api/routes/memory.js.map +1 -1
- package/dist/src/api/server.js +38 -43
- package/dist/src/api/server.js.map +1 -1
- package/dist/src/attendant/AttendantInstance.d.ts +135 -2
- package/dist/src/attendant/AttendantInstance.d.ts.map +1 -1
- package/dist/src/attendant/AttendantInstance.js +1836 -93
- package/dist/src/attendant/AttendantInstance.js.map +1 -1
- package/dist/src/attendant/index.d.ts +1 -1
- package/dist/src/attendant/index.d.ts.map +1 -1
- package/dist/src/attendant/index.js +1 -1
- package/dist/src/attendant/index.js.map +1 -1
- package/dist/src/attendant/registry.d.ts.map +1 -1
- package/dist/src/attendant/registry.js +2 -0
- package/dist/src/attendant/registry.js.map +1 -1
- package/dist/src/chat/index.d.ts +23 -0
- package/dist/src/chat/index.d.ts.map +1 -1
- package/dist/src/chat/index.js +111 -22
- package/dist/src/chat/index.js.map +1 -1
- package/dist/src/generated/prisma/browser.d.ts +5 -0
- package/dist/src/generated/prisma/browser.d.ts.map +1 -1
- package/dist/src/generated/prisma/client.d.ts +5 -0
- package/dist/src/generated/prisma/client.d.ts.map +1 -1
- package/dist/src/generated/prisma/commonInputTypes.d.ts +48 -0
- package/dist/src/generated/prisma/commonInputTypes.d.ts.map +1 -1
- package/dist/src/generated/prisma/internal/class.d.ts +11 -0
- package/dist/src/generated/prisma/internal/class.d.ts.map +1 -1
- package/dist/src/generated/prisma/internal/class.js +4 -4
- package/dist/src/generated/prisma/internal/class.js.map +1 -1
- package/dist/src/generated/prisma/internal/prismaNamespace.d.ts +92 -1
- package/dist/src/generated/prisma/internal/prismaNamespace.d.ts.map +1 -1
- package/dist/src/generated/prisma/internal/prismaNamespace.js +17 -2
- package/dist/src/generated/prisma/internal/prismaNamespace.js.map +1 -1
- package/dist/src/generated/prisma/internal/prismaNamespaceBrowser.d.ts +16 -0
- package/dist/src/generated/prisma/internal/prismaNamespaceBrowser.d.ts.map +1 -1
- package/dist/src/generated/prisma/internal/prismaNamespaceBrowser.js +17 -2
- package/dist/src/generated/prisma/internal/prismaNamespaceBrowser.js.map +1 -1
- package/dist/src/generated/prisma/models/StaffEvent.d.ts +1184 -0
- package/dist/src/generated/prisma/models/StaffEvent.d.ts.map +1 -0
- package/dist/src/generated/prisma/models/StaffEvent.js +3 -0
- package/dist/src/generated/prisma/models/StaffEvent.js.map +1 -0
- package/dist/src/generated/prisma/models.d.ts +1 -0
- package/dist/src/generated/prisma/models.d.ts.map +1 -1
- package/dist/src/lib/assistantCheckpoint.d.ts +21 -0
- package/dist/src/lib/assistantCheckpoint.d.ts.map +1 -0
- package/dist/src/lib/assistantCheckpoint.js +143 -0
- package/dist/src/lib/assistantCheckpoint.js.map +1 -0
- package/dist/src/lib/autoRemember.d.ts +15 -0
- package/dist/src/lib/autoRemember.d.ts.map +1 -1
- package/dist/src/lib/autoRemember.js +433 -71
- package/dist/src/lib/autoRemember.js.map +1 -1
- package/dist/src/lib/cliHelpCatalog.d.ts.map +1 -1
- package/dist/src/lib/cliHelpCatalog.js +23 -11
- package/dist/src/lib/cliHelpCatalog.js.map +1 -1
- package/dist/src/lib/cliHelpRenderer.d.ts +1 -0
- package/dist/src/lib/cliHelpRenderer.d.ts.map +1 -1
- package/dist/src/lib/cliHelpRenderer.js +4 -0
- package/dist/src/lib/cliHelpRenderer.js.map +1 -1
- package/dist/src/lib/commandErrors.d.ts +5 -1
- package/dist/src/lib/commandErrors.d.ts.map +1 -1
- package/dist/src/lib/commandErrors.js +250 -17
- package/dist/src/lib/commandErrors.js.map +1 -1
- package/dist/src/lib/createFirstPartyIranti.d.ts.map +1 -1
- package/dist/src/lib/createFirstPartyIranti.js +1 -0
- package/dist/src/lib/createFirstPartyIranti.js.map +1 -1
- package/dist/src/lib/dbStaffEventEmitter.d.ts +2 -0
- package/dist/src/lib/dbStaffEventEmitter.d.ts.map +1 -1
- package/dist/src/lib/dbStaffEventEmitter.js +15 -0
- package/dist/src/lib/dbStaffEventEmitter.js.map +1 -1
- package/dist/src/lib/hostMemoryFormatting.d.ts +25 -0
- package/dist/src/lib/hostMemoryFormatting.d.ts.map +1 -0
- package/dist/src/lib/hostMemoryFormatting.js +55 -0
- package/dist/src/lib/hostMemoryFormatting.js.map +1 -0
- package/dist/src/lib/issueFacts.d.ts +37 -0
- package/dist/src/lib/issueFacts.d.ts.map +1 -0
- package/dist/src/lib/issueFacts.js +72 -0
- package/dist/src/lib/issueFacts.js.map +1 -0
- package/dist/src/lib/llm.d.ts +8 -0
- package/dist/src/lib/llm.d.ts.map +1 -1
- package/dist/src/lib/llm.js +33 -0
- package/dist/src/lib/llm.js.map +1 -1
- package/dist/src/lib/packageRoot.d.ts +2 -0
- package/dist/src/lib/packageRoot.d.ts.map +1 -0
- package/dist/src/lib/packageRoot.js +22 -0
- package/dist/src/lib/packageRoot.js.map +1 -0
- package/dist/src/lib/projectLearning.d.ts +21 -0
- package/dist/src/lib/projectLearning.d.ts.map +1 -0
- package/dist/src/lib/projectLearning.js +357 -0
- package/dist/src/lib/projectLearning.js.map +1 -0
- package/dist/src/lib/protocolEnforcement.d.ts +29 -0
- package/dist/src/lib/protocolEnforcement.d.ts.map +1 -0
- package/dist/src/lib/protocolEnforcement.js +124 -0
- package/dist/src/lib/protocolEnforcement.js.map +1 -0
- package/dist/src/lib/providers/claude.js +1 -1
- package/dist/src/lib/providers/claude.js.map +1 -1
- package/dist/src/lib/router.js +1 -1
- package/dist/src/lib/router.js.map +1 -1
- package/dist/src/lib/runtimeEnv.d.ts.map +1 -1
- package/dist/src/lib/runtimeEnv.js +8 -3
- package/dist/src/lib/runtimeEnv.js.map +1 -1
- package/dist/src/lib/scaffoldCloseout.d.ts +27 -0
- package/dist/src/lib/scaffoldCloseout.d.ts.map +1 -0
- package/dist/src/lib/scaffoldCloseout.js +139 -0
- package/dist/src/lib/scaffoldCloseout.js.map +1 -0
- package/dist/src/lib/semanticFactTags.d.ts +10 -0
- package/dist/src/lib/semanticFactTags.d.ts.map +1 -0
- package/dist/src/lib/semanticFactTags.js +166 -0
- package/dist/src/lib/semanticFactTags.js.map +1 -0
- package/dist/src/lib/sessionLedger.d.ts +94 -0
- package/dist/src/lib/sessionLedger.d.ts.map +1 -0
- package/dist/src/lib/sessionLedger.js +997 -0
- package/dist/src/lib/sessionLedger.js.map +1 -0
- package/dist/src/lib/sharedStateInvalidation.d.ts +10 -0
- package/dist/src/lib/sharedStateInvalidation.d.ts.map +1 -0
- package/dist/src/lib/sharedStateInvalidation.js +184 -0
- package/dist/src/lib/sharedStateInvalidation.js.map +1 -0
- package/dist/src/lib/staffEventsTable.d.ts +3 -0
- package/dist/src/lib/staffEventsTable.d.ts.map +1 -0
- package/dist/src/lib/staffEventsTable.js +58 -0
- package/dist/src/lib/staffEventsTable.js.map +1 -0
- package/dist/src/librarian/index.d.ts.map +1 -1
- package/dist/src/librarian/index.js +113 -2
- package/dist/src/librarian/index.js.map +1 -1
- package/dist/src/library/client.d.ts +6 -1
- package/dist/src/library/client.d.ts.map +1 -1
- package/dist/src/library/client.js +21 -7
- package/dist/src/library/client.js.map +1 -1
- package/dist/src/library/embeddings.d.ts +9 -1
- package/dist/src/library/embeddings.d.ts.map +1 -1
- package/dist/src/library/embeddings.js +28 -3
- package/dist/src/library/embeddings.js.map +1 -1
- package/dist/src/library/queries.d.ts.map +1 -1
- package/dist/src/library/queries.js +263 -46
- package/dist/src/library/queries.js.map +1 -1
- package/dist/src/sdk/index.d.ts +52 -1
- package/dist/src/sdk/index.d.ts.map +1 -1
- package/dist/src/sdk/index.js +546 -98
- package/dist/src/sdk/index.js.map +1 -1
- package/package.json +24 -3
- package/prisma/migrations/20260331101500_add_staff_events_ledger/migration.sql +24 -0
- package/prisma/schema.prisma +22 -0
package/dist/src/sdk/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.resetStaffEventEmitter = exports.getStaffEventEmitter = exports.setStaffEventEmitter = exports.buildStaffEvent = exports.NoopEventEmitter = exports.Iranti = void 0;
|
|
3
|
+
exports.resetStaffEventEmitter = exports.getStaffEventEmitter = exports.setStaffEventEmitter = exports.buildStaffEvent = exports.NoopEventEmitter = exports.Iranti = exports.ProtocolViolationError = void 0;
|
|
4
4
|
require("dotenv/config");
|
|
5
5
|
const client_1 = require("../library/client");
|
|
6
6
|
const staffEventEmitter_1 = require("../lib/staffEventEmitter");
|
|
@@ -19,8 +19,37 @@ const relationships_1 = require("../library/relationships");
|
|
|
19
19
|
const agent_registry_1 = require("../library/agent-registry");
|
|
20
20
|
const entity_resolution_1 = require("../library/entity-resolution");
|
|
21
21
|
const autoRemember_1 = require("../lib/autoRemember");
|
|
22
|
+
const issueFacts_1 = require("../lib/issueFacts");
|
|
22
23
|
const mock_1 = require("../lib/providers/mock");
|
|
24
|
+
const protocolEnforcement_1 = require("../lib/protocolEnforcement");
|
|
25
|
+
Object.defineProperty(exports, "ProtocolViolationError", { enumerable: true, get: function () { return protocolEnforcement_1.ProtocolViolationError; } });
|
|
23
26
|
const client_2 = require("../generated/prisma/client");
|
|
27
|
+
const sessionLedger_1 = require("../lib/sessionLedger");
|
|
28
|
+
function normalizeDbApplicationToken(value) {
|
|
29
|
+
const trimmed = value?.trim();
|
|
30
|
+
if (!trimmed)
|
|
31
|
+
return undefined;
|
|
32
|
+
const normalized = trimmed
|
|
33
|
+
.toLowerCase()
|
|
34
|
+
.replace(/[^a-z0-9:_-]+/g, '_')
|
|
35
|
+
.replace(/_+/g, '_')
|
|
36
|
+
.replace(/^_+|_+$/g, '');
|
|
37
|
+
return normalized || undefined;
|
|
38
|
+
}
|
|
39
|
+
function deriveDbApplicationName(config) {
|
|
40
|
+
const explicit = normalizeDbApplicationToken(config.dbApplicationName);
|
|
41
|
+
if (explicit) {
|
|
42
|
+
return explicit.slice(0, 63);
|
|
43
|
+
}
|
|
44
|
+
const source = normalizeDbApplicationToken(config.sessionLedgerSource);
|
|
45
|
+
const host = normalizeDbApplicationToken(config.sessionLedgerHost);
|
|
46
|
+
const agentId = normalizeDbApplicationToken(config.sessionLedgerAgentId);
|
|
47
|
+
const parts = ['iranti', source, host ?? agentId].filter((part) => Boolean(part));
|
|
48
|
+
if (parts.length === 1) {
|
|
49
|
+
return undefined;
|
|
50
|
+
}
|
|
51
|
+
return parts.join(':').slice(0, 63);
|
|
52
|
+
}
|
|
24
53
|
// ─── Entity Parsing ──────────────────────────────────────────────────────────
|
|
25
54
|
function parseEntity(entity) {
|
|
26
55
|
if (!entity || typeof entity !== 'string') {
|
|
@@ -143,11 +172,22 @@ function mapArchiveResult(result) {
|
|
|
143
172
|
class Iranti {
|
|
144
173
|
constructor(config = {}) {
|
|
145
174
|
this.config = config;
|
|
175
|
+
this.protocolTracker = new protocolEnforcement_1.AgentProtocolTracker();
|
|
176
|
+
this.sessionLedgerContext = {
|
|
177
|
+
source: config.sessionLedgerSource?.trim() || undefined,
|
|
178
|
+
host: typeof config.sessionLedgerHost === 'string'
|
|
179
|
+
? (config.sessionLedgerHost.trim() || null)
|
|
180
|
+
: (config.sessionLedgerHost ?? null),
|
|
181
|
+
agentId: config.sessionLedgerAgentId?.trim() || undefined,
|
|
182
|
+
};
|
|
146
183
|
const connectionString = config.connectionString ?? process.env.DATABASE_URL;
|
|
147
184
|
if (!connectionString) {
|
|
148
185
|
throw new Error('connectionString is required. Provide it in config or set DATABASE_URL environment variable.');
|
|
149
186
|
}
|
|
150
|
-
(0, client_1.initDb)(connectionString
|
|
187
|
+
(0, client_1.initDb)(connectionString, {
|
|
188
|
+
applicationName: deriveDbApplicationName(config),
|
|
189
|
+
max: config.dbPoolMax,
|
|
190
|
+
});
|
|
151
191
|
if (config.llmProvider) {
|
|
152
192
|
process.env.LLM_PROVIDER = config.llmProvider;
|
|
153
193
|
}
|
|
@@ -159,6 +199,107 @@ class Iranti {
|
|
|
159
199
|
(0, staffEventRegistry_1.setStaffEventEmitter)(config.staffEventEmitter);
|
|
160
200
|
}
|
|
161
201
|
}
|
|
202
|
+
protocolMode() {
|
|
203
|
+
return this.config.protocolEnforcement ?? 'off';
|
|
204
|
+
}
|
|
205
|
+
protocolAgentId() {
|
|
206
|
+
return this.sessionLedgerContext.agentId?.trim() || undefined;
|
|
207
|
+
}
|
|
208
|
+
checkProtocol(operation, requirements) {
|
|
209
|
+
const mode = this.protocolMode();
|
|
210
|
+
if (mode === 'off')
|
|
211
|
+
return;
|
|
212
|
+
const agentId = this.protocolAgentId();
|
|
213
|
+
if (!agentId)
|
|
214
|
+
return;
|
|
215
|
+
const violation = this.protocolTracker.check(agentId, operation, requirements);
|
|
216
|
+
if (!violation)
|
|
217
|
+
return;
|
|
218
|
+
if (mode === 'warn') {
|
|
219
|
+
this.emitLedgerEvent({
|
|
220
|
+
staffComponent: 'Attendant',
|
|
221
|
+
actionType: 'host_failure',
|
|
222
|
+
agentId,
|
|
223
|
+
source: 'sdk',
|
|
224
|
+
reason: violation.code,
|
|
225
|
+
level: 'audit',
|
|
226
|
+
metadata: {
|
|
227
|
+
operation,
|
|
228
|
+
protocolViolation: violation,
|
|
229
|
+
},
|
|
230
|
+
});
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
233
|
+
throw new protocolEnforcement_1.ProtocolViolationError(violation);
|
|
234
|
+
}
|
|
235
|
+
syncMemoryUseCompliance(agentId, compliance) {
|
|
236
|
+
const ignoredMemoryIssue = compliance?.issues.find((issue) => issue.code === 'ignored_injected_memory');
|
|
237
|
+
if (ignoredMemoryIssue?.severity === 'error') {
|
|
238
|
+
this.protocolTracker.markMemoryUseAcknowledgementRequired(agentId);
|
|
239
|
+
return;
|
|
240
|
+
}
|
|
241
|
+
this.protocolTracker.clearMemoryUseAcknowledgementRequired(agentId);
|
|
242
|
+
}
|
|
243
|
+
consumeDiscoveryBudget(operation) {
|
|
244
|
+
if (this.protocolMode() === 'off')
|
|
245
|
+
return;
|
|
246
|
+
const agentId = this.protocolAgentId();
|
|
247
|
+
if (!agentId)
|
|
248
|
+
return;
|
|
249
|
+
if (['query', 'history', 'queryAll', 'search', 'related', 'related_deep', 'who_knows'].includes(operation)) {
|
|
250
|
+
this.protocolTracker.notifyDiscoveryConsumed(agentId);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
setSessionLedgerContext(context) {
|
|
254
|
+
if ('source' in context) {
|
|
255
|
+
this.sessionLedgerContext.source = typeof context.source === 'string'
|
|
256
|
+
? (context.source.trim() || undefined)
|
|
257
|
+
: undefined;
|
|
258
|
+
}
|
|
259
|
+
if ('host' in context) {
|
|
260
|
+
this.sessionLedgerContext.host = typeof context.host === 'string'
|
|
261
|
+
? (context.host.trim() || null)
|
|
262
|
+
: (context.host ?? null);
|
|
263
|
+
}
|
|
264
|
+
if ('agentId' in context) {
|
|
265
|
+
this.sessionLedgerContext.agentId = typeof context.agentId === 'string'
|
|
266
|
+
? (context.agentId.trim() || undefined)
|
|
267
|
+
: undefined;
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
buildSessionLedgerContext() {
|
|
271
|
+
if (!this.sessionLedgerContext.source && !this.sessionLedgerContext.host && !this.sessionLedgerContext.agentId) {
|
|
272
|
+
return undefined;
|
|
273
|
+
}
|
|
274
|
+
return {
|
|
275
|
+
source: this.sessionLedgerContext.source,
|
|
276
|
+
host: this.sessionLedgerContext.host ?? null,
|
|
277
|
+
agentId: this.sessionLedgerContext.agentId,
|
|
278
|
+
};
|
|
279
|
+
}
|
|
280
|
+
emitLedgerEvent(event) {
|
|
281
|
+
const context = this.buildSessionLedgerContext();
|
|
282
|
+
const metadata = event.metadata && typeof event.metadata === 'object'
|
|
283
|
+
? { ...event.metadata }
|
|
284
|
+
: {};
|
|
285
|
+
if (context?.host) {
|
|
286
|
+
metadata.host = context.host;
|
|
287
|
+
}
|
|
288
|
+
(0, staffEventRegistry_1.getStaffEventEmitter)().emit({
|
|
289
|
+
...event,
|
|
290
|
+
agentId: context?.agentId && (!event.agentId || event.agentId === 'sdk')
|
|
291
|
+
? context.agentId
|
|
292
|
+
: event.agentId,
|
|
293
|
+
source: context?.source ?? event.source,
|
|
294
|
+
metadata,
|
|
295
|
+
});
|
|
296
|
+
}
|
|
297
|
+
async noteRediscoveryEvidence() {
|
|
298
|
+
const agentId = this.protocolAgentId();
|
|
299
|
+
if (!agentId)
|
|
300
|
+
return;
|
|
301
|
+
await (0, registry_1.getAttendant)(agentId).noteDiscoveryOccurred();
|
|
302
|
+
}
|
|
162
303
|
// ── Write ───────────────────────────────────────────────────────────────
|
|
163
304
|
async write(input) {
|
|
164
305
|
if (input.confidence < 0 || input.confidence > 100) {
|
|
@@ -186,7 +327,10 @@ class Iranti {
|
|
|
186
327
|
validFrom: input.validFrom,
|
|
187
328
|
validUntil: input.validUntil ?? undefined,
|
|
188
329
|
requestId: input.requestId,
|
|
330
|
+
properties: input.properties,
|
|
189
331
|
});
|
|
332
|
+
await (0, registry_1.getAttendant)(input.agent).notifyWriteOccurred();
|
|
333
|
+
this.protocolTracker.clearMemoryUseAcknowledgementRequired(input.agent);
|
|
190
334
|
return {
|
|
191
335
|
action: result.action,
|
|
192
336
|
key: input.key,
|
|
@@ -195,6 +339,9 @@ class Iranti {
|
|
|
195
339
|
inputEntity: input.entity,
|
|
196
340
|
};
|
|
197
341
|
}
|
|
342
|
+
async writeIssue(input) {
|
|
343
|
+
return this.write((0, issueFacts_1.buildIssueFactWrite)(input));
|
|
344
|
+
}
|
|
198
345
|
// ── Ingest ──────────────────────────────────────────────────────────────
|
|
199
346
|
async ingest(input) {
|
|
200
347
|
const { entityType, entityId } = parseEntity(input.entity);
|
|
@@ -206,6 +353,8 @@ class Iranti {
|
|
|
206
353
|
confidence: input.confidence,
|
|
207
354
|
createdBy: input.agent,
|
|
208
355
|
});
|
|
356
|
+
await (0, registry_1.getAttendant)(input.agent).notifyWriteOccurred();
|
|
357
|
+
this.protocolTracker.clearMemoryUseAcknowledgementRequired(input.agent);
|
|
209
358
|
return {
|
|
210
359
|
extractedCandidates: result.extractedCandidates,
|
|
211
360
|
written: result.written,
|
|
@@ -222,11 +371,16 @@ class Iranti {
|
|
|
222
371
|
}
|
|
223
372
|
// ── Handshake ───────────────────────────────────────────────────────────
|
|
224
373
|
async handshake(input) {
|
|
225
|
-
const
|
|
226
|
-
|
|
374
|
+
const agentId = resolveAgentId(input, 'handshake');
|
|
375
|
+
const attendant = (0, registry_1.getAttendant)(agentId);
|
|
376
|
+
const result = await attendant.handshake({
|
|
227
377
|
task: input.task,
|
|
228
378
|
recentMessages: input.recentMessages,
|
|
379
|
+
ledgerContext: this.buildSessionLedgerContext(),
|
|
229
380
|
});
|
|
381
|
+
this.protocolTracker.markHandshake(agentId);
|
|
382
|
+
this.syncMemoryUseCompliance(agentId, result.compliance);
|
|
383
|
+
return result;
|
|
230
384
|
}
|
|
231
385
|
// ── Reconvene ───────────────────────────────────────────────────────────
|
|
232
386
|
async reconvene(agentId, input) {
|
|
@@ -234,34 +388,42 @@ class Iranti {
|
|
|
234
388
|
return attendant.reconvene({
|
|
235
389
|
task: input.task,
|
|
236
390
|
recentMessages: input.recentMessages,
|
|
391
|
+
ledgerContext: this.buildSessionLedgerContext(),
|
|
237
392
|
});
|
|
238
393
|
}
|
|
239
394
|
async checkpoint(input) {
|
|
240
|
-
const
|
|
241
|
-
|
|
395
|
+
const agentId = resolveAgentId(input, 'checkpoint');
|
|
396
|
+
const attendant = (0, registry_1.getAttendant)(agentId);
|
|
397
|
+
const result = await attendant.checkpoint({
|
|
242
398
|
task: input.task,
|
|
243
399
|
recentMessages: input.recentMessages,
|
|
244
400
|
checkpoint: input.checkpoint,
|
|
245
401
|
sessionId: input.sessionId,
|
|
246
402
|
heartbeatAt: input.heartbeatAt,
|
|
403
|
+
ledgerContext: this.buildSessionLedgerContext(),
|
|
247
404
|
});
|
|
405
|
+
this.protocolTracker.clearMemoryUseAcknowledgementRequired(agentId);
|
|
406
|
+
return result;
|
|
248
407
|
}
|
|
249
408
|
async resumeSession(input) {
|
|
250
409
|
const attendant = (0, registry_1.getAttendant)(resolveAgentId(input, 'resumeSession'));
|
|
251
410
|
return attendant.resumeSession({
|
|
252
411
|
sessionId: input.sessionId,
|
|
412
|
+
ledgerContext: this.buildSessionLedgerContext(),
|
|
253
413
|
});
|
|
254
414
|
}
|
|
255
415
|
async completeSession(input) {
|
|
256
416
|
const attendant = (0, registry_1.getAttendant)(resolveAgentId(input, 'completeSession'));
|
|
257
417
|
return attendant.completeSession({
|
|
258
418
|
sessionId: input.sessionId,
|
|
419
|
+
ledgerContext: this.buildSessionLedgerContext(),
|
|
259
420
|
});
|
|
260
421
|
}
|
|
261
422
|
async abandonSession(input) {
|
|
262
423
|
const attendant = (0, registry_1.getAttendant)(resolveAgentId(input, 'abandonSession'));
|
|
263
424
|
return attendant.abandonSession({
|
|
264
425
|
sessionId: input.sessionId,
|
|
426
|
+
ledgerContext: this.buildSessionLedgerContext(),
|
|
265
427
|
});
|
|
266
428
|
}
|
|
267
429
|
async inspectSession(input) {
|
|
@@ -269,6 +431,7 @@ class Iranti {
|
|
|
269
431
|
return attendant.inspectSession({
|
|
270
432
|
task: input.task,
|
|
271
433
|
recentMessages: input.recentMessages,
|
|
434
|
+
ledgerContext: this.buildSessionLedgerContext(),
|
|
272
435
|
});
|
|
273
436
|
}
|
|
274
437
|
async listSessions(input = {}) {
|
|
@@ -279,7 +442,7 @@ class Iranti {
|
|
|
279
442
|
const checkpoint = raw?.sessionCheckpoint ?? null;
|
|
280
443
|
if (!checkpoint)
|
|
281
444
|
return null;
|
|
282
|
-
return (0, AttendantInstance_1.summarizeSessionState)(entry.entityId, checkpoint, typeof raw?.briefGeneratedAt === 'string' ? raw.briefGeneratedAt : undefined);
|
|
445
|
+
return (0, AttendantInstance_1.summarizeSessionState)(entry.entityId, checkpoint, typeof raw?.briefGeneratedAt === 'string' ? raw.briefGeneratedAt : undefined, raw?.compliance ?? null);
|
|
283
446
|
})
|
|
284
447
|
.filter((entry) => Boolean(entry));
|
|
285
448
|
if (input.operatorState) {
|
|
@@ -294,88 +457,203 @@ class Iranti {
|
|
|
294
457
|
}
|
|
295
458
|
return sessions;
|
|
296
459
|
}
|
|
460
|
+
async listSessionLedger(input = {}) {
|
|
461
|
+
return (0, sessionLedger_1.querySessionLedger)(input);
|
|
462
|
+
}
|
|
297
463
|
getAttendant(agentId) {
|
|
298
464
|
return (0, registry_1.getAttendant)(agentId);
|
|
299
465
|
}
|
|
300
466
|
// ── Query ───────────────────────────────────────────────────────────────
|
|
301
467
|
async query(entity, key, options = {}) {
|
|
468
|
+
this.checkProtocol('query', { handshake: true, attend: true });
|
|
302
469
|
const resolved = await resolveQueryEntity(entity);
|
|
303
470
|
const personalRecallCandidates = (isPersonalEntityString(entity) && (0, autoRemember_1.isPersonalMemoryKey)(key)
|
|
304
471
|
? (0, autoRemember_1.getPersonalRecallEntities)(entity)
|
|
305
472
|
: [])
|
|
306
473
|
.filter((candidate) => candidate !== resolved.canonicalEntity);
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
474
|
+
try {
|
|
475
|
+
if (options.asOf) {
|
|
476
|
+
const current = await (0, queries_1.findEntry)({ entityType: resolved.entityType, entityId: resolved.entityId, key });
|
|
477
|
+
const currentMatches = current && !current.isProtected && current.validFrom <= options.asOf;
|
|
478
|
+
if (currentMatches) {
|
|
479
|
+
this.consumeDiscoveryBudget('query');
|
|
480
|
+
await (0, queries_1.recordKnowledgeEntryAccess)([current.id]);
|
|
481
|
+
this.emitLedgerEvent({
|
|
482
|
+
staffComponent: 'Attendant',
|
|
483
|
+
actionType: 'query_executed',
|
|
484
|
+
agentId: 'sdk',
|
|
485
|
+
source: 'sdk',
|
|
486
|
+
entityType: resolved.entityType,
|
|
487
|
+
entityId: resolved.entityId,
|
|
488
|
+
key,
|
|
489
|
+
reason: 'query_exact_current',
|
|
490
|
+
level: 'audit',
|
|
491
|
+
metadata: {
|
|
492
|
+
found: true,
|
|
493
|
+
fromArchive: false,
|
|
494
|
+
asOf: options.asOf.toISOString(),
|
|
495
|
+
},
|
|
496
|
+
});
|
|
497
|
+
await this.noteRediscoveryEvidence();
|
|
498
|
+
return {
|
|
499
|
+
found: true,
|
|
500
|
+
value: current.valueRaw,
|
|
501
|
+
summary: current.valueSummary,
|
|
502
|
+
confidence: current.confidence,
|
|
503
|
+
source: current.source,
|
|
504
|
+
validFrom: current.validFrom,
|
|
505
|
+
validUntil: current.validUntil,
|
|
506
|
+
contested: false,
|
|
507
|
+
fromArchive: false,
|
|
508
|
+
archivedReason: null,
|
|
509
|
+
resolutionState: null,
|
|
510
|
+
resolutionOutcome: null,
|
|
511
|
+
resolvedEntity: resolved.canonicalEntity,
|
|
512
|
+
inputEntity: entity,
|
|
513
|
+
};
|
|
514
|
+
}
|
|
515
|
+
const historical = await (0, queries_1.findArchiveAsOf)({ entityType: resolved.entityType, entityId: resolved.entityId, key }, options.asOf, {
|
|
516
|
+
includeExpired: options.includeExpired,
|
|
517
|
+
includeContested: options.includeContested,
|
|
518
|
+
});
|
|
519
|
+
if (historical) {
|
|
520
|
+
this.consumeDiscoveryBudget('query');
|
|
521
|
+
this.emitLedgerEvent({
|
|
522
|
+
staffComponent: 'Attendant',
|
|
523
|
+
actionType: 'query_executed',
|
|
524
|
+
agentId: 'sdk',
|
|
525
|
+
source: 'sdk',
|
|
526
|
+
entityType: resolved.entityType,
|
|
527
|
+
entityId: resolved.entityId,
|
|
528
|
+
key,
|
|
529
|
+
reason: 'query_historical_match',
|
|
530
|
+
level: 'audit',
|
|
531
|
+
metadata: {
|
|
532
|
+
found: true,
|
|
533
|
+
fromArchive: true,
|
|
534
|
+
asOf: options.asOf.toISOString(),
|
|
535
|
+
},
|
|
536
|
+
});
|
|
537
|
+
await this.noteRediscoveryEvidence();
|
|
538
|
+
return {
|
|
539
|
+
found: true,
|
|
540
|
+
...mapArchiveResult(historical),
|
|
541
|
+
resolvedEntity: resolved.canonicalEntity,
|
|
542
|
+
inputEntity: entity,
|
|
543
|
+
};
|
|
544
|
+
}
|
|
545
|
+
this.emitLedgerEvent({
|
|
546
|
+
staffComponent: 'Attendant',
|
|
547
|
+
actionType: 'query_executed',
|
|
548
|
+
agentId: 'sdk',
|
|
549
|
+
source: 'sdk',
|
|
550
|
+
entityType: resolved.entityType,
|
|
551
|
+
entityId: resolved.entityId,
|
|
552
|
+
key,
|
|
553
|
+
reason: 'query_historical_miss',
|
|
554
|
+
level: 'audit',
|
|
555
|
+
metadata: {
|
|
556
|
+
found: false,
|
|
557
|
+
fromArchive: true,
|
|
558
|
+
asOf: options.asOf.toISOString(),
|
|
559
|
+
},
|
|
560
|
+
});
|
|
561
|
+
await this.noteRediscoveryEvidence();
|
|
562
|
+
return { found: false, resolvedEntity: resolved.canonicalEntity, inputEntity: entity };
|
|
340
563
|
}
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
564
|
+
const primaryEntry = await (0, queries_1.findEntry)({ entityType: resolved.entityType, entityId: resolved.entityId, key });
|
|
565
|
+
let entry = primaryEntry;
|
|
566
|
+
const resolvedEntity = resolved.canonicalEntity;
|
|
567
|
+
let usedFallback = false;
|
|
568
|
+
if ((!entry || entry.isProtected) && personalRecallCandidates.length > 0) {
|
|
569
|
+
for (const candidate of personalRecallCandidates) {
|
|
570
|
+
const fallback = await resolveQueryEntity(candidate);
|
|
571
|
+
const fallbackEntry = await (0, queries_1.findEntry)({ entityType: fallback.entityType, entityId: fallback.entityId, key });
|
|
572
|
+
if (fallbackEntry && !fallbackEntry.isProtected) {
|
|
573
|
+
entry = fallbackEntry;
|
|
574
|
+
usedFallback = true;
|
|
575
|
+
break;
|
|
576
|
+
}
|
|
354
577
|
}
|
|
355
578
|
}
|
|
579
|
+
if (!entry || entry.isProtected) {
|
|
580
|
+
this.emitLedgerEvent({
|
|
581
|
+
staffComponent: 'Attendant',
|
|
582
|
+
actionType: 'query_executed',
|
|
583
|
+
agentId: 'sdk',
|
|
584
|
+
source: 'sdk',
|
|
585
|
+
entityType: resolved.entityType,
|
|
586
|
+
entityId: resolved.entityId,
|
|
587
|
+
key,
|
|
588
|
+
reason: personalRecallCandidates.length > 0 ? 'query_personal_fallback_miss' : 'query_exact_miss',
|
|
589
|
+
level: 'audit',
|
|
590
|
+
metadata: {
|
|
591
|
+
found: false,
|
|
592
|
+
resolvedEntity,
|
|
593
|
+
inputEntity: entity,
|
|
594
|
+
},
|
|
595
|
+
});
|
|
596
|
+
await this.noteRediscoveryEvidence();
|
|
597
|
+
return { found: false, resolvedEntity, inputEntity: entity };
|
|
598
|
+
}
|
|
599
|
+
await (0, queries_1.recordKnowledgeEntryAccess)([entry.id]);
|
|
600
|
+
this.consumeDiscoveryBudget('query');
|
|
601
|
+
this.emitLedgerEvent({
|
|
602
|
+
staffComponent: 'Attendant',
|
|
603
|
+
actionType: 'query_executed',
|
|
604
|
+
agentId: 'sdk',
|
|
605
|
+
source: 'sdk',
|
|
606
|
+
entityType: entry.entityType,
|
|
607
|
+
entityId: entry.entityId,
|
|
608
|
+
key,
|
|
609
|
+
reason: usedFallback ? 'query_personal_fallback_match' : 'query_exact_match',
|
|
610
|
+
level: 'audit',
|
|
611
|
+
metadata: {
|
|
612
|
+
found: true,
|
|
613
|
+
resolvedEntity,
|
|
614
|
+
inputEntity: entity,
|
|
615
|
+
},
|
|
616
|
+
});
|
|
617
|
+
await this.noteRediscoveryEvidence();
|
|
618
|
+
return {
|
|
619
|
+
found: true,
|
|
620
|
+
value: entry.valueRaw,
|
|
621
|
+
summary: entry.valueSummary,
|
|
622
|
+
confidence: entry.confidence,
|
|
623
|
+
source: entry.source,
|
|
624
|
+
validFrom: entry.validFrom,
|
|
625
|
+
validUntil: entry.validUntil,
|
|
626
|
+
contested: false,
|
|
627
|
+
fromArchive: false,
|
|
628
|
+
archivedReason: null,
|
|
629
|
+
resolutionState: null,
|
|
630
|
+
resolutionOutcome: null,
|
|
631
|
+
resolvedEntity,
|
|
632
|
+
inputEntity: entity,
|
|
633
|
+
};
|
|
356
634
|
}
|
|
357
|
-
|
|
358
|
-
|
|
635
|
+
catch (error) {
|
|
636
|
+
this.emitLedgerEvent({
|
|
637
|
+
staffComponent: 'Attendant',
|
|
638
|
+
actionType: 'host_failure',
|
|
639
|
+
agentId: 'sdk',
|
|
640
|
+
source: 'sdk',
|
|
641
|
+
entityType: resolved.entityType,
|
|
642
|
+
entityId: resolved.entityId,
|
|
643
|
+
key,
|
|
644
|
+
reason: 'query_failed',
|
|
645
|
+
level: 'audit',
|
|
646
|
+
metadata: {
|
|
647
|
+
operation: 'query',
|
|
648
|
+
inputEntity: entity,
|
|
649
|
+
error: error instanceof Error ? error.message : String(error),
|
|
650
|
+
},
|
|
651
|
+
});
|
|
652
|
+
throw error;
|
|
359
653
|
}
|
|
360
|
-
await (0, queries_1.recordKnowledgeEntryAccess)([entry.id]);
|
|
361
|
-
return {
|
|
362
|
-
found: true,
|
|
363
|
-
value: entry.valueRaw,
|
|
364
|
-
summary: entry.valueSummary,
|
|
365
|
-
confidence: entry.confidence,
|
|
366
|
-
source: entry.source,
|
|
367
|
-
validFrom: entry.validFrom,
|
|
368
|
-
validUntil: entry.validUntil,
|
|
369
|
-
contested: false,
|
|
370
|
-
fromArchive: false,
|
|
371
|
-
archivedReason: null,
|
|
372
|
-
resolutionState: null,
|
|
373
|
-
resolutionOutcome: null,
|
|
374
|
-
resolvedEntity,
|
|
375
|
-
inputEntity: entity,
|
|
376
|
-
};
|
|
377
654
|
}
|
|
378
655
|
async history(entity, key, options = {}) {
|
|
656
|
+
this.checkProtocol('history', { handshake: true, attend: true });
|
|
379
657
|
const resolved = await resolveQueryEntity(entity);
|
|
380
658
|
const [archiveRows, current] = await Promise.all([
|
|
381
659
|
(0, queries_1.findArchiveHistory)({ entityType: resolved.entityType, entityId: resolved.entityId, key }, {
|
|
@@ -412,14 +690,18 @@ class Iranti {
|
|
|
412
690
|
resolutionOutcome: null,
|
|
413
691
|
});
|
|
414
692
|
}
|
|
693
|
+
this.consumeDiscoveryBudget('history');
|
|
415
694
|
return history.sort((a, b) => a.validFrom.getTime() - b.validFrom.getTime());
|
|
416
695
|
}
|
|
417
696
|
// ── Query All ───────────────────────────────────────────────────────────
|
|
418
697
|
async queryAll(entity) {
|
|
698
|
+
this.checkProtocol('queryAll', { handshake: true, attend: true });
|
|
419
699
|
const resolved = await resolveQueryEntity(entity);
|
|
420
700
|
const entries = await (0, queries_1.findEntriesByEntity)(resolved.entityType, resolved.entityId);
|
|
421
701
|
const visibleEntries = entries.filter((e) => !e.isProtected);
|
|
422
702
|
await (0, queries_1.recordKnowledgeEntryAccess)(visibleEntries.map((entry) => entry.id));
|
|
703
|
+
this.consumeDiscoveryBudget('queryAll');
|
|
704
|
+
await this.noteRediscoveryEvidence();
|
|
423
705
|
return visibleEntries
|
|
424
706
|
.map((e) => ({
|
|
425
707
|
key: e.key,
|
|
@@ -431,31 +713,69 @@ class Iranti {
|
|
|
431
713
|
}
|
|
432
714
|
// ── Maintenance ─────────────────────────────────────────────────────────
|
|
433
715
|
async search(input) {
|
|
716
|
+
this.checkProtocol('search', { handshake: true, attend: true });
|
|
434
717
|
if (!input.query || typeof input.query !== 'string' || input.query.trim().length === 0) {
|
|
435
718
|
throw new Error('query is required for search().');
|
|
436
719
|
}
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
720
|
+
try {
|
|
721
|
+
const rows = await (0, queries_1.searchEntriesHybrid)({
|
|
722
|
+
query: input.query.trim(),
|
|
723
|
+
limit: input.limit,
|
|
724
|
+
entityType: input.entityType,
|
|
725
|
+
entityId: input.entityId,
|
|
726
|
+
lexicalWeight: input.lexicalWeight,
|
|
727
|
+
vectorWeight: input.vectorWeight,
|
|
728
|
+
minScore: input.minScore,
|
|
729
|
+
});
|
|
730
|
+
this.emitLedgerEvent({
|
|
731
|
+
staffComponent: 'Attendant',
|
|
732
|
+
actionType: 'search_executed',
|
|
733
|
+
agentId: 'sdk',
|
|
734
|
+
source: 'sdk',
|
|
735
|
+
entityType: input.entityType,
|
|
736
|
+
entityId: input.entityId,
|
|
737
|
+
reason: 'hybrid_search',
|
|
738
|
+
level: 'audit',
|
|
739
|
+
metadata: {
|
|
740
|
+
queryPreview: input.query.trim().slice(0, 120),
|
|
741
|
+
resultCount: rows.length,
|
|
742
|
+
minScore: input.minScore ?? null,
|
|
743
|
+
},
|
|
744
|
+
});
|
|
745
|
+
this.consumeDiscoveryBudget('search');
|
|
746
|
+
await this.noteRediscoveryEvidence();
|
|
747
|
+
return rows.map((row) => ({
|
|
748
|
+
id: row.id,
|
|
749
|
+
entity: `${row.entityType}/${row.entityId}`,
|
|
750
|
+
key: row.key,
|
|
751
|
+
value: row.valueRaw,
|
|
752
|
+
summary: row.valueSummary,
|
|
753
|
+
confidence: row.confidence,
|
|
754
|
+
source: row.source,
|
|
755
|
+
validUntil: row.validUntil,
|
|
756
|
+
lexicalScore: row.lexicalScore,
|
|
757
|
+
vectorScore: row.vectorScore,
|
|
758
|
+
score: row.score,
|
|
759
|
+
}));
|
|
760
|
+
}
|
|
761
|
+
catch (error) {
|
|
762
|
+
this.emitLedgerEvent({
|
|
763
|
+
staffComponent: 'Attendant',
|
|
764
|
+
actionType: 'host_failure',
|
|
765
|
+
agentId: 'sdk',
|
|
766
|
+
source: 'sdk',
|
|
767
|
+
entityType: input.entityType,
|
|
768
|
+
entityId: input.entityId,
|
|
769
|
+
reason: 'search_failed',
|
|
770
|
+
level: 'audit',
|
|
771
|
+
metadata: {
|
|
772
|
+
operation: 'search',
|
|
773
|
+
queryPreview: input.query.trim().slice(0, 120),
|
|
774
|
+
error: error instanceof Error ? error.message : String(error),
|
|
775
|
+
},
|
|
776
|
+
});
|
|
777
|
+
throw error;
|
|
778
|
+
}
|
|
459
779
|
}
|
|
460
780
|
async runMaintenance() {
|
|
461
781
|
return (0, archivist_1.runArchivist)();
|
|
@@ -473,14 +793,90 @@ class Iranti {
|
|
|
473
793
|
createdBy: options.createdBy,
|
|
474
794
|
properties: options.properties,
|
|
475
795
|
});
|
|
796
|
+
await (0, registry_1.getAttendant)(options.createdBy).notifyWriteOccurred();
|
|
797
|
+
this.protocolTracker.clearMemoryUseAcknowledgementRequired(options.createdBy);
|
|
476
798
|
}
|
|
477
799
|
async getRelated(entity) {
|
|
800
|
+
this.checkProtocol('related', { handshake: true, attend: true });
|
|
478
801
|
const { entityType, entityId } = parseEntity(entity);
|
|
479
|
-
|
|
802
|
+
try {
|
|
803
|
+
const result = await (0, relationships_1.getRelated)(entityType, entityId);
|
|
804
|
+
this.consumeDiscoveryBudget('related');
|
|
805
|
+
this.emitLedgerEvent({
|
|
806
|
+
staffComponent: 'Attendant',
|
|
807
|
+
actionType: 'related_executed',
|
|
808
|
+
agentId: 'sdk',
|
|
809
|
+
source: 'sdk',
|
|
810
|
+
entityType,
|
|
811
|
+
entityId,
|
|
812
|
+
reason: 'relationship_lookup',
|
|
813
|
+
level: 'audit',
|
|
814
|
+
metadata: {
|
|
815
|
+
resultCount: result.length,
|
|
816
|
+
},
|
|
817
|
+
});
|
|
818
|
+
await this.noteRediscoveryEvidence();
|
|
819
|
+
return result;
|
|
820
|
+
}
|
|
821
|
+
catch (error) {
|
|
822
|
+
this.emitLedgerEvent({
|
|
823
|
+
staffComponent: 'Attendant',
|
|
824
|
+
actionType: 'host_failure',
|
|
825
|
+
agentId: 'sdk',
|
|
826
|
+
source: 'sdk',
|
|
827
|
+
entityType,
|
|
828
|
+
entityId,
|
|
829
|
+
reason: 'related_failed',
|
|
830
|
+
level: 'audit',
|
|
831
|
+
metadata: {
|
|
832
|
+
operation: 'related',
|
|
833
|
+
error: error instanceof Error ? error.message : String(error),
|
|
834
|
+
},
|
|
835
|
+
});
|
|
836
|
+
throw error;
|
|
837
|
+
}
|
|
480
838
|
}
|
|
481
839
|
async getRelatedDeep(entity, depth = 2) {
|
|
840
|
+
this.checkProtocol('related_deep', { handshake: true, attend: true });
|
|
482
841
|
const { entityType, entityId } = parseEntity(entity);
|
|
483
|
-
|
|
842
|
+
try {
|
|
843
|
+
const result = await (0, relationships_1.getRelatedDeep)(entityType, entityId, depth);
|
|
844
|
+
this.consumeDiscoveryBudget('related_deep');
|
|
845
|
+
this.emitLedgerEvent({
|
|
846
|
+
staffComponent: 'Attendant',
|
|
847
|
+
actionType: 'related_deep_executed',
|
|
848
|
+
agentId: 'sdk',
|
|
849
|
+
source: 'sdk',
|
|
850
|
+
entityType,
|
|
851
|
+
entityId,
|
|
852
|
+
reason: 'relationship_lookup_deep',
|
|
853
|
+
level: 'audit',
|
|
854
|
+
metadata: {
|
|
855
|
+
resultCount: result.length,
|
|
856
|
+
depth,
|
|
857
|
+
},
|
|
858
|
+
});
|
|
859
|
+
await this.noteRediscoveryEvidence();
|
|
860
|
+
return result;
|
|
861
|
+
}
|
|
862
|
+
catch (error) {
|
|
863
|
+
this.emitLedgerEvent({
|
|
864
|
+
staffComponent: 'Attendant',
|
|
865
|
+
actionType: 'host_failure',
|
|
866
|
+
agentId: 'sdk',
|
|
867
|
+
source: 'sdk',
|
|
868
|
+
entityType,
|
|
869
|
+
entityId,
|
|
870
|
+
reason: 'related_deep_failed',
|
|
871
|
+
level: 'audit',
|
|
872
|
+
metadata: {
|
|
873
|
+
operation: 'related_deep',
|
|
874
|
+
depth,
|
|
875
|
+
error: error instanceof Error ? error.message : String(error),
|
|
876
|
+
},
|
|
877
|
+
});
|
|
878
|
+
throw error;
|
|
879
|
+
}
|
|
484
880
|
}
|
|
485
881
|
// ── Agent Registry ──────────────────────────────────────────────────────
|
|
486
882
|
async registerAgent(profile) {
|
|
@@ -490,8 +886,44 @@ class Iranti {
|
|
|
490
886
|
return (0, agent_registry_1.getAgent)(agentId);
|
|
491
887
|
}
|
|
492
888
|
async whoKnows(entity) {
|
|
889
|
+
this.checkProtocol('who_knows', { handshake: true, attend: true });
|
|
493
890
|
const { entityType, entityId } = parseEntity(entity);
|
|
494
|
-
|
|
891
|
+
try {
|
|
892
|
+
const result = await (0, agent_registry_1.whoKnows)(entityType, entityId);
|
|
893
|
+
this.consumeDiscoveryBudget('who_knows');
|
|
894
|
+
this.emitLedgerEvent({
|
|
895
|
+
staffComponent: 'Attendant',
|
|
896
|
+
actionType: 'whoknows_executed',
|
|
897
|
+
agentId: 'sdk',
|
|
898
|
+
source: 'sdk',
|
|
899
|
+
entityType,
|
|
900
|
+
entityId,
|
|
901
|
+
reason: 'agent_contribution_lookup',
|
|
902
|
+
level: 'audit',
|
|
903
|
+
metadata: {
|
|
904
|
+
resultCount: result.length,
|
|
905
|
+
},
|
|
906
|
+
});
|
|
907
|
+
await this.noteRediscoveryEvidence();
|
|
908
|
+
return result;
|
|
909
|
+
}
|
|
910
|
+
catch (error) {
|
|
911
|
+
this.emitLedgerEvent({
|
|
912
|
+
staffComponent: 'Attendant',
|
|
913
|
+
actionType: 'host_failure',
|
|
914
|
+
agentId: 'sdk',
|
|
915
|
+
source: 'sdk',
|
|
916
|
+
entityType,
|
|
917
|
+
entityId,
|
|
918
|
+
reason: 'whoknows_failed',
|
|
919
|
+
level: 'audit',
|
|
920
|
+
metadata: {
|
|
921
|
+
operation: 'whoknows',
|
|
922
|
+
error: error instanceof Error ? error.message : String(error),
|
|
923
|
+
},
|
|
924
|
+
});
|
|
925
|
+
throw error;
|
|
926
|
+
}
|
|
495
927
|
}
|
|
496
928
|
async listAgents() {
|
|
497
929
|
return (0, agent_registry_1.listAgents)();
|
|
@@ -502,6 +934,7 @@ class Iranti {
|
|
|
502
934
|
// ── Context Window Observation ────────────────────────────────────────────
|
|
503
935
|
async observe(input) {
|
|
504
936
|
const agentId = resolveAgentId(input, 'observe');
|
|
937
|
+
this.checkProtocol('observe', { handshake: true });
|
|
505
938
|
if (input.entityHints !== undefined) {
|
|
506
939
|
if (!Array.isArray(input.entityHints)) {
|
|
507
940
|
throw new Error('entityHints must be an array of "entityType/entityId" strings.');
|
|
@@ -518,10 +951,14 @@ class Iranti {
|
|
|
518
951
|
currentContext: input.currentContext,
|
|
519
952
|
maxFacts: input.maxFacts,
|
|
520
953
|
entityHints: input.entityHints,
|
|
954
|
+
ledgerContext: this.buildSessionLedgerContext(),
|
|
521
955
|
});
|
|
522
956
|
}
|
|
523
957
|
async attend(input) {
|
|
524
958
|
const agentId = resolveAgentId(input, 'attend');
|
|
959
|
+
if (input.phase === 'pre-response') {
|
|
960
|
+
this.checkProtocol('attend', { postResponse: true });
|
|
961
|
+
}
|
|
525
962
|
if (input.entityHints !== undefined) {
|
|
526
963
|
if (!Array.isArray(input.entityHints)) {
|
|
527
964
|
throw new Error('entityHints must be an array of "entityType/entityId" strings.');
|
|
@@ -534,13 +971,24 @@ class Iranti {
|
|
|
534
971
|
}
|
|
535
972
|
}
|
|
536
973
|
const attendant = (0, registry_1.getAttendant)(agentId);
|
|
537
|
-
|
|
974
|
+
const result = await attendant.attend({
|
|
538
975
|
currentContext: input.currentContext,
|
|
539
976
|
maxFacts: input.maxFacts,
|
|
540
977
|
entityHints: input.entityHints,
|
|
541
978
|
latestMessage: input.latestMessage,
|
|
542
979
|
forceInject: input.forceInject,
|
|
980
|
+
suppressEvents: input.suppressEvents,
|
|
981
|
+
phase: input.phase,
|
|
982
|
+
ledgerContext: this.buildSessionLedgerContext(),
|
|
543
983
|
});
|
|
984
|
+
if (result.bootstrap?.handshakePerformed) {
|
|
985
|
+
this.protocolTracker.markHandshake(agentId);
|
|
986
|
+
}
|
|
987
|
+
this.protocolTracker.markAttend(agentId, input.phase);
|
|
988
|
+
if (input.phase === 'post-response') {
|
|
989
|
+
this.syncMemoryUseCompliance(agentId, result.compliance);
|
|
990
|
+
}
|
|
991
|
+
return result;
|
|
544
992
|
}
|
|
545
993
|
// ── Mock Configuration (dev/test only) ──────────────────────────────────
|
|
546
994
|
configureMock(config) {
|