@undefineds.co/linx 0.3.4 → 0.3.7
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 +58 -23
- package/dist/generated/version.js +1 -1
- package/dist/generated/version.js.map +1 -1
- package/dist/index.js +334 -162
- package/dist/index.js.map +1 -1
- package/dist/lib/account-session.js +4 -8
- package/dist/lib/account-session.js.map +1 -1
- package/dist/lib/ai-command.js +228 -178
- package/dist/lib/ai-command.js.map +1 -1
- package/dist/lib/auto-mode/archive.js +38 -7
- package/dist/lib/auto-mode/archive.js.map +1 -1
- package/dist/lib/auto-mode/auth.js.map +1 -1
- package/dist/lib/auto-mode/display.js +71 -45
- package/dist/lib/auto-mode/display.js.map +1 -1
- package/dist/lib/auto-mode/format.js +9 -7
- package/dist/lib/auto-mode/format.js.map +1 -1
- package/dist/lib/auto-mode/hooks/claude.js +12 -2
- package/dist/lib/auto-mode/hooks/claude.js.map +1 -1
- package/dist/lib/auto-mode/hooks/codex.js +17 -7
- package/dist/lib/auto-mode/hooks/codex.js.map +1 -1
- package/dist/lib/auto-mode/hooks/index.js +28 -8
- package/dist/lib/auto-mode/hooks/index.js.map +1 -1
- package/dist/lib/auto-mode/pod-ai.js +20 -37
- package/dist/lib/auto-mode/pod-ai.js.map +1 -1
- package/dist/lib/auto-mode/pod-approval.js +124 -195
- package/dist/lib/auto-mode/pod-approval.js.map +1 -1
- package/dist/lib/auto-mode/pod-persistence.js +169 -90
- package/dist/lib/auto-mode/pod-persistence.js.map +1 -1
- package/dist/lib/auto-mode/runner.js +683 -81
- package/dist/lib/auto-mode/runner.js.map +1 -1
- package/dist/lib/auto-mode/secretary.js +186 -41
- package/dist/lib/auto-mode/secretary.js.map +1 -1
- package/dist/lib/auto-mode-command.js +32 -32
- package/dist/lib/auto-mode-command.js.map +1 -1
- package/dist/lib/chat-api.js +242 -50
- package/dist/lib/chat-api.js.map +1 -1
- package/dist/lib/codex-plugin/bridge.js +164 -17
- package/dist/lib/codex-plugin/bridge.js.map +1 -1
- package/dist/lib/codex-plugin/codex-native-proxy.js +370 -34
- package/dist/lib/codex-plugin/codex-native-proxy.js.map +1 -1
- package/dist/lib/credentials-store.js +33 -42
- package/dist/lib/credentials-store.js.map +1 -1
- package/dist/lib/linx-cloud-errors.js +61 -0
- package/dist/lib/linx-cloud-errors.js.map +1 -0
- package/dist/lib/linx-tui-contract.js +8 -5
- package/dist/lib/linx-tui-contract.js.map +1 -1
- package/dist/lib/login-command.js +9 -2
- package/dist/lib/login-command.js.map +1 -1
- package/dist/lib/models.js +3 -20
- package/dist/lib/models.js.map +1 -1
- package/dist/lib/oidc-auth.js +143 -17
- package/dist/lib/oidc-auth.js.map +1 -1
- package/dist/lib/oidc-session-storage.js +2 -6
- package/dist/lib/oidc-session-storage.js.map +1 -1
- package/dist/lib/pi-adapter/auto-input-controller.js +988 -0
- package/dist/lib/pi-adapter/auto-input-controller.js.map +1 -0
- package/dist/lib/pi-adapter/backend-command.js +2 -0
- package/dist/lib/pi-adapter/backend-command.js.map +1 -0
- package/dist/lib/pi-adapter/backend-credentials.js +80 -0
- package/dist/lib/pi-adapter/backend-credentials.js.map +1 -0
- package/dist/lib/pi-adapter/branding.js +246 -108
- package/dist/lib/pi-adapter/branding.js.map +1 -1
- package/dist/lib/pi-adapter/control-state.js +72 -0
- package/dist/lib/pi-adapter/control-state.js.map +1 -0
- package/dist/lib/pi-adapter/interactive.js +2634 -30
- package/dist/lib/pi-adapter/interactive.js.map +1 -1
- package/dist/lib/pi-adapter/pod-approval.js +382 -210
- package/dist/lib/pi-adapter/pod-approval.js.map +1 -1
- package/dist/lib/pi-adapter/pod-mirror-mapping.js +71 -17
- package/dist/lib/pi-adapter/pod-mirror-mapping.js.map +1 -1
- package/dist/lib/pi-adapter/pod-mirror.js +531 -64
- package/dist/lib/pi-adapter/pod-mirror.js.map +1 -1
- package/dist/lib/pi-adapter/pod-native.js +81 -85
- package/dist/lib/pi-adapter/pod-native.js.map +1 -1
- package/dist/lib/pi-adapter/pod-status-output.js +54 -0
- package/dist/lib/pi-adapter/pod-status-output.js.map +1 -0
- package/dist/lib/pi-adapter/runtime.js +458 -228
- package/dist/lib/pi-adapter/runtime.js.map +1 -1
- package/dist/lib/pi-adapter/session-control.js +509 -0
- package/dist/lib/pi-adapter/session-control.js.map +1 -0
- package/dist/lib/pi-adapter/session.js +35 -22
- package/dist/lib/pi-adapter/session.js.map +1 -1
- package/dist/lib/pi-adapter/stream.js +89 -32
- package/dist/lib/pi-adapter/stream.js.map +1 -1
- package/dist/lib/pi-adapter/sync-recovery.js +89 -0
- package/dist/lib/pi-adapter/sync-recovery.js.map +1 -0
- package/dist/lib/pi-adapter/web-fetch.js +13 -14
- package/dist/lib/pi-adapter/web-fetch.js.map +1 -1
- package/dist/lib/pod-chat-store.js +254 -78
- package/dist/lib/pod-chat-store.js.map +1 -1
- package/dist/lib/pod-data-session.js +156 -35
- package/dist/lib/pod-data-session.js.map +1 -1
- package/dist/lib/solid-auth-store.js +27 -0
- package/dist/lib/solid-auth-store.js.map +1 -0
- package/dist/lib/solid-auth.js +2 -4
- package/dist/lib/solid-auth.js.map +1 -1
- package/dist/lib/solid-client-credentials-login.js +100 -0
- package/dist/lib/solid-client-credentials-login.js.map +1 -0
- package/dist/lib/solid-local-store.js +31 -0
- package/dist/lib/solid-local-store.js.map +1 -0
- package/dist/lib/symphony/archive.js +328 -18
- package/dist/lib/symphony/archive.js.map +1 -1
- package/dist/lib/symphony/pod-projection.js +2222 -0
- package/dist/lib/symphony/pod-projection.js.map +1 -0
- package/dist/lib/symphony-command.js +602 -178
- package/dist/lib/symphony-command.js.map +1 -1
- package/dist/lib/sync-checkpoint-store.js +74 -0
- package/dist/lib/sync-checkpoint-store.js.map +1 -0
- package/dist/skills/symphony/SKILL.md +665 -0
- package/package.json +15 -9
- package/vendor/agent-runtime/dist/agent-runtime.d.ts +137 -0
- package/vendor/agent-runtime/dist/agent-runtime.js +211 -0
- package/vendor/agent-runtime/dist/auto-mode.d.ts +78 -13
- package/vendor/agent-runtime/dist/auto-mode.js +288 -31
- package/vendor/agent-runtime/dist/control-plane.d.ts +28 -0
- package/vendor/agent-runtime/dist/control-plane.js +79 -0
- package/vendor/agent-runtime/dist/file-sync.d.ts +157 -0
- package/vendor/agent-runtime/dist/file-sync.js +314 -0
- package/vendor/agent-runtime/dist/index.d.ts +7 -0
- package/vendor/agent-runtime/dist/index.js +7 -0
- package/vendor/agent-runtime/dist/reconciler.d.ts +117 -0
- package/vendor/agent-runtime/dist/reconciler.js +361 -0
- package/vendor/agent-runtime/dist/symphony.d.ts +128 -8
- package/vendor/agent-runtime/dist/symphony.js +362 -57
- package/vendor/agent-runtime/dist/sync.d.ts +271 -0
- package/vendor/agent-runtime/dist/sync.js +550 -0
- package/vendor/agent-runtime/dist/thread-reconciler-controller.d.ts +58 -0
- package/vendor/agent-runtime/dist/thread-reconciler-controller.js +137 -0
- package/vendor/agent-runtime/dist/turn-controller.js +2 -2
- package/vendor/agent-runtime/dist/wake-scheduler.d.ts +67 -0
- package/vendor/agent-runtime/dist/wake-scheduler.js +194 -0
- package/vendor/agent-runtime/package.json +8 -1
- package/vendor/pi-web-access/CHANGELOG.md +387 -0
- package/vendor/pi-web-access/LICENSE +21 -0
- package/vendor/pi-web-access/README.md +352 -0
- package/vendor/pi-web-access/activity.ts +101 -0
- package/vendor/pi-web-access/banner.png +0 -0
- package/vendor/pi-web-access/chrome-cookies.ts +322 -0
- package/vendor/pi-web-access/code-search.ts +107 -0
- package/vendor/pi-web-access/curator-page.ts +3359 -0
- package/vendor/pi-web-access/curator-server.ts +605 -0
- package/vendor/pi-web-access/exa.ts +520 -0
- package/vendor/pi-web-access/extract.ts +641 -0
- package/vendor/pi-web-access/gemini-api.ts +112 -0
- package/vendor/pi-web-access/gemini-search.ts +361 -0
- package/vendor/pi-web-access/gemini-url-context.ts +126 -0
- package/vendor/pi-web-access/gemini-web-config.ts +52 -0
- package/vendor/pi-web-access/gemini-web.ts +396 -0
- package/vendor/pi-web-access/github-api.ts +196 -0
- package/vendor/pi-web-access/github-extract.ts +634 -0
- package/vendor/pi-web-access/index.ts +2346 -0
- package/vendor/pi-web-access/package.json +45 -0
- package/vendor/pi-web-access/pdf-extract.ts +192 -0
- package/vendor/pi-web-access/perplexity.ts +195 -0
- package/vendor/pi-web-access/pi-web-fetch-demo.mp4 +0 -0
- package/vendor/pi-web-access/rsc-extract.ts +338 -0
- package/vendor/pi-web-access/skills/librarian/SKILL.md +195 -0
- package/vendor/pi-web-access/storage.ts +72 -0
- package/vendor/pi-web-access/summary-review.ts +276 -0
- package/vendor/pi-web-access/test/gemini-web-cookie-opt-in.test.mjs +41 -0
- package/vendor/pi-web-access/test/pdf-extract.test.mjs +95 -0
- package/vendor/pi-web-access/utils.ts +44 -0
- package/vendor/pi-web-access/video-extract.ts +378 -0
- package/vendor/pi-web-access/youtube-extract.ts +310 -0
- package/dist/lib/pi-adapter/auth.js +0 -68
- package/dist/lib/pi-adapter/auth.js.map +0 -1
- package/dist/lib/pi-adapter/pod-tools.js +0 -140
- package/dist/lib/pi-adapter/pod-tools.js.map +0 -1
- package/dist/skills/drizzle-solid/SKILL.md +0 -340
- package/dist/skills/pod-storage/SKILL.md +0 -100
- package/dist/skills/solid-modeling/SKILL.md +0 -274
- package/dist/skills/xpod-componentsjs/SKILL.md +0 -284
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { setTimeout as delay } from 'node:timers/promises';
|
|
2
|
+
import { resolvePodBaseUrl } from '@undefineds.co/drizzle-solid';
|
|
2
3
|
import { getDefaultPodDataSession } from '../pod-data-session.js';
|
|
3
|
-
import { approvalResource, auditResource,
|
|
4
|
+
import { agentResource, approvalResource, auditResource, chatResource, drizzle, grantResource, inboxNotificationResource, solidResources, threadRepository, } from '../models.js';
|
|
4
5
|
import { AS, ODRL, UDFS } from '@undefineds.co/models/namespaces';
|
|
5
6
|
import { ApprovalVocab, AuditVocab, GrantReadVocab, GrantVocab, InboxNotificationVocab } from '@undefineds.co/models/vocab/sidecar';
|
|
6
|
-
import { autoModeApprovalActionUri, autoModeApprovalRequestMessage, autoModeApprovalRisk, autoModeApprovalToolName, } from '../../../vendor/agent-runtime/dist/auto-mode.js';
|
|
7
|
+
import { autoModeApprovalActionUri, autoModeApprovalDecisionForStoredApproval, autoModeApprovalRequestMessage, autoModeApprovalRisk, autoModeApprovalToolName, buildAutoModeApprovalDecisionReason, encodeAutoModeApprovalOptions, parseAutoModeApprovalDecisionReason, parseAutoModeApprovalOptions, shouldMaterializeAutoModeGrant, } from '../../../vendor/agent-runtime/dist/auto-mode.js';
|
|
7
8
|
import { resolveAutoModeGrantCoverage } from './secretary.js';
|
|
8
9
|
import { buildApprovalDocumentUrl, RDF_TYPE, buildApprovalResourceUrl, buildAuditDocumentUrl, buildAuditResourceUrl, buildGrantResourceUrl, buildInboxResourceUrl, firstIri, firstLiteral, iri, listTurtleResources, listTurtleResourcesRecursive, literal, parseManagedTurtleBlocks, readTurtleResource, subjectIdFromResourceUrl, upsertManagedTurtleBlock, } from '../pi-adapter/pod-native.js';
|
|
9
10
|
const AUTO_MODE_CHAT_ID_PREFIX = 'linx-auto-mode';
|
|
10
|
-
const AUTO_MODE_AGENT_ID = '
|
|
11
|
+
const AUTO_MODE_AGENT_ID = '__secretary__';
|
|
11
12
|
const REMOTE_APPROVAL_POLICY_VERSION = 'linx-auto-mode-remote-approval/v1';
|
|
12
13
|
const DEFAULT_REMOTE_APPROVAL_POLL_MS = 1000;
|
|
13
14
|
const DEFAULT_WARN_ONLY_TIMEOUT_MS = 5000;
|
|
@@ -17,6 +18,7 @@ const MAX_APPROVAL_CONTEXT_LENGTH = 1400;
|
|
|
17
18
|
const MIN_GRANT_COVERAGE_CONFIDENCE = 0.75;
|
|
18
19
|
const MAX_GRANT_COVERAGE_CANDIDATES = 5;
|
|
19
20
|
const remoteApprovalClientCache = new WeakMap();
|
|
21
|
+
let remoteApprovalSyncSeq = 0;
|
|
20
22
|
function createAbortError() {
|
|
21
23
|
const error = new Error('The operation was aborted.');
|
|
22
24
|
error.name = 'AbortError';
|
|
@@ -37,42 +39,32 @@ function toIsoString(value, fallback) {
|
|
|
37
39
|
}
|
|
38
40
|
return fallback;
|
|
39
41
|
}
|
|
40
|
-
function getPodBaseUrl(webIdOrUri) {
|
|
41
|
-
if (webIdOrUri.includes('/profile/card#me')) {
|
|
42
|
-
return webIdOrUri.replace('/profile/card#me', '').replace(/\/$/, '');
|
|
43
|
-
}
|
|
44
|
-
const match = webIdOrUri.match(/^(https?:\/\/[^?#]+?)(?:\/\.data\/|\/inbox\/)/u);
|
|
45
|
-
if (match) {
|
|
46
|
-
return match[1].replace(/\/$/, '');
|
|
47
|
-
}
|
|
48
|
-
return webIdOrUri.replace(/\/$/, '');
|
|
49
|
-
}
|
|
50
42
|
function buildAutoModeChatId(record) {
|
|
51
43
|
return `${AUTO_MODE_CHAT_ID_PREFIX}-${record.backend}`;
|
|
52
44
|
}
|
|
53
|
-
function
|
|
54
|
-
return
|
|
45
|
+
function buildAutoModeChatUri(webId, record) {
|
|
46
|
+
return chatResource.buildIri(webId, { id: buildAutoModeChatId(record) });
|
|
55
47
|
}
|
|
56
|
-
function
|
|
57
|
-
return
|
|
48
|
+
function autoModeThreadUri(webId, record) {
|
|
49
|
+
return threadRepository.iriForChat(webId, buildAutoModeChatId(record), record.id);
|
|
50
|
+
}
|
|
51
|
+
function approvalIriForCreatedAt(webIdOrUri, approvalId, createdAt) {
|
|
52
|
+
return approvalResource.buildIri(webIdOrUri, {
|
|
53
|
+
id: approvalId,
|
|
54
|
+
createdAt,
|
|
55
|
+
});
|
|
58
56
|
}
|
|
59
57
|
function documentUrlFromResourceUri(resourceUri) {
|
|
60
58
|
return resourceUri.split('#', 1)[0] ?? resourceUri;
|
|
61
59
|
}
|
|
62
|
-
function
|
|
63
|
-
return
|
|
64
|
-
}
|
|
65
|
-
function buildPodResourceIri(webIdOrUri, relativeUri) {
|
|
66
|
-
if (/^https?:\/\//.test(relativeUri)) {
|
|
67
|
-
return relativeUri;
|
|
68
|
-
}
|
|
69
|
-
return new URL(relativeUri.replace(/^\//, ''), `${getPodBaseUrl(webIdOrUri)}/`).toString();
|
|
60
|
+
function grantIri(webIdOrUri, grantId) {
|
|
61
|
+
return buildGrantResourceUrl(webIdOrUri, grantId);
|
|
70
62
|
}
|
|
71
63
|
function buildGrantSchemaUri(webIdOrUri) {
|
|
72
|
-
return
|
|
64
|
+
return new URL('settings/autonomy/schema/grant.ttl#GrantWikiPage', `${resolvePodBaseUrl(webIdOrUri)}/`).toString();
|
|
73
65
|
}
|
|
74
|
-
function
|
|
75
|
-
return
|
|
66
|
+
function autoModeAgentUri(webId) {
|
|
67
|
+
return agentResource.buildIri(webId, { id: AUTO_MODE_AGENT_ID });
|
|
76
68
|
}
|
|
77
69
|
function buildActionUri(request) {
|
|
78
70
|
return autoModeApprovalActionUri(request);
|
|
@@ -108,34 +100,6 @@ function extractToolCallId(request) {
|
|
|
108
100
|
?? normalizeString(params?.toolCallId)
|
|
109
101
|
?? crypto.randomUUID();
|
|
110
102
|
}
|
|
111
|
-
function encodeDecisionReason(decision, note) {
|
|
112
|
-
return safeJsonStringify({
|
|
113
|
-
decision,
|
|
114
|
-
...(note?.trim() ? { note: note.trim() } : {}),
|
|
115
|
-
});
|
|
116
|
-
}
|
|
117
|
-
function parseDecisionReason(value) {
|
|
118
|
-
if (typeof value !== 'string' || !value.trim()) {
|
|
119
|
-
return null;
|
|
120
|
-
}
|
|
121
|
-
try {
|
|
122
|
-
const parsed = JSON.parse(value);
|
|
123
|
-
if (!isRecord(parsed)) {
|
|
124
|
-
return null;
|
|
125
|
-
}
|
|
126
|
-
const decision = normalizeString(parsed.decision);
|
|
127
|
-
if (!decision || !['accept', 'accept_for_session', 'decline', 'cancel'].includes(decision)) {
|
|
128
|
-
return null;
|
|
129
|
-
}
|
|
130
|
-
return {
|
|
131
|
-
decision: decision,
|
|
132
|
-
...(normalizeString(parsed.note) ? { note: normalizeString(parsed.note) } : {}),
|
|
133
|
-
};
|
|
134
|
-
}
|
|
135
|
-
catch {
|
|
136
|
-
return null;
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
103
|
async function warnOnly(runtime, task) {
|
|
140
104
|
try {
|
|
141
105
|
await Promise.race([
|
|
@@ -240,7 +204,7 @@ function grantWikiTagsFromApproval(row, explicitTags) {
|
|
|
240
204
|
}
|
|
241
205
|
function grantContextFromApproval(row) {
|
|
242
206
|
return safeCompactJson({
|
|
243
|
-
sourceApproval:
|
|
207
|
+
sourceApproval: approvalIriForCreatedAt(row.session, row.id, new Date(toIsoString(row.createdAt, new Date().toISOString()))),
|
|
244
208
|
session: row.session,
|
|
245
209
|
toolCallId: row.toolCallId,
|
|
246
210
|
toolName: row.toolName,
|
|
@@ -277,45 +241,7 @@ function grantSourceHash(row) {
|
|
|
277
241
|
return `approval:${row.id}:${row.toolCallId}:${row.risk}`;
|
|
278
242
|
}
|
|
279
243
|
function encodeApprovalOptions(options) {
|
|
280
|
-
|
|
281
|
-
return undefined;
|
|
282
|
-
}
|
|
283
|
-
return safeJsonStringify(options);
|
|
284
|
-
}
|
|
285
|
-
function parseApprovalOptions(value) {
|
|
286
|
-
if (typeof value !== 'string' || !value.trim()) {
|
|
287
|
-
return undefined;
|
|
288
|
-
}
|
|
289
|
-
try {
|
|
290
|
-
const parsed = JSON.parse(value);
|
|
291
|
-
if (!Array.isArray(parsed)) {
|
|
292
|
-
return undefined;
|
|
293
|
-
}
|
|
294
|
-
const options = parsed
|
|
295
|
-
.map((option) => {
|
|
296
|
-
if (!isRecord(option)) {
|
|
297
|
-
return null;
|
|
298
|
-
}
|
|
299
|
-
const optionId = normalizeString(option.optionId);
|
|
300
|
-
const label = normalizeString(option.label);
|
|
301
|
-
if (!optionId || !label) {
|
|
302
|
-
return null;
|
|
303
|
-
}
|
|
304
|
-
const kind = normalizeString(option.kind);
|
|
305
|
-
const description = normalizeString(option.description);
|
|
306
|
-
return {
|
|
307
|
-
optionId,
|
|
308
|
-
label,
|
|
309
|
-
...(kind ? { kind } : {}),
|
|
310
|
-
...(description ? { description } : {}),
|
|
311
|
-
};
|
|
312
|
-
})
|
|
313
|
-
.filter((option) => option !== null);
|
|
314
|
-
return options.length > 0 ? options : undefined;
|
|
315
|
-
}
|
|
316
|
-
catch {
|
|
317
|
-
return undefined;
|
|
318
|
-
}
|
|
244
|
+
return encodeAutoModeApprovalOptions(options);
|
|
319
245
|
}
|
|
320
246
|
function normalizeDateLike(value) {
|
|
321
247
|
if (value instanceof Date) {
|
|
@@ -344,24 +270,17 @@ function extractSessionId(sessionUri) {
|
|
|
344
270
|
return sessionUri;
|
|
345
271
|
}
|
|
346
272
|
function decisionFromApprovalRow(row) {
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
if (status === 'rejected') {
|
|
353
|
-
return parsed?.decision === 'cancel' ? 'cancel' : 'decline';
|
|
354
|
-
}
|
|
355
|
-
if (parsed?.decision === 'accept_for_session') {
|
|
356
|
-
return 'accept_for_session';
|
|
357
|
-
}
|
|
358
|
-
return 'accept';
|
|
273
|
+
return autoModeApprovalDecisionForStoredApproval({
|
|
274
|
+
status: normalizeString(row.status),
|
|
275
|
+
reason: row.reason,
|
|
276
|
+
approvalOptions: row.approvalOptions,
|
|
277
|
+
});
|
|
359
278
|
}
|
|
360
279
|
function normalizeApprovalSummary(row) {
|
|
361
280
|
const createdAt = toIsoString(row.createdAt, new Date(0).toISOString());
|
|
362
281
|
const sessionUri = row.session;
|
|
363
282
|
const decision = decisionFromApprovalRow(row);
|
|
364
|
-
const approvalOptions =
|
|
283
|
+
const approvalOptions = parseAutoModeApprovalOptions(row.approvalOptions);
|
|
365
284
|
return {
|
|
366
285
|
id: row.id,
|
|
367
286
|
...(normalizeString(row.approvalUri) ? { approvalUri: normalizeString(row.approvalUri) } : {}),
|
|
@@ -375,7 +294,7 @@ function normalizeApprovalSummary(row) {
|
|
|
375
294
|
...(normalizeString(row.assignedTo) ? { assignedTo: normalizeString(row.assignedTo) } : {}),
|
|
376
295
|
...(normalizeString(row.decisionBy) ? { decisionBy: normalizeString(row.decisionBy) } : {}),
|
|
377
296
|
...(decision ? { decision } : {}),
|
|
378
|
-
...(approvalOptions ? { approvalOptions } : {}),
|
|
297
|
+
...(approvalOptions.length > 0 ? { approvalOptions } : {}),
|
|
379
298
|
createdAt,
|
|
380
299
|
...(row.expiresAt ? { expiresAt: toIsoString(row.expiresAt, createdAt) } : {}),
|
|
381
300
|
...(row.resolvedAt ? { resolvedAt: toIsoString(row.resolvedAt, createdAt) } : {}),
|
|
@@ -501,7 +420,7 @@ function createSharedModelRemoteApprovalStore(webId, getDb) {
|
|
|
501
420
|
}
|
|
502
421
|
if (options.createdAt) {
|
|
503
422
|
const createdAt = new Date(toIsoString(options.createdAt, new Date().toISOString()));
|
|
504
|
-
const iri =
|
|
423
|
+
const iri = approvalIriForCreatedAt(webId, id, createdAt);
|
|
505
424
|
const row = await modelFindByIri(getDb, approvalResource, iri);
|
|
506
425
|
return row ? enrichApprovalRow(webId, row, iri) : null;
|
|
507
426
|
}
|
|
@@ -514,7 +433,7 @@ function createSharedModelRemoteApprovalStore(webId, getDb) {
|
|
|
514
433
|
updateApproval: async (id, patch, options = {}) => {
|
|
515
434
|
const explicitIri = options.resourceUri
|
|
516
435
|
?? normalizeString(patch.approvalUri)
|
|
517
|
-
?? (options.createdAt ?
|
|
436
|
+
?? (options.createdAt ? approvalIriForCreatedAt(webId, id, new Date(toIsoString(options.createdAt, new Date().toISOString()))) : undefined);
|
|
518
437
|
if (explicitIri) {
|
|
519
438
|
await modelUpdateByIri(getDb, approvalResource, explicitIri, omitInternalFields(patch));
|
|
520
439
|
return;
|
|
@@ -543,18 +462,11 @@ async function modelList(getDb, resource) {
|
|
|
543
462
|
}
|
|
544
463
|
async function modelFindByIri(getDb, resource, iri) {
|
|
545
464
|
const db = await getDb();
|
|
546
|
-
|
|
547
|
-
return await db.findByIri(resource, iri);
|
|
548
|
-
}
|
|
549
|
-
const rows = await db.select().from(resource).whereByIri(iri).execute();
|
|
550
|
-
return rows[0] ?? null;
|
|
465
|
+
return await db.findByIri(resource, iri);
|
|
551
466
|
}
|
|
552
467
|
async function modelFindById(getDb, resource, id) {
|
|
553
468
|
const db = await getDb();
|
|
554
|
-
|
|
555
|
-
return await db.findById(resource, id);
|
|
556
|
-
}
|
|
557
|
-
throw new Error('Remote approval shared model store requires findById support');
|
|
469
|
+
return await db.findById(resource, id);
|
|
558
470
|
}
|
|
559
471
|
async function modelInsert(getDb, resource, row) {
|
|
560
472
|
const db = await getDb();
|
|
@@ -565,31 +477,14 @@ async function modelUpdateByIri(getDb, resource, iri, patch) {
|
|
|
565
477
|
const update = stripUndefined(patch);
|
|
566
478
|
delete update.id;
|
|
567
479
|
delete update.approvalUri;
|
|
568
|
-
|
|
569
|
-
await db.updateByIri(resource, iri, update);
|
|
570
|
-
return;
|
|
571
|
-
}
|
|
572
|
-
const query = db.update(resource).set(update);
|
|
573
|
-
if (typeof query.whereByIri !== 'function') {
|
|
574
|
-
throw new Error('Remote approval shared model store requires updateByIri/whereByIri support');
|
|
575
|
-
}
|
|
576
|
-
await query.whereByIri(iri).execute();
|
|
480
|
+
await db.updateByIri(resource, iri, update);
|
|
577
481
|
}
|
|
578
482
|
async function modelUpdateById(getDb, resource, id, patch) {
|
|
579
483
|
const db = await getDb();
|
|
580
484
|
const update = stripUndefined(patch);
|
|
581
485
|
delete update.id;
|
|
582
486
|
delete update.approvalUri;
|
|
583
|
-
|
|
584
|
-
return await db.updateById(resource, id, update);
|
|
585
|
-
}
|
|
586
|
-
const row = await modelFindById(getDb, resource, id);
|
|
587
|
-
const iri = rowSubject(row ?? {});
|
|
588
|
-
if (!iri) {
|
|
589
|
-
return null;
|
|
590
|
-
}
|
|
591
|
-
await modelUpdateByIri(getDb, resource, iri, update);
|
|
592
|
-
return await modelFindByIri(getDb, resource, iri);
|
|
487
|
+
return await db.updateById(resource, id, update);
|
|
593
488
|
}
|
|
594
489
|
function stripUndefined(row) {
|
|
595
490
|
const next = {};
|
|
@@ -605,7 +500,6 @@ function omitInternalFields(row) {
|
|
|
605
500
|
delete next.approvalUri;
|
|
606
501
|
delete next['@id'];
|
|
607
502
|
delete next.subject;
|
|
608
|
-
delete next.source;
|
|
609
503
|
delete next.uri;
|
|
610
504
|
return next;
|
|
611
505
|
}
|
|
@@ -621,7 +515,7 @@ function enrichApprovalRow(webId, row, explicitIri) {
|
|
|
621
515
|
approvalUri: explicitIri
|
|
622
516
|
?? normalizeString(row.approvalUri)
|
|
623
517
|
?? rowSubject(row)
|
|
624
|
-
??
|
|
518
|
+
?? approvalIriForCreatedAt(webId, row.id, createdAt),
|
|
625
519
|
};
|
|
626
520
|
}
|
|
627
521
|
function createNativeRemoteApprovalStore(webId, fetcher) {
|
|
@@ -677,7 +571,7 @@ async function readApprovalRowFromResource(fetcher, resourceUri) {
|
|
|
677
571
|
async function listApprovalRows(webId, fetcher) {
|
|
678
572
|
const urls = [
|
|
679
573
|
...recentApprovalDocumentUrls(webId),
|
|
680
|
-
...await listTurtleResources(fetcher, `${
|
|
574
|
+
...await listTurtleResources(fetcher, `${resolvePodBaseUrl(webId)}/.data/approvals/`).catch(() => []),
|
|
681
575
|
];
|
|
682
576
|
const rows = [];
|
|
683
577
|
for (const url of [...new Set(urls)].filter((entry) => entry.endsWith('.ttl'))) {
|
|
@@ -731,7 +625,7 @@ async function writeApprovalRow(webId, fetcher, row) {
|
|
|
731
625
|
});
|
|
732
626
|
}
|
|
733
627
|
async function listAuditRows(webId, fetcher) {
|
|
734
|
-
const urls = await listTurtleResourcesRecursive(fetcher, `${
|
|
628
|
+
const urls = await listTurtleResourcesRecursive(fetcher, `${resolvePodBaseUrl(webId)}/.data/audits/`);
|
|
735
629
|
const rows = [];
|
|
736
630
|
for (const url of urls.filter((entry) => entry.endsWith('.ttl'))) {
|
|
737
631
|
const turtle = await readTurtleResource(fetcher, url).catch(() => null);
|
|
@@ -769,7 +663,7 @@ async function writeAuditRow(webId, fetcher, row) {
|
|
|
769
663
|
}
|
|
770
664
|
async function listGrantRows(webId, fetcher) {
|
|
771
665
|
const urls = [
|
|
772
|
-
...await listTurtleResources(fetcher, `${
|
|
666
|
+
...await listTurtleResources(fetcher, `${resolvePodBaseUrl(webId)}/settings/autonomy/grants/`).catch(() => []),
|
|
773
667
|
];
|
|
774
668
|
const rows = [];
|
|
775
669
|
for (const url of urls.filter((entry) => entry.endsWith('.ttl'))) {
|
|
@@ -989,8 +883,8 @@ async function resolveSemanticGrantDecision(options) {
|
|
|
989
883
|
}
|
|
990
884
|
function buildAutoModeGrantRequestContext(input) {
|
|
991
885
|
return {
|
|
992
|
-
session:
|
|
993
|
-
target:
|
|
886
|
+
session: autoModeThreadUri(input.webId, input.record),
|
|
887
|
+
target: autoModeThreadUri(input.webId, input.record),
|
|
994
888
|
action: buildActionUri(input.request),
|
|
995
889
|
risk: buildRisk(input.request),
|
|
996
890
|
toolName: buildToolName(input.request),
|
|
@@ -1002,7 +896,7 @@ function buildAutoModeGrantRequestContext(input) {
|
|
|
1002
896
|
function buildGenericGrantRequestContext(input) {
|
|
1003
897
|
return {
|
|
1004
898
|
session: input.subject.sessionUri,
|
|
1005
|
-
target: input.subject.
|
|
899
|
+
target: input.subject.target ?? input.subject.sessionUri,
|
|
1006
900
|
action: input.request.action,
|
|
1007
901
|
risk: input.request.risk,
|
|
1008
902
|
toolName: input.request.toolName,
|
|
@@ -1014,8 +908,8 @@ export async function createRemoteAutoModeApproval(options) {
|
|
|
1014
908
|
const activeRuntime = options.runtime ?? await createDefaultRuntime();
|
|
1015
909
|
return createRemoteApproval({
|
|
1016
910
|
subject: ({ webId }) => ({
|
|
1017
|
-
sessionUri:
|
|
1018
|
-
actorUri:
|
|
911
|
+
sessionUri: autoModeThreadUri(webId, options.record),
|
|
912
|
+
actorUri: autoModeAgentUri(webId),
|
|
1019
913
|
policyVersion: REMOTE_APPROVAL_POLICY_VERSION,
|
|
1020
914
|
}),
|
|
1021
915
|
request: ({ sessionUri }) => ({
|
|
@@ -1047,8 +941,8 @@ export async function createRemoteApproval(options) {
|
|
|
1047
941
|
const approvalId = crypto.randomUUID();
|
|
1048
942
|
const now = activeRuntime.now();
|
|
1049
943
|
const sessionUri = subject.sessionUri;
|
|
1050
|
-
const approvalUri =
|
|
1051
|
-
const
|
|
944
|
+
const approvalUri = approvalIriForCreatedAt(webId, approvalId, now);
|
|
945
|
+
const target = subject.target ?? sessionUri;
|
|
1052
946
|
const assignedTo = subject.assignedTo ?? webId;
|
|
1053
947
|
const onBehalfOf = subject.onBehalfOf ?? webId;
|
|
1054
948
|
const policyVersion = subject.policyVersion ?? REMOTE_APPROVAL_POLICY_VERSION;
|
|
@@ -1061,7 +955,7 @@ export async function createRemoteApproval(options) {
|
|
|
1061
955
|
session: sessionUri,
|
|
1062
956
|
toolCallId: request.toolCallId,
|
|
1063
957
|
toolName: request.toolName,
|
|
1064
|
-
target
|
|
958
|
+
target,
|
|
1065
959
|
action: request.action,
|
|
1066
960
|
risk: request.risk,
|
|
1067
961
|
status: 'pending',
|
|
@@ -1099,7 +993,7 @@ export async function createRemoteApproval(options) {
|
|
|
1099
993
|
session: sessionUri,
|
|
1100
994
|
toolCallId: request.toolCallId,
|
|
1101
995
|
toolName: request.toolName,
|
|
1102
|
-
target
|
|
996
|
+
target,
|
|
1103
997
|
action: request.action,
|
|
1104
998
|
risk: request.risk,
|
|
1105
999
|
status: 'pending',
|
|
@@ -1159,13 +1053,21 @@ export async function requestRemoteAutoModeApproval(options) {
|
|
|
1159
1053
|
request: options.request,
|
|
1160
1054
|
runtime: activeRuntime,
|
|
1161
1055
|
});
|
|
1162
|
-
|
|
1056
|
+
const decision = await waitForRemoteAutoModeApproval({
|
|
1163
1057
|
approvalId: summary.id,
|
|
1164
1058
|
approvalUri: summary.approvalUri,
|
|
1165
1059
|
pollMs: options.pollMs,
|
|
1166
1060
|
signal: options.signal,
|
|
1167
1061
|
runtime: activeRuntime,
|
|
1168
1062
|
});
|
|
1063
|
+
if (decision === 'accept_for_session') {
|
|
1064
|
+
await materializeRemoteAutoModeGrant({
|
|
1065
|
+
approvalId: summary.id,
|
|
1066
|
+
approvalUri: summary.approvalUri,
|
|
1067
|
+
runtime: activeRuntime,
|
|
1068
|
+
});
|
|
1069
|
+
}
|
|
1070
|
+
return decision;
|
|
1169
1071
|
}
|
|
1170
1072
|
export async function resolveExistingRemoteAutoModeGrant(options) {
|
|
1171
1073
|
const activeRuntime = options.runtime ?? await createDefaultRuntime();
|
|
@@ -1249,7 +1151,7 @@ export async function resolveRemoteAutoModeApproval(options) {
|
|
|
1249
1151
|
}
|
|
1250
1152
|
const now = activeRuntime.now();
|
|
1251
1153
|
const approvalCreatedAt = new Date(toIsoString(row.createdAt, now.toISOString()));
|
|
1252
|
-
const approvalUri =
|
|
1154
|
+
const approvalUri = approvalIriForCreatedAt(row.session, row.id, approvalCreatedAt);
|
|
1253
1155
|
const nextStatus = options.decision === 'accept' || options.decision === 'accept_for_session'
|
|
1254
1156
|
? 'approved'
|
|
1255
1157
|
: 'rejected';
|
|
@@ -1259,7 +1161,7 @@ export async function resolveRemoteAutoModeApproval(options) {
|
|
|
1259
1161
|
decisionBy: webId,
|
|
1260
1162
|
decisionRole,
|
|
1261
1163
|
onBehalfOf: webId,
|
|
1262
|
-
reason:
|
|
1164
|
+
reason: buildAutoModeApprovalDecisionReason(options.decision, options.note),
|
|
1263
1165
|
resolvedAt: now,
|
|
1264
1166
|
}, {
|
|
1265
1167
|
resourceUri: options.approvalUri ?? row.approvalUri ?? approvalUri,
|
|
@@ -1278,41 +1180,6 @@ export async function resolveRemoteAutoModeApproval(options) {
|
|
|
1278
1180
|
policyVersion: REMOTE_APPROVAL_POLICY_VERSION,
|
|
1279
1181
|
createdAt: now,
|
|
1280
1182
|
}));
|
|
1281
|
-
if (options.decision === 'accept_for_session') {
|
|
1282
|
-
const grantId = crypto.randomUUID();
|
|
1283
|
-
const body = grantWikiBodyFromApproval(row, options.grantWikiBody);
|
|
1284
|
-
await store.insertGrant({
|
|
1285
|
-
id: grantId,
|
|
1286
|
-
target: row.target,
|
|
1287
|
-
action: row.action,
|
|
1288
|
-
title: grantWikiTitleFromApproval(row, options.grantWikiTitle),
|
|
1289
|
-
summary: grantWikiSummaryFromApproval(row, options.grantWikiSummary),
|
|
1290
|
-
body,
|
|
1291
|
-
schema: buildGrantSchemaUri(webId),
|
|
1292
|
-
pageKind: 'autonomy-grant',
|
|
1293
|
-
wikiStatus: 'active',
|
|
1294
|
-
tags: grantWikiTagsFromApproval(row, options.grantWikiTags),
|
|
1295
|
-
source: 'approval',
|
|
1296
|
-
sourceHash: grantSourceHash(row),
|
|
1297
|
-
compiledAt: now,
|
|
1298
|
-
compiledFrom: [approvalUri],
|
|
1299
|
-
related: [row.session],
|
|
1300
|
-
effect: 'allow',
|
|
1301
|
-
riskCeiling: row.risk,
|
|
1302
|
-
policy: grantIndexTextFromWikiBody(body),
|
|
1303
|
-
context: grantContextFromApproval(row),
|
|
1304
|
-
decisionBy: webId,
|
|
1305
|
-
decisionRole,
|
|
1306
|
-
onBehalfOf: webId,
|
|
1307
|
-
createdAt: now,
|
|
1308
|
-
});
|
|
1309
|
-
await warnOnly(activeRuntime, () => store.insertInboxNotification({
|
|
1310
|
-
id: crypto.randomUUID(),
|
|
1311
|
-
actor: webId,
|
|
1312
|
-
object: buildGrantUri(row.session, grantId),
|
|
1313
|
-
createdAt: now,
|
|
1314
|
-
}));
|
|
1315
|
-
}
|
|
1316
1183
|
await warnOnly(activeRuntime, () => store.insertInboxNotification({
|
|
1317
1184
|
id: crypto.randomUUID(),
|
|
1318
1185
|
actor: webId,
|
|
@@ -1325,12 +1192,73 @@ export async function resolveRemoteAutoModeApproval(options) {
|
|
|
1325
1192
|
decisionBy: webId,
|
|
1326
1193
|
decisionRole,
|
|
1327
1194
|
onBehalfOf: webId,
|
|
1328
|
-
reason:
|
|
1195
|
+
reason: buildAutoModeApprovalDecisionReason(options.decision, options.note),
|
|
1329
1196
|
resolvedAt: now,
|
|
1330
1197
|
};
|
|
1331
1198
|
return normalizeApprovalSummary(nextRow);
|
|
1332
1199
|
});
|
|
1333
1200
|
}
|
|
1201
|
+
export async function materializeRemoteAutoModeGrant(options) {
|
|
1202
|
+
const activeRuntime = options.runtime ?? await createDefaultRuntime();
|
|
1203
|
+
return withRemoteApprovalStore(activeRuntime, async ({ store, webId }) => {
|
|
1204
|
+
const row = await readRemoteApprovalRow(store, {
|
|
1205
|
+
approvalId: options.approvalId,
|
|
1206
|
+
approvalUri: options.approvalUri,
|
|
1207
|
+
});
|
|
1208
|
+
if (!row || row.status !== 'approved') {
|
|
1209
|
+
return null;
|
|
1210
|
+
}
|
|
1211
|
+
const decision = decisionFromApprovalRow(row);
|
|
1212
|
+
if (!shouldMaterializeAutoModeGrant(decision)) {
|
|
1213
|
+
return null;
|
|
1214
|
+
}
|
|
1215
|
+
const existing = await store.listGrants();
|
|
1216
|
+
const sourceHash = grantSourceHash(row);
|
|
1217
|
+
const existingGrant = existing.find((grant) => grant.source === 'approval' && grant.sourceHash === sourceHash);
|
|
1218
|
+
if (existingGrant) {
|
|
1219
|
+
return existingGrant;
|
|
1220
|
+
}
|
|
1221
|
+
const now = activeRuntime.now();
|
|
1222
|
+
const decisionRole = options.decisionRole ?? (row.decisionRole === 'secretary' ? 'secretary' : 'human');
|
|
1223
|
+
const grantId = crypto.randomUUID();
|
|
1224
|
+
const body = grantWikiBodyFromApproval(row, options.grantWikiBody);
|
|
1225
|
+
const approvalCreatedAt = new Date(toIsoString(row.createdAt, now.toISOString()));
|
|
1226
|
+
const approvalUri = options.approvalUri ?? row.approvalUri ?? approvalIriForCreatedAt(row.session, row.id, approvalCreatedAt);
|
|
1227
|
+
const grant = {
|
|
1228
|
+
id: grantId,
|
|
1229
|
+
target: row.target,
|
|
1230
|
+
action: row.action,
|
|
1231
|
+
title: grantWikiTitleFromApproval(row, options.grantWikiTitle),
|
|
1232
|
+
summary: grantWikiSummaryFromApproval(row, options.grantWikiSummary),
|
|
1233
|
+
body,
|
|
1234
|
+
schema: buildGrantSchemaUri(webId),
|
|
1235
|
+
pageKind: 'autonomy-grant',
|
|
1236
|
+
wikiStatus: 'active',
|
|
1237
|
+
tags: grantWikiTagsFromApproval(row, options.grantWikiTags),
|
|
1238
|
+
source: 'approval',
|
|
1239
|
+
sourceHash,
|
|
1240
|
+
compiledAt: now,
|
|
1241
|
+
compiledFrom: [approvalUri],
|
|
1242
|
+
related: [row.session],
|
|
1243
|
+
effect: 'allow',
|
|
1244
|
+
riskCeiling: row.risk,
|
|
1245
|
+
policy: grantIndexTextFromWikiBody(body),
|
|
1246
|
+
context: grantContextFromApproval(row),
|
|
1247
|
+
decisionBy: row.decisionBy ?? webId,
|
|
1248
|
+
decisionRole,
|
|
1249
|
+
onBehalfOf: row.onBehalfOf ?? webId,
|
|
1250
|
+
createdAt: now,
|
|
1251
|
+
};
|
|
1252
|
+
await store.insertGrant(grant);
|
|
1253
|
+
await warnOnly(activeRuntime, () => store.insertInboxNotification({
|
|
1254
|
+
id: crypto.randomUUID(),
|
|
1255
|
+
actor: webId,
|
|
1256
|
+
object: grantIri(row.session, grantId),
|
|
1257
|
+
createdAt: now,
|
|
1258
|
+
}));
|
|
1259
|
+
return grant;
|
|
1260
|
+
});
|
|
1261
|
+
}
|
|
1334
1262
|
async function readRemoteApprovalRow(store, options) {
|
|
1335
1263
|
if (store.findApproval) {
|
|
1336
1264
|
const row = await store.findApproval(options.approvalId, {
|
|
@@ -1353,11 +1281,12 @@ export const __podApprovalInternal = {
|
|
|
1353
1281
|
createNativeRemoteApprovalStore,
|
|
1354
1282
|
extractToolCallId,
|
|
1355
1283
|
decisionFromApprovalRow,
|
|
1356
|
-
encodeDecisionReason,
|
|
1284
|
+
encodeDecisionReason: buildAutoModeApprovalDecisionReason,
|
|
1357
1285
|
formatSummaryHeadline,
|
|
1286
|
+
grantSourceHash,
|
|
1358
1287
|
readRemoteApprovalRow,
|
|
1359
1288
|
isRemoteApprovalAbortError,
|
|
1360
1289
|
normalizeApprovalSummary,
|
|
1361
|
-
parseDecisionReason,
|
|
1290
|
+
parseDecisionReason: parseAutoModeApprovalDecisionReason,
|
|
1362
1291
|
};
|
|
1363
1292
|
//# sourceMappingURL=pod-approval.js.map
|