@undefineds.co/models 0.2.15 → 0.2.18
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 +26 -28
- package/dist/agent.providers.js +11 -0
- package/dist/agent.repository.d.ts +1 -1
- package/dist/ai-config/index.d.ts +10 -2
- package/dist/ai-config/index.js +53 -15
- package/dist/ai-model.schema.js +4 -3
- package/dist/ai-provider.schema.js +1 -1
- package/dist/approval.schema.d.ts +7 -1
- package/dist/approval.schema.js +6 -8
- package/dist/audit.presentation.d.ts +23 -0
- package/dist/audit.presentation.js +275 -0
- package/dist/audit.schema.d.ts +1 -1
- package/dist/audit.schema.js +3 -8
- package/dist/chat.repository.d.ts +1 -1
- package/dist/chat.utils.d.ts +9 -0
- package/dist/chat.utils.js +33 -0
- package/dist/contact.repository.d.ts +1 -1
- package/dist/contact.schema.d.ts +8 -0
- package/dist/contact.schema.js +12 -0
- package/dist/credential.schema.js +1 -1
- package/dist/discovery/models.json +29 -0
- package/dist/discovery/providers.json +10 -0
- package/dist/grant.schema.d.ts +28 -1
- package/dist/grant.schema.js +21 -7
- package/dist/index.d.ts +10 -8
- package/dist/index.js +9 -7
- package/dist/message.repository.d.ts +1 -1
- package/dist/namespaces.js +11 -0
- package/dist/profile.repository.d.ts +7 -7
- package/dist/repository.d.ts +1 -99
- package/dist/repository.js +1 -189
- package/dist/schema.d.ts +34 -0
- package/dist/session/index.d.ts +1 -1
- package/dist/session/index.js +1 -1
- package/dist/session/session.schema.d.ts +2 -1
- package/dist/session/session.schema.js +11 -7
- package/dist/session.repository.d.ts +1 -1
- package/dist/sidecar/persistence-mapping.d.ts +2 -2
- package/dist/sidecar/sidecar-events.d.ts +192 -6
- package/dist/sidecar/sidecar-events.js +10 -0
- package/dist/thread.repository.d.ts +1 -1
- package/dist/vocab/sidecar.vocab.d.ts +17 -0
- package/dist/vocab/sidecar.vocab.js +17 -0
- package/dist/watch/index.d.ts +55 -0
- package/dist/watch/index.js +349 -12
- package/package.json +4 -4
package/dist/watch/index.js
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
export const DEFAULT_WATCH_SECRETARY_REACTION_WINDOW_MS = 5000;
|
|
2
|
+
export const MIN_WATCH_SECRETARY_REACTION_WINDOW_MS = 5000;
|
|
3
|
+
export const MAX_WATCH_SECRETARY_REACTION_WINDOW_MS = 60000;
|
|
1
4
|
export const WATCH_HOME_DIRNAME = 'watch';
|
|
2
5
|
export const WATCH_SESSIONS_DIRNAME = 'sessions';
|
|
3
6
|
export const WATCH_SESSION_FILE_NAME = 'session.json';
|
|
@@ -136,6 +139,97 @@ function normalizeAcpPermissionOptions(value) {
|
|
|
136
139
|
}
|
|
137
140
|
return value.filter((item) => isRecord(item));
|
|
138
141
|
}
|
|
142
|
+
export function normalizeWatchApprovalOptions(value) {
|
|
143
|
+
return normalizeAcpPermissionOptions(value)
|
|
144
|
+
.map((option) => {
|
|
145
|
+
const optionId = typeof option.optionId === 'string' && option.optionId.trim()
|
|
146
|
+
? option.optionId.trim()
|
|
147
|
+
: undefined;
|
|
148
|
+
const label = firstNonEmpty([
|
|
149
|
+
typeof option.name === 'string' ? option.name : undefined,
|
|
150
|
+
typeof option.label === 'string' ? option.label : undefined,
|
|
151
|
+
optionId,
|
|
152
|
+
]);
|
|
153
|
+
if (!optionId || !label) {
|
|
154
|
+
return null;
|
|
155
|
+
}
|
|
156
|
+
const kind = typeof option.kind === 'string' && option.kind.trim()
|
|
157
|
+
? option.kind.trim()
|
|
158
|
+
: undefined;
|
|
159
|
+
const description = firstNonEmpty([
|
|
160
|
+
typeof option.description === 'string' ? option.description : undefined,
|
|
161
|
+
typeof option.detail === 'string' ? option.detail : undefined,
|
|
162
|
+
]);
|
|
163
|
+
return {
|
|
164
|
+
optionId,
|
|
165
|
+
label,
|
|
166
|
+
...(kind ? { kind } : {}),
|
|
167
|
+
...(description ? { description } : {}),
|
|
168
|
+
};
|
|
169
|
+
})
|
|
170
|
+
.filter((option) => option !== null);
|
|
171
|
+
}
|
|
172
|
+
function normalizeDurationMs(value, unit) {
|
|
173
|
+
const numeric = typeof value === 'number'
|
|
174
|
+
? value
|
|
175
|
+
: typeof value === 'string' && value.trim()
|
|
176
|
+
? Number(value)
|
|
177
|
+
: Number.NaN;
|
|
178
|
+
if (!Number.isFinite(numeric) || numeric <= 0) {
|
|
179
|
+
return undefined;
|
|
180
|
+
}
|
|
181
|
+
const milliseconds = unit === 'ms'
|
|
182
|
+
? numeric
|
|
183
|
+
: unit === 'seconds'
|
|
184
|
+
? numeric * 1000
|
|
185
|
+
: numeric > 10000
|
|
186
|
+
? numeric
|
|
187
|
+
: numeric * 1000;
|
|
188
|
+
return Math.round(milliseconds);
|
|
189
|
+
}
|
|
190
|
+
function normalizeIsoDatetime(value) {
|
|
191
|
+
if (value instanceof Date) {
|
|
192
|
+
return Number.isFinite(value.getTime()) ? value.toISOString() : undefined;
|
|
193
|
+
}
|
|
194
|
+
if (typeof value === 'number' && Number.isFinite(value)) {
|
|
195
|
+
const date = new Date(value);
|
|
196
|
+
return Number.isFinite(date.getTime()) ? date.toISOString() : undefined;
|
|
197
|
+
}
|
|
198
|
+
if (typeof value !== 'string' || !value.trim()) {
|
|
199
|
+
return undefined;
|
|
200
|
+
}
|
|
201
|
+
const date = new Date(value);
|
|
202
|
+
return Number.isFinite(date.getTime()) ? date.toISOString() : undefined;
|
|
203
|
+
}
|
|
204
|
+
function extractWatchApprovalTimeoutMs(params, raw) {
|
|
205
|
+
const meta = isRecord(params._meta)
|
|
206
|
+
? params._meta
|
|
207
|
+
: isRecord(raw._meta)
|
|
208
|
+
? raw._meta
|
|
209
|
+
: {};
|
|
210
|
+
return normalizeDurationMs(params.timeoutMs ?? meta.timeoutMs, 'ms')
|
|
211
|
+
?? normalizeDurationMs(params.timeoutMillis ?? params.timeoutMilliseconds ?? meta.timeoutMillis ?? meta.timeoutMilliseconds, 'ms')
|
|
212
|
+
?? normalizeDurationMs(params.timeoutSeconds ?? params.timeoutSec ?? meta.timeoutSeconds ?? meta.timeoutSec, 'seconds')
|
|
213
|
+
?? normalizeDurationMs(params.timeout ?? meta.timeout, 'auto');
|
|
214
|
+
}
|
|
215
|
+
function extractWatchApprovalExpiresAt(params, raw) {
|
|
216
|
+
const meta = isRecord(params._meta)
|
|
217
|
+
? params._meta
|
|
218
|
+
: isRecord(raw._meta)
|
|
219
|
+
? raw._meta
|
|
220
|
+
: {};
|
|
221
|
+
return normalizeIsoDatetime(params.expiresAt ?? params.deadline ?? params.expires ?? meta.expiresAt ?? meta.deadline ?? meta.expires);
|
|
222
|
+
}
|
|
223
|
+
function extractWatchApprovalMetadata(raw, params) {
|
|
224
|
+
const approvalOptions = normalizeWatchApprovalOptions(params.options);
|
|
225
|
+
const timeoutMs = extractWatchApprovalTimeoutMs(params, raw);
|
|
226
|
+
const expiresAt = extractWatchApprovalExpiresAt(params, raw);
|
|
227
|
+
return {
|
|
228
|
+
...(approvalOptions.length > 0 ? { approvalOptions } : {}),
|
|
229
|
+
...(timeoutMs ? { timeoutMs } : {}),
|
|
230
|
+
...(expiresAt ? { expiresAt } : {}),
|
|
231
|
+
};
|
|
232
|
+
}
|
|
139
233
|
function selectAcpPermissionOption(options, decision) {
|
|
140
234
|
if (decision === 'cancel') {
|
|
141
235
|
return undefined;
|
|
@@ -262,9 +356,241 @@ export function resolveWatchAutoApprovalDecision(input) {
|
|
|
262
356
|
}
|
|
263
357
|
return null;
|
|
264
358
|
}
|
|
359
|
+
export function createFallbackWatchSecretaryRecommendation(input) {
|
|
360
|
+
if (input.mode === 'manual' || input.request.kind === 'user-input') {
|
|
361
|
+
return null;
|
|
362
|
+
}
|
|
363
|
+
const decision = resolveWatchAutoApprovalDecision({
|
|
364
|
+
mode: input.mode,
|
|
365
|
+
request: input.request,
|
|
366
|
+
});
|
|
367
|
+
const secretaryDecision = decision === 'accept_for_session' ? 'accept' : decision;
|
|
368
|
+
if (!secretaryDecision) {
|
|
369
|
+
return null;
|
|
370
|
+
}
|
|
371
|
+
return {
|
|
372
|
+
kind: input.request.kind,
|
|
373
|
+
canAutoDecide: true,
|
|
374
|
+
decision: secretaryDecision,
|
|
375
|
+
confidence: input.mode === 'auto' ? 0.7 : 0.6,
|
|
376
|
+
reason: 'Matched local fallback policy while AI secretary was unavailable.',
|
|
377
|
+
reactionWindowMs: 0,
|
|
378
|
+
source: 'fallback',
|
|
379
|
+
};
|
|
380
|
+
}
|
|
381
|
+
export function parseWatchSecretaryRecommendation(text, options) {
|
|
382
|
+
const raw = parseJsonObjectFromText(text);
|
|
383
|
+
if (!raw) {
|
|
384
|
+
return null;
|
|
385
|
+
}
|
|
386
|
+
const canAutoDecide = booleanFromUnknown(raw.canAutoDecide
|
|
387
|
+
?? raw.can_auto_decide
|
|
388
|
+
?? raw.autoApprove
|
|
389
|
+
?? raw.auto_approve
|
|
390
|
+
?? raw.canAnswer
|
|
391
|
+
?? raw.can_answer);
|
|
392
|
+
const confidence = normalizeConfidence(raw.confidence ?? raw.confidenceScore ?? raw.confidence_score);
|
|
393
|
+
const reason = stringFromUnknown(raw.reason ?? raw.rationale ?? raw.explanation);
|
|
394
|
+
const fallbackReactionWindowMs = options.defaultReactionWindowMs ?? DEFAULT_WATCH_SECRETARY_REACTION_WINDOW_MS;
|
|
395
|
+
const reactionWindowMs = confidence !== undefined
|
|
396
|
+
? computeWatchSecretaryReactionWindowMs(confidence, fallbackReactionWindowMs)
|
|
397
|
+
: normalizeReactionWindowMs(raw.reactionWindowMs
|
|
398
|
+
?? raw.reaction_window_ms
|
|
399
|
+
?? raw.reviewWindowMs
|
|
400
|
+
?? raw.review_window_ms
|
|
401
|
+
?? raw.autoDecisionDelayMs
|
|
402
|
+
?? raw.auto_decision_delay_ms, fallbackReactionWindowMs);
|
|
403
|
+
if (options.request.kind === 'user-input') {
|
|
404
|
+
const answers = normalizeSecretaryUserInputAnswers(options.request.questions, raw.answers ?? raw.answer ?? raw.userInputAnswers ?? raw.user_input_answers);
|
|
405
|
+
return {
|
|
406
|
+
kind: 'user-input',
|
|
407
|
+
canAutoDecide: canAutoDecide === true && !!answers,
|
|
408
|
+
...(confidence !== undefined ? { confidence } : {}),
|
|
409
|
+
...(reason ? { reason } : {}),
|
|
410
|
+
...(reactionWindowMs !== undefined ? { reactionWindowMs } : {}),
|
|
411
|
+
...(answers ? { answers } : {}),
|
|
412
|
+
source: 'model',
|
|
413
|
+
};
|
|
414
|
+
}
|
|
415
|
+
const decision = normalizeSecretaryApprovalDecision(raw.decision ?? raw.recommendedDecision ?? raw.recommended_decision);
|
|
416
|
+
if (!decision) {
|
|
417
|
+
return {
|
|
418
|
+
kind: options.request.kind,
|
|
419
|
+
canAutoDecide: false,
|
|
420
|
+
...(confidence !== undefined ? { confidence } : {}),
|
|
421
|
+
...(reason ? { reason } : {}),
|
|
422
|
+
...(reactionWindowMs !== undefined ? { reactionWindowMs } : {}),
|
|
423
|
+
source: 'model',
|
|
424
|
+
};
|
|
425
|
+
}
|
|
426
|
+
return {
|
|
427
|
+
kind: options.request.kind,
|
|
428
|
+
canAutoDecide: canAutoDecide === true,
|
|
429
|
+
decision,
|
|
430
|
+
...(confidence !== undefined ? { confidence } : {}),
|
|
431
|
+
...(reason ? { reason } : {}),
|
|
432
|
+
...(reactionWindowMs !== undefined ? { reactionWindowMs } : {}),
|
|
433
|
+
source: 'model',
|
|
434
|
+
};
|
|
435
|
+
}
|
|
436
|
+
export function watchApprovalDecisionLabel(decision) {
|
|
437
|
+
if (decision === 'accept') {
|
|
438
|
+
return 'Allow once';
|
|
439
|
+
}
|
|
440
|
+
if (decision === 'accept_for_session') {
|
|
441
|
+
return 'Grant';
|
|
442
|
+
}
|
|
443
|
+
if (decision === 'decline') {
|
|
444
|
+
return 'Deny';
|
|
445
|
+
}
|
|
446
|
+
return 'Cancel';
|
|
447
|
+
}
|
|
448
|
+
export function watchUserInputAnswersSummary(answers) {
|
|
449
|
+
return Object.entries(answers)
|
|
450
|
+
.map(([key, value]) => `${key}: ${value.answers.join(', ')}`)
|
|
451
|
+
.join('; ');
|
|
452
|
+
}
|
|
453
|
+
export function parseWatchGrantCoverageDecision(text) {
|
|
454
|
+
const raw = parseJsonObjectFromText(text);
|
|
455
|
+
if (!raw) {
|
|
456
|
+
return null;
|
|
457
|
+
}
|
|
458
|
+
const covers = booleanFromUnknown(raw.covers ?? raw.covered ?? raw.applies ?? raw.allowed);
|
|
459
|
+
if (covers === undefined) {
|
|
460
|
+
return null;
|
|
461
|
+
}
|
|
462
|
+
const confidence = normalizeConfidence(raw.confidence ?? raw.confidenceScore ?? raw.confidence_score);
|
|
463
|
+
const reason = stringFromUnknown(raw.reason ?? raw.rationale ?? raw.explanation);
|
|
464
|
+
return {
|
|
465
|
+
covers,
|
|
466
|
+
...(confidence !== undefined ? { confidence } : {}),
|
|
467
|
+
...(reason ? { reason } : {}),
|
|
468
|
+
source: 'model',
|
|
469
|
+
};
|
|
470
|
+
}
|
|
265
471
|
function isRecord(value) {
|
|
266
472
|
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
267
473
|
}
|
|
474
|
+
function stringFromUnknown(value) {
|
|
475
|
+
return typeof value === 'string' && value.trim() ? value.trim() : undefined;
|
|
476
|
+
}
|
|
477
|
+
function booleanFromUnknown(value) {
|
|
478
|
+
if (typeof value === 'boolean') {
|
|
479
|
+
return value;
|
|
480
|
+
}
|
|
481
|
+
if (typeof value === 'string') {
|
|
482
|
+
const normalized = value.trim().toLowerCase();
|
|
483
|
+
if (['true', 'yes', 'y', '1'].includes(normalized)) {
|
|
484
|
+
return true;
|
|
485
|
+
}
|
|
486
|
+
if (['false', 'no', 'n', '0'].includes(normalized)) {
|
|
487
|
+
return false;
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
return undefined;
|
|
491
|
+
}
|
|
492
|
+
function normalizeConfidence(value) {
|
|
493
|
+
if (typeof value === 'number' && Number.isFinite(value)) {
|
|
494
|
+
if (value > 1 && value <= 100) {
|
|
495
|
+
return Math.max(0, Math.min(1, value / 100));
|
|
496
|
+
}
|
|
497
|
+
return Math.max(0, Math.min(1, value));
|
|
498
|
+
}
|
|
499
|
+
if (typeof value === 'string' && value.trim()) {
|
|
500
|
+
const parsed = Number(value);
|
|
501
|
+
return Number.isFinite(parsed) ? normalizeConfidence(parsed) : undefined;
|
|
502
|
+
}
|
|
503
|
+
return undefined;
|
|
504
|
+
}
|
|
505
|
+
function normalizeReactionWindowMs(value, fallback) {
|
|
506
|
+
const parsed = normalizeDurationMs(value ?? fallback, 'ms');
|
|
507
|
+
if (parsed === undefined) {
|
|
508
|
+
return undefined;
|
|
509
|
+
}
|
|
510
|
+
return Math.max(0, Math.min(MAX_WATCH_SECRETARY_REACTION_WINDOW_MS, parsed));
|
|
511
|
+
}
|
|
512
|
+
export function computeWatchSecretaryReactionWindowMs(confidence, fallback = DEFAULT_WATCH_SECRETARY_REACTION_WINDOW_MS) {
|
|
513
|
+
if (typeof confidence !== 'number' || !Number.isFinite(confidence)) {
|
|
514
|
+
return Math.max(0, Math.min(MAX_WATCH_SECRETARY_REACTION_WINDOW_MS, fallback));
|
|
515
|
+
}
|
|
516
|
+
const normalized = Math.max(0, Math.min(1, confidence));
|
|
517
|
+
const window = Math.round(MIN_WATCH_SECRETARY_REACTION_WINDOW_MS
|
|
518
|
+
+ (1 - normalized) * (MAX_WATCH_SECRETARY_REACTION_WINDOW_MS - MIN_WATCH_SECRETARY_REACTION_WINDOW_MS));
|
|
519
|
+
return Math.max(MIN_WATCH_SECRETARY_REACTION_WINDOW_MS, Math.min(MAX_WATCH_SECRETARY_REACTION_WINDOW_MS, window));
|
|
520
|
+
}
|
|
521
|
+
function normalizeSecretaryApprovalDecision(value) {
|
|
522
|
+
if (typeof value !== 'string') {
|
|
523
|
+
return undefined;
|
|
524
|
+
}
|
|
525
|
+
const normalized = value.trim().toLowerCase().replace(/-/g, '_');
|
|
526
|
+
if (['accept', 'allow', 'allow_once', 'approve', 'yes', 'accept_for_session', 'allow_always', 'grant', 'session', 'approve_for_session'].includes(normalized)) {
|
|
527
|
+
return 'accept';
|
|
528
|
+
}
|
|
529
|
+
if (['decline', 'deny', 'reject', 'reject_once', 'reject_always', 'no'].includes(normalized)) {
|
|
530
|
+
return 'decline';
|
|
531
|
+
}
|
|
532
|
+
if (['cancel', 'abort'].includes(normalized)) {
|
|
533
|
+
return 'cancel';
|
|
534
|
+
}
|
|
535
|
+
return undefined;
|
|
536
|
+
}
|
|
537
|
+
function parseJsonObjectFromText(text) {
|
|
538
|
+
const trimmed = text.trim();
|
|
539
|
+
if (!trimmed) {
|
|
540
|
+
return null;
|
|
541
|
+
}
|
|
542
|
+
for (const candidate of [
|
|
543
|
+
trimmed,
|
|
544
|
+
extractFencedJson(trimmed),
|
|
545
|
+
extractBracedJson(trimmed),
|
|
546
|
+
]) {
|
|
547
|
+
if (!candidate) {
|
|
548
|
+
continue;
|
|
549
|
+
}
|
|
550
|
+
try {
|
|
551
|
+
const parsed = JSON.parse(candidate);
|
|
552
|
+
return recordFromUnknown(parsed);
|
|
553
|
+
}
|
|
554
|
+
catch {
|
|
555
|
+
// Try the next extraction shape.
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
return null;
|
|
559
|
+
}
|
|
560
|
+
function extractFencedJson(text) {
|
|
561
|
+
const match = text.match(/```(?:json)?\s*([\s\S]*?)```/iu);
|
|
562
|
+
return match?.[1]?.trim() || null;
|
|
563
|
+
}
|
|
564
|
+
function extractBracedJson(text) {
|
|
565
|
+
const start = text.indexOf('{');
|
|
566
|
+
const end = text.lastIndexOf('}');
|
|
567
|
+
return start !== -1 && end > start ? text.slice(start, end + 1) : null;
|
|
568
|
+
}
|
|
569
|
+
function normalizeSecretaryUserInputAnswers(questions, rawAnswers) {
|
|
570
|
+
const source = recordFromUnknown(rawAnswers);
|
|
571
|
+
if (!source) {
|
|
572
|
+
return undefined;
|
|
573
|
+
}
|
|
574
|
+
const answers = {};
|
|
575
|
+
for (const question of questions) {
|
|
576
|
+
const raw = source[question.id] ?? source[question.header] ?? source[question.question];
|
|
577
|
+
const normalizedAnswers = normalizeSecretaryAnswerValues(raw);
|
|
578
|
+
if (normalizedAnswers.length > 0) {
|
|
579
|
+
answers[question.id] = { answers: normalizedAnswers };
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
return Object.keys(answers).length > 0 ? answers : undefined;
|
|
583
|
+
}
|
|
584
|
+
function normalizeSecretaryAnswerValues(value) {
|
|
585
|
+
const answerRecord = recordFromUnknown(value);
|
|
586
|
+
if (answerRecord) {
|
|
587
|
+
return normalizeSecretaryAnswerValues(answerRecord.answers ?? answerRecord.value ?? answerRecord.answer);
|
|
588
|
+
}
|
|
589
|
+
const values = Array.isArray(value) ? value : [value];
|
|
590
|
+
return values
|
|
591
|
+
.map((entry) => typeof entry === 'string' ? entry.trim() : '')
|
|
592
|
+
.filter(Boolean);
|
|
593
|
+
}
|
|
268
594
|
function firstNonEmpty(values) {
|
|
269
595
|
for (const value of values) {
|
|
270
596
|
if (typeof value === 'string' && value.trim()) {
|
|
@@ -433,6 +759,7 @@ export function normalizeCodexAppServerInteractionRequest(message) {
|
|
|
433
759
|
const params = (typeof message.params === 'object' && message.params !== null
|
|
434
760
|
? message.params
|
|
435
761
|
: {});
|
|
762
|
+
const approvalMetadata = extractWatchApprovalMetadata(message, params);
|
|
436
763
|
if (method === 'item/commandExecution/requestApproval') {
|
|
437
764
|
const command = typeof params.command === 'string' ? params.command : undefined;
|
|
438
765
|
const cwd = typeof params.cwd === 'string' ? params.cwd : undefined;
|
|
@@ -441,6 +768,7 @@ export function normalizeCodexAppServerInteractionRequest(message) {
|
|
|
441
768
|
message: command || 'Codex requests command approval',
|
|
442
769
|
command,
|
|
443
770
|
cwd,
|
|
771
|
+
...approvalMetadata,
|
|
444
772
|
raw: message,
|
|
445
773
|
};
|
|
446
774
|
}
|
|
@@ -450,6 +778,7 @@ export function normalizeCodexAppServerInteractionRequest(message) {
|
|
|
450
778
|
kind: 'file-change-approval',
|
|
451
779
|
message: reason && reason.trim() ? reason : 'Codex requests file-change approval',
|
|
452
780
|
...(reason ? { reason } : {}),
|
|
781
|
+
...approvalMetadata,
|
|
453
782
|
raw: message,
|
|
454
783
|
};
|
|
455
784
|
}
|
|
@@ -460,6 +789,7 @@ export function normalizeCodexAppServerInteractionRequest(message) {
|
|
|
460
789
|
kind: 'permissions-approval',
|
|
461
790
|
message: reason && reason.trim() ? reason : 'Codex requests additional permissions',
|
|
462
791
|
permissions,
|
|
792
|
+
...approvalMetadata,
|
|
463
793
|
raw: message,
|
|
464
794
|
};
|
|
465
795
|
}
|
|
@@ -480,6 +810,7 @@ export function normalizeCodexAppServerInteractionRequest(message) {
|
|
|
480
810
|
return {
|
|
481
811
|
kind: 'codex-approval',
|
|
482
812
|
message: 'Codex requests approval',
|
|
813
|
+
...approvalMetadata,
|
|
483
814
|
raw: message,
|
|
484
815
|
};
|
|
485
816
|
}
|
|
@@ -542,6 +873,7 @@ export function normalizeAcpInteractionRequest(message) {
|
|
|
542
873
|
const method = typeof message.method === 'string' ? message.method.toLowerCase() : '';
|
|
543
874
|
const params = (recordFromUnknown(message.params) ?? {});
|
|
544
875
|
if (method === 'session/request_permission' || Array.isArray(params.options)) {
|
|
876
|
+
const approvalMetadata = extractWatchApprovalMetadata(message, params);
|
|
545
877
|
const toolCall = (recordFromUnknown(params.toolCall) ?? {});
|
|
546
878
|
const toolKind = typeof toolCall.kind === 'string' ? toolCall.kind : '';
|
|
547
879
|
const command = extractAcpCommand(toolCall.rawInput);
|
|
@@ -563,6 +895,7 @@ export function normalizeAcpInteractionRequest(message) {
|
|
|
563
895
|
message: command ?? messageText,
|
|
564
896
|
...(command ? { command } : {}),
|
|
565
897
|
...(cwd ? { cwd } : {}),
|
|
898
|
+
...approvalMetadata,
|
|
566
899
|
raw: message,
|
|
567
900
|
};
|
|
568
901
|
}
|
|
@@ -571,6 +904,7 @@ export function normalizeAcpInteractionRequest(message) {
|
|
|
571
904
|
kind: 'file-change-approval',
|
|
572
905
|
message: messageText,
|
|
573
906
|
reason: messageText,
|
|
907
|
+
...approvalMetadata,
|
|
574
908
|
raw: message,
|
|
575
909
|
};
|
|
576
910
|
}
|
|
@@ -578,6 +912,7 @@ export function normalizeAcpInteractionRequest(message) {
|
|
|
578
912
|
kind: 'permissions-approval',
|
|
579
913
|
message: messageText,
|
|
580
914
|
permissions: recordFromUnknown(toolCall.rawInput) ?? {},
|
|
915
|
+
...approvalMetadata,
|
|
581
916
|
raw: message,
|
|
582
917
|
};
|
|
583
918
|
}
|
|
@@ -788,6 +1123,7 @@ function maybeWatchApprovalEvent(json, lowerType) {
|
|
|
788
1123
|
kind: 'permissions-approval',
|
|
789
1124
|
message: message || 'Approval required',
|
|
790
1125
|
permissions: json.permissions,
|
|
1126
|
+
...extractWatchApprovalMetadata(json, json),
|
|
791
1127
|
raw: json,
|
|
792
1128
|
},
|
|
793
1129
|
}
|
|
@@ -1048,13 +1384,14 @@ export function buildWatchThreadMetadata(record) {
|
|
|
1048
1384
|
backendSessionId: record.backendSessionId,
|
|
1049
1385
|
};
|
|
1050
1386
|
}
|
|
1051
|
-
function pushWatchTranscriptMessage(messages, role, content, createdAt) {
|
|
1387
|
+
function pushWatchTranscriptMessage(messages, role, source, content, createdAt) {
|
|
1052
1388
|
const normalized = content?.replace(/\r/g, '').trimEnd();
|
|
1053
1389
|
if (!normalized) {
|
|
1054
1390
|
return;
|
|
1055
1391
|
}
|
|
1056
1392
|
messages.push({
|
|
1057
1393
|
role,
|
|
1394
|
+
source,
|
|
1058
1395
|
content: normalized,
|
|
1059
1396
|
createdAt,
|
|
1060
1397
|
});
|
|
@@ -1065,7 +1402,7 @@ function flushWatchAssistantMessage(messages, state, fallbackTimestamp) {
|
|
|
1065
1402
|
state.assistantTimestamp = undefined;
|
|
1066
1403
|
return;
|
|
1067
1404
|
}
|
|
1068
|
-
pushWatchTranscriptMessage(messages, 'assistant', state.assistantText, state.assistantTimestamp ?? fallbackTimestamp);
|
|
1405
|
+
pushWatchTranscriptMessage(messages, 'assistant', 'primary-agent', state.assistantText, state.assistantTimestamp ?? fallbackTimestamp);
|
|
1069
1406
|
state.assistantText = '';
|
|
1070
1407
|
state.assistantTimestamp = undefined;
|
|
1071
1408
|
}
|
|
@@ -1079,7 +1416,7 @@ function appendWatchTranscriptEvent(messages, state, entry, event) {
|
|
|
1079
1416
|
}
|
|
1080
1417
|
if (event.type === 'assistant.done') {
|
|
1081
1418
|
if (event.text && !state.assistantText) {
|
|
1082
|
-
pushWatchTranscriptMessage(messages, 'assistant', event.text, entry.timestamp);
|
|
1419
|
+
pushWatchTranscriptMessage(messages, 'assistant', 'primary-agent', event.text, entry.timestamp);
|
|
1083
1420
|
return;
|
|
1084
1421
|
}
|
|
1085
1422
|
flushWatchAssistantMessage(messages, state, entry.timestamp);
|
|
@@ -1087,18 +1424,18 @@ function appendWatchTranscriptEvent(messages, state, entry, event) {
|
|
|
1087
1424
|
}
|
|
1088
1425
|
flushWatchAssistantMessage(messages, state, entry.timestamp);
|
|
1089
1426
|
if (event.type === 'tool.call') {
|
|
1090
|
-
pushWatchTranscriptMessage(messages, 'system', `[tool] ${event.name}${event.arguments ? ` ${JSON.stringify(event.arguments)}` : ''}`, entry.timestamp);
|
|
1427
|
+
pushWatchTranscriptMessage(messages, 'system', 'tool', `[tool] ${event.name}${event.arguments ? ` ${JSON.stringify(event.arguments)}` : ''}`, entry.timestamp);
|
|
1091
1428
|
return;
|
|
1092
1429
|
}
|
|
1093
1430
|
if (event.type === 'approval.required') {
|
|
1094
|
-
pushWatchTranscriptMessage(messages, 'system', `[approval] ${event.message}`, entry.timestamp);
|
|
1431
|
+
pushWatchTranscriptMessage(messages, 'system', 'secretary', `[approval] ${event.message}`, entry.timestamp);
|
|
1095
1432
|
return;
|
|
1096
1433
|
}
|
|
1097
1434
|
if (event.type === 'input.required') {
|
|
1098
|
-
pushWatchTranscriptMessage(messages, 'system', `[input] ${event.message}`, entry.timestamp);
|
|
1435
|
+
pushWatchTranscriptMessage(messages, 'system', 'secretary', `[input] ${event.message}`, entry.timestamp);
|
|
1099
1436
|
return;
|
|
1100
1437
|
}
|
|
1101
|
-
pushWatchTranscriptMessage(messages, 'system', `[note] ${event.message}`, entry.timestamp);
|
|
1438
|
+
pushWatchTranscriptMessage(messages, 'system', 'system', `[note] ${event.message}`, entry.timestamp);
|
|
1102
1439
|
}
|
|
1103
1440
|
function appendWatchTranscriptRawEntry(messages, entry) {
|
|
1104
1441
|
const trimmed = entry.line.trim();
|
|
@@ -1109,7 +1446,7 @@ function appendWatchTranscriptRawEntry(messages, entry) {
|
|
|
1109
1446
|
const parsed = JSON.parse(trimmed);
|
|
1110
1447
|
const type = typeof parsed.type === 'string' ? parsed.type : '';
|
|
1111
1448
|
if (type === 'user.turn' && typeof parsed.text === 'string') {
|
|
1112
|
-
pushWatchTranscriptMessage(messages, 'user', parsed.text, entry.timestamp);
|
|
1449
|
+
pushWatchTranscriptMessage(messages, 'user', 'user', parsed.text, entry.timestamp);
|
|
1113
1450
|
return;
|
|
1114
1451
|
}
|
|
1115
1452
|
if (type === 'turn.start') {
|
|
@@ -1117,24 +1454,24 @@ function appendWatchTranscriptRawEntry(messages, entry) {
|
|
|
1117
1454
|
const args = Array.isArray(parsed.args)
|
|
1118
1455
|
? parsed.args.filter((value) => typeof value === 'string')
|
|
1119
1456
|
: [];
|
|
1120
|
-
pushWatchTranscriptMessage(messages, 'system', `[turn] ${[command, ...args].join(' ').trim()}`, entry.timestamp);
|
|
1457
|
+
pushWatchTranscriptMessage(messages, 'system', 'system', `[turn] ${[command, ...args].join(' ').trim()}`, entry.timestamp);
|
|
1121
1458
|
return;
|
|
1122
1459
|
}
|
|
1123
1460
|
if (type === 'credentials.resolve') {
|
|
1124
1461
|
const requested = typeof parsed.requestedCredentialSource === 'string' ? parsed.requestedCredentialSource : 'auto';
|
|
1125
1462
|
const resolved = typeof parsed.resolvedCredentialSource === 'string' ? parsed.resolvedCredentialSource : requested;
|
|
1126
|
-
pushWatchTranscriptMessage(messages, 'system', `[credentials] ${requested} -> ${resolved}`, entry.timestamp);
|
|
1463
|
+
pushWatchTranscriptMessage(messages, 'system', 'system', `[credentials] ${requested} -> ${resolved}`, entry.timestamp);
|
|
1127
1464
|
return;
|
|
1128
1465
|
}
|
|
1129
1466
|
if (type === 'process.error' && typeof parsed.message === 'string') {
|
|
1130
|
-
pushWatchTranscriptMessage(messages, 'system', `[error] ${parsed.message}`, entry.timestamp);
|
|
1467
|
+
pushWatchTranscriptMessage(messages, 'system', 'system', `[error] ${parsed.message}`, entry.timestamp);
|
|
1131
1468
|
return;
|
|
1132
1469
|
}
|
|
1133
1470
|
}
|
|
1134
1471
|
catch {
|
|
1135
1472
|
// Keep original line when it is not structured JSON.
|
|
1136
1473
|
}
|
|
1137
|
-
pushWatchTranscriptMessage(messages, 'system', entry.stream === 'stderr' ? `stderr> ${trimmed}` : trimmed, entry.timestamp);
|
|
1474
|
+
pushWatchTranscriptMessage(messages, 'system', entry.stream === 'stderr' ? 'system' : 'primary-agent', entry.stream === 'stderr' ? `stderr> ${trimmed}` : trimmed, entry.timestamp);
|
|
1138
1475
|
}
|
|
1139
1476
|
export function buildWatchTranscriptMessages(entries) {
|
|
1140
1477
|
const messages = [];
|
package/package.json
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@undefineds.co/models",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.18",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
6
8
|
"exports": {
|
|
7
9
|
".": {
|
|
8
10
|
"types": "./dist/index.d.ts",
|
|
@@ -60,7 +62,7 @@
|
|
|
60
62
|
"dependencies": {
|
|
61
63
|
"@comunica/query-sparql-solid": "^4.0.2",
|
|
62
64
|
"@inrupt/vocab-common-rdf": "^1.0.5",
|
|
63
|
-
"@undefineds.co/drizzle-solid": "^0.3.
|
|
65
|
+
"@undefineds.co/drizzle-solid": "^0.3.9",
|
|
64
66
|
"n3": "^1.26.0",
|
|
65
67
|
"zod": "^3.22.4"
|
|
66
68
|
},
|
|
@@ -69,8 +71,6 @@
|
|
|
69
71
|
"typescript": "^5.4.0",
|
|
70
72
|
"vitest": "^1.6.0"
|
|
71
73
|
},
|
|
72
|
-
"main": "./dist/index.js",
|
|
73
|
-
"types": "./dist/index.d.ts",
|
|
74
74
|
"files": [
|
|
75
75
|
"dist",
|
|
76
76
|
"README.md",
|