@salesforcedevs/dx-components 1.28.7-alpha.2 → 1.29.0

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@salesforcedevs/dx-components",
3
- "version": "1.28.7-alpha.2",
3
+ "version": "1.29.0",
4
4
  "description": "DX Lightning web components",
5
5
  "license": "MIT",
6
6
  "engines": {
@@ -44,5 +44,5 @@
44
44
  "luxon": "3.4.4",
45
45
  "msw": "^2.12.4"
46
46
  },
47
- "gitHead": "e01282790aaa44be0931fa6ddbf78126fa2a8a4c"
47
+ "gitHead": "6b290fbf6e3032a9708592af2932b43d5e970bfc"
48
48
  }
@@ -48,6 +48,10 @@
48
48
  <dx-sidebar-search
49
49
  onchange={onSearchChange}
50
50
  onloading={onSearchLoading}
51
+ coveo-organization-id={coveoOrganizationId}
52
+ coveo-public-access-token={coveoPublicAccessToken}
53
+ coveo-search-hub={coveoSearchHub}
54
+ coveo-advanced-query-config={coveoAdvancedQueryConfig}
51
55
  ></dx-sidebar-search>
52
56
  </div>
53
57
  <slot name="version-picker"></slot>
@@ -1,18 +1,18 @@
1
1
  import cx from "classnames";
2
2
  import { api, track } from "lwc";
3
3
  import { TreeNode, SidebarSearchResult } from "typings/custom";
4
+ import { getSidebarSearchParams } from "dxUtils/coveo";
4
5
  import { toJson } from "dxUtils/normalizers";
5
6
  import SidebarSearch from "dx/sidebarSearch";
6
7
  import { SidebarBase } from "dxBaseElements/sidebarBase";
7
8
 
8
9
  const MOBILE_SIZE_MATCH = "768px";
9
10
 
10
- const getSearchQueryParam = (): string | null =>
11
- typeof window !== "undefined"
12
- ? new URLSearchParams(window.location.search).get("q")
13
- : null;
14
-
15
11
  export default class Sidebar extends SidebarBase {
12
+ @api coveoOrganizationId!: string;
13
+ @api coveoPublicAccessToken!: string;
14
+ @api coveoSearchHub!: string;
15
+ @api coveoAdvancedQueryConfig!: string;
16
16
  @api header: string = "";
17
17
 
18
18
  @api
@@ -130,7 +130,7 @@ export default class Sidebar extends SidebarBase {
130
130
  constructor() {
131
131
  super();
132
132
 
133
- if (getSearchQueryParam()) {
133
+ if (getSidebarSearchParams()) {
134
134
  this.isSearchLoading = true;
135
135
  this.scrollToSelectedSearchResult = true;
136
136
  }
@@ -175,7 +175,7 @@ export default class Sidebar extends SidebarBase {
175
175
  this.isSearchLoading = e.detail;
176
176
  }
177
177
 
178
- private onSidebarSearchContentScroll(scrollEvent: Event) {
178
+ private onSidebarSearchContentScroll(scrollEvent) {
179
179
  if (this.isSearchLoading) {
180
180
  return;
181
181
  }
@@ -1,45 +1,75 @@
1
1
  import { LightningElement, api } from "lwc";
2
2
  import debounce from "debounce";
3
+ import {
4
+ Result,
5
+ ResultList,
6
+ Unsubscribe,
7
+ ResultsPerPage,
8
+ SearchBox,
9
+ buildInteractiveResult,
10
+ buildResultList,
11
+ buildResultsPerPage,
12
+ buildSearchBox,
13
+ loadAdvancedSearchQueryActions,
14
+ SearchEngine,
15
+ SearchAppState,
16
+ loadQueryActions
17
+ } from "@coveo/headless";
18
+ import { buildSearchEngine, getSidebarSearchParams } from "dxUtils/coveo";
3
19
  import { RecentSearches } from "dxUtils/recentSearches";
20
+ import { toJson } from "dxUtils/normalizers";
4
21
  import {
5
22
  Option,
6
23
  PopoverRequestCloseType,
7
24
  SidebarSearchResult
8
25
  } from "typings/custom";
9
26
 
10
- const SEARCH_DEBOUNCE_DELAY = 1200;
11
- const DATA_CLOUD_SEARCH_PATH = "/data-cloud-search/search";
27
+ const RESULT_CLICK_LOCAL_STORAGE_KEY = "dx-sidebar-search-result-click";
28
+ export const SESSION_KEY = "dx-sidebar-search-state";
12
29
 
13
- /** Origin used for Data Cloud search (always production so results point to developer.salesforce.com). */
14
- const DATA_CLOUD_SEARCH_ORIGIN = "https://developer.salesforce.com";
30
+ const DEFAULT_RESULT_COUNT = 20;
31
+ const SEARCH_DEBOUNCE_DELAY = 1200;
15
32
 
16
33
  const UserRecentSearches = new RecentSearches();
17
34
 
18
- const getSearchQueryParam = (): string =>
19
- new URLSearchParams(window.location.search).get("q") ?? "";
20
-
21
- /**
22
- * Returns the base URL path for the current page, always using developer.salesforce.com.
23
- * e.g. on QA or prod, path /docs/atlas.en-us.apexcode.meta/apexcode/apex_dev_guide.htm
24
- * -> https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode
25
- */
26
- const getBaseUrlPath = (): string => {
27
- const url = DATA_CLOUD_SEARCH_ORIGIN + window.location.pathname;
28
- const lastSlash = url.lastIndexOf("/");
29
- return lastSlash > 0 ? url.substring(0, lastSlash) : url;
30
- };
31
-
32
- /** Data Cloud Search API result item (title, url, matchedText) */
33
- interface DataCloudSearchResultItem {
34
- title?: string;
35
- url?: string;
36
- matchedText?: string;
37
- }
35
+ const normalizeCoveoAdvancedQueryValue = (version: string): string =>
36
+ version?.split(".").join("\\.");
38
37
 
39
38
  export default class SidebarSearch extends LightningElement {
39
+ @api coveoOrganizationId!: string;
40
+ @api coveoPublicAccessToken!: string;
41
+ @api coveoSearchHub!: string;
42
+ @api
43
+ get coveoAdvancedQueryConfig(): { [key: string]: any } {
44
+ return this._coveoAdvancedQueryConfig;
45
+ }
46
+ set coveoAdvancedQueryConfig(value) {
47
+ const jsonValue = toJson(value);
48
+ const hasChanged =
49
+ this._coveoAdvancedQueryConfig &&
50
+ Object.entries(jsonValue).some(
51
+ ([key, val]: [string, any]) =>
52
+ this._coveoAdvancedQueryConfig[key] !== val
53
+ );
54
+ this._coveoAdvancedQueryConfig = jsonValue;
55
+
56
+ if (hasChanged && this.engine && this.value !== "") {
57
+ this.dispatchOnLoading(true);
58
+ }
59
+
60
+ if (hasChanged && this.engine) {
61
+ // set advanced filters needs access to the latest coveoAdvancedQueryConfig
62
+ this.setAdvancedFilters(this.engine);
63
+ this.submitSearch(true);
64
+ }
65
+ }
66
+
40
67
  @api
41
68
  public fetchMoreResults() {
42
- // Data Cloud Search API does not expose pagination in the same way; no-op
69
+ if (this.resultList?.state?.moreResultsAvailable) {
70
+ this.fetchingMoreResults = true;
71
+ this.resultList.fetchMoreResults();
72
+ }
43
73
  }
44
74
 
45
75
  @api
@@ -55,98 +85,313 @@ export default class SidebarSearch extends LightningElement {
55
85
  this.dropdownRequestedOpen = value;
56
86
  }
57
87
 
88
+ private _coveoAdvancedQueryConfig!: { [key: string]: any };
58
89
  private dropdownRequestedOpen: boolean = false;
59
90
  private recentSearches: Option[] = [];
60
- private value: string = "";
91
+ private unsubscribeFromResultList: Unsubscribe = () => {};
92
+ private resultList: ResultList | null = null;
93
+ private resultsPerPage: ResultsPerPage | null = null;
94
+ private preloadedState?: SearchAppState;
95
+ private searchBox: SearchBox | null = null;
96
+ private value?: string = "";
97
+ private engine: SearchEngine | null = null;
98
+ private fetchingMoreResults: boolean = false;
61
99
  private didRender = false;
62
- private dataCloudSearchInitialized: boolean = false;
100
+
101
+ private get hasCorrectCoveoConfig(): boolean {
102
+ const coveoConfigurations = [
103
+ this.coveoOrganizationId,
104
+ this.coveoPublicAccessToken,
105
+ this.coveoSearchHub,
106
+ this.coveoAdvancedQueryConfig
107
+ ];
108
+
109
+ return coveoConfigurations.every(
110
+ (val) =>
111
+ !!val && (typeof val === "string" || typeof val === "object")
112
+ );
113
+ }
63
114
 
64
115
  private get isDropdownOpen() {
65
116
  return (
66
117
  this.dropdownRequestedOpen &&
67
- this.recentSearches?.length > 0 &&
118
+ this.recentSearches &&
119
+ this.recentSearches.length > 0 &&
68
120
  !this.value
69
121
  );
70
122
  }
71
123
 
72
124
  constructor() {
73
125
  super();
126
+
74
127
  this.updateRecentSearches();
75
- this.value = getSearchQueryParam();
128
+ this.value = getSidebarSearchParams() || "";
129
+ }
130
+
131
+ disconnectedCallback() {
132
+ this.unsubscribeFromResultList();
76
133
  }
77
134
 
78
135
  renderedCallback() {
79
- if (!this.dataCloudSearchInitialized) {
80
- this.dataCloudSearchInitialized = true;
81
- if (!this.didRender && this.value) {
82
- this.dispatchHighlightedTermChange();
83
- }
84
- if (!this.value) {
85
- this.dispatchOnLoading(false);
86
- }
136
+ // in prod some of the critical coveo configuration attributes seem to arrive later
137
+ // so I needed to put this coveo startup flow here where we can wait for them to arrive
138
+
139
+ if (this.hasCorrectCoveoConfig && !this.engine) {
140
+ this.initializeUserSession();
141
+ this.initializeCoveo();
142
+ } else if (!this.hasCorrectCoveoConfig) {
143
+ console.error(
144
+ "Incorrect coveo search configuration provided. All coveo configuration attributes must be defined.",
145
+ {
146
+ coveoOrganizationId: this.coveoOrganizationId,
147
+ coveoPublicAccessToken: this.coveoPublicAccessToken,
148
+ coveoSearchHub: this.coveoSearchHub,
149
+ coveoAdvancedQueryConfig: this.coveoAdvancedQueryConfig
150
+ }
151
+ );
87
152
  }
153
+
154
+ // If this is the first render and there is a search value, trigger
155
+ // term highlighting
88
156
  if (!this.didRender && this.value) {
89
157
  this.dispatchHighlightedTermChange();
90
158
  }
159
+
91
160
  this.didRender = true;
92
161
  }
93
162
 
94
- private normalizeDataCloudResult = (
95
- item: DataCloudSearchResultItem,
96
- index: number
97
- ): SidebarSearchResult => {
98
- const href = item.url ?? "";
99
- const resultPath = href.startsWith("http")
100
- ? new URL(href).pathname
101
- : href;
102
- const isSelected =
103
- !!resultPath && resultPath === window.location.pathname;
163
+ private initializeUserSession() {
164
+ const stringified = window.sessionStorage.getItem(SESSION_KEY);
165
+
166
+ if (!stringified) {
167
+ return;
168
+ }
169
+
170
+ try {
171
+ const json = JSON.parse(stringified);
172
+
173
+ const hasSameConfig = Object.entries(
174
+ json.coveoAdvancedQueryConfig
175
+ ).every(
176
+ ([key, value]: [string, any]) =>
177
+ this.coveoAdvancedQueryConfig[key] === value
178
+ );
179
+ const hasSameQuery = json?.state?.query?.q === this.value;
180
+
181
+ if (hasSameConfig && hasSameQuery) {
182
+ this.preloadedState = json?.state;
183
+ } else {
184
+ window.sessionStorage.removeItem(SESSION_KEY);
185
+ }
186
+ } catch (e) {
187
+ console.error(e);
188
+ window.sessionStorage.removeItem(SESSION_KEY);
189
+ }
190
+ }
191
+
192
+ private initializeCoveo = () => {
193
+ try {
194
+ this.engine = buildSearchEngine({
195
+ organizationId: this.coveoOrganizationId,
196
+ publicAccessToken: this.coveoPublicAccessToken,
197
+ searchHub: this.coveoSearchHub,
198
+ preloadedState: this.preloadedState
199
+ });
200
+ } catch (ex) {
201
+ console.error(`Coveo engine failed to initialize (${ex})`);
202
+ }
203
+
204
+ if (!this.engine) {
205
+ console.error("Coveo engine failed to initialize!");
206
+ return;
207
+ }
208
+
209
+ if (this.preloadedState) {
210
+ const actions = loadQueryActions(this.engine);
211
+ this.engine.dispatch(actions.updateQuery({ q: this.value || "" }));
212
+ }
213
+
214
+ this.resultList = buildResultList(this.engine, {
215
+ options: { fieldsToInclude: ["sfhtml_url__c"] }
216
+ });
217
+
218
+ this.resultsPerPage = buildResultsPerPage(this.engine, {
219
+ initialState: {
220
+ numberOfResults: DEFAULT_RESULT_COUNT
221
+ }
222
+ });
223
+
224
+ this.searchBox = buildSearchBox(this.engine, {
225
+ options: { numberOfSuggestions: 3 }
226
+ });
227
+
228
+ this.setAdvancedFilters(this.engine);
229
+
230
+ this.unsubscribeFromResultList = this.resultList?.subscribe(
231
+ this.onResultListChange
232
+ );
233
+
234
+ if (this.value) {
235
+ this.dispatchHighlightedTermChange();
236
+ }
237
+
238
+ if (!this.preloadedState) {
239
+ if (this.value) {
240
+ this.submitSearch();
241
+ } else {
242
+ this.dispatchOnLoading(false);
243
+ }
244
+ }
245
+
246
+ this.syncAnalytics();
247
+ };
248
+
249
+ private syncAnalytics = () => {
250
+ const storedResult = window.localStorage.getItem(
251
+ RESULT_CLICK_LOCAL_STORAGE_KEY
252
+ );
253
+ if (storedResult) {
254
+ const interactiveResult = buildInteractiveResult(this.engine!, {
255
+ options: { result: JSON.parse(storedResult) }
256
+ });
257
+ interactiveResult.cancelPendingSelect();
258
+ interactiveResult.select();
259
+ window.localStorage.removeItem(RESULT_CLICK_LOCAL_STORAGE_KEY);
260
+ }
261
+ };
262
+
263
+ private onResultListChange = () => {
264
+ if (!this.resultList) {
265
+ return;
266
+ }
267
+
268
+ const { isLoading, firstSearchExecuted, results } =
269
+ this.resultList.state;
270
+
271
+ if ((!firstSearchExecuted && !isLoading) || !this.value) {
272
+ // coveo search is firing off some unwanted payloads on startup
273
+ return;
274
+ }
275
+
276
+ if (!isLoading) {
277
+ this.dispatchOnChangeEvent(results);
278
+ }
279
+
280
+ if (!this.fetchingMoreResults) {
281
+ this.dispatchOnLoading(isLoading);
282
+ }
283
+
284
+ if (!isLoading && this.fetchingMoreResults) {
285
+ this.fetchingMoreResults = false;
286
+ }
287
+ };
288
+
289
+ private setAdvancedFilters(engine: SearchEngine) {
290
+ const aq = Object.entries(this.coveoAdvancedQueryConfig).reduce(
291
+ (result, [key, value]) =>
292
+ `${result}(@${key}=="${normalizeCoveoAdvancedQueryValue(
293
+ value
294
+ )}")`,
295
+ ""
296
+ );
297
+
298
+ const registerSearchQueryAction = loadAdvancedSearchQueryActions(
299
+ engine
300
+ ).registerAdvancedSearchQueries({
301
+ aq: aq
302
+ });
303
+
304
+ engine.dispatch(registerSearchQueryAction);
305
+ }
306
+
307
+ private normalizeCoveoResult = (result: Result): SidebarSearchResult => {
308
+ const {
309
+ clickUri,
310
+ excerpt,
311
+ excerptHighlights,
312
+ raw: { sfhtml_url__c },
313
+ title,
314
+ titleHighlights,
315
+ uniqueId
316
+ } = result;
317
+
318
+ // discussion about this normalization here: https://salesforce-internal.slack.com/archives/C020S6784JX/p1639506238376600
319
+
320
+ let pathname, queryParam;
321
+ if (sfhtml_url__c) {
322
+ pathname = `/docs/${sfhtml_url__c}`;
323
+ } else {
324
+ const isNestedGuide = clickUri.includes("/guide/");
325
+ const url = new URL(clickUri);
326
+ const extension =
327
+ isNestedGuide && !url.pathname?.endsWith(".html")
328
+ ? ".html"
329
+ : "";
330
+ pathname = `${url.pathname}${extension}`;
331
+ queryParam = url.search;
332
+ }
333
+
334
+ let href;
335
+ let isSelected = false;
336
+ const isReferenceUrl = clickUri.includes("/references/");
337
+ if (isReferenceUrl) {
338
+ if (queryParam) {
339
+ href = `${pathname}${queryParam}&q=${this.value}`;
340
+ } else {
341
+ href = `${pathname}?q=${this.value}`;
342
+ }
343
+
344
+ //NOTE: This is specific to references related comparison
345
+ const resultHrefWithMetaQuery = `${pathname}${queryParam}`;
346
+
347
+ const urlParams = new URLSearchParams(window.location.search);
348
+ const metaQueryParam = urlParams.get("meta");
349
+
350
+ let currentUrlPathWithQuery = window.location.pathname;
351
+ if (metaQueryParam) {
352
+ currentUrlPathWithQuery = `${currentUrlPathWithQuery}?meta=${metaQueryParam}`;
353
+ }
354
+
355
+ isSelected = resultHrefWithMetaQuery === currentUrlPathWithQuery;
356
+ } else {
357
+ href = `${pathname}?q=${this.value}`;
358
+ isSelected = pathname === window.location.pathname;
359
+ }
360
+
104
361
  return {
105
- title: item.title ?? "",
106
- titleHighlights: [],
107
- excerpt: "",
108
- excerptHighlights: [],
109
- uniqueId: href || `result-${index}`,
362
+ title,
363
+ titleHighlights,
364
+ excerpt,
365
+ excerptHighlights,
366
+ uniqueId,
110
367
  href,
111
368
  selected: isSelected,
112
- select: () => {}
369
+ select: () =>
370
+ window.localStorage.setItem(
371
+ RESULT_CLICK_LOCAL_STORAGE_KEY,
372
+ JSON.stringify(result)
373
+ )
113
374
  };
114
375
  };
115
376
 
116
- private async fetchDataCloudSearch(): Promise<void> {
117
- const body = {
118
- searchQuery: this.value.trim(),
119
- baseUrlPath: getBaseUrlPath()
120
- };
121
- try {
122
- const res = await fetch(DATA_CLOUD_SEARCH_PATH, {
123
- method: "POST",
124
- headers: { "Content-Type": "application/json" },
125
- body: JSON.stringify(body)
126
- });
127
- if (!res.ok) {
128
- throw new Error(`Search API error: ${res.status}`);
129
- }
130
- const data = await res.json();
131
- const rawResults: DataCloudSearchResultItem[] = Array.isArray(data)
132
- ? data
133
- : data?.results ?? data?.data?.results ?? [];
134
- const results: SidebarSearchResult[] = rawResults.map(
135
- this.normalizeDataCloudResult
136
- );
137
- this.dispatchChange(results);
138
- } catch (err) {
139
- console.error("Data Cloud Search request failed", err);
140
- this.dispatchChange([]);
141
- } finally {
142
- this.dispatchOnLoading(false);
143
- }
377
+ private updateSessionStorage() {
378
+ window.sessionStorage.setItem(
379
+ SESSION_KEY,
380
+ JSON.stringify({
381
+ coveoAdvancedQueryConfig: this.coveoAdvancedQueryConfig,
382
+ state: this.engine?.state
383
+ })
384
+ );
144
385
  }
145
386
 
146
- private dispatchChange(results: SidebarSearchResult[]) {
387
+ private dispatchOnChangeEvent(results: Result[]) {
388
+ this.updateSessionStorage();
147
389
  this.dispatchEvent(
148
390
  new CustomEvent("change", {
149
- detail: { results, value: this.value }
391
+ detail: {
392
+ results: results.map(this.normalizeCoveoResult),
393
+ value: this.value
394
+ }
150
395
  })
151
396
  );
152
397
  }
@@ -182,12 +427,19 @@ export default class SidebarSearch extends LightningElement {
182
427
  }
183
428
 
184
429
  private submitSearch = debounce((isSyncingSearchValue = false) => {
185
- UserRecentSearches.add(this.value);
186
- this.updateRecentSearches();
187
- if (!isSyncingSearchValue) {
188
- this.dispatchSidebarSearchChange(this.value);
430
+ if (this.searchBox) {
431
+ UserRecentSearches.add(this.value);
432
+ this.updateRecentSearches();
433
+
434
+ // When `isSyncingSearchValue` is true, we are submitting in a case
435
+ // where the search box is already synced correctly.
436
+ if (!isSyncingSearchValue) {
437
+ this.dispatchSidebarSearchChange(this.value);
438
+ }
439
+
440
+ this.searchBox.updateText(this.value || "");
441
+ this.searchBox.submit();
189
442
  }
190
- this.fetchDataCloudSearch();
191
443
  }, SEARCH_DEBOUNCE_DELAY);
192
444
 
193
445
  private onClickRecentSearch(e: CustomEvent) {
@@ -209,6 +461,7 @@ export default class SidebarSearch extends LightningElement {
209
461
 
210
462
  private onInputChange(e: CustomEvent) {
211
463
  this.value = e.detail;
464
+
212
465
  this.handleValueChange(false);
213
466
  this.dispatchHighlightedTermChange();
214
467
  }
@@ -224,10 +477,16 @@ export default class SidebarSearch extends LightningElement {
224
477
  private handleValueChange(isSyncingSearchValue = false) {
225
478
  if (this.value) {
226
479
  this.dispatchOnLoading(true);
227
- this.submitSearch(isSyncingSearchValue);
480
+ if (this.searchBox) {
481
+ this.submitSearch(isSyncingSearchValue);
482
+ }
228
483
  } else {
484
+ // coveo's reaction to an empty value triggers a return of results
485
+ // bootlegging our own ux here`
229
486
  this.dispatchOnLoading(false);
230
- this.dispatchChange([]);
487
+ this.dispatchOnChangeEvent([]);
488
+ // Empty search values are not submitted for search, so we need to manually
489
+ // trigger a search change on our own here
231
490
  this.dispatchSidebarSearchChange(this.value);
232
491
  }
233
492
  }
@@ -1,8 +1,8 @@
1
1
  import { LightningElement, api } from "lwc";
2
2
  import cx from "classnames";
3
- import { HighlightedSections } from "typings/custom";
3
+ import { CoveoHighlights } from "typings/custom";
4
4
 
5
- const toChunks = (value: string, highlights: HighlightedSections) => {
5
+ const toChunks = (value: string, highlights: CoveoHighlights) => {
6
6
  if (!highlights || highlights.length < 1) {
7
7
  return [
8
8
  {
@@ -51,11 +51,11 @@ const toChunks = (value: string, highlights: HighlightedSections) => {
51
51
 
52
52
  export default class SidebarSearchResult extends LightningElement {
53
53
  @api description!: string;
54
- @api descriptionHighlights!: HighlightedSections;
54
+ @api descriptionHighlights!: CoveoHighlights;
55
55
  @api href!: string;
56
56
  @api selected!: boolean;
57
57
  @api header!: string;
58
- @api titleHighlights!: HighlightedSections;
58
+ @api titleHighlights!: CoveoHighlights;
59
59
  @api select!: Function;
60
60
 
61
61
  private get titleChunks() {
@@ -1315,7 +1315,7 @@ const agentscriptGrammar = {
1315
1315
  beginCaptures: {
1316
1316
  "1": { name: "keyword.control.block.agentscript" }
1317
1317
  },
1318
- end: "^(?=topic\\b|variables\\b|start_agent\\b|system\\b|knowledge_action\\b|connection\\b|language\\b|\\z)",
1318
+ end: "^(?=topic\\b|variables\\b|start_agent\\b|system\\b|knowledge\\b|connection\\b|language\\b|model_config\\b|\\z)",
1319
1319
  patterns: [
1320
1320
  {
1321
1321
  name: "comment.line.agentscript",
@@ -1323,12 +1323,16 @@ const agentscriptGrammar = {
1323
1323
  },
1324
1324
  {
1325
1325
  name: "keyword.config.key.agentscript",
1326
- match: "^\\s+(model_provider|agent_id|agent_name|planner_type|agent_version|agent_type|agent_label|default_agent_user|developer_name|description|agent_description|enable_enhanced_event_logs|agent_template|outbound_flow)(?=\\s?:)"
1326
+ match: "^\\s+(model_provider|agent_id|agent_name|agent_version|agent_type|agent_label|default_agent_user|developer_name|description|agent_description|enable_enhanced_event_logs|agent_template|outbound_flow)(?=\\s?:)"
1327
1327
  },
1328
1328
  {
1329
1329
  name: "entity.name.config.agentscript",
1330
1330
  match: "^\\s+([a-zA-Z_][a-zA-Z0-9_]*)(?=\\s?:)"
1331
1331
  },
1332
+ {
1333
+ name: "keyword.config.empty.agentscript",
1334
+ match: "^\\s+empty\\b"
1335
+ },
1332
1336
  { include: "#values" }
1333
1337
  ]
1334
1338
  },
@@ -1338,7 +1342,7 @@ const agentscriptGrammar = {
1338
1342
  beginCaptures: {
1339
1343
  "1": { name: "keyword.control.block.agentscript" }
1340
1344
  },
1341
- end: "^(?=topic\\b|config\\b|variables\\b|connection\\b|start_agent\\b|system\\b|knowledge_action\\b|\\z)",
1345
+ end: "^(?=topic\\b|config\\b|variables\\b|connection\\b|start_agent\\b|system\\b|knowledge\\b|model_config\\b|\\z)",
1342
1346
  patterns: [
1343
1347
  {
1344
1348
  name: "comment.line.agentscript",
@@ -1357,7 +1361,7 @@ const agentscriptGrammar = {
1357
1361
  beginCaptures: {
1358
1362
  "1": { name: "keyword.control.block.agentscript" }
1359
1363
  },
1360
- end: "^(?=topic\\b|config\\b|start_agent\\b|system\\b|knowledge_action\\b|connection\\b|language\\b|\\z)",
1364
+ end: "^(?=topic\\b|config\\b|start_agent\\b|system\\b|knowledge\\b|connection\\b|language\\b|model_config\\b|\\z)",
1361
1365
  patterns: [
1362
1366
  {
1363
1367
  name: "comment.line.agentscript",
@@ -1365,7 +1369,7 @@ const agentscriptGrammar = {
1365
1369
  },
1366
1370
  {
1367
1371
  name: "keyword.variable.metadata.agentscript",
1368
- match: "^\\s+(description|source|label)(?=\\s?:)"
1372
+ match: "^\\s+(description|source|label|visibility)(?=\\s?:)"
1369
1373
  },
1370
1374
  {
1371
1375
  name: "variable.definition.agentscript",
@@ -1384,16 +1388,17 @@ const agentscriptGrammar = {
1384
1388
  match: "\\b(string|number|boolean|object|date|timestamp|currency|id|list)\\b"
1385
1389
  },
1386
1390
  { include: "#json-structures" },
1391
+ { include: "#plain-template-block" },
1387
1392
  { include: "#values" }
1388
1393
  ]
1389
1394
  },
1390
1395
  {
1391
1396
  name: "meta.knowledge.agentscript",
1392
- begin: "^(knowledge_action):",
1397
+ begin: "^(knowledge):",
1393
1398
  beginCaptures: {
1394
1399
  "1": { name: "keyword.control.block.agentscript" }
1395
1400
  },
1396
- end: "^(?=topic\\b|config\\b|variables\\b|connection\\b|start_agent\\b|system\\b|language\\b|connection\\b|\\z)",
1401
+ end: "^(?=topic\\b|config\\b|variables\\b|connection\\b|start_agent\\b|system\\b|language\\b|connection\\b|model_config\\b|\\z)",
1397
1402
  patterns: [
1398
1403
  {
1399
1404
  name: "comment.line.agentscript",
@@ -1413,7 +1418,7 @@ const agentscriptGrammar = {
1413
1418
  "1": { name: "keyword.control.block.agentscript" },
1414
1419
  "2": { name: "entity.name.connection.agentscript" }
1415
1420
  },
1416
- end: "^(?=topic\\b|config\\b|variables\\b|knowledge_action\\b|start_agent\\b|system\\b|language\\b|connection\\b|\\z)",
1421
+ end: "^(?=topic\\b|config\\b|variables\\b|knowledge\\b|start_agent\\b|system\\b|language\\b|connection\\b|model_config\\b|\\z)",
1417
1422
  patterns: [
1418
1423
  {
1419
1424
  name: "comment.line.agentscript",
@@ -1423,6 +1428,29 @@ const agentscriptGrammar = {
1423
1428
  name: "keyword.connection.field.agentscript",
1424
1429
  match: "^\\s+(escalation_message|outbound_route_type|outbound_route_name|adaptive_response_allowed)(?=\\s?:)"
1425
1430
  },
1431
+ {
1432
+ name: "keyword.connection.empty.agentscript",
1433
+ match: "^\\s+empty\\b"
1434
+ },
1435
+ { include: "#values" }
1436
+ ]
1437
+ },
1438
+ {
1439
+ name: "meta.model-config.agentscript",
1440
+ begin: "^(model_config):",
1441
+ beginCaptures: {
1442
+ "1": { name: "keyword.control.block.agentscript" }
1443
+ },
1444
+ end: "^(?=topic\\b|config\\b|variables\\b|start_agent\\b|system\\b|knowledge\\b|connection\\b|language\\b|\\z)",
1445
+ patterns: [
1446
+ {
1447
+ name: "comment.line.agentscript",
1448
+ match: "(^|[ \t]+)#.*$"
1449
+ },
1450
+ {
1451
+ name: "keyword.model-config.field.agentscript",
1452
+ match: "^\\s+model\\s*:"
1453
+ },
1426
1454
  { include: "#values" }
1427
1455
  ]
1428
1456
  },
@@ -1432,13 +1460,14 @@ const agentscriptGrammar = {
1432
1460
  beginCaptures: {
1433
1461
  "1": { name: "keyword.control.block.agentscript" }
1434
1462
  },
1435
- end: "^(?=topic\\b|config\\b|variables\\b|start_agent\\b|knowledge_action\\b|connection\\b|language\\b|\\z)",
1463
+ end: "^(?=topic\\b|config\\b|variables\\b|start_agent\\b|knowledge\\b|connection\\b|language\\b|model_config\\b|\\z)",
1436
1464
  patterns: [
1437
1465
  {
1438
1466
  name: "comment.line.agentscript",
1439
1467
  match: "(^|[ \t]+)#.*$"
1440
1468
  },
1441
1469
  { include: "#block-instructions" },
1470
+ { include: "#system-message-template-block" },
1442
1471
  {
1443
1472
  name: "keyword.system.agentscript",
1444
1473
  match: "^\\s+(instructions|messages|prompt)(?=\\s?:)"
@@ -1447,6 +1476,10 @@ const agentscriptGrammar = {
1447
1476
  name: "keyword.system.message-type.agentscript",
1448
1477
  match: "^\\s{2,}(error|welcome)(?=\\s?:)"
1449
1478
  },
1479
+ {
1480
+ name: "keyword.system.empty.agentscript",
1481
+ match: "^\\s+empty\\b"
1482
+ },
1450
1483
  { include: "#values" }
1451
1484
  ]
1452
1485
  },
@@ -1457,7 +1490,7 @@ const agentscriptGrammar = {
1457
1490
  "1": { name: "keyword.control.block.agentscript" },
1458
1491
  "2": { name: "entity.name.topic.agentscript" }
1459
1492
  },
1460
- end: "^(?=topic\\b|config\\b|variables\\b|start_agent\\b|system\\b|knowledge_action\\b|connection\\b|language\\b|\\z)",
1493
+ end: "^(?=topic\\b|config\\b|variables\\b|start_agent\\b|system\\b|knowledge\\b|connection\\b|language\\b|model_config\\b|\\z)",
1461
1494
  patterns: [
1462
1495
  {
1463
1496
  name: "comment.line.agentscript",
@@ -1470,6 +1503,7 @@ const agentscriptGrammar = {
1470
1503
  { include: "#agent-task" },
1471
1504
  { include: "#task-content" },
1472
1505
  { include: "#description-section" },
1506
+ { include: "#model-config-section" },
1473
1507
  { include: "#before-or-after-reasoning" },
1474
1508
  { include: "#directives" },
1475
1509
  {
@@ -1488,7 +1522,7 @@ const agentscriptGrammar = {
1488
1522
  "1": { name: "keyword.control.block.agentscript" },
1489
1523
  "2": { name: "entity.name.agent.agentscript" }
1490
1524
  },
1491
- end: "^(?=topic\\b|config\\b|variables\\b|start_agent\\b|system\\b|knowledge_action\\b|connection\\b|language\\b|\\z)",
1525
+ end: "^(?=topic\\b|config\\b|variables\\b|start_agent\\b|system\\b|knowledge\\b|connection\\b|language\\b|model_config\\b|\\z)",
1492
1526
  patterns: [
1493
1527
  {
1494
1528
  name: "comment.line.agentscript",
@@ -1501,6 +1535,7 @@ const agentscriptGrammar = {
1501
1535
  { include: "#agent-task" },
1502
1536
  { include: "#task-content" },
1503
1537
  { include: "#description-section" },
1538
+ { include: "#model-config-section" },
1504
1539
  { include: "#before-or-after-reasoning" },
1505
1540
  { include: "#directives" },
1506
1541
  {
@@ -1575,7 +1610,7 @@ const agentscriptGrammar = {
1575
1610
  },
1576
1611
  {
1577
1612
  name: "meta.variable.reference.agentscript",
1578
- match: "(@)(variables|outputs|inputs|topic|actions|knowledge_action)(\\.)([a-zA-Z_][a-zA-Z0-9_]*)",
1613
+ match: "(@)(variables|outputs|inputs|topic|actions|knowledge|system_variables)(\\.)([a-zA-Z_][a-zA-Z0-9_]*)",
1579
1614
  captures: {
1580
1615
  "1": { name: "support.class.agentscript" },
1581
1616
  "2": { name: "support.class.agentscript" },
@@ -1589,7 +1624,7 @@ const agentscriptGrammar = {
1589
1624
  },
1590
1625
  {
1591
1626
  name: "variable.other.member.agentscript",
1592
- match: "(?<=@(?:variables|topic|inputs|actions|outputs|knowledge_action)\\.)\\b[a-zA-Z_][a-zA-Z0-9_]*\\b"
1627
+ match: "(?<=@(?:variables|topic|inputs|actions|outputs|knowledge|system_variables)\\.)\\b[a-zA-Z_][a-zA-Z0-9_]*\\b"
1593
1628
  },
1594
1629
  {
1595
1630
  name: "operator.arithmetic.agentscript",
@@ -1654,7 +1689,7 @@ const agentscriptGrammar = {
1654
1689
  },
1655
1690
  {
1656
1691
  name: "variable.other.member.agentscript",
1657
- match: "(?<=@(?:variables|topic|inputs|actions|outputs|knowledge_action)\\.)\\b[a-zA-Z_][a-zA-Z0-9_]*\\b"
1692
+ match: "(?<=@(?:variables|topic|inputs|actions|outputs|knowledge|system_variables)\\.)\\b[a-zA-Z_][a-zA-Z0-9_]*\\b"
1658
1693
  }
1659
1694
  ]
1660
1695
  },
@@ -1704,12 +1739,31 @@ const agentscriptGrammar = {
1704
1739
  beginCaptures: {
1705
1740
  "1": { name: "keyword.topic.section.agentscript" }
1706
1741
  },
1707
- end: "^(?=\\s+(reasoning|system|description|before_reasoning|after_reasoning|actions|variables|instructions)\\b)|^(?=topic\\b|config\\b|variables\\b|start_agent\\b|language\\b|knowledge_action\\b|connection\\b)",
1742
+ end: "^(?=\\s+(reasoning|system|description|before_reasoning|after_reasoning|actions|variables|instructions|model_config)\\b)|^(?=topic\\b|config\\b|variables\\b|start_agent\\b|language\\b|knowledge\\b|connection\\b)",
1743
+ patterns: [
1744
+ {
1745
+ name: "comment.line.agentscript",
1746
+ match: "(^|[ \t]+)#.*$"
1747
+ },
1748
+ { include: "#values" }
1749
+ ]
1750
+ },
1751
+ "model-config-section": {
1752
+ name: "meta.model-config.section.agentscript",
1753
+ begin: "^\\s+(model_config)\\s*:",
1754
+ beginCaptures: {
1755
+ "1": { name: "keyword.topic.section.agentscript" }
1756
+ },
1757
+ end: "^(?=\\s+(reasoning|label|system|description|before_reasoning|after_reasoning|actions|variables|instructions|model_config)\\b)|^(?=topic\\b|config\\b|variables\\b|start_agent\\b|system\\b|language\\b|knowledge\\b|connection\\b)",
1708
1758
  patterns: [
1709
1759
  {
1710
1760
  name: "comment.line.agentscript",
1711
1761
  match: "(^|[ \t]+)#.*$"
1712
1762
  },
1763
+ {
1764
+ name: "keyword.model-config.field.agentscript",
1765
+ match: "^\\s+model\\s*:"
1766
+ },
1713
1767
  { include: "#values" }
1714
1768
  ]
1715
1769
  },
@@ -1719,7 +1773,7 @@ const agentscriptGrammar = {
1719
1773
  beginCaptures: {
1720
1774
  "1": { name: "keyword.topic.section.agentscript" }
1721
1775
  },
1722
- end: "^(?=\\s+(reasoning|label|description|before_reasoning|after_reasoning|actions)\\b)|^(?=topic\\b|config\\b|language\\b|knowledge_action\\b|connection\\b)",
1776
+ end: "^(?=\\s+(reasoning|label|description|before_reasoning|after_reasoning|actions|model_config)\\b)|^(?=topic\\b|config\\b|language\\b|knowledge\\b|connection\\b)",
1723
1777
  patterns: [
1724
1778
  {
1725
1779
  name: "comment.line.agentscript",
@@ -1739,7 +1793,7 @@ const agentscriptGrammar = {
1739
1793
  beginCaptures: {
1740
1794
  "1": { name: "keyword.topic.section.agentscript" }
1741
1795
  },
1742
- end: "^(?=\\s+(label|system|description|before_reasoning|after_reasoning|variables)\\b)|^(?=\\s{1,5}actions\\b)|^(?=topic\\b|config\\b|variables\\b|start_agent\\b|system\\b|language\\b|knowledge_action\\b|connection\\b)",
1796
+ end: "^(?=\\s+(label|system|description|before_reasoning|after_reasoning|variables|model_config)\\b)|^(?=\\s{1,5}actions\\b)|^(?=topic\\b|config\\b|variables\\b|start_agent\\b|system\\b|language\\b|knowledge\\b|connection\\b)",
1743
1797
  patterns: [
1744
1798
  {
1745
1799
  name: "comment.line.agentscript",
@@ -1751,7 +1805,7 @@ const agentscriptGrammar = {
1751
1805
  },
1752
1806
  "block-instructions": {
1753
1807
  name: "meta.block.instructions.agentscript",
1754
- begin: "^(\\s{4,8})(instructions)\\s*(:\\s*(->|\\|))",
1808
+ begin: "^(\\s+)(instructions)\\s*(:\\s*(->|\\|))",
1755
1809
  beginCaptures: {
1756
1810
  "2": { name: "keyword.topic.section.agentscript" },
1757
1811
  "3": {
@@ -1767,28 +1821,28 @@ const agentscriptGrammar = {
1767
1821
  ]
1768
1822
  }
1769
1823
  },
1770
- end: "^(?=\\s+(reasoning|actions|before_reasoning|after_reasoning)\\s?:)|^(?=topic\\b|config\\b|variables\\b|start_agent\\b|system\\b|language\\b|knowledge_action\\b|connection\\b)",
1824
+ end: "^(?=\\s+(reasoning|actions|before_reasoning|after_reasoning|model_config|messages)\\s?:)|^(?=topic\\b|config\\b|variables\\b|start_agent\\b|system\\b|language\\b|knowledge\\b|connection\\b)",
1771
1825
  patterns: [
1772
1826
  {
1773
1827
  name: "comment.line.agentscript",
1774
1828
  match: "(^|[ \t]+)#.*$"
1775
1829
  },
1830
+ { include: "#directives" },
1776
1831
  {
1777
1832
  name: "string.heredoc.agentscript",
1778
- begin: "^\\s+",
1833
+ begin: "^(\\s+)(?!#)(?!\\s*(?:if|else|run|set|with|transition\\s+to|delegate\\s+to|available\\s+when)\\b)(?!\\s*@)",
1779
1834
  beginCaptures: {
1780
1835
  "1": { name: "keyword.operator.heredoc.agentscript" }
1781
1836
  },
1782
- end: "^(?=\\s{0,8}\\S)|^(?=\\s{4}(reasoning|actions|before_reasoning|after_reasoning|description|label|system|variables|instructions|override)\\b)|^(?=topic\\b|config\\b|variables\\b|start_agent\\b|system\\b|language\\b|knowledge_action\\b|connection\\b)",
1837
+ end: "^(?=\\s+(reasoning|actions|before_reasoning|after_reasoning|description|label|system|variables|instructions|override|model_config|messages)\\s?:)|^(?=topic\\b|config\\b|variables\\b|start_agent\\b|system\\b|language\\b|knowledge\\b|connection\\b)",
1783
1838
  patterns: [
1784
1839
  { include: "#template-expression" },
1785
1840
  {
1786
1841
  name: "string.unquoted.heredoc.agentscript",
1787
- match: "."
1842
+ match: "(?:[^{]|\\{(?!!))*"
1788
1843
  }
1789
1844
  ]
1790
- },
1791
- { include: "#directives" }
1845
+ }
1792
1846
  ]
1793
1847
  },
1794
1848
  "template-block": {
@@ -1800,12 +1854,56 @@ const agentscriptGrammar = {
1800
1854
  end: "^(?!\\s+\\|)",
1801
1855
  patterns: [
1802
1856
  { include: "#template-expression" },
1857
+ {
1858
+ name: "string.unquoted.template.agentscript",
1859
+ match: "(?:[^{]|\\{(?!!))*"
1860
+ }
1861
+ ]
1862
+ },
1863
+ "plain-template-block": {
1864
+ name: "meta.plain.template.block.agentscript",
1865
+ begin: "^\\s+(\\|)",
1866
+ beginCaptures: {
1867
+ "1": { name: "keyword.operator.template.agentscript" }
1868
+ },
1869
+ end: "^(?!\\s+\\|)",
1870
+ patterns: [
1803
1871
  {
1804
1872
  name: "string.unquoted.template.agentscript",
1805
1873
  match: ".*"
1806
1874
  }
1807
1875
  ]
1808
1876
  },
1877
+ "system-message-template-block": {
1878
+ name: "meta.system.message.template.agentscript",
1879
+ begin: "^(\\s+)(welcome|error)\\s*:\\s*(\\|)\\s*$",
1880
+ beginCaptures: {
1881
+ "2": { name: "keyword.system.message-type.agentscript" },
1882
+ "3": { name: "keyword.operator.template.agentscript" }
1883
+ },
1884
+ end: "^(?=\\s{2,}(welcome|error)\\s*:)|^(?=\\s+(instructions|messages|prompt)\\s*:)|^(?=topic\\b|config\\b|variables\\b|start_agent\\b|system\\b|knowledge\\b|connection\\b|language\\b|model_config\\b|\\z)",
1885
+ patterns: [
1886
+ {
1887
+ name: "comment.line.agentscript",
1888
+ match: "(^|[ \t]+)#.*$"
1889
+ },
1890
+ {
1891
+ name: "string.heredoc.agentscript",
1892
+ begin: "^(\\s+)(?!#)(?!\\s*(welcome|error)\\s*:)",
1893
+ beginCaptures: {
1894
+ "1": { name: "keyword.operator.heredoc.agentscript" }
1895
+ },
1896
+ end: "^(?=\\s{2,}(welcome|error)\\s*:)|^(?=\\s+(instructions|messages|prompt)\\s*:)|^(?=topic\\b|config\\b|variables\\b|start_agent\\b|system\\b|knowledge\\b|connection\\b|language\\b|model_config\\b|\\z)",
1897
+ patterns: [
1898
+ { include: "#template-expression" },
1899
+ {
1900
+ name: "string.unquoted.heredoc.agentscript",
1901
+ match: "(?:[^{]|\\{(?!!))*"
1902
+ }
1903
+ ]
1904
+ }
1905
+ ]
1906
+ },
1809
1907
  "agent-task": {
1810
1908
  patterns: [
1811
1909
  {
@@ -1823,7 +1921,7 @@ const agentscriptGrammar = {
1823
1921
  { include: "#template-expression" },
1824
1922
  {
1825
1923
  name: "string.unquoted.heredoc.agentscript",
1826
- match: ".*"
1924
+ match: "(?:[^{]|\\{(?!!))*"
1827
1925
  }
1828
1926
  ]
1829
1927
  },
@@ -1876,7 +1974,7 @@ const agentscriptGrammar = {
1876
1974
  beginCaptures: {
1877
1975
  "1": { name: "keyword.topic.section.agentscript" }
1878
1976
  },
1879
- end: "^(?=\\s+(reasoning|label|system|actions|before_reasoning|after_reasoning|variables|instructions)\\b)|^(?=\\s{4}override\\s+system\\.instructions:)|^(?=topic\\b|config\\b|variables\\b|start_agent\\b|system\\b|language\\b|knowledge_action\\b|connection\\b)",
1977
+ end: "^(?=\\s+(reasoning|label|system|actions|before_reasoning|after_reasoning|variables|instructions|model_config)\\b)|^(?=\\s{4}override\\s+system\\.instructions:)|^(?=topic\\b|config\\b|variables\\b|start_agent\\b|system\\b|language\\b|knowledge\\b|connection\\b)",
1880
1978
  patterns: [
1881
1979
  {
1882
1980
  name: "comment.line.agentscript",
@@ -1888,16 +1986,17 @@ const agentscriptGrammar = {
1888
1986
  end: '"',
1889
1987
  patterns: [{ include: "#template-expression" }]
1890
1988
  },
1989
+ { include: "#plain-template-block" },
1891
1990
  { include: "#values" }
1892
1991
  ]
1893
1992
  },
1894
1993
  "before-or-after-reasoning": {
1895
1994
  name: "meta.before-or-after-reasoning.agentscript",
1896
- begin: "^(\\s+)(before_reasoning|after_reasoning):",
1995
+ begin: "^(\\s+)(before_reasoning|after_reasoning)(?::|\\s*:\\s*->)",
1897
1996
  beginCaptures: {
1898
1997
  "2": { name: "keyword.topic.section.agentscript" }
1899
1998
  },
1900
- end: "^(?=\\s{2,4}(reasoning|actions|after_reasoning|before_reasoning|description|label|system|variables|instructions|override)\\b)|^(?=\\s{4}override\\s+system\\.instructions:)|^(?=topic\\b|config\\b|variables\\b|start_agent\\b|system\\b|language\\b|knowledge_action\\b|connection\\b)",
1999
+ end: "^(?=\\s{2,4}(reasoning|actions|after_reasoning|before_reasoning|description|label|system|variables|instructions|override|model_config)\\b)|^(?=\\s{4}override\\s+system\\.instructions:)|^(?=topic\\b|config\\b|variables\\b|start_agent\\b|system\\b|language\\b|knowledge\\b|connection\\b)",
1901
2000
  patterns: [
1902
2001
  {
1903
2002
  name: "comment.line.agentscript",
@@ -1916,7 +2015,7 @@ const agentscriptGrammar = {
1916
2015
  },
1917
2016
  {
1918
2017
  name: "meta.variable.reference.agentscript",
1919
- match: "(@)(actions|topic|variables|outputs|inputs|knowledge_action)(\\.)([a-zA-Z_][a-zA-Z0-9_]*)",
2018
+ match: "(@)(actions|topic|variables|outputs|inputs|knowledge|system_variables)(\\.)([a-zA-Z_][a-zA-Z0-9_]*)",
1920
2019
  captures: {
1921
2020
  "1": { name: "support.class.agentscript" },
1922
2021
  "2": { name: "support.class.agentscript" },
@@ -1957,7 +2056,7 @@ const agentscriptGrammar = {
1957
2056
  beginCaptures: {
1958
2057
  "2": { name: "keyword.topic.section.agentscript" }
1959
2058
  },
1960
- end: "^(?=\\s{2,4}(reasoning|before_reasoning|after_reasoning|description|label|system|variables|instructions|override)\\b)|^(?=topic\\b|config\\b|variables\\b|start_agent\\b|system\\b|language\\b|knowledge_action\\b|connection\\b)",
2059
+ end: "^(?=\\s{2,4}(reasoning|before_reasoning|after_reasoning|description|label|system|variables|instructions|override|model_config)\\b)|^(?=topic\\b|config\\b|variables\\b|start_agent\\b|system\\b|language\\b|knowledge\\b|connection\\b)",
1961
2060
  patterns: [
1962
2061
  {
1963
2062
  name: "comment.line.agentscript",
@@ -1969,7 +2068,7 @@ const agentscriptGrammar = {
1969
2068
  beginCaptures: {
1970
2069
  "1": { name: "keyword.action.property.agentscript" }
1971
2070
  },
1972
- end: "^(?=\\s+(target|inputs|outputs|label|reasoning|require_user_confirmation|include_in_progress_indicator|progress_indicator_message)\\b)|^(?=\\s{4,8}[a-zA-Z_]\\s*:)|^(?=topic\\b|config\\b|variables\\b|start_agent\\b|system\\b|language\\b|knowledge_action\\b|connection\\b)",
2071
+ end: "^(?=\\s+(target|inputs|outputs|label|reasoning|require_user_confirmation|include_in_progress_indicator|progress_indicator_message)\\b)|^(?=\\s{4,8}[a-zA-Z_]\\s*:)|^(?=topic\\b|config\\b|variables\\b|start_agent\\b|system\\b|language\\b|knowledge\\b|connection\\b)",
1973
2072
  patterns: [
1974
2073
  {
1975
2074
  name: "comment.line.agentscript",
@@ -1977,13 +2076,13 @@ const agentscriptGrammar = {
1977
2076
  },
1978
2077
  {
1979
2078
  name: "meta.action.parameter.definition.agentscript",
1980
- begin: "^\\s{8,16}(?!(?:description|is_required|is_user_input|label|is_displayable|is_used_by_planner|complex_data_type_name)\\s*:)([a-zA-Z_][a-zA-Z0-9_]*):\\s*",
2079
+ begin: "^\\s{8,16}(?!(?:description|is_required|is_user_input|label|is_displayable|is_used_by_planner|complex_data_type_name|filter_from_agent|schema)\\s*:)([a-zA-Z_][a-zA-Z0-9_]*):\\s*",
1981
2080
  beginCaptures: {
1982
2081
  "1": {
1983
2082
  name: "variable.parameter.name.agentscript"
1984
2083
  }
1985
2084
  },
1986
- end: "^(?=\\s+(?!(?:description|is_required|is_user_input|label|is_displayable|is_used_by_planner|complex_data_type_name)\\s*:)[a-zA-Z_][a-zA-Z0-9_]*\\s*:)|^(?=topic\\b|config\\b|variables\\b|start_agent\\b|system\\b|language\\b|knowledge_action\\b|connection\\b)",
2085
+ end: "^(?=\\s+(?!(?:description|is_required|is_user_input|label|is_displayable|is_used_by_planner|complex_data_type_name|filter_from_agent|schema)\\s*:)[a-zA-Z_][a-zA-Z0-9_]*\\s*:)|^(?=topic\\b|config\\b|variables\\b|start_agent\\b|system\\b|language\\b|knowledge\\b|connection\\b)",
1987
2086
  patterns: [
1988
2087
  {
1989
2088
  name: "comment.line.agentscript",
@@ -1995,21 +2094,23 @@ const agentscriptGrammar = {
1995
2094
  },
1996
2095
  {
1997
2096
  name: "keyword.action.parameter.metadata.agentscript",
1998
- match: "^\\s+(description|is_required|is_user_input|label|complex_data_type_name|is_used_by_planner|is_displayable)(?=:)"
2097
+ match: "^\\s+(description|is_required|is_user_input|label|complex_data_type_name|is_used_by_planner|is_displayable|filter_from_agent|schema)(?=:)"
1999
2098
  },
2000
2099
  {
2001
2100
  name: "variable.parameter.name.agentscript",
2002
- match: "^\\s+(?!(?:description|is_required|is_user_input|label|is_displayable|is_used_by_planner|complex_data_type_name)\\s*:)[a-zA-Z_][a-zA-Z0-9_]*\\s*:"
2101
+ match: "^\\s+(?!(?:description|is_required|is_user_input|label|is_displayable|is_used_by_planner|complex_data_type_name|filter_from_agent|schema)\\s*:)[a-zA-Z_][a-zA-Z0-9_]*\\s*:"
2003
2102
  },
2103
+ { include: "#plain-template-block" },
2004
2104
  { include: "#values" }
2005
2105
  ]
2006
2106
  },
2107
+ { include: "#plain-template-block" },
2007
2108
  { include: "#values" }
2008
2109
  ]
2009
2110
  },
2010
2111
  {
2011
2112
  name: "keyword.action.property.agentscript",
2012
- match: "^\\s{6,12}(description|target|parameters|returns|label|require_user_confirmation|include_in_progress_indicator|progress_indicator_message|is_required|is_user_input|developer_name|complex_data_type_name|is_used_by_planner|is_displayable)(?=:)"
2113
+ match: "^\\s{6,12}(description|target|parameters|returns|label|require_user_confirmation|include_in_progress_indicator|progress_indicator_message|is_required|is_user_input|developer_name|complex_data_type_name|is_used_by_planner|is_displayable|filter_from_agent)(?=:)"
2013
2114
  },
2014
2115
  {
2015
2116
  name: "entity.name.action.agentscript",
@@ -2021,6 +2122,7 @@ const agentscriptGrammar = {
2021
2122
  },
2022
2123
  { include: "#operators" },
2023
2124
  { include: "#punctuation" },
2125
+ { include: "#plain-template-block" },
2024
2126
  { include: "#values" }
2025
2127
  ]
2026
2128
  },
@@ -2030,7 +2132,7 @@ const agentscriptGrammar = {
2030
2132
  beginCaptures: {
2031
2133
  "2": { name: "keyword.topic.section.agentscript" }
2032
2134
  },
2033
- end: "^(?=\\s+(instructions|before_reasoning|after_reasoning|label|system|override|actions)\\s?:)|^(?=topic\\b|config\\b|variables\\b|start_agent\\b|system\\b|language\\b|knowledge_action\\b|connection\\b)|^(?=\\s{2,4}(description\\s?:))",
2135
+ end: "^(?=\\s+(instructions|before_reasoning|after_reasoning|label|system|override|actions)\\s?:)|^(?=topic\\b|config\\b|variables\\b|start_agent\\b|system\\b|language\\b|knowledge\\b|connection\\b)|^(?=\\s{2,4}(description\\s?:))",
2034
2136
  patterns: [
2035
2137
  {
2036
2138
  name: "comment.line.agentscript",
@@ -2042,7 +2144,7 @@ const agentscriptGrammar = {
2042
2144
  },
2043
2145
  {
2044
2146
  name: "meta.tool.declaration.agentscript",
2045
- match: "^\\s+(([a-zA-Z_][a-zA-Z0-9_]*)):\\s*(@(actions|utils|topic|knowledge_action))",
2147
+ match: "^\\s+(([a-zA-Z_][a-zA-Z0-9_]*)):\\s*(@(actions|utils|topic|knowledge))",
2046
2148
  captures: {
2047
2149
  "2": { name: "entity.name.tool.agentscript" },
2048
2150
  "3": { name: "support.class.agentscript" },
@@ -2061,7 +2163,7 @@ const agentscriptGrammar = {
2061
2163
  },
2062
2164
  {
2063
2165
  name: "meta.variable.reference.agentscript",
2064
- match: "(@)(actions|topic|variables|outputs|inputs|knowledge_action)(\\.)([a-zA-Z_][a-zA-Z0-9_]*)",
2166
+ match: "(@)(actions|topic|variables|outputs|inputs|knowledge|system_variables)(\\.)([a-zA-Z_][a-zA-Z0-9_]*)",
2065
2167
  captures: {
2066
2168
  "1": { name: "support.class.agentscript" },
2067
2169
  "2": { name: "support.class.agentscript" },
@@ -2152,12 +2254,20 @@ const agentscriptGrammar = {
2152
2254
  },
2153
2255
  {
2154
2256
  name: "keyword.knowledge-action-ref.agentscript",
2155
- match: "(@knowledge_action)",
2257
+ match: "(@knowledge)",
2156
2258
  captures: { "1": { name: "support.class.agentscript" } }
2157
2259
  },
2260
+ {
2261
+ name: "keyword.system-variables-ref.agentscript",
2262
+ match: "(@system_variables)(\\.)",
2263
+ captures: {
2264
+ "1": { name: "support.class.agentscript" },
2265
+ "2": { name: "punctuation.accessor.dot.agentscript" }
2266
+ }
2267
+ },
2158
2268
  {
2159
2269
  name: "variable.other.member.agentscript",
2160
- match: "(?<=@(?:variables|topic|inputs|actions|outputs)\\.)\\b[a-zA-Z_][a-zA-Z0-9_]*\\b"
2270
+ match: "(?<=@(?:variables|topic|inputs|actions|outputs|knowledge|system_variables)\\.)\\b[a-zA-Z_][a-zA-Z0-9_]*\\b"
2161
2271
  },
2162
2272
  { include: "#operators" },
2163
2273
  { include: "#values" }