@datalayer/agent-runtimes 1.3.53 → 1.3.55
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/lib/examples/AgentStrategyExample.d.ts +12 -0
- package/lib/examples/{AgentLoopExample.js → AgentStrategyExample.js} +62 -62
- package/lib/examples/example-selector.js +1 -1
- package/lib/examples/index.d.ts +1 -1
- package/lib/examples/index.js +1 -1
- package/lib/examples/main.js +3 -3
- package/lib/loop/apps/visitorToken.d.ts +35 -0
- package/lib/loop/apps/visitorToken.js +114 -0
- package/lib/loop/embed/LoopEmbed.js +1 -0
- package/lib/loop/plugins/agents/DatalayerAgentBridge.js +15 -3
- package/lib/loop/plugins/agents/plugin.d.ts +24 -0
- package/lib/loop/plugins/agents/plugin.js +0 -17
- package/lib/loop/plugins/chat/ChatView.js +10 -1
- package/lib/loop/presets.d.ts +2 -0
- package/lib/loop/presets.js +2 -1
- package/lib/specs/index.d.ts +1 -1
- package/lib/specs/index.js +1 -1
- package/lib/specs/strategies.d.ts +34 -0
- package/lib/specs/{loops.js → strategies.js} +30 -30
- package/lib/types/index.d.ts +1 -1
- package/lib/types/index.js +1 -1
- package/lib/types/{loops.d.ts → strategies.d.ts} +17 -17
- package/package.json +2 -2
- package/scripts/codegen/generate_agents.py +1 -1
- package/scripts/codegen/{generate_loops.py → generate_strategies.py} +81 -81
- package/lib/examples/AgentLoopExample.d.ts +0 -12
- package/lib/specs/loops.d.ts +0 -34
- /package/lib/types/{loops.js → strategies.js} +0 -0
|
@@ -3,18 +3,18 @@
|
|
|
3
3
|
# Distributed under the terms of the Modified BSD License.
|
|
4
4
|
|
|
5
5
|
"""
|
|
6
|
-
Generate Python and TypeScript code from YAML
|
|
6
|
+
Generate Python and TypeScript code from YAML strategy specifications.
|
|
7
7
|
|
|
8
|
-
A *
|
|
9
|
-
|
|
10
|
-
constraints and success criteria that bound it, where state lives
|
|
11
|
-
iterations, how the human participates, and when
|
|
8
|
+
A *strategy* is the control loop an agent reasons with: how it progresses from
|
|
9
|
+
one decision to the next (observe/think/act/evaluate), the objective it works
|
|
10
|
+
toward, the constraints and success criteria that bound it, where state lives
|
|
11
|
+
between iterations, how the human participates, and when it terminates.
|
|
12
12
|
|
|
13
13
|
Usage:
|
|
14
|
-
python
|
|
15
|
-
--specs-dir agentspecs/agentspecs/
|
|
16
|
-
--python-output agent_runtimes/specs/
|
|
17
|
-
--typescript-output src/specs/
|
|
14
|
+
python generate_strategies.py \\
|
|
15
|
+
--specs-dir agentspecs/agentspecs/strategies \\
|
|
16
|
+
--python-output agent_runtimes/specs/strategies.py \\
|
|
17
|
+
--typescript-output src/specs/strategies.ts
|
|
18
18
|
"""
|
|
19
19
|
|
|
20
20
|
import argparse
|
|
@@ -26,14 +26,14 @@ import yaml
|
|
|
26
26
|
from versioning import ensure_spec_version, version_suffix
|
|
27
27
|
|
|
28
28
|
|
|
29
|
-
def _make_const_name(
|
|
30
|
-
"""Convert a
|
|
31
|
-
return f"{
|
|
29
|
+
def _make_const_name(strategy_id: str) -> str:
|
|
30
|
+
"""Convert a strategy ID to a constant name (e.g., 'ooda' -> 'OODA_STRATEGY')."""
|
|
31
|
+
return f"{strategy_id.upper().replace('-', '_')}_STRATEGY"
|
|
32
32
|
|
|
33
33
|
|
|
34
|
-
def _make_enum_name(
|
|
35
|
-
"""Convert a
|
|
36
|
-
return
|
|
34
|
+
def _make_enum_name(strategy_id: str) -> str:
|
|
35
|
+
"""Convert a strategy ID to an enum member name (e.g., 'data-analysis' -> 'DATA_ANALYSIS')."""
|
|
36
|
+
return strategy_id.upper().replace("-", "_")
|
|
37
37
|
|
|
38
38
|
|
|
39
39
|
def _clean(text: str) -> str:
|
|
@@ -65,8 +65,8 @@ def _ts_list(items: list) -> str:
|
|
|
65
65
|
return "[" + ", ".join(_ts_str(item) for item in items) + "]"
|
|
66
66
|
|
|
67
67
|
|
|
68
|
-
def
|
|
69
|
-
"""Load all
|
|
68
|
+
def load_strategy_specs(specs_dir: Path) -> list[dict[str, Any]]:
|
|
69
|
+
"""Load all strategy YAML specifications from a directory."""
|
|
70
70
|
specs = []
|
|
71
71
|
for yaml_file in sorted(specs_dir.glob("*.yaml")):
|
|
72
72
|
with open(yaml_file) as f:
|
|
@@ -77,14 +77,14 @@ def load_loop_specs(specs_dir: Path) -> list[dict[str, Any]]:
|
|
|
77
77
|
|
|
78
78
|
|
|
79
79
|
def generate_python_code(specs: list[dict[str, Any]]) -> str:
|
|
80
|
-
"""Generate Python code from
|
|
80
|
+
"""Generate Python code from strategy specifications."""
|
|
81
81
|
lines = [
|
|
82
82
|
"# Copyright (c) 2025-2026 Datalayer, Inc.",
|
|
83
83
|
"# Distributed under the terms of the Modified BSD License.",
|
|
84
84
|
'"""',
|
|
85
|
-
"
|
|
85
|
+
"Strategy Catalog.",
|
|
86
86
|
"",
|
|
87
|
-
"Predefined agent
|
|
87
|
+
"Predefined agent reasoning strategies (control loops) that agents can use.",
|
|
88
88
|
"",
|
|
89
89
|
"This file is AUTO-GENERATED from YAML specifications.",
|
|
90
90
|
"DO NOT EDIT MANUALLY - run 'make specs' to regenerate.",
|
|
@@ -93,16 +93,16 @@ def generate_python_code(specs: list[dict[str, Any]]) -> str:
|
|
|
93
93
|
"from enum import Enum",
|
|
94
94
|
"from typing import Optional",
|
|
95
95
|
"",
|
|
96
|
-
"from agent_runtimes.types import
|
|
96
|
+
"from agent_runtimes.types import StrategyHuman, StrategySpec, StrategyTermination",
|
|
97
97
|
"",
|
|
98
98
|
"",
|
|
99
99
|
"# " + "=" * 76,
|
|
100
|
-
"#
|
|
100
|
+
"# Strategies Enum",
|
|
101
101
|
"# " + "=" * 76,
|
|
102
102
|
"",
|
|
103
103
|
"",
|
|
104
|
-
"class
|
|
105
|
-
' """Enumeration of available agent
|
|
104
|
+
"class Strategies(str, Enum):",
|
|
105
|
+
' """Enumeration of available agent reasoning strategies."""',
|
|
106
106
|
"",
|
|
107
107
|
]
|
|
108
108
|
|
|
@@ -114,7 +114,7 @@ def generate_python_code(specs: list[dict[str, Any]]) -> str:
|
|
|
114
114
|
"",
|
|
115
115
|
"",
|
|
116
116
|
"# " + "=" * 76,
|
|
117
|
-
"#
|
|
117
|
+
"# Strategy Definitions",
|
|
118
118
|
"# " + "=" * 76,
|
|
119
119
|
"",
|
|
120
120
|
]
|
|
@@ -124,7 +124,7 @@ def generate_python_code(specs: list[dict[str, Any]]) -> str:
|
|
|
124
124
|
version = spec["version"]
|
|
125
125
|
const_name = _make_const_name(spec["id"]) + version_suffix(version)
|
|
126
126
|
|
|
127
|
-
lines.append(f"{const_name} =
|
|
127
|
+
lines.append(f"{const_name} = StrategySpec(")
|
|
128
128
|
lines.append(f' id="{spec["id"]}",')
|
|
129
129
|
lines.append(f' version="{version}",')
|
|
130
130
|
lines.append(f' name="{spec["name"]}",')
|
|
@@ -138,7 +138,7 @@ def generate_python_code(specs: list[dict[str, Any]]) -> str:
|
|
|
138
138
|
|
|
139
139
|
term = spec.get("termination")
|
|
140
140
|
if term:
|
|
141
|
-
lines.append(" termination=
|
|
141
|
+
lines.append(" termination=StrategyTermination(")
|
|
142
142
|
lines.append(
|
|
143
143
|
f" max_iterations={int(term.get('max_iterations', 10))},"
|
|
144
144
|
)
|
|
@@ -155,7 +155,7 @@ def generate_python_code(specs: list[dict[str, Any]]) -> str:
|
|
|
155
155
|
|
|
156
156
|
human = spec.get("human")
|
|
157
157
|
if human:
|
|
158
|
-
lines.append(" human=
|
|
158
|
+
lines.append(" human=StrategyHuman(")
|
|
159
159
|
lines.append(f" mode={_py_str(human.get('mode', 'initiate'))},")
|
|
160
160
|
lines.append(
|
|
161
161
|
f" approval_required={bool(human.get('approval_required', False))},"
|
|
@@ -179,10 +179,10 @@ def generate_python_code(specs: list[dict[str, Any]]) -> str:
|
|
|
179
179
|
[
|
|
180
180
|
"",
|
|
181
181
|
"# " + "=" * 76,
|
|
182
|
-
"#
|
|
182
|
+
"# Strategy Catalog",
|
|
183
183
|
"# " + "=" * 76,
|
|
184
184
|
"",
|
|
185
|
-
"
|
|
185
|
+
"STRATEGY_CATALOGUE: dict[str, StrategySpec] = {",
|
|
186
186
|
]
|
|
187
187
|
)
|
|
188
188
|
|
|
@@ -195,46 +195,46 @@ def generate_python_code(specs: list[dict[str, Any]]) -> str:
|
|
|
195
195
|
"}",
|
|
196
196
|
"",
|
|
197
197
|
"",
|
|
198
|
-
'
|
|
198
|
+
'DEFAULT_STRATEGY: str = "data-analysis"',
|
|
199
199
|
"",
|
|
200
200
|
"",
|
|
201
|
-
"def
|
|
201
|
+
"def get_strategy(strategy_id: str) -> Optional[StrategySpec]:",
|
|
202
202
|
' """',
|
|
203
|
-
" Get a
|
|
203
|
+
" Get a strategy specification by ID (accepts both bare and versioned refs).",
|
|
204
204
|
"",
|
|
205
205
|
" Args:",
|
|
206
|
-
"
|
|
206
|
+
" strategy_id: The unique identifier of the strategy.",
|
|
207
207
|
"",
|
|
208
208
|
" Returns:",
|
|
209
|
-
" The
|
|
209
|
+
" The StrategySpec, or None if not found.",
|
|
210
210
|
' """',
|
|
211
|
-
"
|
|
212
|
-
" if
|
|
213
|
-
" return
|
|
214
|
-
" base, _, ver =
|
|
211
|
+
" strategy = STRATEGY_CATALOGUE.get(strategy_id)",
|
|
212
|
+
" if strategy is not None:",
|
|
213
|
+
" return strategy",
|
|
214
|
+
" base, _, ver = strategy_id.rpartition(':')",
|
|
215
215
|
" if base and '.' in ver:",
|
|
216
|
-
" return
|
|
216
|
+
" return STRATEGY_CATALOGUE.get(base)",
|
|
217
217
|
" return None",
|
|
218
218
|
"",
|
|
219
219
|
"",
|
|
220
|
-
"def
|
|
220
|
+
"def get_default_strategy() -> Optional[StrategySpec]:",
|
|
221
221
|
' """',
|
|
222
|
-
" Get the default
|
|
222
|
+
" Get the default strategy.",
|
|
223
223
|
"",
|
|
224
224
|
" Returns:",
|
|
225
|
-
" The default
|
|
225
|
+
" The default StrategySpec, or None if no default is set.",
|
|
226
226
|
' """',
|
|
227
|
-
" return
|
|
227
|
+
" return STRATEGY_CATALOGUE.get(DEFAULT_STRATEGY)",
|
|
228
228
|
"",
|
|
229
229
|
"",
|
|
230
|
-
"def
|
|
230
|
+
"def list_strategies() -> list[StrategySpec]:",
|
|
231
231
|
' """',
|
|
232
|
-
" List all available
|
|
232
|
+
" List all available strategies.",
|
|
233
233
|
"",
|
|
234
234
|
" Returns:",
|
|
235
|
-
" List of all
|
|
235
|
+
" List of all StrategySpec specifications.",
|
|
236
236
|
' """',
|
|
237
|
-
" return list(
|
|
237
|
+
" return list(STRATEGY_CATALOGUE.values())",
|
|
238
238
|
"",
|
|
239
239
|
]
|
|
240
240
|
)
|
|
@@ -243,7 +243,7 @@ def generate_python_code(specs: list[dict[str, Any]]) -> str:
|
|
|
243
243
|
|
|
244
244
|
|
|
245
245
|
def generate_typescript_code(specs: list[dict[str, Any]]) -> str:
|
|
246
|
-
"""Generate TypeScript code from
|
|
246
|
+
"""Generate TypeScript code from strategy specifications."""
|
|
247
247
|
lines = [
|
|
248
248
|
"/*",
|
|
249
249
|
" * Copyright (c) 2025-2026 Datalayer, Inc.",
|
|
@@ -251,21 +251,21 @@ def generate_typescript_code(specs: list[dict[str, Any]]) -> str:
|
|
|
251
251
|
" */",
|
|
252
252
|
"",
|
|
253
253
|
"/**",
|
|
254
|
-
" *
|
|
254
|
+
" * Strategy Catalog",
|
|
255
255
|
" *",
|
|
256
|
-
" * Predefined agent
|
|
256
|
+
" * Predefined agent reasoning strategies (control loops).",
|
|
257
257
|
" *",
|
|
258
258
|
" * This file is AUTO-GENERATED from YAML specifications.",
|
|
259
259
|
" * DO NOT EDIT MANUALLY - run 'make specs' to regenerate.",
|
|
260
260
|
" */",
|
|
261
261
|
"",
|
|
262
|
-
"import type {
|
|
262
|
+
"import type { StrategySpec } from '../types';",
|
|
263
263
|
"",
|
|
264
264
|
"// " + "=" * 76,
|
|
265
|
-
"//
|
|
265
|
+
"// Strategies Enum",
|
|
266
266
|
"// " + "=" * 76,
|
|
267
267
|
"",
|
|
268
|
-
"export const
|
|
268
|
+
"export const Strategies = {",
|
|
269
269
|
]
|
|
270
270
|
|
|
271
271
|
for spec in specs:
|
|
@@ -275,10 +275,10 @@ def generate_typescript_code(specs: list[dict[str, Any]]) -> str:
|
|
|
275
275
|
[
|
|
276
276
|
"} as const;",
|
|
277
277
|
"",
|
|
278
|
-
"export type
|
|
278
|
+
"export type StrategyId = (typeof Strategies)[keyof typeof Strategies];",
|
|
279
279
|
"",
|
|
280
280
|
"// " + "=" * 76,
|
|
281
|
-
"//
|
|
281
|
+
"// Strategy Definitions",
|
|
282
282
|
"// " + "=" * 76,
|
|
283
283
|
"",
|
|
284
284
|
]
|
|
@@ -288,7 +288,7 @@ def generate_typescript_code(specs: list[dict[str, Any]]) -> str:
|
|
|
288
288
|
version = spec["version"]
|
|
289
289
|
const_name = _make_const_name(spec["id"]) + version_suffix(version)
|
|
290
290
|
|
|
291
|
-
lines.append(f"export const {const_name}:
|
|
291
|
+
lines.append(f"export const {const_name}: StrategySpec = {{")
|
|
292
292
|
lines.append(f" id: '{spec['id']}',")
|
|
293
293
|
lines.append(f" version: '{version}',")
|
|
294
294
|
lines.append(f" name: {_ts_str(spec['name'])},")
|
|
@@ -336,10 +336,10 @@ def generate_typescript_code(specs: list[dict[str, Any]]) -> str:
|
|
|
336
336
|
lines.extend(
|
|
337
337
|
[
|
|
338
338
|
"// " + "=" * 76,
|
|
339
|
-
"//
|
|
339
|
+
"// Strategy Catalog",
|
|
340
340
|
"// " + "=" * 76,
|
|
341
341
|
"",
|
|
342
|
-
"export const
|
|
342
|
+
"export const STRATEGY_CATALOGUE: Record<string, StrategySpec> = {",
|
|
343
343
|
]
|
|
344
344
|
)
|
|
345
345
|
|
|
@@ -351,37 +351,37 @@ def generate_typescript_code(specs: list[dict[str, Any]]) -> str:
|
|
|
351
351
|
[
|
|
352
352
|
"};",
|
|
353
353
|
"",
|
|
354
|
-
"export const
|
|
354
|
+
"export const DEFAULT_STRATEGY: StrategyId = Strategies.DATA_ANALYSIS;",
|
|
355
355
|
"",
|
|
356
|
-
"function
|
|
357
|
-
" if (
|
|
358
|
-
" const idx =
|
|
356
|
+
"function resolveStrategyId(strategyId: string): string {",
|
|
357
|
+
" if (strategyId in STRATEGY_CATALOGUE) return strategyId;",
|
|
358
|
+
" const idx = strategyId.lastIndexOf(':');",
|
|
359
359
|
" if (idx > 0) {",
|
|
360
|
-
" const base =
|
|
361
|
-
" if (base in
|
|
360
|
+
" const base = strategyId.slice(0, idx);",
|
|
361
|
+
" if (base in STRATEGY_CATALOGUE) return base;",
|
|
362
362
|
" }",
|
|
363
|
-
" return
|
|
363
|
+
" return strategyId;",
|
|
364
364
|
"}",
|
|
365
365
|
"",
|
|
366
366
|
"/**",
|
|
367
|
-
" * Get a
|
|
367
|
+
" * Get a strategy specification by ID.",
|
|
368
368
|
" */",
|
|
369
|
-
"export function
|
|
370
|
-
" return
|
|
369
|
+
"export function getStrategy(strategyId: string): StrategySpec | undefined {",
|
|
370
|
+
" return STRATEGY_CATALOGUE[resolveStrategyId(strategyId)];",
|
|
371
371
|
"}",
|
|
372
372
|
"",
|
|
373
373
|
"/**",
|
|
374
|
-
" * Get the default
|
|
374
|
+
" * Get the default strategy.",
|
|
375
375
|
" */",
|
|
376
|
-
"export function
|
|
377
|
-
" return
|
|
376
|
+
"export function getDefaultStrategy(): StrategySpec | undefined {",
|
|
377
|
+
" return STRATEGY_CATALOGUE[DEFAULT_STRATEGY];",
|
|
378
378
|
"}",
|
|
379
379
|
"",
|
|
380
380
|
"/**",
|
|
381
|
-
" * List all available
|
|
381
|
+
" * List all available strategies.",
|
|
382
382
|
" */",
|
|
383
|
-
"export function
|
|
384
|
-
" return Object.values(
|
|
383
|
+
"export function listStrategies(): StrategySpec[] {",
|
|
384
|
+
" return Object.values(STRATEGY_CATALOGUE);",
|
|
385
385
|
"}",
|
|
386
386
|
"",
|
|
387
387
|
]
|
|
@@ -393,13 +393,13 @@ def generate_typescript_code(specs: list[dict[str, Any]]) -> str:
|
|
|
393
393
|
def main():
|
|
394
394
|
"""Main entry point."""
|
|
395
395
|
parser = argparse.ArgumentParser(
|
|
396
|
-
description="Generate Python and TypeScript code from YAML
|
|
396
|
+
description="Generate Python and TypeScript code from YAML strategy specifications"
|
|
397
397
|
)
|
|
398
398
|
parser.add_argument(
|
|
399
399
|
"--specs-dir",
|
|
400
400
|
type=Path,
|
|
401
401
|
required=True,
|
|
402
|
-
help="Directory containing YAML
|
|
402
|
+
help="Directory containing YAML strategy specification files",
|
|
403
403
|
)
|
|
404
404
|
parser.add_argument(
|
|
405
405
|
"--python-output",
|
|
@@ -420,9 +420,9 @@ def main():
|
|
|
420
420
|
print(f"Error: Specs directory does not exist: {args.specs_dir}")
|
|
421
421
|
sys.exit(1)
|
|
422
422
|
|
|
423
|
-
print(f"Loading
|
|
424
|
-
specs =
|
|
425
|
-
print(f"Loaded {len(specs)}
|
|
423
|
+
print(f"Loading strategy specs from {args.specs_dir}...")
|
|
424
|
+
specs = load_strategy_specs(args.specs_dir)
|
|
425
|
+
print(f"Loaded {len(specs)} strategy specifications")
|
|
426
426
|
|
|
427
427
|
print("Generating Python code...")
|
|
428
428
|
python_code = generate_python_code(specs)
|
|
@@ -436,7 +436,7 @@ def main():
|
|
|
436
436
|
args.typescript_output.write_text(typescript_code)
|
|
437
437
|
print(f"✓ Generated {args.typescript_output}")
|
|
438
438
|
|
|
439
|
-
print(f"\n✓ Successfully generated code from {len(specs)}
|
|
439
|
+
print(f"\n✓ Successfully generated code from {len(specs)} strategy specs")
|
|
440
440
|
|
|
441
441
|
|
|
442
442
|
if __name__ == "__main__":
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { ServiceManager } from '@jupyterlab/services';
|
|
2
|
-
interface AgentLoopExampleInnerProps {
|
|
3
|
-
serviceManager?: ServiceManager.IManager;
|
|
4
|
-
}
|
|
5
|
-
export declare function AgentLoopExampleInner({ serviceManager, }: AgentLoopExampleInnerProps): import("react").JSX.Element;
|
|
6
|
-
/**
|
|
7
|
-
* Main example component with Jupyter provider wrapper.
|
|
8
|
-
*/
|
|
9
|
-
export declare function AgentLoopExample({ serviceManager, }: {
|
|
10
|
-
serviceManager?: ServiceManager.IManager;
|
|
11
|
-
}): import("react").JSX.Element;
|
|
12
|
-
export default AgentLoopExample;
|
package/lib/specs/loops.d.ts
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Loop Catalog
|
|
3
|
-
*
|
|
4
|
-
* Predefined agent execution-loop specifications.
|
|
5
|
-
*
|
|
6
|
-
* This file is AUTO-GENERATED from YAML specifications.
|
|
7
|
-
* DO NOT EDIT MANUALLY - run 'make specs' to regenerate.
|
|
8
|
-
*/
|
|
9
|
-
import type { LoopSpec } from '../types';
|
|
10
|
-
export declare const Loops: {
|
|
11
|
-
readonly DATA_ANALYSIS: "data-analysis";
|
|
12
|
-
readonly HUMAN_IN_THE_LOOP: "human-in-the-loop";
|
|
13
|
-
readonly OODA: "ooda";
|
|
14
|
-
readonly PLAN_EXECUTE_CRITIC: "plan-execute-critic";
|
|
15
|
-
};
|
|
16
|
-
export type LoopId = (typeof Loops)[keyof typeof Loops];
|
|
17
|
-
export declare const DATA_ANALYSIS_LOOP_0_0_1: LoopSpec;
|
|
18
|
-
export declare const HUMAN_IN_THE_LOOP_LOOP_0_0_1: LoopSpec;
|
|
19
|
-
export declare const OODA_LOOP_0_0_1: LoopSpec;
|
|
20
|
-
export declare const PLAN_EXECUTE_CRITIC_LOOP_0_0_1: LoopSpec;
|
|
21
|
-
export declare const LOOP_CATALOGUE: Record<string, LoopSpec>;
|
|
22
|
-
export declare const DEFAULT_LOOP: LoopId;
|
|
23
|
-
/**
|
|
24
|
-
* Get a loop specification by ID.
|
|
25
|
-
*/
|
|
26
|
-
export declare function getLoop(loopId: string): LoopSpec | undefined;
|
|
27
|
-
/**
|
|
28
|
-
* Get the default loop.
|
|
29
|
-
*/
|
|
30
|
-
export declare function getDefaultLoop(): LoopSpec | undefined;
|
|
31
|
-
/**
|
|
32
|
-
* List all available loops.
|
|
33
|
-
*/
|
|
34
|
-
export declare function listLoops(): LoopSpec[];
|
|
File without changes
|