@promptbook/browser 0.112.0-30 → 0.112.0-32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/esm/index.es.js +137 -40
  2. package/esm/index.es.js.map +1 -1
  3. package/esm/src/_packages/components.index.d.ts +6 -0
  4. package/esm/src/_packages/types.index.d.ts +6 -0
  5. package/esm/src/book-2.0/agent-source/AgentReferenceResolver.d.ts +11 -0
  6. package/esm/src/book-2.0/agent-source/CreateAgentModelRequirementsOptions.d.ts +8 -0
  7. package/esm/src/book-2.0/agent-source/TeammateProfileResolver.d.ts +33 -0
  8. package/esm/src/book-2.0/agent-source/createTeamToolName.d.ts +7 -7
  9. package/esm/src/book-components/Chat/Chat/ChatActionsBar.d.ts +5 -0
  10. package/esm/src/book-components/Chat/Chat/ChatMessageItem.d.ts +17 -1
  11. package/esm/src/book-components/Chat/Chat/ChatMessageItem.test.d.ts +1 -1
  12. package/esm/src/book-components/Chat/Chat/ChatMessageList.d.ts +14 -0
  13. package/esm/src/book-components/Chat/Chat/ChatProps.d.ts +290 -0
  14. package/esm/src/book-components/Chat/Chat/ChatToolCallModal.d.ts +16 -0
  15. package/esm/src/book-components/Chat/Chat/renderAdvancedToolCallDetails.d.ts +4 -0
  16. package/esm/src/book-components/Chat/Chat/renderToolCallDetails.d.ts +9 -0
  17. package/esm/src/book-components/Chat/MarkdownContent/MarkdownContent.d.ts +2 -1
  18. package/esm/src/book-components/Chat/MarkdownContent/MarkdownContent.test.d.ts +2 -0
  19. package/esm/src/book-components/Chat/hooks/useChatCompleteNotification.d.ts +18 -0
  20. package/esm/src/book-components/Chat/hooks/useChatCompleteNotification.test.d.ts +2 -0
  21. package/esm/src/book-components/Chat/types/ChatMessage.d.ts +77 -1
  22. package/esm/src/book-components/Chat/utils/formatToolCallDateTime.d.ts +37 -0
  23. package/esm/src/book-components/Chat/utils/formatToolCallLocalTime.d.ts +11 -0
  24. package/esm/src/book-components/Chat/utils/formatToolCallTranslationTemplate.d.ts +10 -0
  25. package/esm/src/book-components/Chat/utils/getChatMessageTimingDisplay.d.ts +5 -1
  26. package/esm/src/book-components/Chat/utils/getToolCallChipletInfo.d.ts +26 -1
  27. package/esm/src/book-components/Chat/utils/timeoutToolCallPresentation.d.ts +26 -3
  28. package/esm/src/utils/toolCalls/mergeToolCalls.d.ts +1 -1
  29. package/esm/src/version.d.ts +1 -1
  30. package/package.json +2 -2
  31. package/umd/index.umd.js +137 -40
  32. package/umd/index.umd.js.map +1 -1
  33. package/umd/src/_packages/components.index.d.ts +6 -0
  34. package/umd/src/_packages/types.index.d.ts +6 -0
  35. package/umd/src/book-2.0/agent-source/AgentReferenceResolver.d.ts +11 -0
  36. package/umd/src/book-2.0/agent-source/CreateAgentModelRequirementsOptions.d.ts +8 -0
  37. package/umd/src/book-2.0/agent-source/TeammateProfileResolver.d.ts +33 -0
  38. package/umd/src/book-2.0/agent-source/createTeamToolName.d.ts +7 -7
  39. package/umd/src/book-components/Chat/Chat/ChatActionsBar.d.ts +5 -0
  40. package/umd/src/book-components/Chat/Chat/ChatMessageItem.d.ts +17 -1
  41. package/umd/src/book-components/Chat/Chat/ChatMessageItem.test.d.ts +1 -1
  42. package/umd/src/book-components/Chat/Chat/ChatMessageList.d.ts +14 -0
  43. package/umd/src/book-components/Chat/Chat/ChatProps.d.ts +290 -0
  44. package/umd/src/book-components/Chat/Chat/ChatToolCallModal.d.ts +16 -0
  45. package/umd/src/book-components/Chat/Chat/renderAdvancedToolCallDetails.d.ts +4 -0
  46. package/umd/src/book-components/Chat/Chat/renderToolCallDetails.d.ts +9 -0
  47. package/umd/src/book-components/Chat/MarkdownContent/MarkdownContent.d.ts +2 -1
  48. package/umd/src/book-components/Chat/MarkdownContent/MarkdownContent.test.d.ts +2 -0
  49. package/umd/src/book-components/Chat/hooks/useChatCompleteNotification.d.ts +18 -0
  50. package/umd/src/book-components/Chat/hooks/useChatCompleteNotification.test.d.ts +2 -0
  51. package/umd/src/book-components/Chat/types/ChatMessage.d.ts +77 -1
  52. package/umd/src/book-components/Chat/utils/formatToolCallDateTime.d.ts +37 -0
  53. package/umd/src/book-components/Chat/utils/formatToolCallLocalTime.d.ts +11 -0
  54. package/umd/src/book-components/Chat/utils/formatToolCallTranslationTemplate.d.ts +10 -0
  55. package/umd/src/book-components/Chat/utils/getChatMessageTimingDisplay.d.ts +5 -1
  56. package/umd/src/book-components/Chat/utils/getToolCallChipletInfo.d.ts +26 -1
  57. package/umd/src/book-components/Chat/utils/timeoutToolCallPresentation.d.ts +26 -3
  58. package/umd/src/utils/toolCalls/mergeToolCalls.d.ts +1 -1
  59. package/umd/src/version.d.ts +1 -1
@@ -1,6 +1,9 @@
1
1
  import { Message } from '../../../types/Message';
2
+ import type { LlmToolDefinition } from '../../../types/LlmToolDefinition';
3
+ import type { ChatModelRequirements } from '../../../types/ModelRequirements';
2
4
  import type { ToolCall } from '../../../types/ToolCall';
3
- import type { id, string_date_iso8601, string_markdown } from '../../../types/typeAliases';
5
+ import type { TODO_object } from '../../../utils/organization/TODO_object';
6
+ import type { id, Parameters, string_date_iso8601, string_markdown, string_prompt, string_title } from '../../../types/typeAliases';
4
7
  export type ChatToolCall = ToolCall;
5
8
  /**
6
9
  * One item in a user-facing progress card shown while assistant response is still running.
@@ -52,6 +55,63 @@ export type ChatProgressCard = {
52
55
  */
53
56
  readonly isVisible?: boolean;
54
57
  };
58
+ /**
59
+ * Serializable prompt snapshot stored alongside one assistant message for debugging and inspection.
60
+ */
61
+ type ChatMessagePrompt = {
62
+ /**
63
+ * Human-readable label used for the prompt execution.
64
+ */
65
+ readonly title: string_title;
66
+ /**
67
+ * User-facing chat content submitted into the prompt pipeline.
68
+ */
69
+ readonly content: string_prompt;
70
+ /**
71
+ * Resolved prompt parameters passed into the agent turn.
72
+ */
73
+ readonly parameters: Parameters;
74
+ /**
75
+ * Chat-model requirements used when the turn was executed.
76
+ */
77
+ readonly modelRequirements: ChatModelRequirements;
78
+ /**
79
+ * Prior thread history provided to the prompt.
80
+ */
81
+ readonly thread?: ReadonlyArray<ChatMessage>;
82
+ /**
83
+ * Attachments submitted with the user turn.
84
+ */
85
+ readonly attachments?: ReadonlyArray<{
86
+ name: string;
87
+ type: string;
88
+ url: string;
89
+ }>;
90
+ /**
91
+ * Runtime tools explicitly passed on the chat prompt object.
92
+ */
93
+ readonly tools?: ReadonlyArray<LlmToolDefinition>;
94
+ /**
95
+ * Full list of tools available to the model for this turn.
96
+ */
97
+ readonly availableTools?: ReadonlyArray<LlmToolDefinition>;
98
+ /**
99
+ * Tool calls associated with the generated message, duplicated here for raw prompt inspection.
100
+ */
101
+ readonly toolCalls?: ReadonlyArray<ChatToolCall>;
102
+ /**
103
+ * Completed tool calls associated with the generated message, duplicated here for raw prompt inspection.
104
+ */
105
+ readonly completedToolCalls?: ReadonlyArray<ChatToolCall>;
106
+ /**
107
+ * Provider-facing prompt text after agent/runtime preparation, when available.
108
+ */
109
+ readonly rawPromptContent?: string_prompt;
110
+ /**
111
+ * Provider-facing raw request payload, when available.
112
+ */
113
+ readonly rawRequest?: TODO_object | null;
114
+ };
55
115
  /**
56
116
  * Represents a single message within a chat interface.
57
117
  *
@@ -165,7 +225,23 @@ export type ChatMessage = Omit<Message<id>, 'direction' | 'recipients' | 'thread
165
225
  * Optional structured progress-card payload shown while a response is still in progress.
166
226
  */
167
227
  readonly progressCard?: ChatProgressCard;
228
+ /**
229
+ * Optional list of tools that were available to the model when generating this message.
230
+ *
231
+ * This field is populated by the server from the exact tool definitions passed to the LLM
232
+ * request so developers can inspect what capabilities the model had access to during
233
+ * each conversation turn.
234
+ */
235
+ readonly availableTools?: ReadonlyArray<LlmToolDefinition>;
236
+ /**
237
+ * Optional prompt snapshot from which this message was generated.
238
+ *
239
+ * Intended for advanced/raw inspection so developers can see the exact chat prompt,
240
+ * resolved parameters, tool availability, and provider payload associated with one turn.
241
+ */
242
+ readonly prompt?: ChatMessagePrompt;
168
243
  };
244
+ export {};
169
245
  /**
170
246
  * TODO: Make all fields readonly
171
247
  * TODO: Delete `expectedAnswer` from ChatMessage
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Locale-aware date/time labels derived from one tool-call timestamp.
3
+ *
4
+ * @private utility of `<Chat/>`
5
+ */
6
+ type ToolCallDateTimeLabels = {
7
+ /**
8
+ * Primary local time label shown in chips and clock panels.
9
+ */
10
+ readonly localTimeLabel: string;
11
+ /**
12
+ * Local calendar date label shown under the primary time.
13
+ */
14
+ readonly localDateLabel: string;
15
+ /**
16
+ * Exact local timestamp label used in detail sections.
17
+ */
18
+ readonly localDateTimeLabel: string;
19
+ /**
20
+ * Relative label such as `in 5 minutes` or `2 minutes ago`.
21
+ */
22
+ readonly relativeTimeLabel: string | null;
23
+ };
24
+ /**
25
+ * Formats one tool-call timestamp into shared locale-aware labels.
26
+ *
27
+ * @param date - Timestamp to format.
28
+ * @param options - Optional locale and relative-time reference point.
29
+ * @returns Shared labels consumed by tool-call chips and modals.
30
+ *
31
+ * @private utility of `<Chat/>`
32
+ */
33
+ export declare function formatToolCallDateTime(date: Date, options?: {
34
+ locale?: string;
35
+ currentDate?: Date;
36
+ }): ToolCallDateTimeLabels;
37
+ export {};
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Formats a Date as a locale-aware short time string (e.g. "5:30 PM" or "17:30").
3
+ *
4
+ * @param date - Date to format.
5
+ * @param locale - Optional BCP-47 locale string (e.g. `"en"`, `"cs"`).
6
+ * When omitted the browser/OS default locale is used.
7
+ * @returns Formatted time string such as `"5:30 PM"` or `"17:30"`.
8
+ *
9
+ * @private utility of `<Chat/>`
10
+ */
11
+ export declare function formatToolCallLocalTime(date: Date, locale?: string): string;
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Applies `{placeholder}` values to one tool-call translation template.
3
+ *
4
+ * @param template - Template from the host application or fallback copy.
5
+ * @param variables - Placeholder values keyed by variable name.
6
+ * @returns Formatted string ready for rendering.
7
+ *
8
+ * @private utility of `<Chat/>`
9
+ */
10
+ export declare function formatToolCallTranslationTemplate(template: string, variables: Record<string, string | number>): string;
@@ -1,3 +1,4 @@
1
+ import 'moment/locale/cs';
1
2
  import type { ChatMessage } from '../types/ChatMessage';
2
3
  /**
3
4
  * Display-ready timestamp values for a chat message.
@@ -21,6 +22,9 @@ export type ChatMessageTimingDisplay = {
21
22
  /**
22
23
  * Builds display-ready timestamp and duration labels for a chat message.
23
24
  *
25
+ * @param message - Message with optional timestamp metadata.
26
+ * @param locale - Optional moment locale used for formatting.
27
+ *
24
28
  * @private utility of `<Chat/>` component
25
29
  */
26
- export declare function getChatMessageTimingDisplay(message: ChatMessage): ChatMessageTimingDisplay | null;
30
+ export declare function getChatMessageTimingDisplay(message: ChatMessage, locale?: string): ChatMessageTimingDisplay | null;
@@ -15,6 +15,25 @@ export type ToolCallChipletInfo = {
15
15
  */
16
16
  agentData?: AgentChipData;
17
17
  };
18
+ /**
19
+ * Optional user-facing title overrides for technical tool names.
20
+ *
21
+ * @private utility of `<Chat/>`
22
+ */
23
+ type ToolCallTitleOverrides = Readonly<Record<string, string>>;
24
+ /**
25
+ * Optional localized labels used for user-facing chip text.
26
+ *
27
+ * @private utility of `<Chat/>`
28
+ */
29
+ type ToolCallChipTranslations = {
30
+ readonly toolCallTimeChipLabel?: string;
31
+ readonly toolCallTimeoutChipLabel?: string;
32
+ readonly toolCallTimeoutChipCancelledLabel?: string;
33
+ readonly toolCallTimeoutChipInactiveLabel?: string;
34
+ readonly toolCallTimeoutChipUpdatedLabel?: string;
35
+ readonly toolCallTimeoutChipFallbackLabel?: string;
36
+ };
18
37
  /**
19
38
  * Builds display text for a tool call chiplet.
20
39
  *
@@ -35,6 +54,12 @@ export declare const TOOL_TITLES: Record<string, {
35
54
  /**
36
55
  * Gets the chiplet information including text and agent data (for team tools).
37
56
  *
57
+ * @param toolCall - Tool call to build chiplet info for.
58
+ * @param locale - Optional BCP-47 locale string used to format time labels.
59
+ * @param titleOverrides - Optional localized titles keyed by tool name.
60
+ * @param chipTranslations - Optional localized chip templates for time-related tools.
61
+ *
38
62
  * @private [🧠] Maybe public?
39
63
  */
40
- export declare function getToolCallChipletInfo(toolCall: ToolCall): ToolCallChipletInfo;
64
+ export declare function getToolCallChipletInfo(toolCall: ToolCall, locale?: string, titleOverrides?: ToolCallTitleOverrides, chipTranslations?: ToolCallChipTranslations): ToolCallChipletInfo;
65
+ export {};
@@ -64,6 +64,24 @@ export type TimeoutToolCallPresentation = {
64
64
  */
65
65
  readonly localDueDateLabel: string | null;
66
66
  };
67
+ /**
68
+ * Optional localized labels used by timeout chips and friendly modal copy.
69
+ *
70
+ * @private internal utility of `<Chat/>`
71
+ */
72
+ type TimeoutToolCallTranslations = {
73
+ readonly toolCallTimeoutChipLabel?: string;
74
+ readonly toolCallTimeoutChipCancelledLabel?: string;
75
+ readonly toolCallTimeoutChipInactiveLabel?: string;
76
+ readonly toolCallTimeoutChipUpdatedLabel?: string;
77
+ readonly toolCallTimeoutChipFallbackLabel?: string;
78
+ readonly toolCallTimeoutPrimaryScheduledLabel?: string;
79
+ readonly toolCallTimeoutSecondaryDurationLabel?: string;
80
+ readonly toolCallTimeoutPrimaryCancelledLabel?: string;
81
+ readonly toolCallTimeoutPrimaryInactiveLabel?: string;
82
+ readonly toolCallTimeoutPrimaryUpdatedLabel?: string;
83
+ readonly toolCallTimeoutPrimaryFallbackLabel?: string;
84
+ };
67
85
  /**
68
86
  * Inputs required to derive timeout presentation metadata.
69
87
  *
@@ -86,6 +104,11 @@ type ResolveTimeoutToolCallPresentationOptions = {
86
104
  * Current date used to calculate relative labels.
87
105
  */
88
106
  readonly currentDate?: Date;
107
+ /**
108
+ * Optional BCP-47 locale string used to format local-time labels.
109
+ * When omitted the browser/OS default locale is used.
110
+ */
111
+ readonly locale?: string;
89
112
  };
90
113
  /**
91
114
  * Determines whether a tool name belongs to the timeout commitment.
@@ -104,19 +127,19 @@ export declare function resolveTimeoutToolCallPresentation(options: ResolveTimeo
104
127
  *
105
128
  * @private internal utility of `<Chat/>`
106
129
  */
107
- export declare function buildTimeoutToolCallChipLabel(presentation: TimeoutToolCallPresentation): string;
130
+ export declare function buildTimeoutToolCallChipLabel(presentation: TimeoutToolCallPresentation, translations?: TimeoutToolCallTranslations): string;
108
131
  /**
109
132
  * Builds the primary timeout sentence shown in default modal view.
110
133
  *
111
134
  * @private internal utility of `<Chat/>`
112
135
  */
113
- export declare function buildTimeoutToolPrimarySentence(presentation: TimeoutToolCallPresentation): string;
136
+ export declare function buildTimeoutToolPrimarySentence(presentation: TimeoutToolCallPresentation, translations?: TimeoutToolCallTranslations): string;
114
137
  /**
115
138
  * Builds one default-view scheduling sentence with local-time and relative context.
116
139
  *
117
140
  * @private internal utility of `<Chat/>`
118
141
  */
119
- export declare function buildTimeoutToolScheduleSentence(presentation: TimeoutToolCallPresentation): string | null;
142
+ export declare function buildTimeoutToolScheduleSentence(presentation: TimeoutToolCallPresentation, translations?: TimeoutToolCallTranslations): string | null;
120
143
  export {};
121
144
  /**
122
145
  * Note: [💞] Ignore a discrepancy between file name and entity name
@@ -1,4 +1,4 @@
1
- import type { ToolCall } from '../../types/ToolCall';
1
+ import { type ToolCall } from '../../types/ToolCall';
2
2
  /**
3
3
  * Merges streamed tool-call snapshots by stable identity while preserving incremental logs,
4
4
  * warnings, and partial results.
@@ -15,7 +15,7 @@ export declare const BOOK_LANGUAGE_VERSION: string_semantic_version;
15
15
  export declare const PROMPTBOOK_ENGINE_VERSION: string_promptbook_version;
16
16
  /**
17
17
  * Represents the version string of the Promptbook engine.
18
- * It follows semantic versioning (e.g., `0.112.0-29`).
18
+ * It follows semantic versioning (e.g., `0.112.0-31`).
19
19
  *
20
20
  * @generated
21
21
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@promptbook/browser",
3
- "version": "0.112.0-30",
3
+ "version": "0.112.0-32",
4
4
  "description": "Promptbook: Turn your company's scattered knowledge into AI ready books",
5
5
  "private": false,
6
6
  "sideEffects": false,
@@ -97,7 +97,7 @@
97
97
  "module": "./esm/index.es.js",
98
98
  "typings": "./esm/typings/src/_packages/browser.index.d.ts",
99
99
  "peerDependencies": {
100
- "@promptbook/core": "0.112.0-30"
100
+ "@promptbook/core": "0.112.0-32"
101
101
  },
102
102
  "dependencies": {
103
103
  "@openai/agents": "0.4.12",
package/umd/index.umd.js CHANGED
@@ -27,7 +27,7 @@
27
27
  * @generated
28
28
  * @see https://github.com/webgptorg/promptbook
29
29
  */
30
- const PROMPTBOOK_ENGINE_VERSION = '0.112.0-30';
30
+ const PROMPTBOOK_ENGINE_VERSION = '0.112.0-32';
31
31
  /**
32
32
  * TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
33
33
  * Note: [💞] Ignore a discrepancy between file name and entity name
@@ -9898,10 +9898,6 @@
9898
9898
  * Prefix used for TEAM tool names.
9899
9899
  */
9900
9900
  const TEAM_TOOL_PREFIX = 'team_chat_';
9901
- /**
9902
- * Length of URL hash suffix appended to TEAM tool names.
9903
- */
9904
- const TEAM_TOOL_HASH_LENGTH = 10;
9905
9901
  /**
9906
9902
  * Fallback normalized name when teammate label is empty.
9907
9903
  */
@@ -9918,20 +9914,19 @@
9918
9914
  return normalized || TEAM_TOOL_FALLBACK_NAME;
9919
9915
  }
9920
9916
  /**
9921
- * Builds a deterministic TEAM tool name from teammate identity.
9917
+ * Builds a deterministic TEAM tool name from the teammate label.
9922
9918
  *
9923
- * The readable part is based on teammate label while the hash suffix
9924
- * keeps uniqueness and stable mapping for the underlying teammate URL.
9919
+ * The tool name is derived solely from the human-readable label so that it
9920
+ * remains stable and predictable regardless of internal technical identifiers.
9925
9921
  *
9926
- * @param teammateUrl - Canonical teammate URL used at runtime.
9927
- * @param teammateLabel - Human-readable teammate label.
9928
- * @returns Deterministic TEAM tool name.
9922
+ * @param _teammateUrl - Canonical teammate URL (kept for API compatibility, not used).
9923
+ * @param teammateLabel - Human-readable teammate label used as the basis for the name.
9924
+ * @returns TEAM tool name derived from the label.
9929
9925
  * @private internal utility of TEAM commitments and chat UI mapping
9930
9926
  */
9931
- function createTeamToolName(teammateUrl, teammateLabel) {
9927
+ function createTeamToolName(_teammateUrl, teammateLabel) {
9932
9928
  const normalizedLabel = normalizeTeammateToolNamePart(teammateLabel);
9933
- const hash = computeHash(teammateUrl).substring(0, TEAM_TOOL_HASH_LENGTH);
9934
- return `${TEAM_TOOL_PREFIX}${normalizedLabel}_${hash}`;
9929
+ return `${TEAM_TOOL_PREFIX}${normalizedLabel}`;
9935
9930
  }
9936
9931
 
9937
9932
  const urlRegex = /https?:\/\/[^\s]+/gi;
@@ -10136,7 +10131,7 @@
10136
10131
  `);
10137
10132
  }
10138
10133
  applyToAgentModelRequirements(requirements, content) {
10139
- var _a, _b;
10134
+ var _a, _b, _c;
10140
10135
  const trimmedContent = content.trim();
10141
10136
  if (!trimmedContent) {
10142
10137
  return requirements;
@@ -10148,14 +10143,18 @@
10148
10143
  }
10149
10144
  const agentName = ((_a = requirements._metadata) === null || _a === void 0 ? void 0 : _a.agentName) || 'Agent';
10150
10145
  const existingTeammates = ((_b = requirements._metadata) === null || _b === void 0 ? void 0 : _b.teammates) || [];
10146
+ const preResolvedProfiles = (((_c = requirements._metadata) === null || _c === void 0 ? void 0 : _c.preResolvedTeammateProfiles) || {});
10151
10147
  const resolvedTeammates = resolveTeamTeammateLabels(trimmedContent, teammates);
10152
10148
  const teamEntries = resolvedTeammates.map((teammate) => {
10149
+ const profile = preResolvedProfiles[teammate.url];
10150
+ const resolvedLabel = (profile === null || profile === void 0 ? void 0 : profile.agentName) || teammate.label;
10153
10151
  const existingTeammate = existingTeammates.find((entry) => entry.url === teammate.url);
10154
10152
  return {
10155
10153
  toolName: ((existingTeammate === null || existingTeammate === void 0 ? void 0 : existingTeammate.toolName) ||
10156
- createTeamToolName(teammate.url, teammate.label)),
10157
- teammate,
10154
+ createTeamToolName(teammate.url, resolvedLabel)),
10155
+ teammate: { ...teammate, label: resolvedLabel },
10158
10156
  agentName,
10157
+ description: (profile === null || profile === void 0 ? void 0 : profile.personaDescription) || null,
10159
10158
  };
10160
10159
  });
10161
10160
  for (const entry of teamEntries) {
@@ -10167,9 +10166,12 @@
10167
10166
  if (updatedTools.some((tool) => tool.name === entry.toolName)) {
10168
10167
  continue;
10169
10168
  }
10169
+ const toolDescription = entry.description
10170
+ ? `Consult teammate ${entry.teammate.label}\n${entry.description}`
10171
+ : `Consult teammate ${entry.teammate.label}`;
10170
10172
  updatedTools.push({
10171
10173
  name: entry.toolName,
10172
- description: `Consult teammate ${entry.teammate.label}`,
10174
+ description: toolDescription,
10173
10175
  parameters: {
10174
10176
  type: 'object',
10175
10177
  properties: {
@@ -10198,8 +10200,7 @@
10198
10200
  toolName: entry.toolName,
10199
10201
  });
10200
10202
  }
10201
- const teamOverviewText = createTeamOverviewText(trimmedContent, teamEntries);
10202
- const teamSystemMessage = this.createSystemMessageSection('Teammates:', buildTeamSystemMessageBody(teamOverviewText, teamEntries));
10203
+ const teamSystemMessage = this.createSystemMessageSection('Teammates:', buildTeamSystemMessageBody(teamEntries));
10203
10204
  return this.appendToSystemMessage({
10204
10205
  ...requirements,
10205
10206
  tools: updatedTools,
@@ -10236,25 +10237,24 @@
10236
10237
  };
10237
10238
  });
10238
10239
  }
10239
- /**
10240
- * Rewrites TEAM commitment content into a URL-free teammate overview text.
10241
- */
10242
- function createTeamOverviewText(teamContent, teamEntries) {
10243
- let overviewText = teamContent;
10244
- for (const entry of teamEntries) {
10245
- overviewText = overviewText.split(entry.teammate.url).join(entry.teammate.label);
10246
- }
10247
- return overviewText.trim();
10248
- }
10249
10240
  /**
10250
10241
  * Builds the textual TEAM section body for the final system message.
10242
+ *
10243
+ * Each teammate is listed with its tool name and, when available, a one-line description.
10244
+ * Uses `spaceTrim` to ensure consistent whitespace and indentation.
10251
10245
  */
10252
- function buildTeamSystemMessageBody(teamOverviewText, teamEntries) {
10253
- const teammateLines = teamEntries.map((entry, index) => `${index + 1}) ${entry.teammate.label} tool \`${entry.toolName}\``);
10254
- if (!teamOverviewText) {
10255
- return teammateLines.join('\n');
10256
- }
10257
- return `${teamOverviewText}\n\n${teammateLines.join('\n')}`;
10246
+ function buildTeamSystemMessageBody(teamEntries) {
10247
+ const lines = teamEntries.map((entry, index) => {
10248
+ const toolLine = `${index + 1}) ${entry.teammate.label} tool \`${entry.toolName}\``;
10249
+ if (!entry.description) {
10250
+ return toolLine;
10251
+ }
10252
+ return spacetrim.spaceTrim(`
10253
+ ${toolLine}
10254
+ ${entry.description}
10255
+ `);
10256
+ });
10257
+ return lines.join('\n');
10258
10258
  }
10259
10259
  /**
10260
10260
  * Registers tool function and title for a teammate tool.
@@ -18280,13 +18280,23 @@
18280
18280
  */
18281
18281
  function mergeToolCalls(existingToolCalls, incomingToolCalls) {
18282
18282
  if (!existingToolCalls || existingToolCalls.length === 0) {
18283
- return incomingToolCalls ? [...incomingToolCalls] : [];
18283
+ return incomingToolCalls ? deduplicatePreparationToolCalls([...incomingToolCalls]) : [];
18284
18284
  }
18285
18285
  if (!incomingToolCalls || incomingToolCalls.length === 0) {
18286
18286
  return [...existingToolCalls];
18287
18287
  }
18288
18288
  const mergedToolCalls = [...existingToolCalls];
18289
18289
  for (const incomingToolCall of incomingToolCalls) {
18290
+ if (isAssistantPreparationToolCall(incomingToolCall)) {
18291
+ // A new preparation phase always replaces any previous assistant_preparation tool
18292
+ // call, regardless of phase argument, so only one chip is ever shown at a time.
18293
+ const existingPreparationIndex = mergedToolCalls.findIndex(isAssistantPreparationToolCall);
18294
+ if (existingPreparationIndex !== -1) {
18295
+ mergedToolCalls.splice(existingPreparationIndex, 1);
18296
+ }
18297
+ mergedToolCalls.push(incomingToolCall);
18298
+ continue;
18299
+ }
18290
18300
  const incomingIdentity = getToolCallIdentity(incomingToolCall);
18291
18301
  const existingIndex = mergedToolCalls.findIndex((existingToolCall) => getToolCallIdentity(existingToolCall) === incomingIdentity);
18292
18302
  if (existingIndex === -1) {
@@ -18398,6 +18408,30 @@
18398
18408
  return String(value);
18399
18409
  }
18400
18410
  }
18411
+ /**
18412
+ * Ensures at most one `assistant_preparation` tool call survives in the list,
18413
+ * keeping the last occurrence so the most recent preparation phase is shown.
18414
+ *
18415
+ * @param toolCalls - Mutable list to deduplicate in-place.
18416
+ * @returns The same array after removing redundant preparation entries.
18417
+ * @private helper of `mergeToolCalls`
18418
+ */
18419
+ function deduplicatePreparationToolCalls(toolCalls) {
18420
+ let lastPreparationIndex = -1;
18421
+ for (let index = toolCalls.length - 1; index >= 0; index--) {
18422
+ if (!isAssistantPreparationToolCall(toolCalls[index])) {
18423
+ continue;
18424
+ }
18425
+ if (lastPreparationIndex === -1) {
18426
+ lastPreparationIndex = index;
18427
+ }
18428
+ else {
18429
+ // Remove earlier duplicate — keep only the last (most recent) one.
18430
+ toolCalls.splice(index, 1);
18431
+ }
18432
+ }
18433
+ return toolCalls;
18434
+ }
18401
18435
 
18402
18436
  /**
18403
18437
  * Gets all tool titles provided by all commitments
@@ -22653,7 +22687,7 @@
22653
22687
  * @private @@@
22654
22688
  */
22655
22689
  async function createAgentModelRequirementsWithCommitments(agentSource, modelName, options) {
22656
- var _a;
22690
+ var _a, _b, _c;
22657
22691
  const agentReferenceResolver = options === null || options === void 0 ? void 0 : options.agentReferenceResolver;
22658
22692
  // Parse the agent source to extract commitments
22659
22693
  const parseResult = parseAgentSourceWithCommitments(agentSource);
@@ -22721,6 +22755,36 @@
22721
22755
  if (commitment.type === 'CLOSED' && i !== filteredCommitments.length - 1) {
22722
22756
  continue;
22723
22757
  }
22758
+ // For TEAM commitments, pre-resolve teammate profiles if a resolver is provided
22759
+ // and store them in metadata before the commitment is applied.
22760
+ const profileResolver = (_a = options === null || options === void 0 ? void 0 : options.teammateProfileResolver) !== null && _a !== void 0 ? _a : options === null || options === void 0 ? void 0 : options.agentReferenceResolver;
22761
+ if (commitment.type === 'TEAM' && (profileResolver === null || profileResolver === void 0 ? void 0 : profileResolver.resolveTeammateProfile)) {
22762
+ try {
22763
+ const parsedTeammates = parseTeamCommitmentContent(commitmentContent, { strict: false });
22764
+ const preResolved = {
22765
+ ...(_b = requirements._metadata) === null || _b === void 0 ? void 0 : _b.preResolvedTeammateProfiles,
22766
+ };
22767
+ for (const teammate of parsedTeammates) {
22768
+ if (preResolved[teammate.url]) {
22769
+ continue;
22770
+ }
22771
+ const profile = await profileResolver.resolveTeammateProfile(teammate.url);
22772
+ if (profile) {
22773
+ preResolved[teammate.url] = profile;
22774
+ }
22775
+ }
22776
+ requirements = {
22777
+ ...requirements,
22778
+ _metadata: {
22779
+ ...requirements._metadata,
22780
+ preResolvedTeammateProfiles: preResolved,
22781
+ },
22782
+ };
22783
+ }
22784
+ catch (error) {
22785
+ console.warn('Failed to pre-resolve teammate profiles for TEAM commitment:', error);
22786
+ }
22787
+ }
22724
22788
  const definition = getCommitmentDefinition(commitment.type);
22725
22789
  if (definition) {
22726
22790
  try {
@@ -22816,7 +22880,7 @@
22816
22880
  // Add example interactions to the system message
22817
22881
  const examples = [];
22818
22882
  // 1. Initial message as an example agent response
22819
- const initialMessage = (_a = parseResult.commitments.find((c) => c.type === 'INITIAL MESSAGE')) === null || _a === void 0 ? void 0 : _a.content;
22883
+ const initialMessage = (_c = parseResult.commitments.find((c) => c.type === 'INITIAL MESSAGE')) === null || _c === void 0 ? void 0 : _c.content;
22820
22884
  if (initialMessage) {
22821
22885
  examples.push(`Agent: ${initialMessage}`);
22822
22886
  }
@@ -28661,6 +28725,7 @@
28661
28725
 
28662
28726
  - Decide what the agent should learn from this interaction.
28663
28727
  - Append new commitments at the end of the agent source.
28728
+ - Return only newly learned commitments, never repeat commitments that are already present.
28664
28729
  - Do not modify the current agent source, just return new commitments (KNOWLEDGE, RULE, etc.).
28665
28730
  - If there is nothing new to learn, return empty book code block
28666
28731
  - Wrap the commitments in a book code block.
@@ -28713,10 +28778,42 @@
28713
28778
  */
28714
28779
  appendToAgentSource(section) {
28715
28780
  const currentSource = this.options.getAgentSource();
28716
- const newSource = padBook(validateBook(spacetrim.spaceTrim(currentSource) + section));
28781
+ const normalizedSection = normalizeBookSection(section);
28782
+ if (!normalizedSection) {
28783
+ return;
28784
+ }
28785
+ if (containsNormalizedBookSection(currentSource, normalizedSection)) {
28786
+ return;
28787
+ }
28788
+ const newSource = padBook(validateBook(`${normalizeBookSection(currentSource)}\n\n${normalizedSection}`));
28717
28789
  this.options.updateAgentSource(newSource);
28718
28790
  }
28719
28791
  }
28792
+ /**
28793
+ * Normalizes one book fragment for deduplication and append composition.
28794
+ *
28795
+ * @param section Raw fragment from self-learning workflow.
28796
+ * @returns Trimmed fragment, or empty string when nothing remains.
28797
+ * @private function of Agent
28798
+ */
28799
+ function normalizeBookSection(section) {
28800
+ return spacetrim.spaceTrim(section).replace(/\r\n/g, '\n');
28801
+ }
28802
+ /**
28803
+ * Checks whether one normalized fragment already exists inside the current source.
28804
+ *
28805
+ * @param agentSource Current source.
28806
+ * @param normalizedSection Candidate fragment expected to be normalized first.
28807
+ * @returns True when appending would duplicate an existing fragment.
28808
+ * @private function of Agent
28809
+ */
28810
+ function containsNormalizedBookSection(agentSource, normalizedSection) {
28811
+ if (!normalizedSection) {
28812
+ return true;
28813
+ }
28814
+ const normalizedSource = normalizeBookSection(agentSource);
28815
+ return normalizedSource.includes(normalizedSection);
28816
+ }
28720
28817
  /**
28721
28818
  * Determines whether the interaction runs in OpenAI-compatible JSON schema mode.
28722
28819
  *