@promptbook/node 0.112.0-56 → 0.112.0-57
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/esm/index.es.js +990 -1005
- package/esm/index.es.js.map +1 -1
- package/esm/src/book-2.0/agent-source/createAgentModelRequirementsWithCommitments/ParsedAgentSourceWithCommitments.d.ts +7 -0
- package/esm/src/book-2.0/agent-source/createAgentModelRequirementsWithCommitments/applyCommitmentsToAgentModelRequirements.d.ts +14 -0
- package/esm/src/book-2.0/agent-source/createAgentModelRequirementsWithCommitments/augmentAgentModelRequirementsFromSource.d.ts +14 -0
- package/esm/src/book-2.0/agent-source/createAgentModelRequirementsWithCommitments/filterCommitmentsForAgentModelRequirements.d.ts +10 -0
- package/esm/src/book-2.0/agent-source/createAgentModelRequirementsWithCommitments/materializeInlineKnowledgeSources.d.ts +12 -0
- package/esm/src/book-2.0/agent-source/parseAgentSource/ParseAgentSourceState.d.ts +10 -0
- package/esm/src/book-2.0/agent-source/parseAgentSource/ParsedAgentProfile.d.ts +7 -0
- package/esm/src/book-2.0/agent-source/parseAgentSource/applyMetaCommitment.d.ts +8 -0
- package/esm/src/book-2.0/agent-source/parseAgentSource/consumeConversationSampleCommitment.d.ts +8 -0
- package/esm/src/book-2.0/agent-source/parseAgentSource/createCapabilitiesFromCommitment.d.ts +9 -0
- package/esm/src/book-2.0/agent-source/parseAgentSource/ensureMetaFullname.d.ts +7 -0
- package/esm/src/book-2.0/agent-source/parseAgentSource/extractAgentProfileText.d.ts +8 -0
- package/esm/src/book-2.0/agent-source/parseAgentSource/extractInitialMessage.d.ts +7 -0
- package/esm/src/book-2.0/agent-source/parseAgentSource/extractParsedAgentProfile.d.ts +8 -0
- package/esm/src/types/LlmToolDefinition.d.ts +17 -7
- package/esm/src/version.d.ts +1 -1
- package/package.json +2 -2
- package/umd/index.umd.js +990 -1005
- package/umd/index.umd.js.map +1 -1
- package/umd/src/book-2.0/agent-source/createAgentModelRequirementsWithCommitments/ParsedAgentSourceWithCommitments.d.ts +7 -0
- package/umd/src/book-2.0/agent-source/createAgentModelRequirementsWithCommitments/applyCommitmentsToAgentModelRequirements.d.ts +14 -0
- package/umd/src/book-2.0/agent-source/createAgentModelRequirementsWithCommitments/augmentAgentModelRequirementsFromSource.d.ts +14 -0
- package/umd/src/book-2.0/agent-source/createAgentModelRequirementsWithCommitments/filterCommitmentsForAgentModelRequirements.d.ts +10 -0
- package/umd/src/book-2.0/agent-source/createAgentModelRequirementsWithCommitments/materializeInlineKnowledgeSources.d.ts +12 -0
- package/umd/src/book-2.0/agent-source/parseAgentSource/ParseAgentSourceState.d.ts +10 -0
- package/umd/src/book-2.0/agent-source/parseAgentSource/ParsedAgentProfile.d.ts +7 -0
- package/umd/src/book-2.0/agent-source/parseAgentSource/applyMetaCommitment.d.ts +8 -0
- package/umd/src/book-2.0/agent-source/parseAgentSource/consumeConversationSampleCommitment.d.ts +8 -0
- package/umd/src/book-2.0/agent-source/parseAgentSource/createCapabilitiesFromCommitment.d.ts +9 -0
- package/umd/src/book-2.0/agent-source/parseAgentSource/ensureMetaFullname.d.ts +7 -0
- package/umd/src/book-2.0/agent-source/parseAgentSource/extractAgentProfileText.d.ts +8 -0
- package/umd/src/book-2.0/agent-source/parseAgentSource/extractInitialMessage.d.ts +7 -0
- package/umd/src/book-2.0/agent-source/parseAgentSource/extractParsedAgentProfile.d.ts +8 -0
- package/umd/src/types/LlmToolDefinition.d.ts +17 -7
- package/umd/src/version.d.ts +1 -1
package/umd/index.umd.js
CHANGED
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
* @generated
|
|
49
49
|
* @see https://github.com/webgptorg/promptbook
|
|
50
50
|
*/
|
|
51
|
-
const PROMPTBOOK_ENGINE_VERSION = '0.112.0-
|
|
51
|
+
const PROMPTBOOK_ENGINE_VERSION = '0.112.0-57';
|
|
52
52
|
/**
|
|
53
53
|
* TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
|
|
54
54
|
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
@@ -24171,6 +24171,44 @@
|
|
|
24171
24171
|
* @private constant of createUseCalendarTools
|
|
24172
24172
|
*/
|
|
24173
24173
|
const CALENDAR_URL_PARAMETER_DESCRIPTION = 'Google Calendar URL configured by USE CALENDAR (for example "https://calendar.google.com/...").';
|
|
24174
|
+
/**
|
|
24175
|
+
* Shared schema for string arrays used by USE CALENDAR tools.
|
|
24176
|
+
*
|
|
24177
|
+
* @private constant of createUseCalendarTools
|
|
24178
|
+
*/
|
|
24179
|
+
const STRING_ARRAY_ITEMS_SCHEMA = {
|
|
24180
|
+
type: 'string',
|
|
24181
|
+
};
|
|
24182
|
+
/**
|
|
24183
|
+
* Shared schema for integer arrays used by USE CALENDAR tools.
|
|
24184
|
+
*
|
|
24185
|
+
* @private constant of createUseCalendarTools
|
|
24186
|
+
*/
|
|
24187
|
+
const INTEGER_ARRAY_ITEMS_SCHEMA = {
|
|
24188
|
+
type: 'integer',
|
|
24189
|
+
};
|
|
24190
|
+
/**
|
|
24191
|
+
* Shared `sendUpdates` schema used by USE CALENDAR tools.
|
|
24192
|
+
*
|
|
24193
|
+
* @private constant of createUseCalendarTools
|
|
24194
|
+
*/
|
|
24195
|
+
const SEND_UPDATES_PARAMETER_SCHEMA = {
|
|
24196
|
+
type: 'string',
|
|
24197
|
+
description: 'Guest update policy ("all", "externalOnly", "none").',
|
|
24198
|
+
enum: ['all', 'externalOnly', 'none'],
|
|
24199
|
+
};
|
|
24200
|
+
/**
|
|
24201
|
+
* Creates an array parameter schema with explicit item definition so OpenAI accepts it.
|
|
24202
|
+
*
|
|
24203
|
+
* @private function of createUseCalendarTools
|
|
24204
|
+
*/
|
|
24205
|
+
function createArrayParameterSchema(description, items) {
|
|
24206
|
+
return {
|
|
24207
|
+
type: 'array',
|
|
24208
|
+
description,
|
|
24209
|
+
items,
|
|
24210
|
+
};
|
|
24211
|
+
}
|
|
24174
24212
|
/**
|
|
24175
24213
|
* Adds USE CALENDAR tool definitions while keeping already registered tools untouched.
|
|
24176
24214
|
*
|
|
@@ -24277,18 +24315,9 @@
|
|
|
24277
24315
|
type: 'string',
|
|
24278
24316
|
description: 'Optional timezone for datetime values.',
|
|
24279
24317
|
},
|
|
24280
|
-
attendees:
|
|
24281
|
-
|
|
24282
|
-
|
|
24283
|
-
},
|
|
24284
|
-
reminderMinutes: {
|
|
24285
|
-
type: 'array',
|
|
24286
|
-
description: 'Optional popup reminder minute offsets.',
|
|
24287
|
-
},
|
|
24288
|
-
sendUpdates: {
|
|
24289
|
-
type: 'string',
|
|
24290
|
-
description: 'Guest update policy ("all", "externalOnly", "none").',
|
|
24291
|
-
},
|
|
24318
|
+
attendees: createArrayParameterSchema('Optional guest email list.', STRING_ARRAY_ITEMS_SCHEMA),
|
|
24319
|
+
reminderMinutes: createArrayParameterSchema('Optional popup reminder minute offsets.', INTEGER_ARRAY_ITEMS_SCHEMA),
|
|
24320
|
+
sendUpdates: SEND_UPDATES_PARAMETER_SCHEMA,
|
|
24292
24321
|
},
|
|
24293
24322
|
required: ['summary', 'start', 'end'],
|
|
24294
24323
|
},
|
|
@@ -24331,18 +24360,9 @@
|
|
|
24331
24360
|
type: 'string',
|
|
24332
24361
|
description: 'Optional timezone for datetime values.',
|
|
24333
24362
|
},
|
|
24334
|
-
attendees:
|
|
24335
|
-
|
|
24336
|
-
|
|
24337
|
-
},
|
|
24338
|
-
reminderMinutes: {
|
|
24339
|
-
type: 'array',
|
|
24340
|
-
description: 'Optional replacement popup reminder minute offsets.',
|
|
24341
|
-
},
|
|
24342
|
-
sendUpdates: {
|
|
24343
|
-
type: 'string',
|
|
24344
|
-
description: 'Guest update policy ("all", "externalOnly", "none").',
|
|
24345
|
-
},
|
|
24363
|
+
attendees: createArrayParameterSchema('Optional replacement guest email list.', STRING_ARRAY_ITEMS_SCHEMA),
|
|
24364
|
+
reminderMinutes: createArrayParameterSchema('Optional replacement popup reminder minute offsets.', INTEGER_ARRAY_ITEMS_SCHEMA),
|
|
24365
|
+
sendUpdates: SEND_UPDATES_PARAMETER_SCHEMA,
|
|
24346
24366
|
},
|
|
24347
24367
|
required: ['eventId'],
|
|
24348
24368
|
},
|
|
@@ -24361,10 +24381,7 @@
|
|
|
24361
24381
|
type: 'string',
|
|
24362
24382
|
description: 'Google Calendar event id.',
|
|
24363
24383
|
},
|
|
24364
|
-
sendUpdates:
|
|
24365
|
-
type: 'string',
|
|
24366
|
-
description: 'Guest update policy ("all", "externalOnly", "none").',
|
|
24367
|
-
},
|
|
24384
|
+
sendUpdates: SEND_UPDATES_PARAMETER_SCHEMA,
|
|
24368
24385
|
},
|
|
24369
24386
|
required: ['eventId'],
|
|
24370
24387
|
},
|
|
@@ -24383,14 +24400,8 @@
|
|
|
24383
24400
|
type: 'string',
|
|
24384
24401
|
description: 'Google Calendar event id.',
|
|
24385
24402
|
},
|
|
24386
|
-
guests:
|
|
24387
|
-
|
|
24388
|
-
description: 'Guest email list to add to the event.',
|
|
24389
|
-
},
|
|
24390
|
-
sendUpdates: {
|
|
24391
|
-
type: 'string',
|
|
24392
|
-
description: 'Guest update policy ("all", "externalOnly", "none").',
|
|
24393
|
-
},
|
|
24403
|
+
guests: createArrayParameterSchema('Guest email list to add to the event.', STRING_ARRAY_ITEMS_SCHEMA),
|
|
24404
|
+
sendUpdates: SEND_UPDATES_PARAMETER_SCHEMA,
|
|
24394
24405
|
},
|
|
24395
24406
|
required: ['eventId', 'guests'],
|
|
24396
24407
|
},
|
|
@@ -31343,6 +31354,297 @@
|
|
|
31343
31354
|
return normalizeAgentName(`Agent ${agentHash.substring(0, LIMITS.SHORT_NAME_LENGTH)}`);
|
|
31344
31355
|
}
|
|
31345
31356
|
|
|
31357
|
+
/**
|
|
31358
|
+
* Consumes the agent-name prelude from raw source.
|
|
31359
|
+
*
|
|
31360
|
+
* Leading whitespace-only lines are skipped. The first subsequent line that contains any
|
|
31361
|
+
* non-whitespace characters is always treated as plain-text agent name, even when it starts
|
|
31362
|
+
* with a commitment keyword or other book syntax.
|
|
31363
|
+
*
|
|
31364
|
+
* @param agentSource - Raw agent source.
|
|
31365
|
+
* @returns Parsed prelude with shared line metadata.
|
|
31366
|
+
*
|
|
31367
|
+
* @private internal utility of book agent-source parsing
|
|
31368
|
+
*/
|
|
31369
|
+
function parseAgentSourcePrelude(agentSource) {
|
|
31370
|
+
const lines = agentSource.split(/\r?\n/);
|
|
31371
|
+
for (let lineIndex = 0; lineIndex < lines.length; lineIndex++) {
|
|
31372
|
+
const line = lines[lineIndex];
|
|
31373
|
+
if (line === undefined) {
|
|
31374
|
+
continue;
|
|
31375
|
+
}
|
|
31376
|
+
const trimmedLine = line.trim();
|
|
31377
|
+
if (!trimmedLine) {
|
|
31378
|
+
continue;
|
|
31379
|
+
}
|
|
31380
|
+
return {
|
|
31381
|
+
lines,
|
|
31382
|
+
agentName: trimmedLine,
|
|
31383
|
+
agentNameLineIndex: lineIndex,
|
|
31384
|
+
agentNameLineNumber: lineIndex + 1,
|
|
31385
|
+
};
|
|
31386
|
+
}
|
|
31387
|
+
return {
|
|
31388
|
+
lines,
|
|
31389
|
+
agentName: null,
|
|
31390
|
+
agentNameLineIndex: -1,
|
|
31391
|
+
};
|
|
31392
|
+
}
|
|
31393
|
+
|
|
31394
|
+
/**
|
|
31395
|
+
* Regex pattern to match horizontal lines (markdown thematic breaks)
|
|
31396
|
+
* Matches 3 or more hyphens, underscores, or asterisks (with optional spaces between)
|
|
31397
|
+
*/
|
|
31398
|
+
const HORIZONTAL_LINE_PATTERN$1 = /^[\s]*[-_*][\s]*[-_*][\s]*[-_*][\s]*[-_*]*[\s]*$/;
|
|
31399
|
+
/**
|
|
31400
|
+
* Parses agent source using the new commitment system with multiline support
|
|
31401
|
+
* This function replaces the hardcoded commitment parsing in the original parseAgentSource
|
|
31402
|
+
*
|
|
31403
|
+
* The first non-empty line is always consumed as plain-text agent name. Commitment parsing
|
|
31404
|
+
* starts only after that title line has been fixed.
|
|
31405
|
+
*
|
|
31406
|
+
* @private internal utility of `parseAgentSource`
|
|
31407
|
+
*/
|
|
31408
|
+
function parseAgentSourceWithCommitments(agentSource) {
|
|
31409
|
+
var _a, _b;
|
|
31410
|
+
if (!agentSource || !agentSource.trim()) {
|
|
31411
|
+
return {
|
|
31412
|
+
agentName: null,
|
|
31413
|
+
commitments: [],
|
|
31414
|
+
nonCommitmentLines: [],
|
|
31415
|
+
};
|
|
31416
|
+
}
|
|
31417
|
+
const { lines, agentName, agentNameLineIndex, agentNameLineNumber } = parseAgentSourcePrelude(agentSource);
|
|
31418
|
+
const commitments = [];
|
|
31419
|
+
const nonCommitmentLines = agentNameLineIndex >= 0 ? [lines[agentNameLineIndex]] : [];
|
|
31420
|
+
// Parse commitments with multiline support
|
|
31421
|
+
let currentCommitment = null;
|
|
31422
|
+
// Process lines starting from after the agent name line
|
|
31423
|
+
const startIndex = agentNameLineIndex >= 0 ? agentNameLineIndex + 1 : 0;
|
|
31424
|
+
let isInsideCodeBlock = false;
|
|
31425
|
+
for (let i = startIndex; i < lines.length; i++) {
|
|
31426
|
+
const line = lines[i];
|
|
31427
|
+
if (line === undefined) {
|
|
31428
|
+
continue;
|
|
31429
|
+
}
|
|
31430
|
+
const trimmedLine = line.trim();
|
|
31431
|
+
// Check if this line starts or ends a code block
|
|
31432
|
+
if (trimmedLine.startsWith('```')) {
|
|
31433
|
+
isInsideCodeBlock = !isInsideCodeBlock;
|
|
31434
|
+
if (currentCommitment) {
|
|
31435
|
+
// If we are inside a commitment, the code block is part of it
|
|
31436
|
+
currentCommitment.contentLines.push(line);
|
|
31437
|
+
}
|
|
31438
|
+
else {
|
|
31439
|
+
// If we are not inside a commitment, the code block is non-commitment
|
|
31440
|
+
nonCommitmentLines.push(line);
|
|
31441
|
+
}
|
|
31442
|
+
continue;
|
|
31443
|
+
}
|
|
31444
|
+
if (isInsideCodeBlock) {
|
|
31445
|
+
if (currentCommitment) {
|
|
31446
|
+
// If we are inside a commitment and a code block, the line is part of the commitment
|
|
31447
|
+
currentCommitment.contentLines.push(line);
|
|
31448
|
+
}
|
|
31449
|
+
else {
|
|
31450
|
+
// If we are inside a code block but not a commitment, the line is non-commitment
|
|
31451
|
+
nonCommitmentLines.push(line);
|
|
31452
|
+
}
|
|
31453
|
+
continue;
|
|
31454
|
+
}
|
|
31455
|
+
// Check if this line starts a new commitment
|
|
31456
|
+
let foundNewCommitment = false;
|
|
31457
|
+
for (const definition of COMMITMENT_REGISTRY) {
|
|
31458
|
+
const typeRegex = definition.createTypeRegex();
|
|
31459
|
+
const match = typeRegex.exec(line.trim());
|
|
31460
|
+
if (match && ((_a = match.groups) === null || _a === void 0 ? void 0 : _a.type)) {
|
|
31461
|
+
// Save the previous commitment if it exists
|
|
31462
|
+
if (currentCommitment) {
|
|
31463
|
+
const fullContent = currentCommitment.contentLines.join('\n');
|
|
31464
|
+
commitments.push({
|
|
31465
|
+
type: currentCommitment.type,
|
|
31466
|
+
content: _spaceTrim.spaceTrim(fullContent),
|
|
31467
|
+
originalLine: currentCommitment.originalStartLine,
|
|
31468
|
+
lineNumber: currentCommitment.startLineNumber,
|
|
31469
|
+
});
|
|
31470
|
+
}
|
|
31471
|
+
// Extract the initial content from the commitment line
|
|
31472
|
+
const fullRegex = definition.createRegex();
|
|
31473
|
+
const fullMatch = fullRegex.exec(line.trim());
|
|
31474
|
+
const initialContent = ((_b = fullMatch === null || fullMatch === void 0 ? void 0 : fullMatch.groups) === null || _b === void 0 ? void 0 : _b.contents) || '';
|
|
31475
|
+
// Start a new commitment
|
|
31476
|
+
currentCommitment = {
|
|
31477
|
+
type: definition.type,
|
|
31478
|
+
startLineNumber: i + 1,
|
|
31479
|
+
originalStartLine: line,
|
|
31480
|
+
contentLines: initialContent ? [initialContent] : [],
|
|
31481
|
+
};
|
|
31482
|
+
foundNewCommitment = true;
|
|
31483
|
+
break;
|
|
31484
|
+
}
|
|
31485
|
+
}
|
|
31486
|
+
// Check if this is a horizontal line (ends any current commitment)
|
|
31487
|
+
const isHorizontalLine = HORIZONTAL_LINE_PATTERN$1.test(line);
|
|
31488
|
+
if (isHorizontalLine) {
|
|
31489
|
+
// Save the current commitment if it exists
|
|
31490
|
+
if (currentCommitment) {
|
|
31491
|
+
const fullContent = currentCommitment.contentLines.join('\n');
|
|
31492
|
+
commitments.push({
|
|
31493
|
+
type: currentCommitment.type,
|
|
31494
|
+
content: _spaceTrim.spaceTrim(fullContent),
|
|
31495
|
+
originalLine: currentCommitment.originalStartLine,
|
|
31496
|
+
lineNumber: currentCommitment.startLineNumber,
|
|
31497
|
+
});
|
|
31498
|
+
currentCommitment = null;
|
|
31499
|
+
}
|
|
31500
|
+
// Add horizontal line to non-commitment lines
|
|
31501
|
+
nonCommitmentLines.push(line);
|
|
31502
|
+
continue;
|
|
31503
|
+
}
|
|
31504
|
+
if (!foundNewCommitment) {
|
|
31505
|
+
if (currentCommitment) {
|
|
31506
|
+
// This line belongs to the current commitment
|
|
31507
|
+
currentCommitment.contentLines.push(line);
|
|
31508
|
+
}
|
|
31509
|
+
else {
|
|
31510
|
+
// This line is not part of any commitment
|
|
31511
|
+
nonCommitmentLines.push(line);
|
|
31512
|
+
}
|
|
31513
|
+
}
|
|
31514
|
+
}
|
|
31515
|
+
// Don't forget to save the last commitment if it exists
|
|
31516
|
+
if (currentCommitment) {
|
|
31517
|
+
const fullContent = currentCommitment.contentLines.join('\n');
|
|
31518
|
+
commitments.push({
|
|
31519
|
+
type: currentCommitment.type,
|
|
31520
|
+
content: _spaceTrim.spaceTrim(fullContent),
|
|
31521
|
+
originalLine: currentCommitment.originalStartLine,
|
|
31522
|
+
lineNumber: currentCommitment.startLineNumber,
|
|
31523
|
+
});
|
|
31524
|
+
}
|
|
31525
|
+
return {
|
|
31526
|
+
agentName,
|
|
31527
|
+
agentNameLineNumber,
|
|
31528
|
+
commitments,
|
|
31529
|
+
nonCommitmentLines,
|
|
31530
|
+
};
|
|
31531
|
+
}
|
|
31532
|
+
|
|
31533
|
+
/**
|
|
31534
|
+
* Parses parameters from text using both supported notations:
|
|
31535
|
+
* 1. @Parameter - single word parameter starting with @
|
|
31536
|
+
* 2. {parameterName} or {parameter with multiple words} or {parameterName: description text}
|
|
31537
|
+
*
|
|
31538
|
+
* Both notations represent the same syntax feature - parameters
|
|
31539
|
+
*
|
|
31540
|
+
* @param text - Text to extract parameters from
|
|
31541
|
+
* @returns Array of parsed parameters with unified representation
|
|
31542
|
+
*
|
|
31543
|
+
* @public exported from `@promptbook/core`
|
|
31544
|
+
*/
|
|
31545
|
+
function parseParameters(text) {
|
|
31546
|
+
const parameters = [];
|
|
31547
|
+
// [🧠] Parameter syntax parsing - unified approach for two different notations of the same syntax feature
|
|
31548
|
+
// The Book language supports parameters in two different notations but they represent the same concept
|
|
31549
|
+
// Extract @Parameter notation (single word parameters starting with @)
|
|
31550
|
+
const atParameterRegex = /@[\w\u00C0-\u017F\u0100-\u024F\u1E00-\u1EFF]+/gim;
|
|
31551
|
+
text.replace(atParameterRegex, (match) => {
|
|
31552
|
+
const parameterName = match.slice(1); // Remove the @ symbol
|
|
31553
|
+
parameters.push({
|
|
31554
|
+
text: match,
|
|
31555
|
+
notation: 'at',
|
|
31556
|
+
name: parameterName,
|
|
31557
|
+
});
|
|
31558
|
+
return match;
|
|
31559
|
+
});
|
|
31560
|
+
// Extract {parameter} notation (parameters in braces)
|
|
31561
|
+
const braceParameterRegex = /\{([^}]+)\}/gim;
|
|
31562
|
+
text.replace(braceParameterRegex, (match, content) => {
|
|
31563
|
+
// Check if the parameter has a description (parameterName: description)
|
|
31564
|
+
const colonIndex = content.indexOf(':');
|
|
31565
|
+
if (colonIndex !== -1) {
|
|
31566
|
+
const name = content.substring(0, colonIndex).trim();
|
|
31567
|
+
const description = content.substring(colonIndex + 1).trim();
|
|
31568
|
+
parameters.push({
|
|
31569
|
+
text: match,
|
|
31570
|
+
notation: 'brace',
|
|
31571
|
+
name,
|
|
31572
|
+
description,
|
|
31573
|
+
});
|
|
31574
|
+
}
|
|
31575
|
+
else {
|
|
31576
|
+
// Simple parameter without description
|
|
31577
|
+
parameters.push({
|
|
31578
|
+
text: match,
|
|
31579
|
+
notation: 'brace',
|
|
31580
|
+
name: content.trim(),
|
|
31581
|
+
});
|
|
31582
|
+
}
|
|
31583
|
+
return match;
|
|
31584
|
+
});
|
|
31585
|
+
// Remove duplicates based on name (keep the first occurrence)
|
|
31586
|
+
const uniqueParameters = parameters.filter((parameter, index, array) => {
|
|
31587
|
+
return array.findIndex((parameterItem) => parameterItem.name === parameter.name) === index;
|
|
31588
|
+
});
|
|
31589
|
+
return uniqueParameters;
|
|
31590
|
+
}
|
|
31591
|
+
|
|
31592
|
+
/**
|
|
31593
|
+
* Ensures the parsed profile always exposes a fullname value.
|
|
31594
|
+
*
|
|
31595
|
+
* @private internal utility of `parseAgentSource`
|
|
31596
|
+
*/
|
|
31597
|
+
function ensureMetaFullname(meta, fallbackFullname) {
|
|
31598
|
+
if (!meta.fullname) {
|
|
31599
|
+
meta.fullname = fallbackFullname;
|
|
31600
|
+
}
|
|
31601
|
+
}
|
|
31602
|
+
|
|
31603
|
+
/**
|
|
31604
|
+
* Resolves the public agent profile text from the last GOAL/GOALS commitment,
|
|
31605
|
+
* falling back to the deprecated PERSONA/PERSONAE commitments when no goal exists.
|
|
31606
|
+
*
|
|
31607
|
+
* @private internal utility of `parseAgentSource`
|
|
31608
|
+
*/
|
|
31609
|
+
function extractAgentProfileText(commitments) {
|
|
31610
|
+
let goalDescription = '';
|
|
31611
|
+
let hasGoalDescription = false;
|
|
31612
|
+
let personaDescription = '';
|
|
31613
|
+
let hasPersonaDescription = false;
|
|
31614
|
+
for (const commitment of commitments) {
|
|
31615
|
+
if (commitment.type === 'GOAL' || commitment.type === 'GOALS') {
|
|
31616
|
+
goalDescription = commitment.content;
|
|
31617
|
+
hasGoalDescription = true;
|
|
31618
|
+
}
|
|
31619
|
+
if (commitment.type === 'PERSONA' || commitment.type === 'PERSONAE') {
|
|
31620
|
+
personaDescription = commitment.content;
|
|
31621
|
+
hasPersonaDescription = true;
|
|
31622
|
+
}
|
|
31623
|
+
}
|
|
31624
|
+
if (hasGoalDescription) {
|
|
31625
|
+
return goalDescription;
|
|
31626
|
+
}
|
|
31627
|
+
if (hasPersonaDescription) {
|
|
31628
|
+
return personaDescription;
|
|
31629
|
+
}
|
|
31630
|
+
return null;
|
|
31631
|
+
}
|
|
31632
|
+
|
|
31633
|
+
/**
|
|
31634
|
+
* Resolves the last INITIAL MESSAGE commitment, which is the public initial-message value.
|
|
31635
|
+
*
|
|
31636
|
+
* @private internal utility of `parseAgentSource`
|
|
31637
|
+
*/
|
|
31638
|
+
function extractInitialMessage(commitments) {
|
|
31639
|
+
let initialMessage = null;
|
|
31640
|
+
for (const commitment of commitments) {
|
|
31641
|
+
if (commitment.type === 'INITIAL MESSAGE') {
|
|
31642
|
+
initialMessage = commitment.content;
|
|
31643
|
+
}
|
|
31644
|
+
}
|
|
31645
|
+
return initialMessage;
|
|
31646
|
+
}
|
|
31647
|
+
|
|
31346
31648
|
/**
|
|
31347
31649
|
* Normalizes a domain-like string into a comparable hostname form.
|
|
31348
31650
|
*
|
|
@@ -31382,274 +31684,178 @@
|
|
|
31382
31684
|
}
|
|
31383
31685
|
|
|
31384
31686
|
/**
|
|
31385
|
-
*
|
|
31386
|
-
|
|
31387
|
-
|
|
31388
|
-
|
|
31389
|
-
|
|
31390
|
-
|
|
31391
|
-
|
|
31392
|
-
|
|
31687
|
+
* Dedicated handlers for META-style commitments that directly map onto parsed meta fields.
|
|
31688
|
+
*/
|
|
31689
|
+
const META_COMMITMENT_APPLIERS = {
|
|
31690
|
+
'META AVATAR': applyMetaAvatarContent,
|
|
31691
|
+
'META LINK': applyMetaLinkContent,
|
|
31692
|
+
'META DOMAIN': applyMetaDomainContent,
|
|
31693
|
+
'META IMAGE': applyMetaImageContent,
|
|
31694
|
+
'META DESCRIPTION': applyMetaDescriptionContent,
|
|
31695
|
+
'META DISCLAIMER': applyMetaDisclaimerContent,
|
|
31696
|
+
'META INPUT PLACEHOLDER': applyMetaInputPlaceholderContent,
|
|
31697
|
+
'MESSAGE SUFFIX': applyMessageSuffixContent,
|
|
31698
|
+
'META COLOR': applyMetaColorContent,
|
|
31699
|
+
'META FONT': applyMetaFontContent,
|
|
31700
|
+
'META VOICE': applyMetaVoiceContent,
|
|
31701
|
+
};
|
|
31702
|
+
/**
|
|
31703
|
+
* Applies META-style commitments that mutate parsed profile metadata.
|
|
31393
31704
|
*
|
|
31394
|
-
* @private internal utility of
|
|
31705
|
+
* @private internal utility of `parseAgentSource`
|
|
31395
31706
|
*/
|
|
31396
|
-
function
|
|
31397
|
-
const
|
|
31398
|
-
|
|
31399
|
-
|
|
31400
|
-
|
|
31401
|
-
|
|
31402
|
-
|
|
31403
|
-
|
|
31404
|
-
if (!trimmedLine) {
|
|
31405
|
-
continue;
|
|
31406
|
-
}
|
|
31407
|
-
return {
|
|
31408
|
-
lines,
|
|
31409
|
-
agentName: trimmedLine,
|
|
31410
|
-
agentNameLineIndex: lineIndex,
|
|
31411
|
-
agentNameLineNumber: lineIndex + 1,
|
|
31412
|
-
};
|
|
31707
|
+
function applyMetaCommitment(state, commitment) {
|
|
31708
|
+
const applyMetaContent = META_COMMITMENT_APPLIERS[commitment.type];
|
|
31709
|
+
if (applyMetaContent) {
|
|
31710
|
+
applyMetaContent(state, commitment.content);
|
|
31711
|
+
return;
|
|
31712
|
+
}
|
|
31713
|
+
if (commitment.type === 'META') {
|
|
31714
|
+
applyGenericMetaCommitment(state, commitment.content);
|
|
31413
31715
|
}
|
|
31414
|
-
return {
|
|
31415
|
-
lines,
|
|
31416
|
-
agentName: null,
|
|
31417
|
-
agentNameLineIndex: -1,
|
|
31418
|
-
};
|
|
31419
31716
|
}
|
|
31420
|
-
|
|
31421
|
-
/**
|
|
31422
|
-
* Regex pattern to match horizontal lines (markdown thematic breaks)
|
|
31423
|
-
* Matches 3 or more hyphens, underscores, or asterisks (with optional spaces between)
|
|
31424
|
-
*/
|
|
31425
|
-
const HORIZONTAL_LINE_PATTERN$1 = /^[\s]*[-_*][\s]*[-_*][\s]*[-_*][\s]*[-_*]*[\s]*$/;
|
|
31426
31717
|
/**
|
|
31427
|
-
*
|
|
31428
|
-
* This function replaces the hardcoded commitment parsing in the original parseAgentSource
|
|
31429
|
-
*
|
|
31430
|
-
* The first non-empty line is always consumed as plain-text agent name. Commitment parsing
|
|
31431
|
-
* starts only after that title line has been fixed.
|
|
31432
|
-
*
|
|
31433
|
-
* @private internal utility of `parseAgentSource`
|
|
31718
|
+
* Applies the generic META commitment form (`META TYPE value`).
|
|
31434
31719
|
*/
|
|
31435
|
-
function
|
|
31436
|
-
|
|
31437
|
-
|
|
31438
|
-
|
|
31439
|
-
|
|
31440
|
-
commitments: [],
|
|
31441
|
-
nonCommitmentLines: [],
|
|
31442
|
-
};
|
|
31720
|
+
function applyGenericMetaCommitment(state, content) {
|
|
31721
|
+
const metaTypeRaw = content.split(' ')[0] || 'NONE';
|
|
31722
|
+
const metaValue = _spaceTrim.spaceTrim(content.substring(metaTypeRaw.length));
|
|
31723
|
+
if (metaTypeRaw === 'LINK') {
|
|
31724
|
+
state.links.push(metaValue);
|
|
31443
31725
|
}
|
|
31444
|
-
|
|
31445
|
-
|
|
31446
|
-
|
|
31447
|
-
// Parse commitments with multiline support
|
|
31448
|
-
let currentCommitment = null;
|
|
31449
|
-
// Process lines starting from after the agent name line
|
|
31450
|
-
const startIndex = agentNameLineIndex >= 0 ? agentNameLineIndex + 1 : 0;
|
|
31451
|
-
let isInsideCodeBlock = false;
|
|
31452
|
-
for (let i = startIndex; i < lines.length; i++) {
|
|
31453
|
-
const line = lines[i];
|
|
31454
|
-
if (line === undefined) {
|
|
31455
|
-
continue;
|
|
31456
|
-
}
|
|
31457
|
-
const trimmedLine = line.trim();
|
|
31458
|
-
// Check if this line starts or ends a code block
|
|
31459
|
-
if (trimmedLine.startsWith('```')) {
|
|
31460
|
-
isInsideCodeBlock = !isInsideCodeBlock;
|
|
31461
|
-
if (currentCommitment) {
|
|
31462
|
-
// If we are inside a commitment, the code block is part of it
|
|
31463
|
-
currentCommitment.contentLines.push(line);
|
|
31464
|
-
}
|
|
31465
|
-
else {
|
|
31466
|
-
// If we are not inside a commitment, the code block is non-commitment
|
|
31467
|
-
nonCommitmentLines.push(line);
|
|
31468
|
-
}
|
|
31469
|
-
continue;
|
|
31470
|
-
}
|
|
31471
|
-
if (isInsideCodeBlock) {
|
|
31472
|
-
if (currentCommitment) {
|
|
31473
|
-
// If we are inside a commitment and a code block, the line is part of the commitment
|
|
31474
|
-
currentCommitment.contentLines.push(line);
|
|
31475
|
-
}
|
|
31476
|
-
else {
|
|
31477
|
-
// If we are inside a code block but not a commitment, the line is non-commitment
|
|
31478
|
-
nonCommitmentLines.push(line);
|
|
31479
|
-
}
|
|
31480
|
-
continue;
|
|
31481
|
-
}
|
|
31482
|
-
// Check if this line starts a new commitment
|
|
31483
|
-
let foundNewCommitment = false;
|
|
31484
|
-
for (const definition of COMMITMENT_REGISTRY) {
|
|
31485
|
-
const typeRegex = definition.createTypeRegex();
|
|
31486
|
-
const match = typeRegex.exec(line.trim());
|
|
31487
|
-
if (match && ((_a = match.groups) === null || _a === void 0 ? void 0 : _a.type)) {
|
|
31488
|
-
// Save the previous commitment if it exists
|
|
31489
|
-
if (currentCommitment) {
|
|
31490
|
-
const fullContent = currentCommitment.contentLines.join('\n');
|
|
31491
|
-
commitments.push({
|
|
31492
|
-
type: currentCommitment.type,
|
|
31493
|
-
content: _spaceTrim.spaceTrim(fullContent),
|
|
31494
|
-
originalLine: currentCommitment.originalStartLine,
|
|
31495
|
-
lineNumber: currentCommitment.startLineNumber,
|
|
31496
|
-
});
|
|
31497
|
-
}
|
|
31498
|
-
// Extract the initial content from the commitment line
|
|
31499
|
-
const fullRegex = definition.createRegex();
|
|
31500
|
-
const fullMatch = fullRegex.exec(line.trim());
|
|
31501
|
-
const initialContent = ((_b = fullMatch === null || fullMatch === void 0 ? void 0 : fullMatch.groups) === null || _b === void 0 ? void 0 : _b.contents) || '';
|
|
31502
|
-
// Start a new commitment
|
|
31503
|
-
currentCommitment = {
|
|
31504
|
-
type: definition.type,
|
|
31505
|
-
startLineNumber: i + 1,
|
|
31506
|
-
originalStartLine: line,
|
|
31507
|
-
contentLines: initialContent ? [initialContent] : [],
|
|
31508
|
-
};
|
|
31509
|
-
foundNewCommitment = true;
|
|
31510
|
-
break;
|
|
31511
|
-
}
|
|
31512
|
-
}
|
|
31513
|
-
// Check if this is a horizontal line (ends any current commitment)
|
|
31514
|
-
const isHorizontalLine = HORIZONTAL_LINE_PATTERN$1.test(line);
|
|
31515
|
-
if (isHorizontalLine) {
|
|
31516
|
-
// Save the current commitment if it exists
|
|
31517
|
-
if (currentCommitment) {
|
|
31518
|
-
const fullContent = currentCommitment.contentLines.join('\n');
|
|
31519
|
-
commitments.push({
|
|
31520
|
-
type: currentCommitment.type,
|
|
31521
|
-
content: _spaceTrim.spaceTrim(fullContent),
|
|
31522
|
-
originalLine: currentCommitment.originalStartLine,
|
|
31523
|
-
lineNumber: currentCommitment.startLineNumber,
|
|
31524
|
-
});
|
|
31525
|
-
currentCommitment = null;
|
|
31526
|
-
}
|
|
31527
|
-
// Add horizontal line to non-commitment lines
|
|
31528
|
-
nonCommitmentLines.push(line);
|
|
31529
|
-
continue;
|
|
31530
|
-
}
|
|
31531
|
-
if (!foundNewCommitment) {
|
|
31532
|
-
if (currentCommitment) {
|
|
31533
|
-
// This line belongs to the current commitment
|
|
31534
|
-
currentCommitment.contentLines.push(line);
|
|
31535
|
-
}
|
|
31536
|
-
else {
|
|
31537
|
-
// This line is not part of any commitment
|
|
31538
|
-
nonCommitmentLines.push(line);
|
|
31539
|
-
}
|
|
31540
|
-
}
|
|
31726
|
+
if (metaTypeRaw.toUpperCase() === 'AVATAR') {
|
|
31727
|
+
applyMetaAvatarContent(state, metaValue);
|
|
31728
|
+
return;
|
|
31541
31729
|
}
|
|
31542
|
-
|
|
31543
|
-
|
|
31544
|
-
|
|
31545
|
-
|
|
31546
|
-
|
|
31547
|
-
|
|
31548
|
-
|
|
31549
|
-
|
|
31550
|
-
|
|
31730
|
+
const metaType = normalizeTo_camelCase(metaTypeRaw);
|
|
31731
|
+
state.meta[metaType] = metaValue;
|
|
31732
|
+
}
|
|
31733
|
+
/**
|
|
31734
|
+
* Applies META AVATAR content into the canonical `meta.avatar` field.
|
|
31735
|
+
*/
|
|
31736
|
+
function applyMetaAvatarContent(state, content) {
|
|
31737
|
+
const avatarVisualId = resolveAvatarVisualId(content);
|
|
31738
|
+
if (avatarVisualId) {
|
|
31739
|
+
state.meta.avatar = avatarVisualId;
|
|
31740
|
+
return;
|
|
31551
31741
|
}
|
|
31552
|
-
|
|
31553
|
-
agentName,
|
|
31554
|
-
agentNameLineNumber,
|
|
31555
|
-
commitments,
|
|
31556
|
-
nonCommitmentLines,
|
|
31557
|
-
};
|
|
31742
|
+
delete state.meta.avatar;
|
|
31558
31743
|
}
|
|
31559
|
-
|
|
31560
31744
|
/**
|
|
31561
|
-
*
|
|
31562
|
-
|
|
31563
|
-
|
|
31564
|
-
|
|
31565
|
-
|
|
31745
|
+
* Applies META LINK content into links and the canonical `meta.link` field.
|
|
31746
|
+
*/
|
|
31747
|
+
function applyMetaLinkContent(state, content) {
|
|
31748
|
+
const linkValue = _spaceTrim.spaceTrim(content);
|
|
31749
|
+
state.links.push(linkValue);
|
|
31750
|
+
state.meta.link = linkValue;
|
|
31751
|
+
}
|
|
31752
|
+
/**
|
|
31753
|
+
* Applies META DOMAIN content into the normalized `meta.domain` field.
|
|
31754
|
+
*/
|
|
31755
|
+
function applyMetaDomainContent(state, content) {
|
|
31756
|
+
state.meta.domain = normalizeMetaDomain(content);
|
|
31757
|
+
}
|
|
31758
|
+
/**
|
|
31759
|
+
* Applies META IMAGE content into the canonical `meta.image` field.
|
|
31760
|
+
*/
|
|
31761
|
+
function applyMetaImageContent(state, content) {
|
|
31762
|
+
state.meta.image = _spaceTrim.spaceTrim(content);
|
|
31763
|
+
}
|
|
31764
|
+
/**
|
|
31765
|
+
* Applies META DESCRIPTION content into the canonical `meta.description` field.
|
|
31766
|
+
*/
|
|
31767
|
+
function applyMetaDescriptionContent(state, content) {
|
|
31768
|
+
state.meta.description = _spaceTrim.spaceTrim(content);
|
|
31769
|
+
}
|
|
31770
|
+
/**
|
|
31771
|
+
* Applies META DISCLAIMER content into the canonical `meta.disclaimer` field.
|
|
31772
|
+
*/
|
|
31773
|
+
function applyMetaDisclaimerContent(state, content) {
|
|
31774
|
+
state.meta.disclaimer = content;
|
|
31775
|
+
}
|
|
31776
|
+
/**
|
|
31777
|
+
* Applies META INPUT PLACEHOLDER content into the canonical `meta.inputPlaceholder` field.
|
|
31778
|
+
*/
|
|
31779
|
+
function applyMetaInputPlaceholderContent(state, content) {
|
|
31780
|
+
state.meta.inputPlaceholder = _spaceTrim.spaceTrim(content);
|
|
31781
|
+
}
|
|
31782
|
+
/**
|
|
31783
|
+
* Applies MESSAGE SUFFIX content into the canonical `meta.messageSuffix` field.
|
|
31784
|
+
*/
|
|
31785
|
+
function applyMessageSuffixContent(state, content) {
|
|
31786
|
+
state.meta.messageSuffix = content;
|
|
31787
|
+
}
|
|
31788
|
+
/**
|
|
31789
|
+
* Applies META COLOR content into the canonical `meta.color` field.
|
|
31790
|
+
*/
|
|
31791
|
+
function applyMetaColorContent(state, content) {
|
|
31792
|
+
state.meta.color = normalizeSeparator(content);
|
|
31793
|
+
}
|
|
31794
|
+
/**
|
|
31795
|
+
* Applies META FONT content into the canonical `meta.font` field.
|
|
31796
|
+
*/
|
|
31797
|
+
function applyMetaFontContent(state, content) {
|
|
31798
|
+
state.meta.font = normalizeSeparator(content);
|
|
31799
|
+
}
|
|
31800
|
+
/**
|
|
31801
|
+
* Applies META VOICE content into the canonical `meta.voice` field.
|
|
31802
|
+
*/
|
|
31803
|
+
function applyMetaVoiceContent(state, content) {
|
|
31804
|
+
state.meta.voice = _spaceTrim.spaceTrim(content);
|
|
31805
|
+
}
|
|
31806
|
+
/**
|
|
31807
|
+
* Normalizes the separator in the content
|
|
31566
31808
|
*
|
|
31567
|
-
* @param
|
|
31568
|
-
* @returns
|
|
31809
|
+
* @param content - The content to normalize
|
|
31810
|
+
* @returns The content with normalized separators
|
|
31811
|
+
*/
|
|
31812
|
+
function normalizeSeparator(content) {
|
|
31813
|
+
const trimmed = _spaceTrim.spaceTrim(content);
|
|
31814
|
+
if (trimmed.includes(',')) {
|
|
31815
|
+
return trimmed;
|
|
31816
|
+
}
|
|
31817
|
+
return trimmed.split(/\s+/).join(', ');
|
|
31818
|
+
}
|
|
31819
|
+
/**
|
|
31820
|
+
* Normalizes META DOMAIN content to a hostname-like value when possible.
|
|
31569
31821
|
*
|
|
31570
|
-
* @
|
|
31822
|
+
* @param content - Raw META DOMAIN content.
|
|
31823
|
+
* @returns Normalized domain or a trimmed fallback.
|
|
31571
31824
|
*/
|
|
31572
|
-
function
|
|
31573
|
-
const
|
|
31574
|
-
|
|
31575
|
-
// The Book language supports parameters in two different notations but they represent the same concept
|
|
31576
|
-
// Extract @Parameter notation (single word parameters starting with @)
|
|
31577
|
-
const atParameterRegex = /@[\w\u00C0-\u017F\u0100-\u024F\u1E00-\u1EFF]+/gim;
|
|
31578
|
-
text.replace(atParameterRegex, (match) => {
|
|
31579
|
-
const parameterName = match.slice(1); // Remove the @ symbol
|
|
31580
|
-
parameters.push({
|
|
31581
|
-
text: match,
|
|
31582
|
-
notation: 'at',
|
|
31583
|
-
name: parameterName,
|
|
31584
|
-
});
|
|
31585
|
-
return match;
|
|
31586
|
-
});
|
|
31587
|
-
// Extract {parameter} notation (parameters in braces)
|
|
31588
|
-
const braceParameterRegex = /\{([^}]+)\}/gim;
|
|
31589
|
-
text.replace(braceParameterRegex, (match, content) => {
|
|
31590
|
-
// Check if the parameter has a description (parameterName: description)
|
|
31591
|
-
const colonIndex = content.indexOf(':');
|
|
31592
|
-
if (colonIndex !== -1) {
|
|
31593
|
-
const name = content.substring(0, colonIndex).trim();
|
|
31594
|
-
const description = content.substring(colonIndex + 1).trim();
|
|
31595
|
-
parameters.push({
|
|
31596
|
-
text: match,
|
|
31597
|
-
notation: 'brace',
|
|
31598
|
-
name,
|
|
31599
|
-
description,
|
|
31600
|
-
});
|
|
31601
|
-
}
|
|
31602
|
-
else {
|
|
31603
|
-
// Simple parameter without description
|
|
31604
|
-
parameters.push({
|
|
31605
|
-
text: match,
|
|
31606
|
-
notation: 'brace',
|
|
31607
|
-
name: content.trim(),
|
|
31608
|
-
});
|
|
31609
|
-
}
|
|
31610
|
-
return match;
|
|
31611
|
-
});
|
|
31612
|
-
// Remove duplicates based on name (keep the first occurrence)
|
|
31613
|
-
const uniqueParameters = parameters.filter((parameter, index, array) => {
|
|
31614
|
-
return array.findIndex((parameterItem) => parameterItem.name === parameter.name) === index;
|
|
31615
|
-
});
|
|
31616
|
-
return uniqueParameters;
|
|
31825
|
+
function normalizeMetaDomain(content) {
|
|
31826
|
+
const trimmed = _spaceTrim.spaceTrim(content);
|
|
31827
|
+
return normalizeDomainForMatching(trimmed) || trimmed.toLowerCase();
|
|
31617
31828
|
}
|
|
31618
31829
|
|
|
31619
31830
|
/**
|
|
31620
|
-
*
|
|
31621
|
-
*
|
|
31622
|
-
* There are 2 similar functions:
|
|
31623
|
-
* - `parseAgentSource` which is a lightweight parser for agent source, it parses basic information and its purpose is to be quick and synchronous. The commitments there are hardcoded.
|
|
31624
|
-
* - `createAgentModelRequirements` which is an asynchronous function that creates model requirements it applies each commitment one by one and works asynchronously.
|
|
31831
|
+
* Updates sample-conversation state for communication commitments.
|
|
31625
31832
|
*
|
|
31626
|
-
* @
|
|
31833
|
+
* @private internal utility of `parseAgentSource`
|
|
31627
31834
|
*/
|
|
31628
|
-
function
|
|
31629
|
-
|
|
31630
|
-
|
|
31631
|
-
|
|
31632
|
-
|
|
31633
|
-
|
|
31634
|
-
|
|
31635
|
-
|
|
31636
|
-
|
|
31637
|
-
|
|
31638
|
-
|
|
31639
|
-
|
|
31640
|
-
|
|
31641
|
-
|
|
31642
|
-
|
|
31643
|
-
|
|
31644
|
-
|
|
31645
|
-
|
|
31646
|
-
|
|
31647
|
-
}
|
|
31835
|
+
function consumeConversationSampleCommitment(state, commitment) {
|
|
31836
|
+
switch (commitment.type) {
|
|
31837
|
+
case 'INITIAL MESSAGE':
|
|
31838
|
+
state.samples.push({ question: null, answer: commitment.content });
|
|
31839
|
+
return true;
|
|
31840
|
+
case 'USER MESSAGE':
|
|
31841
|
+
state.pendingUserMessage = commitment.content;
|
|
31842
|
+
return true;
|
|
31843
|
+
case 'INTERNAL MESSAGE':
|
|
31844
|
+
// INTERNAL MESSAGE stores trace payloads and is intentionally ignored in basic profile samples.
|
|
31845
|
+
return true;
|
|
31846
|
+
case 'AGENT MESSAGE':
|
|
31847
|
+
if (state.pendingUserMessage !== null) {
|
|
31848
|
+
state.samples.push({ question: state.pendingUserMessage, answer: commitment.content });
|
|
31849
|
+
state.pendingUserMessage = null;
|
|
31850
|
+
}
|
|
31851
|
+
return true;
|
|
31852
|
+
default:
|
|
31853
|
+
return false;
|
|
31854
|
+
}
|
|
31648
31855
|
}
|
|
31856
|
+
|
|
31649
31857
|
/**
|
|
31650
31858
|
* Static capability descriptors for commitments that map one-to-one to a visible capability.
|
|
31651
|
-
*
|
|
31652
|
-
* @private internal utility of `parseAgentSource`
|
|
31653
31859
|
*/
|
|
31654
31860
|
const SIMPLE_CAPABILITY_BY_COMMITMENT_TYPE = {
|
|
31655
31861
|
'USE BROWSER': {
|
|
@@ -31712,142 +31918,11 @@
|
|
|
31712
31918
|
label: 'Calendar',
|
|
31713
31919
|
iconName: 'Calendar',
|
|
31714
31920
|
},
|
|
31715
|
-
};
|
|
31716
|
-
/**
|
|
31717
|
-
*
|
|
31718
|
-
|
|
31719
|
-
|
|
31720
|
-
*/
|
|
31721
|
-
const META_COMMITMENT_APPLIERS = {
|
|
31722
|
-
'META AVATAR': applyMetaAvatarContent,
|
|
31723
|
-
'META LINK': applyMetaLinkContent,
|
|
31724
|
-
'META DOMAIN': applyMetaDomainContent,
|
|
31725
|
-
'META IMAGE': applyMetaImageContent,
|
|
31726
|
-
'META DESCRIPTION': applyMetaDescriptionContent,
|
|
31727
|
-
'META DISCLAIMER': applyMetaDisclaimerContent,
|
|
31728
|
-
'META INPUT PLACEHOLDER': applyMetaInputPlaceholderContent,
|
|
31729
|
-
'MESSAGE SUFFIX': applyMessageSuffixContent,
|
|
31730
|
-
'META COLOR': applyMetaColorContent,
|
|
31731
|
-
'META FONT': applyMetaFontContent,
|
|
31732
|
-
'META VOICE': applyMetaVoiceContent,
|
|
31733
|
-
};
|
|
31734
|
-
/**
|
|
31735
|
-
* Detects local slash-based references used by FROM and IMPORT commitments.
|
|
31736
|
-
*
|
|
31737
|
-
* @private internal utility of `parseAgentSource`
|
|
31738
|
-
*/
|
|
31739
|
-
const LOCAL_AGENT_REFERENCE_PREFIXES = ['./', '../', '/'];
|
|
31740
|
-
/**
|
|
31741
|
-
* Resolves the public agent profile text from the last GOAL/GOALS commitment,
|
|
31742
|
-
* falling back to the deprecated PERSONA/PERSONAE commitments when no goal exists.
|
|
31743
|
-
*
|
|
31744
|
-
* @private internal utility of `parseAgentSource`
|
|
31745
|
-
*/
|
|
31746
|
-
function extractAgentProfileText(commitments) {
|
|
31747
|
-
let goalDescription = '';
|
|
31748
|
-
let hasGoalDescription = false;
|
|
31749
|
-
let personaDescription = '';
|
|
31750
|
-
let hasPersonaDescription = false;
|
|
31751
|
-
for (const commitment of commitments) {
|
|
31752
|
-
if (commitment.type === 'GOAL' || commitment.type === 'GOALS') {
|
|
31753
|
-
goalDescription = commitment.content;
|
|
31754
|
-
hasGoalDescription = true;
|
|
31755
|
-
}
|
|
31756
|
-
if (commitment.type === 'PERSONA' || commitment.type === 'PERSONAE') {
|
|
31757
|
-
personaDescription = commitment.content;
|
|
31758
|
-
hasPersonaDescription = true;
|
|
31759
|
-
}
|
|
31760
|
-
}
|
|
31761
|
-
if (hasGoalDescription) {
|
|
31762
|
-
return goalDescription;
|
|
31763
|
-
}
|
|
31764
|
-
if (hasPersonaDescription) {
|
|
31765
|
-
return personaDescription;
|
|
31766
|
-
}
|
|
31767
|
-
return null;
|
|
31768
|
-
}
|
|
31769
|
-
/**
|
|
31770
|
-
* Resolves the last INITIAL MESSAGE commitment, which is the public initial-message value.
|
|
31771
|
-
*
|
|
31772
|
-
* @private internal utility of `parseAgentSource`
|
|
31773
|
-
*/
|
|
31774
|
-
function extractInitialMessage(commitments) {
|
|
31775
|
-
let initialMessage = null;
|
|
31776
|
-
for (const commitment of commitments) {
|
|
31777
|
-
if (commitment.type === 'INITIAL MESSAGE') {
|
|
31778
|
-
initialMessage = commitment.content;
|
|
31779
|
-
}
|
|
31780
|
-
}
|
|
31781
|
-
return initialMessage;
|
|
31782
|
-
}
|
|
31783
|
-
/**
|
|
31784
|
-
* Collects capability, sample, meta, link, and knowledge-source data from commitments.
|
|
31785
|
-
*
|
|
31786
|
-
* @private internal utility of `parseAgentSource`
|
|
31787
|
-
*/
|
|
31788
|
-
function extractParsedAgentProfile(commitments) {
|
|
31789
|
-
const state = {
|
|
31790
|
-
meta: {},
|
|
31791
|
-
links: [],
|
|
31792
|
-
capabilities: [],
|
|
31793
|
-
samples: [],
|
|
31794
|
-
knowledgeSources: [],
|
|
31795
|
-
pendingUserMessage: null,
|
|
31796
|
-
knownKnowledgeSourceUrls: new Set(),
|
|
31797
|
-
};
|
|
31798
|
-
for (const commitment of commitments) {
|
|
31799
|
-
processParsedCommitment(state, commitment);
|
|
31800
|
-
}
|
|
31801
|
-
return {
|
|
31802
|
-
meta: state.meta,
|
|
31803
|
-
links: state.links,
|
|
31804
|
-
capabilities: state.capabilities,
|
|
31805
|
-
samples: state.samples,
|
|
31806
|
-
knowledgeSources: state.knowledgeSources,
|
|
31807
|
-
};
|
|
31808
|
-
}
|
|
31809
|
-
/**
|
|
31810
|
-
* Processes one parsed commitment through the sample, capability, and meta stages.
|
|
31811
|
-
*
|
|
31812
|
-
* @private internal utility of `parseAgentSource`
|
|
31813
|
-
*/
|
|
31814
|
-
function processParsedCommitment(state, commitment) {
|
|
31815
|
-
if (consumeConversationSampleCommitment(state, commitment)) {
|
|
31816
|
-
return;
|
|
31817
|
-
}
|
|
31818
|
-
const capabilities = createCapabilitiesFromCommitment(state, commitment);
|
|
31819
|
-
if (capabilities.length > 0) {
|
|
31820
|
-
state.capabilities.push(...capabilities);
|
|
31821
|
-
return;
|
|
31822
|
-
}
|
|
31823
|
-
applyMetaCommitment(state, commitment);
|
|
31824
|
-
}
|
|
31825
|
-
/**
|
|
31826
|
-
* Updates sample-conversation state for communication commitments.
|
|
31827
|
-
*
|
|
31828
|
-
* @private internal utility of `parseAgentSource`
|
|
31829
|
-
*/
|
|
31830
|
-
function consumeConversationSampleCommitment(state, commitment) {
|
|
31831
|
-
switch (commitment.type) {
|
|
31832
|
-
case 'INITIAL MESSAGE':
|
|
31833
|
-
state.samples.push({ question: null, answer: commitment.content });
|
|
31834
|
-
return true;
|
|
31835
|
-
case 'USER MESSAGE':
|
|
31836
|
-
state.pendingUserMessage = commitment.content;
|
|
31837
|
-
return true;
|
|
31838
|
-
case 'INTERNAL MESSAGE':
|
|
31839
|
-
// INTERNAL MESSAGE stores trace payloads and is intentionally ignored in basic profile samples.
|
|
31840
|
-
return true;
|
|
31841
|
-
case 'AGENT MESSAGE':
|
|
31842
|
-
if (state.pendingUserMessage !== null) {
|
|
31843
|
-
state.samples.push({ question: state.pendingUserMessage, answer: commitment.content });
|
|
31844
|
-
state.pendingUserMessage = null;
|
|
31845
|
-
}
|
|
31846
|
-
return true;
|
|
31847
|
-
default:
|
|
31848
|
-
return false;
|
|
31849
|
-
}
|
|
31850
|
-
}
|
|
31921
|
+
};
|
|
31922
|
+
/**
|
|
31923
|
+
* Detects local slash-based references used by FROM and IMPORT commitments.
|
|
31924
|
+
*/
|
|
31925
|
+
const LOCAL_AGENT_REFERENCE_PREFIXES = ['./', '../', '/'];
|
|
31851
31926
|
/**
|
|
31852
31927
|
* Creates the visible capabilities produced by one parsed commitment.
|
|
31853
31928
|
*
|
|
@@ -31877,8 +31952,6 @@
|
|
|
31877
31952
|
}
|
|
31878
31953
|
/**
|
|
31879
31954
|
* Clones one static capability descriptor for a simple capability commitment.
|
|
31880
|
-
*
|
|
31881
|
-
* @private internal utility of `parseAgentSource`
|
|
31882
31955
|
*/
|
|
31883
31956
|
function createSimpleCapability(commitmentType) {
|
|
31884
31957
|
const capability = SIMPLE_CAPABILITY_BY_COMMITMENT_TYPE[commitmentType];
|
|
@@ -31886,8 +31959,6 @@
|
|
|
31886
31959
|
}
|
|
31887
31960
|
/**
|
|
31888
31961
|
* Creates the USE PROJECT capability badge.
|
|
31889
|
-
*
|
|
31890
|
-
* @private internal utility of `parseAgentSource`
|
|
31891
31962
|
*/
|
|
31892
31963
|
function createProjectCapability(content) {
|
|
31893
31964
|
var _a;
|
|
@@ -31901,8 +31972,6 @@
|
|
|
31901
31972
|
}
|
|
31902
31973
|
/**
|
|
31903
31974
|
* Creates the FROM inheritance capability when the reference should stay visible in the profile.
|
|
31904
|
-
*
|
|
31905
|
-
* @private internal utility of `parseAgentSource`
|
|
31906
31975
|
*/
|
|
31907
31976
|
function createInheritanceCapability(content) {
|
|
31908
31977
|
const reference = extractFirstCommitmentLine(content);
|
|
@@ -31929,8 +31998,6 @@
|
|
|
31929
31998
|
}
|
|
31930
31999
|
/**
|
|
31931
32000
|
* Creates the IMPORT capability badge.
|
|
31932
|
-
*
|
|
31933
|
-
* @private internal utility of `parseAgentSource`
|
|
31934
32001
|
*/
|
|
31935
32002
|
function createImportCapability(content) {
|
|
31936
32003
|
const reference = extractFirstCommitmentLine(content);
|
|
@@ -31958,8 +32025,6 @@
|
|
|
31958
32025
|
}
|
|
31959
32026
|
/**
|
|
31960
32027
|
* Creates TEAM capability badges for all parsed teammates.
|
|
31961
|
-
*
|
|
31962
|
-
* @private internal utility of `parseAgentSource`
|
|
31963
32028
|
*/
|
|
31964
32029
|
function createTeamCapabilities(content) {
|
|
31965
32030
|
const teammates = parseTeamCommitmentContent(content);
|
|
@@ -31972,8 +32037,6 @@
|
|
|
31972
32037
|
}
|
|
31973
32038
|
/**
|
|
31974
32039
|
* Creates the KNOWLEDGE capability badge and records URL-based knowledge sources.
|
|
31975
|
-
*
|
|
31976
|
-
* @private internal utility of `parseAgentSource`
|
|
31977
32040
|
*/
|
|
31978
32041
|
function createKnowledgeCapability(state, content) {
|
|
31979
32042
|
const trimmedContent = _spaceTrim.spaceTrim(content);
|
|
@@ -31988,8 +32051,6 @@
|
|
|
31988
32051
|
}
|
|
31989
32052
|
/**
|
|
31990
32053
|
* Stores unique URL-based knowledge sources for later citation resolution.
|
|
31991
|
-
*
|
|
31992
|
-
* @private internal utility of `parseAgentSource`
|
|
31993
32054
|
*/
|
|
31994
32055
|
function rememberKnowledgeSources(state, extractedUrls) {
|
|
31995
32056
|
for (const extractedUrl of extractedUrls) {
|
|
@@ -32013,8 +32074,6 @@
|
|
|
32013
32074
|
}
|
|
32014
32075
|
/**
|
|
32015
32076
|
* Derives the visible KNOWLEDGE badge label and icon from commitment content.
|
|
32016
|
-
*
|
|
32017
|
-
* @private internal utility of `parseAgentSource`
|
|
32018
32077
|
*/
|
|
32019
32078
|
function createKnowledgeCapabilityPresentation(content, extractedUrls) {
|
|
32020
32079
|
let label = content;
|
|
@@ -32047,8 +32106,6 @@
|
|
|
32047
32106
|
}
|
|
32048
32107
|
/**
|
|
32049
32108
|
* Shortens text-only KNOWLEDGE commitments into the same preview label as before.
|
|
32050
|
-
*
|
|
32051
|
-
* @private internal utility of `parseAgentSource`
|
|
32052
32109
|
*/
|
|
32053
32110
|
function createKnowledgeTextLabel(content) {
|
|
32054
32111
|
const words = content.split(/\s+/);
|
|
@@ -32057,592 +32114,196 @@
|
|
|
32057
32114
|
}
|
|
32058
32115
|
return content;
|
|
32059
32116
|
}
|
|
32060
|
-
/**
|
|
32061
|
-
* Applies META-style commitments that mutate parsed profile metadata.
|
|
32062
|
-
*
|
|
32063
|
-
* @private internal utility of `parseAgentSource`
|
|
32064
|
-
*/
|
|
32065
|
-
function applyMetaCommitment(state, commitment) {
|
|
32066
|
-
const applyMetaContent = META_COMMITMENT_APPLIERS[commitment.type];
|
|
32067
|
-
if (applyMetaContent) {
|
|
32068
|
-
applyMetaContent(state, commitment.content);
|
|
32069
|
-
return;
|
|
32070
|
-
}
|
|
32071
|
-
if (commitment.type === 'META') {
|
|
32072
|
-
applyGenericMetaCommitment(state, commitment.content);
|
|
32073
|
-
}
|
|
32074
|
-
}
|
|
32075
|
-
/**
|
|
32076
|
-
* Applies the generic META commitment form (`META TYPE value`).
|
|
32077
|
-
*
|
|
32078
|
-
* @private internal utility of `parseAgentSource`
|
|
32079
|
-
*/
|
|
32080
|
-
function applyGenericMetaCommitment(state, content) {
|
|
32081
|
-
const metaTypeRaw = content.split(' ')[0] || 'NONE';
|
|
32082
|
-
const metaValue = _spaceTrim.spaceTrim(content.substring(metaTypeRaw.length));
|
|
32083
|
-
if (metaTypeRaw === 'LINK') {
|
|
32084
|
-
state.links.push(metaValue);
|
|
32085
|
-
}
|
|
32086
|
-
if (metaTypeRaw.toUpperCase() === 'AVATAR') {
|
|
32087
|
-
applyMetaAvatarContent(state, metaValue);
|
|
32088
|
-
return;
|
|
32089
|
-
}
|
|
32090
|
-
const metaType = normalizeTo_camelCase(metaTypeRaw);
|
|
32091
|
-
state.meta[metaType] = metaValue;
|
|
32092
|
-
}
|
|
32093
|
-
/**
|
|
32094
|
-
* Applies META AVATAR content into the canonical `meta.avatar` field.
|
|
32095
|
-
*
|
|
32096
|
-
* @private internal utility of `parseAgentSource`
|
|
32097
|
-
*/
|
|
32098
|
-
function applyMetaAvatarContent(state, content) {
|
|
32099
|
-
const avatarVisualId = resolveAvatarVisualId(content);
|
|
32100
|
-
if (avatarVisualId) {
|
|
32101
|
-
state.meta.avatar = avatarVisualId;
|
|
32102
|
-
return;
|
|
32103
|
-
}
|
|
32104
|
-
delete state.meta.avatar;
|
|
32105
|
-
}
|
|
32106
|
-
/**
|
|
32107
|
-
* Applies META LINK content into links and the canonical `meta.link` field.
|
|
32108
|
-
*
|
|
32109
|
-
* @private internal utility of `parseAgentSource`
|
|
32110
|
-
*/
|
|
32111
|
-
function applyMetaLinkContent(state, content) {
|
|
32112
|
-
const linkValue = _spaceTrim.spaceTrim(content);
|
|
32113
|
-
state.links.push(linkValue);
|
|
32114
|
-
state.meta.link = linkValue;
|
|
32115
|
-
}
|
|
32116
|
-
/**
|
|
32117
|
-
* Applies META DOMAIN content into the normalized `meta.domain` field.
|
|
32118
|
-
*
|
|
32119
|
-
* @private internal utility of `parseAgentSource`
|
|
32120
|
-
*/
|
|
32121
|
-
function applyMetaDomainContent(state, content) {
|
|
32122
|
-
state.meta.domain = normalizeMetaDomain(content);
|
|
32123
|
-
}
|
|
32124
|
-
/**
|
|
32125
|
-
* Applies META IMAGE content into the canonical `meta.image` field.
|
|
32126
|
-
*
|
|
32127
|
-
* @private internal utility of `parseAgentSource`
|
|
32128
|
-
*/
|
|
32129
|
-
function applyMetaImageContent(state, content) {
|
|
32130
|
-
state.meta.image = _spaceTrim.spaceTrim(content);
|
|
32131
|
-
}
|
|
32132
|
-
/**
|
|
32133
|
-
* Applies META DESCRIPTION content into the canonical `meta.description` field.
|
|
32134
|
-
*
|
|
32135
|
-
* @private internal utility of `parseAgentSource`
|
|
32136
|
-
*/
|
|
32137
|
-
function applyMetaDescriptionContent(state, content) {
|
|
32138
|
-
state.meta.description = _spaceTrim.spaceTrim(content);
|
|
32139
|
-
}
|
|
32140
|
-
/**
|
|
32141
|
-
* Applies META DISCLAIMER content into the canonical `meta.disclaimer` field.
|
|
32142
|
-
*
|
|
32143
|
-
* @private internal utility of `parseAgentSource`
|
|
32144
|
-
*/
|
|
32145
|
-
function applyMetaDisclaimerContent(state, content) {
|
|
32146
|
-
state.meta.disclaimer = content;
|
|
32147
|
-
}
|
|
32148
|
-
/**
|
|
32149
|
-
* Applies META INPUT PLACEHOLDER content into the canonical `meta.inputPlaceholder` field.
|
|
32150
|
-
*
|
|
32151
|
-
* @private internal utility of `parseAgentSource`
|
|
32152
|
-
*/
|
|
32153
|
-
function applyMetaInputPlaceholderContent(state, content) {
|
|
32154
|
-
state.meta.inputPlaceholder = _spaceTrim.spaceTrim(content);
|
|
32155
|
-
}
|
|
32156
|
-
/**
|
|
32157
|
-
* Applies MESSAGE SUFFIX content into the canonical `meta.messageSuffix` field.
|
|
32158
|
-
*
|
|
32159
|
-
* @private internal utility of `parseAgentSource`
|
|
32160
|
-
*/
|
|
32161
|
-
function applyMessageSuffixContent(state, content) {
|
|
32162
|
-
state.meta.messageSuffix = content;
|
|
32163
|
-
}
|
|
32164
|
-
/**
|
|
32165
|
-
* Applies META COLOR content into the canonical `meta.color` field.
|
|
32166
|
-
*
|
|
32167
|
-
* @private internal utility of `parseAgentSource`
|
|
32168
|
-
*/
|
|
32169
|
-
function applyMetaColorContent(state, content) {
|
|
32170
|
-
state.meta.color = normalizeSeparator(content);
|
|
32171
|
-
}
|
|
32172
|
-
/**
|
|
32173
|
-
* Applies META FONT content into the canonical `meta.font` field.
|
|
32174
|
-
*
|
|
32175
|
-
* @private internal utility of `parseAgentSource`
|
|
32176
|
-
*/
|
|
32177
|
-
function applyMetaFontContent(state, content) {
|
|
32178
|
-
state.meta.font = normalizeSeparator(content);
|
|
32179
|
-
}
|
|
32180
|
-
/**
|
|
32181
|
-
* Applies META VOICE content into the canonical `meta.voice` field.
|
|
32182
|
-
*
|
|
32183
|
-
* @private internal utility of `parseAgentSource`
|
|
32184
|
-
*/
|
|
32185
|
-
function applyMetaVoiceContent(state, content) {
|
|
32186
|
-
state.meta.voice = _spaceTrim.spaceTrim(content);
|
|
32187
|
-
}
|
|
32188
|
-
/**
|
|
32189
|
-
* Ensures the parsed profile always exposes a fullname value.
|
|
32190
|
-
*
|
|
32191
|
-
* @private internal utility of `parseAgentSource`
|
|
32192
|
-
*/
|
|
32193
|
-
function ensureMetaFullname(meta, fallbackFullname) {
|
|
32194
|
-
if (!meta.fullname) {
|
|
32195
|
-
meta.fullname = fallbackFullname;
|
|
32196
|
-
}
|
|
32197
|
-
}
|
|
32198
32117
|
/**
|
|
32199
32118
|
* Extracts the first logical line from multiline commitment content.
|
|
32200
|
-
*
|
|
32201
|
-
* @private internal utility of `parseAgentSource`
|
|
32202
32119
|
*/
|
|
32203
32120
|
function extractFirstCommitmentLine(content) {
|
|
32204
32121
|
return _spaceTrim.spaceTrim(content).split(/\r?\n/)[0] || '';
|
|
32205
32122
|
}
|
|
32206
32123
|
/**
|
|
32207
32124
|
* Detects local FROM/IMPORT references that should use local-link labels and icons.
|
|
32208
|
-
*
|
|
32209
|
-
* @private internal utility of `parseAgentSource`
|
|
32210
32125
|
*/
|
|
32211
32126
|
function isLocalAgentReference(reference) {
|
|
32212
32127
|
return LOCAL_AGENT_REFERENCE_PREFIXES.some((prefix) => reference.startsWith(prefix));
|
|
32213
32128
|
}
|
|
32214
|
-
/**
|
|
32215
|
-
* Normalizes the separator in the content
|
|
32216
|
-
*
|
|
32217
|
-
* @param content - The content to normalize
|
|
32218
|
-
* @returns The content with normalized separators
|
|
32219
|
-
*
|
|
32220
|
-
* @private internal utility of `parseAgentSource`
|
|
32221
|
-
*/
|
|
32222
|
-
function normalizeSeparator(content) {
|
|
32223
|
-
const trimmed = _spaceTrim.spaceTrim(content);
|
|
32224
|
-
if (trimmed.includes(',')) {
|
|
32225
|
-
return trimmed;
|
|
32226
|
-
}
|
|
32227
|
-
return trimmed.split(/\s+/).join(', ');
|
|
32228
|
-
}
|
|
32229
|
-
/**
|
|
32230
|
-
* Normalizes META DOMAIN content to a hostname-like value when possible.
|
|
32231
|
-
*
|
|
32232
|
-
* @param content - Raw META DOMAIN content.
|
|
32233
|
-
* @returns Normalized domain or a trimmed fallback.
|
|
32234
|
-
*
|
|
32235
|
-
* @private internal utility of `parseAgentSource`
|
|
32236
|
-
*/
|
|
32237
|
-
function normalizeMetaDomain(content) {
|
|
32238
|
-
const trimmed = _spaceTrim.spaceTrim(content);
|
|
32239
|
-
return normalizeDomainForMatching(trimmed) || trimmed.toLowerCase();
|
|
32240
|
-
}
|
|
32241
|
-
// TODO: [🕛] Unite `AgentBasicInformation`, `ChatParticipant`, `LlmExecutionTools` + `LlmToolsMetadata`
|
|
32242
32129
|
|
|
32243
32130
|
/**
|
|
32244
|
-
*
|
|
32131
|
+
* Collects capability, sample, meta, link, and knowledge-source data from commitments.
|
|
32245
32132
|
*
|
|
32246
|
-
* @
|
|
32133
|
+
* @private internal utility of `parseAgentSource`
|
|
32247
32134
|
*/
|
|
32248
|
-
function
|
|
32249
|
-
const
|
|
32250
|
-
|
|
32251
|
-
|
|
32252
|
-
|
|
32253
|
-
|
|
32254
|
-
|
|
32255
|
-
|
|
32256
|
-
|
|
32257
|
-
|
|
32258
|
-
|
|
32135
|
+
function extractParsedAgentProfile(commitments) {
|
|
32136
|
+
const state = {
|
|
32137
|
+
meta: {},
|
|
32138
|
+
links: [],
|
|
32139
|
+
capabilities: [],
|
|
32140
|
+
samples: [],
|
|
32141
|
+
knowledgeSources: [],
|
|
32142
|
+
pendingUserMessage: null,
|
|
32143
|
+
knownKnowledgeSourceUrls: new Set(),
|
|
32144
|
+
};
|
|
32145
|
+
for (const commitment of commitments) {
|
|
32146
|
+
processParsedCommitment(state, commitment);
|
|
32259
32147
|
}
|
|
32260
|
-
return
|
|
32148
|
+
return {
|
|
32149
|
+
meta: state.meta,
|
|
32150
|
+
links: state.links,
|
|
32151
|
+
capabilities: state.capabilities,
|
|
32152
|
+
samples: state.samples,
|
|
32153
|
+
knowledgeSources: state.knowledgeSources,
|
|
32154
|
+
};
|
|
32261
32155
|
}
|
|
32262
|
-
|
|
32263
32156
|
/**
|
|
32264
|
-
*
|
|
32265
|
-
*
|
|
32266
|
-
* @see Updatable
|
|
32267
|
-
*
|
|
32268
|
-
* @private internal utility <- TODO: [🧠] Maybe export from `@promptbook/types`
|
|
32157
|
+
* Processes one parsed commitment through the sample, capability, and meta stages.
|
|
32269
32158
|
*/
|
|
32270
|
-
function
|
|
32271
|
-
if (
|
|
32272
|
-
return
|
|
32273
|
-
}
|
|
32274
|
-
else if (Array.isArray(value)) {
|
|
32275
|
-
if (value.length !== 2) {
|
|
32276
|
-
throw new TypeError('`asUpdatableSubject`: Invalid tuple length, expected 2 elements');
|
|
32277
|
-
}
|
|
32278
|
-
if (typeof value[1] !== 'function') {
|
|
32279
|
-
throw new TypeError('`asUpdatableSubject`: Invalid tuple, expected second element to be a function');
|
|
32280
|
-
}
|
|
32281
|
-
const [theValue, setValue] = value;
|
|
32282
|
-
const subject = new rxjs.BehaviorSubject(theValue);
|
|
32283
|
-
subject.subscribe((newValue) => {
|
|
32284
|
-
setValue(newValue);
|
|
32285
|
-
});
|
|
32286
|
-
return subject;
|
|
32159
|
+
function processParsedCommitment(state, commitment) {
|
|
32160
|
+
if (consumeConversationSampleCommitment(state, commitment)) {
|
|
32161
|
+
return;
|
|
32287
32162
|
}
|
|
32288
|
-
|
|
32289
|
-
|
|
32163
|
+
const capabilities = createCapabilitiesFromCommitment(state, commitment);
|
|
32164
|
+
if (capabilities.length > 0) {
|
|
32165
|
+
state.capabilities.push(...capabilities);
|
|
32166
|
+
return;
|
|
32290
32167
|
}
|
|
32168
|
+
applyMetaCommitment(state, commitment);
|
|
32291
32169
|
}
|
|
32292
|
-
// TODO: [🧠] Maybe `BehaviorSubject` is too heavy for this use case, maybe just tuple `[value,setValue]` is enough
|
|
32293
32170
|
|
|
32294
32171
|
/**
|
|
32295
|
-
*
|
|
32296
|
-
* This serves as the starting point for the reduce-like pattern
|
|
32297
|
-
* where each commitment applies its changes to build the final requirements
|
|
32172
|
+
* Parses basic information from agent source
|
|
32298
32173
|
*
|
|
32299
|
-
*
|
|
32300
|
-
|
|
32301
|
-
|
|
32302
|
-
return {
|
|
32303
|
-
systemMessage: '',
|
|
32304
|
-
promptSuffix: '',
|
|
32305
|
-
// modelName: 'gpt-5',
|
|
32306
|
-
modelName: 'gpt-5.4-mini',
|
|
32307
|
-
temperature: 0.7,
|
|
32308
|
-
topP: 0.9,
|
|
32309
|
-
topK: 50,
|
|
32310
|
-
parentAgentUrl: null,
|
|
32311
|
-
isClosed: false,
|
|
32312
|
-
};
|
|
32313
|
-
}
|
|
32314
|
-
/**
|
|
32315
|
-
* Creates a basic agent model requirements with just the agent name
|
|
32316
|
-
* This is used when we have an agent name but no commitments
|
|
32174
|
+
* There are 2 similar functions:
|
|
32175
|
+
* - `parseAgentSource` which is a lightweight parser for agent source, it parses basic information and its purpose is to be quick and synchronous. The commitments there are hardcoded.
|
|
32176
|
+
* - `createAgentModelRequirements` which is an asynchronous function that creates model requirements it applies each commitment one by one and works asynchronously.
|
|
32317
32177
|
*
|
|
32318
32178
|
* @public exported from `@promptbook/core`
|
|
32319
32179
|
*/
|
|
32320
|
-
function
|
|
32321
|
-
const
|
|
32180
|
+
function parseAgentSource(agentSource) {
|
|
32181
|
+
const parseResult = parseAgentSourceWithCommitments(agentSource);
|
|
32182
|
+
const resolvedAgentName = parseResult.agentName || createDefaultAgentName(agentSource);
|
|
32183
|
+
const personaDescription = extractAgentProfileText(parseResult.commitments);
|
|
32184
|
+
const initialMessage = extractInitialMessage(parseResult.commitments);
|
|
32185
|
+
const parsedProfile = extractParsedAgentProfile(parseResult.commitments);
|
|
32186
|
+
ensureMetaFullname(parsedProfile.meta, resolvedAgentName);
|
|
32322
32187
|
return {
|
|
32323
|
-
|
|
32324
|
-
|
|
32188
|
+
agentName: normalizeAgentName(resolvedAgentName),
|
|
32189
|
+
agentHash: computeAgentHash(agentSource),
|
|
32190
|
+
permanentId: parsedProfile.meta.id,
|
|
32191
|
+
personaDescription,
|
|
32192
|
+
initialMessage,
|
|
32193
|
+
meta: parsedProfile.meta,
|
|
32194
|
+
links: parsedProfile.links,
|
|
32195
|
+
parameters: parseParameters(agentSource),
|
|
32196
|
+
capabilities: parsedProfile.capabilities,
|
|
32197
|
+
samples: parsedProfile.samples,
|
|
32198
|
+
knowledgeSources: parsedProfile.knowledgeSources,
|
|
32325
32199
|
};
|
|
32326
32200
|
}
|
|
32327
|
-
// TODO: [
|
|
32328
|
-
|
|
32329
|
-
/**
|
|
32330
|
-
* Gets a commitment definition by its type
|
|
32331
|
-
*
|
|
32332
|
-
* @param type The commitment type to look up
|
|
32333
|
-
* @returns The commitment definition or null if not found
|
|
32334
|
-
*
|
|
32335
|
-
* @public exported from `@promptbook/core`
|
|
32336
|
-
*/
|
|
32337
|
-
function getCommitmentDefinition(type) {
|
|
32338
|
-
return COMMITMENT_REGISTRY.find((commitmentDefinition) => commitmentDefinition.type === type) || null;
|
|
32339
|
-
}
|
|
32340
|
-
|
|
32341
|
-
/**
|
|
32342
|
-
* Plugin for importing agent books *(`.book` files)*
|
|
32343
|
-
*
|
|
32344
|
-
* @private [🥝] Maybe export the import plugins through some package
|
|
32345
|
-
*/
|
|
32346
|
-
const AgentFileImportPlugin = {
|
|
32347
|
-
name: 'agent-file-import-plugin',
|
|
32348
|
-
canImport(mimeType) {
|
|
32349
|
-
// [🧠] Should we have a specific MIME type for agent books?
|
|
32350
|
-
// For now, let's assume it's identified by .book extension or certain MIME types if provided
|
|
32351
|
-
return mimeType === 'text/x-promptbook' || mimeType === 'application/x-promptbook';
|
|
32352
|
-
},
|
|
32353
|
-
import(content) {
|
|
32354
|
-
const parseResult = parseAgentSourceWithCommitments(content);
|
|
32355
|
-
// Bring only the agent corpus (non-commitment lines and relevant commitments)
|
|
32356
|
-
// Stripping the agent name (which is usually the first line)
|
|
32357
|
-
const corpus = parseResult.nonCommitmentLines
|
|
32358
|
-
.filter((line, index) => index > 0 || !parseResult.agentName)
|
|
32359
|
-
.join('\n')
|
|
32360
|
-
.trim();
|
|
32361
|
-
// Also include relevant commitments that make up the "corpus" of the agent
|
|
32362
|
-
// For example PERSONA, RULE, KNOWLEDGE
|
|
32363
|
-
const relevantCommitments = parseResult.commitments
|
|
32364
|
-
.filter((c) => ['PERSONA', 'RULE', 'KNOWLEDGE'].includes(c.type))
|
|
32365
|
-
.map((c) => `${c.type} ${c.content}`)
|
|
32366
|
-
.join('\n\n');
|
|
32367
|
-
return _spaceTrim.spaceTrim((block) => `
|
|
32368
|
-
${block(relevantCommitments)}
|
|
32369
|
-
|
|
32370
|
-
${block(corpus)}
|
|
32371
|
-
`).trim();
|
|
32372
|
-
},
|
|
32373
|
-
};
|
|
32374
|
-
|
|
32375
|
-
/**
|
|
32376
|
-
* Plugin for importing JSON files
|
|
32377
|
-
*
|
|
32378
|
-
* @private [🥝] Maybe export the import plugins through some package
|
|
32379
|
-
*/
|
|
32380
|
-
const JsonFileImportPlugin = {
|
|
32381
|
-
name: 'json-file-import-plugin',
|
|
32382
|
-
canImport(mimeType) {
|
|
32383
|
-
return mimeType === 'application/json' || mimeType.endsWith('+json');
|
|
32384
|
-
},
|
|
32385
|
-
import(content) {
|
|
32386
|
-
try {
|
|
32387
|
-
const json = JSON.parse(content);
|
|
32388
|
-
const formattedJson = JSON.stringify(json, null, 4);
|
|
32389
|
-
return `\`\`\`json\n${formattedJson}\n\`\`\``;
|
|
32390
|
-
}
|
|
32391
|
-
catch (error) {
|
|
32392
|
-
// If JSON is invalid, still import it but maybe not as pretty JSON
|
|
32393
|
-
return `\`\`\`json\n${content}\n\`\`\``;
|
|
32394
|
-
}
|
|
32395
|
-
},
|
|
32396
|
-
};
|
|
32397
|
-
|
|
32398
|
-
/**
|
|
32399
|
-
* Plugin for importing generic text files
|
|
32400
|
-
*
|
|
32401
|
-
* @private [🥝] Maybe export the import plugins through some package
|
|
32402
|
-
*/
|
|
32403
|
-
const TextFileImportPlugin = {
|
|
32404
|
-
name: 'text-file-import-plugin',
|
|
32405
|
-
canImport(mimeType) {
|
|
32406
|
-
return (mimeType === 'text/plain' ||
|
|
32407
|
-
mimeType === 'text/markdown' ||
|
|
32408
|
-
mimeType === 'text/x-typescript' ||
|
|
32409
|
-
mimeType === 'text/javascript' ||
|
|
32410
|
-
mimeType === 'text/css' ||
|
|
32411
|
-
mimeType === 'text/html' ||
|
|
32412
|
-
mimeType.startsWith('text/'));
|
|
32413
|
-
},
|
|
32414
|
-
import(content, mimeType) {
|
|
32415
|
-
const extension = mimeTypeToExtension(mimeType);
|
|
32416
|
-
const codeBlockType = extension || 'txt';
|
|
32417
|
-
return `\`\`\`${codeBlockType}\n${content}\n\`\`\``;
|
|
32418
|
-
},
|
|
32419
|
-
};
|
|
32420
|
-
|
|
32421
|
-
/**
|
|
32422
|
-
* All available file import plugins
|
|
32423
|
-
*
|
|
32424
|
-
* @private [🥝] Maybe export the import plugins through some package
|
|
32425
|
-
*/
|
|
32426
|
-
const $fileImportPlugins = [
|
|
32427
|
-
AgentFileImportPlugin,
|
|
32428
|
-
JsonFileImportPlugin,
|
|
32429
|
-
TextFileImportPlugin,
|
|
32430
|
-
];
|
|
32431
|
-
|
|
32432
|
-
/**
|
|
32433
|
-
* Removes single-hash comment lines (`# Comment`) from a system message
|
|
32434
|
-
* This is used to clean up the final system message before sending it to the AI model
|
|
32435
|
-
* while preserving the original content with comments in metadata
|
|
32436
|
-
*
|
|
32437
|
-
* @param systemMessage The system message that may contain comment lines
|
|
32438
|
-
* @returns The system message with single-hash comment lines removed
|
|
32439
|
-
*
|
|
32440
|
-
* @private - TODO: [🧠] Maybe should be public?
|
|
32441
|
-
*/
|
|
32442
|
-
function removeCommentsFromSystemMessage(systemMessage) {
|
|
32443
|
-
if (!systemMessage) {
|
|
32444
|
-
return systemMessage;
|
|
32445
|
-
}
|
|
32446
|
-
const lines = systemMessage.split(/\r?\n/);
|
|
32447
|
-
const filteredLines = lines.filter((line) => {
|
|
32448
|
-
const trimmedLine = line.trim();
|
|
32449
|
-
// Remove only single-hash comment markers (`# Comment`) and keep markdown headings (`## Heading`).
|
|
32450
|
-
return !/^#(?!#)\s/.test(trimmedLine);
|
|
32451
|
-
});
|
|
32452
|
-
return filteredLines.join('\n').trim();
|
|
32453
|
-
}
|
|
32454
|
-
|
|
32455
|
-
/**
|
|
32456
|
-
* Commitment types whose content may contain compact agent references that must be resolved before applying the commitment.
|
|
32457
|
-
*
|
|
32458
|
-
* @private internal constant of `createAgentModelRequirementsWithCommitments`
|
|
32459
|
-
*/
|
|
32460
|
-
const COMMITMENTS_WITH_AGENT_REFERENCES = new Set(['FROM', 'IMPORT', 'IMPORTS', 'TEAM']);
|
|
32461
|
-
/**
|
|
32462
|
-
* DELETE-like commitment types that invalidate earlier tagged commitments.
|
|
32463
|
-
*
|
|
32464
|
-
* @private internal constant of `createAgentModelRequirementsWithCommitments`
|
|
32465
|
-
*/
|
|
32466
|
-
const DELETE_COMMITMENT_TYPES = new Set(['DELETE', 'CANCEL', 'DISCARD', 'REMOVE']);
|
|
32467
|
-
/**
|
|
32468
|
-
* Commitments whose earlier occurrences are overwritten by the last occurrence in source order.
|
|
32469
|
-
*
|
|
32470
|
-
* @private internal constant of `createAgentModelRequirementsWithCommitments`
|
|
32471
|
-
*/
|
|
32472
|
-
const OVERWRITTEN_COMMITMENT_GROUP_BY_TYPE = new Map([
|
|
32473
|
-
['GOAL', 'GOAL'],
|
|
32474
|
-
['GOALS', 'GOAL'],
|
|
32475
|
-
]);
|
|
32476
|
-
/**
|
|
32477
|
-
* Regex pattern matching markdown horizontal lines that should not be copied into the final system message.
|
|
32478
|
-
*
|
|
32479
|
-
* @private internal constant of `createAgentModelRequirementsWithCommitments`
|
|
32480
|
-
*/
|
|
32481
|
-
const HORIZONTAL_LINE_PATTERN = /^[\s]*[-_*][\s]*[-_*][\s]*[-_*][\s]*[-_*]*[\s]*$/;
|
|
32482
|
-
/**
|
|
32483
|
-
* MIME type prefixes treated as binary and therefore not eligible for text import plugins.
|
|
32484
|
-
*
|
|
32485
|
-
* @private internal constant of `createAgentModelRequirementsWithCommitments`
|
|
32486
|
-
*/
|
|
32487
|
-
const BINARY_MIME_TYPE_PREFIXES = [
|
|
32488
|
-
'image/',
|
|
32489
|
-
'video/',
|
|
32490
|
-
'audio/',
|
|
32491
|
-
'application/octet-stream',
|
|
32492
|
-
'application/pdf',
|
|
32493
|
-
'application/zip',
|
|
32494
|
-
];
|
|
32495
|
-
/**
|
|
32496
|
-
* Returns a safe fallback content when a resolver fails to transform a reference commitment.
|
|
32497
|
-
*
|
|
32498
|
-
* @param commitmentType - Commitment being resolved.
|
|
32499
|
-
* @param originalContent - Original unresolved commitment content.
|
|
32500
|
-
* @returns Fallback content that keeps requirement creation resilient.
|
|
32501
|
-
*
|
|
32502
|
-
* @private internal utility of `createAgentModelRequirementsWithCommitments`
|
|
32503
|
-
*/
|
|
32504
|
-
function getSafeReferenceCommitmentFallback(commitmentType, originalContent) {
|
|
32505
|
-
if (commitmentType === 'FROM') {
|
|
32506
|
-
return 'VOID';
|
|
32507
|
-
}
|
|
32508
|
-
if (commitmentType === 'IMPORT' || commitmentType === 'IMPORTS' || commitmentType === 'TEAM') {
|
|
32509
|
-
return '';
|
|
32510
|
-
}
|
|
32511
|
-
return originalContent;
|
|
32512
|
-
}
|
|
32513
|
-
/**
|
|
32514
|
-
* Creates agent model requirements by parsing commitments, applying them in source order,
|
|
32515
|
-
* and finalizing derived sections such as imports, example interactions, and inline knowledge uploads.
|
|
32516
|
-
*
|
|
32517
|
-
* @param agentSource - Agent source book to parse.
|
|
32518
|
-
* @param modelName - Optional override for the agent model name.
|
|
32519
|
-
* @param options - Additional options such as reference and teammate resolvers.
|
|
32520
|
-
* @returns Fully prepared model requirements for the parsed agent source.
|
|
32521
|
-
*
|
|
32522
|
-
* @private internal utility of `createAgentModelRequirements`
|
|
32523
|
-
*/
|
|
32524
|
-
async function createAgentModelRequirementsWithCommitments(agentSource, modelName, options) {
|
|
32525
|
-
const parseResult = parseAgentSourceWithCommitments(agentSource);
|
|
32526
|
-
const filteredCommitments = filterOverwrittenCommitments(filterDeletedCommitments(parseResult.commitments));
|
|
32527
|
-
let requirements = createInitialAgentModelRequirements(parseResult.agentName, modelName);
|
|
32528
|
-
requirements = await applyCommitmentsToRequirements(requirements, filteredCommitments, options);
|
|
32529
|
-
requirements = aggregateUseCommitmentSystemMessages(requirements, filteredCommitments);
|
|
32530
|
-
requirements = await importReferencedFiles(requirements);
|
|
32531
|
-
requirements = appendMcpServers(requirements, agentSource);
|
|
32532
|
-
requirements = appendNonCommitmentContent(requirements, parseResult);
|
|
32533
|
-
requirements = appendExampleInteractions(requirements, parseResult);
|
|
32534
|
-
requirements = await applyPendingInlineKnowledgeSources(requirements, options === null || options === void 0 ? void 0 : options.inlineKnowledgeSourceUploader);
|
|
32535
|
-
return finalizeRequirements(requirements);
|
|
32536
|
-
}
|
|
32201
|
+
// TODO: [🕛] Unite `AgentBasicInformation`, `ChatParticipant`, `LlmExecutionTools` + `LlmToolsMetadata`
|
|
32202
|
+
|
|
32537
32203
|
/**
|
|
32538
|
-
*
|
|
32204
|
+
* Gets all tool titles provided by all commitments
|
|
32539
32205
|
*
|
|
32540
|
-
*
|
|
32541
|
-
|
|
32206
|
+
* @public exported from `@promptbook/core`
|
|
32207
|
+
*/
|
|
32208
|
+
function getAllCommitmentsToolTitles() {
|
|
32209
|
+
const allToolTitles = {};
|
|
32210
|
+
for (const commitmentDefinition of getAllCommitmentDefinitions()) {
|
|
32211
|
+
const toolTitles = commitmentDefinition.getToolTitles();
|
|
32212
|
+
for (const [funcName, title] of Object.entries(toolTitles)) {
|
|
32213
|
+
if (allToolTitles[funcName] !== undefined &&
|
|
32214
|
+
just(false) /* <- Note: [⛹️] How to deal with commitment aliases */) {
|
|
32215
|
+
throw new UnexpectedError(`Duplicate tool function name detected: \`${funcName}\` provided by commitment \`${commitmentDefinition.type}\``);
|
|
32216
|
+
}
|
|
32217
|
+
allToolTitles[funcName] = title;
|
|
32218
|
+
}
|
|
32219
|
+
}
|
|
32220
|
+
return allToolTitles;
|
|
32221
|
+
}
|
|
32222
|
+
|
|
32223
|
+
/**
|
|
32224
|
+
* Restricts an Updatable to a (2) BehaviorSubject variant
|
|
32542
32225
|
*
|
|
32543
|
-
* @
|
|
32544
|
-
* @returns Commitments with overwritten entries removed while preserving source order.
|
|
32226
|
+
* @see Updatable
|
|
32545
32227
|
*
|
|
32546
|
-
* @private internal utility
|
|
32228
|
+
* @private internal utility <- TODO: [🧠] Maybe export from `@promptbook/types`
|
|
32547
32229
|
*/
|
|
32548
|
-
function
|
|
32549
|
-
|
|
32550
|
-
|
|
32551
|
-
|
|
32552
|
-
|
|
32553
|
-
|
|
32554
|
-
|
|
32555
|
-
keptCommitments.push(commitment);
|
|
32556
|
-
continue;
|
|
32230
|
+
function asUpdatableSubject(value) {
|
|
32231
|
+
if (value instanceof rxjs.BehaviorSubject) {
|
|
32232
|
+
return value;
|
|
32233
|
+
}
|
|
32234
|
+
else if (Array.isArray(value)) {
|
|
32235
|
+
if (value.length !== 2) {
|
|
32236
|
+
throw new TypeError('`asUpdatableSubject`: Invalid tuple length, expected 2 elements');
|
|
32557
32237
|
}
|
|
32558
|
-
if (
|
|
32559
|
-
|
|
32238
|
+
if (typeof value[1] !== 'function') {
|
|
32239
|
+
throw new TypeError('`asUpdatableSubject`: Invalid tuple, expected second element to be a function');
|
|
32560
32240
|
}
|
|
32561
|
-
|
|
32562
|
-
|
|
32241
|
+
const [theValue, setValue] = value;
|
|
32242
|
+
const subject = new rxjs.BehaviorSubject(theValue);
|
|
32243
|
+
subject.subscribe((newValue) => {
|
|
32244
|
+
setValue(newValue);
|
|
32245
|
+
});
|
|
32246
|
+
return subject;
|
|
32247
|
+
}
|
|
32248
|
+
else {
|
|
32249
|
+
return new rxjs.BehaviorSubject(value);
|
|
32563
32250
|
}
|
|
32564
|
-
return keptCommitments.reverse();
|
|
32565
32251
|
}
|
|
32252
|
+
// TODO: [🧠] Maybe `BehaviorSubject` is too heavy for this use case, maybe just tuple `[value,setValue]` is enough
|
|
32253
|
+
|
|
32566
32254
|
/**
|
|
32567
|
-
* Creates
|
|
32568
|
-
*
|
|
32569
|
-
*
|
|
32570
|
-
* @param modelName - Optional explicit model name override.
|
|
32571
|
-
* @returns Initial requirements before any commitment is applied.
|
|
32255
|
+
* Creates an empty/basic agent model requirements object
|
|
32256
|
+
* This serves as the starting point for the reduce-like pattern
|
|
32257
|
+
* where each commitment applies its changes to build the final requirements
|
|
32572
32258
|
*
|
|
32573
|
-
* @
|
|
32259
|
+
* @public exported from `@promptbook/core`
|
|
32574
32260
|
*/
|
|
32575
|
-
function
|
|
32576
|
-
const initialRequirements = createBasicAgentModelRequirements(agentName);
|
|
32577
|
-
const requirementsWithMetadata = {
|
|
32578
|
-
...initialRequirements,
|
|
32579
|
-
_metadata: {
|
|
32580
|
-
...initialRequirements._metadata,
|
|
32581
|
-
agentName,
|
|
32582
|
-
},
|
|
32583
|
-
};
|
|
32584
|
-
if (!modelName) {
|
|
32585
|
-
return requirementsWithMetadata;
|
|
32586
|
-
}
|
|
32261
|
+
function createEmptyAgentModelRequirements() {
|
|
32587
32262
|
return {
|
|
32588
|
-
|
|
32589
|
-
|
|
32263
|
+
systemMessage: '',
|
|
32264
|
+
promptSuffix: '',
|
|
32265
|
+
// modelName: 'gpt-5',
|
|
32266
|
+
modelName: 'gpt-5.4-mini',
|
|
32267
|
+
temperature: 0.7,
|
|
32268
|
+
topP: 0.9,
|
|
32269
|
+
topK: 50,
|
|
32270
|
+
parentAgentUrl: null,
|
|
32271
|
+
isClosed: false,
|
|
32590
32272
|
};
|
|
32591
32273
|
}
|
|
32592
32274
|
/**
|
|
32593
|
-
*
|
|
32594
|
-
*
|
|
32595
|
-
* @param commitments - Parsed commitments in original source order.
|
|
32596
|
-
* @returns Filtered commitments with earlier deleted items removed.
|
|
32275
|
+
* Creates a basic agent model requirements with just the agent name
|
|
32276
|
+
* This is used when we have an agent name but no commitments
|
|
32597
32277
|
*
|
|
32598
|
-
* @
|
|
32278
|
+
* @public exported from `@promptbook/core`
|
|
32599
32279
|
*/
|
|
32600
|
-
function
|
|
32601
|
-
const
|
|
32602
|
-
|
|
32603
|
-
|
|
32604
|
-
|
|
32605
|
-
|
|
32606
|
-
}
|
|
32607
|
-
const targetParameterNames = getCommitmentParameterNames(commitment.content);
|
|
32608
|
-
if (targetParameterNames.length === 0) {
|
|
32609
|
-
continue;
|
|
32610
|
-
}
|
|
32611
|
-
for (let index = filteredCommitments.length - 1; index >= 0; index--) {
|
|
32612
|
-
const previousCommitment = filteredCommitments[index];
|
|
32613
|
-
const previousParameterNames = getCommitmentParameterNames(previousCommitment.content);
|
|
32614
|
-
const isTargeted = previousParameterNames.some((parameterName) => targetParameterNames.includes(parameterName));
|
|
32615
|
-
if (isTargeted) {
|
|
32616
|
-
filteredCommitments.splice(index, 1);
|
|
32617
|
-
}
|
|
32618
|
-
}
|
|
32619
|
-
}
|
|
32620
|
-
return filteredCommitments;
|
|
32280
|
+
function createBasicAgentModelRequirements(agentName) {
|
|
32281
|
+
const empty = createEmptyAgentModelRequirements();
|
|
32282
|
+
return {
|
|
32283
|
+
...empty,
|
|
32284
|
+
systemMessage: `You are ${agentName || 'AI Agent'}`,
|
|
32285
|
+
};
|
|
32621
32286
|
}
|
|
32287
|
+
// TODO: [🐤] Deduplicate `AgentModelRequirements` and `ModelRequirements` model requirements
|
|
32288
|
+
|
|
32622
32289
|
/**
|
|
32623
|
-
*
|
|
32290
|
+
* Gets a commitment definition by its type
|
|
32624
32291
|
*
|
|
32625
|
-
* @param
|
|
32626
|
-
* @returns
|
|
32292
|
+
* @param type The commitment type to look up
|
|
32293
|
+
* @returns The commitment definition or null if not found
|
|
32627
32294
|
*
|
|
32628
|
-
* @
|
|
32295
|
+
* @public exported from `@promptbook/core`
|
|
32629
32296
|
*/
|
|
32630
|
-
function
|
|
32631
|
-
return
|
|
32297
|
+
function getCommitmentDefinition(type) {
|
|
32298
|
+
return COMMITMENT_REGISTRY.find((commitmentDefinition) => commitmentDefinition.type === type) || null;
|
|
32632
32299
|
}
|
|
32300
|
+
|
|
32633
32301
|
/**
|
|
32634
|
-
*
|
|
32635
|
-
*
|
|
32636
|
-
* @param content - Commitment content to parse.
|
|
32637
|
-
* @returns Lower-cased non-empty parameter names.
|
|
32302
|
+
* Commitment types whose content may contain compact agent references that must be resolved before applying the commitment.
|
|
32638
32303
|
*
|
|
32639
|
-
* @private internal
|
|
32304
|
+
* @private internal constant of `applyCommitmentsToAgentModelRequirements`
|
|
32640
32305
|
*/
|
|
32641
|
-
|
|
32642
|
-
return parseParameters(content)
|
|
32643
|
-
.map((parameter) => parameter.name.trim().toLowerCase())
|
|
32644
|
-
.filter(Boolean);
|
|
32645
|
-
}
|
|
32306
|
+
const COMMITMENTS_WITH_AGENT_REFERENCES = new Set(['FROM', 'IMPORT', 'IMPORTS', 'TEAM']);
|
|
32646
32307
|
/**
|
|
32647
32308
|
* Applies parsed commitments one by one while keeping the per-commitment steps focused and easy to follow.
|
|
32648
32309
|
*
|
|
@@ -32651,9 +32312,9 @@
|
|
|
32651
32312
|
* @param options - Optional reference and teammate resolvers.
|
|
32652
32313
|
* @returns Requirements after all applicable commitments are processed.
|
|
32653
32314
|
*
|
|
32654
|
-
* @private
|
|
32315
|
+
* @private function of `createAgentModelRequirementsWithCommitments`
|
|
32655
32316
|
*/
|
|
32656
|
-
async function
|
|
32317
|
+
async function applyCommitmentsToAgentModelRequirements(requirements, commitments, options) {
|
|
32657
32318
|
for (const [index, commitment] of commitments.entries()) {
|
|
32658
32319
|
if (shouldSkipCommitmentApplication(commitment, index, commitments.length)) {
|
|
32659
32320
|
continue;
|
|
@@ -32671,7 +32332,7 @@
|
|
|
32671
32332
|
* @param agentReferenceResolver - Optional resolver for compact agent references.
|
|
32672
32333
|
* @returns Original or resolved commitment content.
|
|
32673
32334
|
*
|
|
32674
|
-
* @private internal utility of `
|
|
32335
|
+
* @private internal utility of `applyCommitmentsToAgentModelRequirements`
|
|
32675
32336
|
*/
|
|
32676
32337
|
async function resolveCommitmentContent(commitment, agentReferenceResolver) {
|
|
32677
32338
|
if (!agentReferenceResolver || !isAgentReferenceCommitment(commitment.type)) {
|
|
@@ -32685,6 +32346,24 @@
|
|
|
32685
32346
|
return getSafeReferenceCommitmentFallback(commitment.type, commitment.content);
|
|
32686
32347
|
}
|
|
32687
32348
|
}
|
|
32349
|
+
/**
|
|
32350
|
+
* Returns a safe fallback content when a resolver fails to transform a reference commitment.
|
|
32351
|
+
*
|
|
32352
|
+
* @param commitmentType - Commitment being resolved.
|
|
32353
|
+
* @param originalContent - Original unresolved commitment content.
|
|
32354
|
+
* @returns Fallback content that keeps requirement creation resilient.
|
|
32355
|
+
*
|
|
32356
|
+
* @private internal utility of `applyCommitmentsToAgentModelRequirements`
|
|
32357
|
+
*/
|
|
32358
|
+
function getSafeReferenceCommitmentFallback(commitmentType, originalContent) {
|
|
32359
|
+
if (commitmentType === 'FROM') {
|
|
32360
|
+
return 'VOID';
|
|
32361
|
+
}
|
|
32362
|
+
if (commitmentType === 'IMPORT' || commitmentType === 'IMPORTS' || commitmentType === 'TEAM') {
|
|
32363
|
+
return '';
|
|
32364
|
+
}
|
|
32365
|
+
return originalContent;
|
|
32366
|
+
}
|
|
32688
32367
|
/**
|
|
32689
32368
|
* Checks whether the commitment content may need agent-reference resolution before application.
|
|
32690
32369
|
*
|
|
@@ -32704,7 +32383,7 @@
|
|
|
32704
32383
|
* @param commitmentCount - Total number of filtered commitments.
|
|
32705
32384
|
* @returns `true` when the commitment should not be applied.
|
|
32706
32385
|
*
|
|
32707
|
-
* @private internal utility of `
|
|
32386
|
+
* @private internal utility of `applyCommitmentsToAgentModelRequirements`
|
|
32708
32387
|
*/
|
|
32709
32388
|
function shouldSkipCommitmentApplication(commitment, commitmentIndex, commitmentCount) {
|
|
32710
32389
|
return commitment.type === 'CLOSED' && commitmentIndex !== commitmentCount - 1;
|
|
@@ -32718,7 +32397,7 @@
|
|
|
32718
32397
|
* @param options - Optional teammate profile resolvers.
|
|
32719
32398
|
* @returns Requirements with pre-resolved teammate profiles stored in metadata when possible.
|
|
32720
32399
|
*
|
|
32721
|
-
* @private internal utility of `
|
|
32400
|
+
* @private internal utility of `applyCommitmentsToAgentModelRequirements`
|
|
32722
32401
|
*/
|
|
32723
32402
|
async function preResolveTeammateProfilesForTeamCommitment(requirements, commitment, commitmentContent, options) {
|
|
32724
32403
|
var _a;
|
|
@@ -32773,7 +32452,7 @@
|
|
|
32773
32452
|
* @param commitmentContent - Final content passed into the definition.
|
|
32774
32453
|
* @returns Updated requirements, or the original requirements when the commitment fails.
|
|
32775
32454
|
*
|
|
32776
|
-
* @private internal utility of `
|
|
32455
|
+
* @private internal utility of `applyCommitmentsToAgentModelRequirements`
|
|
32777
32456
|
*/
|
|
32778
32457
|
function applyCommitmentDefinitionSafely(requirements, commitment, commitmentContent) {
|
|
32779
32458
|
const definition = getCommitmentDefinition(commitment.type);
|
|
@@ -32788,13 +32467,140 @@
|
|
|
32788
32467
|
return requirements;
|
|
32789
32468
|
}
|
|
32790
32469
|
}
|
|
32470
|
+
|
|
32471
|
+
/**
|
|
32472
|
+
* Plugin for importing agent books *(`.book` files)*
|
|
32473
|
+
*
|
|
32474
|
+
* @private [🥝] Maybe export the import plugins through some package
|
|
32475
|
+
*/
|
|
32476
|
+
const AgentFileImportPlugin = {
|
|
32477
|
+
name: 'agent-file-import-plugin',
|
|
32478
|
+
canImport(mimeType) {
|
|
32479
|
+
// [🧠] Should we have a specific MIME type for agent books?
|
|
32480
|
+
// For now, let's assume it's identified by .book extension or certain MIME types if provided
|
|
32481
|
+
return mimeType === 'text/x-promptbook' || mimeType === 'application/x-promptbook';
|
|
32482
|
+
},
|
|
32483
|
+
import(content) {
|
|
32484
|
+
const parseResult = parseAgentSourceWithCommitments(content);
|
|
32485
|
+
// Bring only the agent corpus (non-commitment lines and relevant commitments)
|
|
32486
|
+
// Stripping the agent name (which is usually the first line)
|
|
32487
|
+
const corpus = parseResult.nonCommitmentLines
|
|
32488
|
+
.filter((line, index) => index > 0 || !parseResult.agentName)
|
|
32489
|
+
.join('\n')
|
|
32490
|
+
.trim();
|
|
32491
|
+
// Also include relevant commitments that make up the "corpus" of the agent
|
|
32492
|
+
// For example PERSONA, RULE, KNOWLEDGE
|
|
32493
|
+
const relevantCommitments = parseResult.commitments
|
|
32494
|
+
.filter((c) => ['PERSONA', 'RULE', 'KNOWLEDGE'].includes(c.type))
|
|
32495
|
+
.map((c) => `${c.type} ${c.content}`)
|
|
32496
|
+
.join('\n\n');
|
|
32497
|
+
return _spaceTrim.spaceTrim((block) => `
|
|
32498
|
+
${block(relevantCommitments)}
|
|
32499
|
+
|
|
32500
|
+
${block(corpus)}
|
|
32501
|
+
`).trim();
|
|
32502
|
+
},
|
|
32503
|
+
};
|
|
32504
|
+
|
|
32505
|
+
/**
|
|
32506
|
+
* Plugin for importing JSON files
|
|
32507
|
+
*
|
|
32508
|
+
* @private [🥝] Maybe export the import plugins through some package
|
|
32509
|
+
*/
|
|
32510
|
+
const JsonFileImportPlugin = {
|
|
32511
|
+
name: 'json-file-import-plugin',
|
|
32512
|
+
canImport(mimeType) {
|
|
32513
|
+
return mimeType === 'application/json' || mimeType.endsWith('+json');
|
|
32514
|
+
},
|
|
32515
|
+
import(content) {
|
|
32516
|
+
try {
|
|
32517
|
+
const json = JSON.parse(content);
|
|
32518
|
+
const formattedJson = JSON.stringify(json, null, 4);
|
|
32519
|
+
return `\`\`\`json\n${formattedJson}\n\`\`\``;
|
|
32520
|
+
}
|
|
32521
|
+
catch (error) {
|
|
32522
|
+
// If JSON is invalid, still import it but maybe not as pretty JSON
|
|
32523
|
+
return `\`\`\`json\n${content}\n\`\`\``;
|
|
32524
|
+
}
|
|
32525
|
+
},
|
|
32526
|
+
};
|
|
32527
|
+
|
|
32528
|
+
/**
|
|
32529
|
+
* Plugin for importing generic text files
|
|
32530
|
+
*
|
|
32531
|
+
* @private [🥝] Maybe export the import plugins through some package
|
|
32532
|
+
*/
|
|
32533
|
+
const TextFileImportPlugin = {
|
|
32534
|
+
name: 'text-file-import-plugin',
|
|
32535
|
+
canImport(mimeType) {
|
|
32536
|
+
return (mimeType === 'text/plain' ||
|
|
32537
|
+
mimeType === 'text/markdown' ||
|
|
32538
|
+
mimeType === 'text/x-typescript' ||
|
|
32539
|
+
mimeType === 'text/javascript' ||
|
|
32540
|
+
mimeType === 'text/css' ||
|
|
32541
|
+
mimeType === 'text/html' ||
|
|
32542
|
+
mimeType.startsWith('text/'));
|
|
32543
|
+
},
|
|
32544
|
+
import(content, mimeType) {
|
|
32545
|
+
const extension = mimeTypeToExtension(mimeType);
|
|
32546
|
+
const codeBlockType = extension || 'txt';
|
|
32547
|
+
return `\`\`\`${codeBlockType}\n${content}\n\`\`\``;
|
|
32548
|
+
},
|
|
32549
|
+
};
|
|
32550
|
+
|
|
32551
|
+
/**
|
|
32552
|
+
* All available file import plugins
|
|
32553
|
+
*
|
|
32554
|
+
* @private [🥝] Maybe export the import plugins through some package
|
|
32555
|
+
*/
|
|
32556
|
+
const $fileImportPlugins = [
|
|
32557
|
+
AgentFileImportPlugin,
|
|
32558
|
+
JsonFileImportPlugin,
|
|
32559
|
+
TextFileImportPlugin,
|
|
32560
|
+
];
|
|
32561
|
+
|
|
32562
|
+
/**
|
|
32563
|
+
* Regex pattern matching markdown horizontal lines that should not be copied into the final system message.
|
|
32564
|
+
*
|
|
32565
|
+
* @private internal constant of `augmentAgentModelRequirementsFromSource`
|
|
32566
|
+
*/
|
|
32567
|
+
const HORIZONTAL_LINE_PATTERN = /^[\s]*[-_*][\s]*[-_*][\s]*[-_*][\s]*[-_*]*[\s]*$/;
|
|
32568
|
+
/**
|
|
32569
|
+
* MIME type prefixes treated as binary and therefore not eligible for text import plugins.
|
|
32570
|
+
*
|
|
32571
|
+
* @private internal constant of `augmentAgentModelRequirementsFromSource`
|
|
32572
|
+
*/
|
|
32573
|
+
const BINARY_MIME_TYPE_PREFIXES = [
|
|
32574
|
+
'image/',
|
|
32575
|
+
'video/',
|
|
32576
|
+
'audio/',
|
|
32577
|
+
'application/octet-stream',
|
|
32578
|
+
'application/pdf',
|
|
32579
|
+
'application/zip',
|
|
32580
|
+
];
|
|
32581
|
+
/**
|
|
32582
|
+
* Adds source-derived sections after commitments have been applied.
|
|
32583
|
+
*
|
|
32584
|
+
* @param requirements - Requirements after commitment application and USE aggregation.
|
|
32585
|
+
* @param parseResult - Parsed source used to recover non-commitment prose and examples.
|
|
32586
|
+
* @param agentSource - Original source used to recover MCP server declarations.
|
|
32587
|
+
* @returns Requirements with source-derived sections appended.
|
|
32588
|
+
*
|
|
32589
|
+
* @private function of `createAgentModelRequirementsWithCommitments`
|
|
32590
|
+
*/
|
|
32591
|
+
async function augmentAgentModelRequirementsFromSource(requirements, parseResult, agentSource) {
|
|
32592
|
+
requirements = await importReferencedFiles(requirements);
|
|
32593
|
+
requirements = appendMcpServers(requirements, agentSource);
|
|
32594
|
+
requirements = appendNonCommitmentContent(requirements, parseResult);
|
|
32595
|
+
return appendExampleInteractions(requirements, parseResult);
|
|
32596
|
+
}
|
|
32791
32597
|
/**
|
|
32792
32598
|
* Imports text files referenced by IMPORT commitments and appends their transformed content to the system message.
|
|
32793
32599
|
*
|
|
32794
32600
|
* @param requirements - Requirements possibly containing `importedFileUrls`.
|
|
32795
32601
|
* @returns Requirements with imported file content appended to the system message.
|
|
32796
32602
|
*
|
|
32797
|
-
* @private internal utility of `
|
|
32603
|
+
* @private internal utility of `augmentAgentModelRequirementsFromSource`
|
|
32798
32604
|
*/
|
|
32799
32605
|
async function importReferencedFiles(requirements) {
|
|
32800
32606
|
const importedFileUrls = requirements.importedFileUrls;
|
|
@@ -32880,7 +32686,7 @@
|
|
|
32880
32686
|
* @param agentSource - Original agent source used for MCP extraction.
|
|
32881
32687
|
* @returns Requirements with `mcpServers` set when MCP commitments are present.
|
|
32882
32688
|
*
|
|
32883
|
-
* @private internal utility of `
|
|
32689
|
+
* @private internal utility of `augmentAgentModelRequirementsFromSource`
|
|
32884
32690
|
*/
|
|
32885
32691
|
function appendMcpServers(requirements, agentSource) {
|
|
32886
32692
|
const mcpServers = extractMcpServers(agentSource);
|
|
@@ -32899,7 +32705,7 @@
|
|
|
32899
32705
|
* @param parseResult - Parsed source including non-commitment lines.
|
|
32900
32706
|
* @returns Requirements with the remaining prose appended to the system message.
|
|
32901
32707
|
*
|
|
32902
|
-
* @private internal utility of `
|
|
32708
|
+
* @private internal utility of `augmentAgentModelRequirementsFromSource`
|
|
32903
32709
|
*/
|
|
32904
32710
|
function appendNonCommitmentContent(requirements, parseResult) {
|
|
32905
32711
|
const nonCommitmentContent = getNonCommitmentContent(parseResult);
|
|
@@ -32942,7 +32748,7 @@
|
|
|
32942
32748
|
* @param parseResult - Parsed source used to recover initial message content.
|
|
32943
32749
|
* @returns Requirements with the example interaction block appended when examples exist.
|
|
32944
32750
|
*
|
|
32945
|
-
* @private internal utility of `
|
|
32751
|
+
* @private internal utility of `augmentAgentModelRequirementsFromSource`
|
|
32946
32752
|
*/
|
|
32947
32753
|
function appendExampleInteractions(requirements, parseResult) {
|
|
32948
32754
|
const exampleInteractionsContent = createExampleInteractionsContent(parseResult, requirements.samples);
|
|
@@ -32997,7 +32803,7 @@
|
|
|
32997
32803
|
* @param section - Section content to append.
|
|
32998
32804
|
* @returns Requirements with the additional system-message block appended.
|
|
32999
32805
|
*
|
|
33000
|
-
* @private internal utility of `
|
|
32806
|
+
* @private internal utility of `augmentAgentModelRequirementsFromSource`
|
|
33001
32807
|
*/
|
|
33002
32808
|
function appendSystemMessageSection(requirements, section) {
|
|
33003
32809
|
return {
|
|
@@ -33006,29 +32812,149 @@
|
|
|
33006
32812
|
};
|
|
33007
32813
|
}
|
|
33008
32814
|
/**
|
|
33009
|
-
*
|
|
32815
|
+
* Mocked security check for imported files.
|
|
33010
32816
|
*
|
|
33011
|
-
* @param
|
|
33012
|
-
* @returns
|
|
32817
|
+
* @param urlOrPath - The URL or local path of the file to check.
|
|
32818
|
+
* @returns A promise that resolves if the file is considered safe.
|
|
33013
32819
|
*
|
|
33014
|
-
* @private internal utility of `
|
|
32820
|
+
* @private internal utility of `createImportedFileSystemMessage`
|
|
33015
32821
|
*/
|
|
33016
|
-
function
|
|
33017
|
-
|
|
33018
|
-
|
|
33019
|
-
|
|
33020
|
-
|
|
32822
|
+
async function mockedSecurityCheck(urlOrPath) {
|
|
32823
|
+
// TODO: Implement proper security checks
|
|
32824
|
+
await new Promise((resolve) => setTimeout(resolve, 10));
|
|
32825
|
+
if (urlOrPath.includes('malicious')) {
|
|
32826
|
+
throw new Error(`Security check failed for: ${urlOrPath}`);
|
|
32827
|
+
}
|
|
32828
|
+
}
|
|
32829
|
+
/**
|
|
32830
|
+
* Checks whether the given MIME type belongs to a binary file.
|
|
32831
|
+
*
|
|
32832
|
+
* @param mimeType - The MIME type to check.
|
|
32833
|
+
* @returns `true` when the MIME type is treated as binary.
|
|
32834
|
+
*
|
|
32835
|
+
* @private internal utility of `createImportedFileSystemMessage`
|
|
32836
|
+
*/
|
|
32837
|
+
function isBinaryMimeType(mimeType) {
|
|
32838
|
+
return BINARY_MIME_TYPE_PREFIXES.some((prefix) => mimeType.startsWith(prefix));
|
|
32839
|
+
}
|
|
32840
|
+
|
|
32841
|
+
/**
|
|
32842
|
+
* DELETE-like commitment types that invalidate earlier tagged commitments.
|
|
32843
|
+
*
|
|
32844
|
+
* @private internal constant of `filterCommitmentsForAgentModelRequirements`
|
|
32845
|
+
*/
|
|
32846
|
+
const DELETE_COMMITMENT_TYPES = new Set(['DELETE', 'CANCEL', 'DISCARD', 'REMOVE']);
|
|
32847
|
+
/**
|
|
32848
|
+
* Commitments whose earlier occurrences are overwritten by the last occurrence in source order.
|
|
32849
|
+
*
|
|
32850
|
+
* @private internal constant of `filterCommitmentsForAgentModelRequirements`
|
|
32851
|
+
*/
|
|
32852
|
+
const OVERWRITTEN_COMMITMENT_GROUP_BY_TYPE = new Map([
|
|
32853
|
+
['GOAL', 'GOAL'],
|
|
32854
|
+
['GOALS', 'GOAL'],
|
|
32855
|
+
]);
|
|
32856
|
+
/**
|
|
32857
|
+
* Applies the commitment filtering rules used before commitment definitions are executed.
|
|
32858
|
+
*
|
|
32859
|
+
* @param commitments - Parsed commitments in original source order.
|
|
32860
|
+
* @returns Commitments after DELETE-like invalidation and overwritten-goal filtering.
|
|
32861
|
+
*
|
|
32862
|
+
* @private function of `createAgentModelRequirementsWithCommitments`
|
|
32863
|
+
*/
|
|
32864
|
+
function filterCommitmentsForAgentModelRequirements(commitments) {
|
|
32865
|
+
return filterOverwrittenCommitments(filterDeletedCommitments(commitments));
|
|
32866
|
+
}
|
|
32867
|
+
/**
|
|
32868
|
+
* Removes earlier commitments that are overwritten by later commitments of the same semantic group.
|
|
32869
|
+
*
|
|
32870
|
+
* @param commitments - Parsed commitments after DELETE-like filtering.
|
|
32871
|
+
* @returns Commitments with overwritten entries removed while preserving source order.
|
|
32872
|
+
*
|
|
32873
|
+
* @private internal utility of `filterCommitmentsForAgentModelRequirements`
|
|
32874
|
+
*/
|
|
32875
|
+
function filterOverwrittenCommitments(commitments) {
|
|
32876
|
+
const seenOverwriteGroups = new Set();
|
|
32877
|
+
const keptCommitments = [];
|
|
32878
|
+
for (let index = commitments.length - 1; index >= 0; index--) {
|
|
32879
|
+
const commitment = commitments[index];
|
|
32880
|
+
const overwriteGroup = OVERWRITTEN_COMMITMENT_GROUP_BY_TYPE.get(commitment.type);
|
|
32881
|
+
if (!overwriteGroup) {
|
|
32882
|
+
keptCommitments.push(commitment);
|
|
32883
|
+
continue;
|
|
32884
|
+
}
|
|
32885
|
+
if (seenOverwriteGroups.has(overwriteGroup)) {
|
|
32886
|
+
continue;
|
|
32887
|
+
}
|
|
32888
|
+
seenOverwriteGroups.add(overwriteGroup);
|
|
32889
|
+
keptCommitments.push(commitment);
|
|
32890
|
+
}
|
|
32891
|
+
return keptCommitments.reverse();
|
|
32892
|
+
}
|
|
32893
|
+
/**
|
|
32894
|
+
* Applies DELETE-like invalidation commitments and returns only commitments that should continue through the pipeline.
|
|
32895
|
+
*
|
|
32896
|
+
* @param commitments - Parsed commitments in original source order.
|
|
32897
|
+
* @returns Filtered commitments with earlier deleted items removed.
|
|
32898
|
+
*
|
|
32899
|
+
* @private internal utility of `filterCommitmentsForAgentModelRequirements`
|
|
32900
|
+
*/
|
|
32901
|
+
function filterDeletedCommitments(commitments) {
|
|
32902
|
+
const filteredCommitments = [];
|
|
32903
|
+
for (const commitment of commitments) {
|
|
32904
|
+
if (!isDeleteCommitmentType(commitment.type)) {
|
|
32905
|
+
filteredCommitments.push(commitment);
|
|
32906
|
+
continue;
|
|
32907
|
+
}
|
|
32908
|
+
const targetParameterNames = getCommitmentParameterNames(commitment.content);
|
|
32909
|
+
if (targetParameterNames.length === 0) {
|
|
32910
|
+
continue;
|
|
32911
|
+
}
|
|
32912
|
+
for (let index = filteredCommitments.length - 1; index >= 0; index--) {
|
|
32913
|
+
const previousCommitment = filteredCommitments[index];
|
|
32914
|
+
const previousParameterNames = getCommitmentParameterNames(previousCommitment.content);
|
|
32915
|
+
const isTargeted = previousParameterNames.some((parameterName) => targetParameterNames.includes(parameterName));
|
|
32916
|
+
if (isTargeted) {
|
|
32917
|
+
filteredCommitments.splice(index, 1);
|
|
32918
|
+
}
|
|
32919
|
+
}
|
|
32920
|
+
}
|
|
32921
|
+
return filteredCommitments;
|
|
32922
|
+
}
|
|
32923
|
+
/**
|
|
32924
|
+
* Checks whether a commitment type behaves like DELETE and therefore invalidates earlier tagged commitments.
|
|
32925
|
+
*
|
|
32926
|
+
* @param commitmentType - Commitment type to check.
|
|
32927
|
+
* @returns `true` when the commitment removes prior tagged commitments.
|
|
32928
|
+
*
|
|
32929
|
+
* @private internal utility of `filterDeletedCommitments`
|
|
32930
|
+
*/
|
|
32931
|
+
function isDeleteCommitmentType(commitmentType) {
|
|
32932
|
+
return DELETE_COMMITMENT_TYPES.has(commitmentType);
|
|
32933
|
+
}
|
|
32934
|
+
/**
|
|
32935
|
+
* Extracts normalized parameter names used for DELETE-like invalidation matching.
|
|
32936
|
+
*
|
|
32937
|
+
* @param content - Commitment content to parse.
|
|
32938
|
+
* @returns Lower-cased non-empty parameter names.
|
|
32939
|
+
*
|
|
32940
|
+
* @private internal utility of `filterDeletedCommitments`
|
|
32941
|
+
*/
|
|
32942
|
+
function getCommitmentParameterNames(content) {
|
|
32943
|
+
return parseParameters(content)
|
|
32944
|
+
.map((parameter) => parameter.name.trim().toLowerCase())
|
|
32945
|
+
.filter(Boolean);
|
|
33021
32946
|
}
|
|
32947
|
+
|
|
33022
32948
|
/**
|
|
33023
|
-
*
|
|
32949
|
+
* Converts staged inline knowledge files into the final knowledge source URLs stored on requirements.
|
|
33024
32950
|
*
|
|
33025
32951
|
* @param requirements - Current requirements snapshot.
|
|
33026
32952
|
* @param uploader - Optional uploader for inline knowledge files.
|
|
33027
32953
|
* @returns Requirements with inline knowledge converted into upload URLs or data URLs.
|
|
33028
32954
|
*
|
|
33029
|
-
* @private
|
|
32955
|
+
* @private function of `createAgentModelRequirementsWithCommitments`
|
|
33030
32956
|
*/
|
|
33031
|
-
async function
|
|
32957
|
+
async function materializeInlineKnowledgeSources(requirements, uploader) {
|
|
33032
32958
|
var _a;
|
|
33033
32959
|
const inlineSources = extractInlineKnowledgeSources(requirements._metadata);
|
|
33034
32960
|
if (inlineSources.length === 0) {
|
|
@@ -33054,7 +32980,7 @@
|
|
|
33054
32980
|
* @param uploader - Upload implementation provided by the caller.
|
|
33055
32981
|
* @returns Uploaded knowledge URL or a legacy data URL fallback.
|
|
33056
32982
|
*
|
|
33057
|
-
* @private internal utility of `
|
|
32983
|
+
* @private internal utility of `materializeInlineKnowledgeSources`
|
|
33058
32984
|
*/
|
|
33059
32985
|
async function uploadInlineKnowledgeSourceWithFallback(inlineSource, uploader) {
|
|
33060
32986
|
try {
|
|
@@ -33074,7 +33000,7 @@
|
|
|
33074
33000
|
* @param metadata - Current requirements metadata.
|
|
33075
33001
|
* @returns Inline knowledge files collected during commitment application.
|
|
33076
33002
|
*
|
|
33077
|
-
* @private internal utility of `
|
|
33003
|
+
* @private internal utility of `materializeInlineKnowledgeSources`
|
|
33078
33004
|
*/
|
|
33079
33005
|
function extractInlineKnowledgeSources(metadata) {
|
|
33080
33006
|
if (!metadata) {
|
|
@@ -33089,7 +33015,7 @@
|
|
|
33089
33015
|
* @param metadata - Current requirements metadata.
|
|
33090
33016
|
* @returns Metadata without the temporary inline knowledge staging field.
|
|
33091
33017
|
*
|
|
33092
|
-
* @private internal utility of `
|
|
33018
|
+
* @private internal utility of `materializeInlineKnowledgeSources`
|
|
33093
33019
|
*/
|
|
33094
33020
|
function stripInlineKnowledgeMetadata(metadata) {
|
|
33095
33021
|
if (!metadata || !Object.prototype.hasOwnProperty.call(metadata, 'inlineKnowledgeSources')) {
|
|
@@ -33098,31 +33024,90 @@
|
|
|
33098
33024
|
const { inlineKnowledgeSources: _unusedInlineKnowledgeSources, ...rest } = metadata;
|
|
33099
33025
|
return Object.keys(rest).length > 0 ? rest : undefined;
|
|
33100
33026
|
}
|
|
33027
|
+
|
|
33101
33028
|
/**
|
|
33102
|
-
*
|
|
33029
|
+
* Removes single-hash comment lines (`# Comment`) from a system message
|
|
33030
|
+
* This is used to clean up the final system message before sending it to the AI model
|
|
33031
|
+
* while preserving the original content with comments in metadata
|
|
33103
33032
|
*
|
|
33104
|
-
* @param
|
|
33105
|
-
* @returns
|
|
33033
|
+
* @param systemMessage The system message that may contain comment lines
|
|
33034
|
+
* @returns The system message with single-hash comment lines removed
|
|
33106
33035
|
*
|
|
33107
|
-
* @private
|
|
33036
|
+
* @private - TODO: [🧠] Maybe should be public?
|
|
33108
33037
|
*/
|
|
33109
|
-
|
|
33110
|
-
|
|
33111
|
-
|
|
33112
|
-
|
|
33113
|
-
|
|
33038
|
+
function removeCommentsFromSystemMessage(systemMessage) {
|
|
33039
|
+
if (!systemMessage) {
|
|
33040
|
+
return systemMessage;
|
|
33041
|
+
}
|
|
33042
|
+
const lines = systemMessage.split(/\r?\n/);
|
|
33043
|
+
const filteredLines = lines.filter((line) => {
|
|
33044
|
+
const trimmedLine = line.trim();
|
|
33045
|
+
// Remove only single-hash comment markers (`# Comment`) and keep markdown headings (`## Heading`).
|
|
33046
|
+
return !/^#(?!#)\s/.test(trimmedLine);
|
|
33047
|
+
});
|
|
33048
|
+
return filteredLines.join('\n').trim();
|
|
33049
|
+
}
|
|
33050
|
+
|
|
33051
|
+
/**
|
|
33052
|
+
* Creates agent model requirements by parsing commitments, applying them in source order,
|
|
33053
|
+
* and finalizing derived sections such as imports, example interactions, and inline knowledge uploads.
|
|
33054
|
+
*
|
|
33055
|
+
* @param agentSource - Agent source book to parse.
|
|
33056
|
+
* @param modelName - Optional override for the agent model name.
|
|
33057
|
+
* @param options - Additional options such as reference and teammate resolvers.
|
|
33058
|
+
* @returns Fully prepared model requirements for the parsed agent source.
|
|
33059
|
+
*
|
|
33060
|
+
* @private internal utility of `createAgentModelRequirements`
|
|
33061
|
+
*/
|
|
33062
|
+
async function createAgentModelRequirementsWithCommitments(agentSource, modelName, options) {
|
|
33063
|
+
const parseResult = parseAgentSourceWithCommitments(agentSource);
|
|
33064
|
+
const filteredCommitments = filterCommitmentsForAgentModelRequirements(parseResult.commitments);
|
|
33065
|
+
let requirements = createInitialAgentModelRequirements(parseResult.agentName, modelName);
|
|
33066
|
+
requirements = await applyCommitmentsToAgentModelRequirements(requirements, filteredCommitments, options);
|
|
33067
|
+
requirements = aggregateUseCommitmentSystemMessages(requirements, filteredCommitments);
|
|
33068
|
+
requirements = await augmentAgentModelRequirementsFromSource(requirements, parseResult, agentSource);
|
|
33069
|
+
requirements = await materializeInlineKnowledgeSources(requirements, options === null || options === void 0 ? void 0 : options.inlineKnowledgeSourceUploader);
|
|
33070
|
+
return finalizeRequirements(requirements);
|
|
33071
|
+
}
|
|
33072
|
+
/**
|
|
33073
|
+
* Creates the initial requirements object with the parsed agent name stored in metadata and an optional model override.
|
|
33074
|
+
*
|
|
33075
|
+
* @param agentName - Parsed agent name from the source prelude.
|
|
33076
|
+
* @param modelName - Optional explicit model name override.
|
|
33077
|
+
* @returns Initial requirements before any commitment is applied.
|
|
33078
|
+
*
|
|
33079
|
+
* @private internal utility of `createAgentModelRequirementsWithCommitments`
|
|
33080
|
+
*/
|
|
33081
|
+
function createInitialAgentModelRequirements(agentName, modelName) {
|
|
33082
|
+
const initialRequirements = createBasicAgentModelRequirements(agentName);
|
|
33083
|
+
const requirementsWithMetadata = {
|
|
33084
|
+
...initialRequirements,
|
|
33085
|
+
_metadata: {
|
|
33086
|
+
...initialRequirements._metadata,
|
|
33087
|
+
agentName,
|
|
33088
|
+
},
|
|
33089
|
+
};
|
|
33090
|
+
if (!modelName) {
|
|
33091
|
+
return requirementsWithMetadata;
|
|
33114
33092
|
}
|
|
33093
|
+
return {
|
|
33094
|
+
...requirementsWithMetadata,
|
|
33095
|
+
modelName,
|
|
33096
|
+
};
|
|
33115
33097
|
}
|
|
33116
33098
|
/**
|
|
33117
|
-
*
|
|
33099
|
+
* Performs the final system-message cleanup pass after all other augmentation steps are complete.
|
|
33118
33100
|
*
|
|
33119
|
-
* @param
|
|
33120
|
-
* @returns
|
|
33101
|
+
* @param requirements - Fully built requirements before final cleanup.
|
|
33102
|
+
* @returns Requirements with comment lines removed from the final system message.
|
|
33121
33103
|
*
|
|
33122
|
-
* @private internal utility of `
|
|
33104
|
+
* @private internal utility of `createAgentModelRequirementsWithCommitments`
|
|
33123
33105
|
*/
|
|
33124
|
-
function
|
|
33125
|
-
return
|
|
33106
|
+
function finalizeRequirements(requirements) {
|
|
33107
|
+
return {
|
|
33108
|
+
...requirements,
|
|
33109
|
+
systemMessage: removeCommentsFromSystemMessage(requirements.systemMessage),
|
|
33110
|
+
};
|
|
33126
33111
|
}
|
|
33127
33112
|
|
|
33128
33113
|
/**
|