@a5c-ai/agent-core 5.0.1-staging.69cb593ea536 → 5.0.1-staging.6ab464ce4307
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -7
- package/dist/agenticTools/background/state.d.ts +6 -4
- package/dist/agenticTools/background/state.d.ts.map +1 -1
- package/dist/agenticTools/background/state.js +9 -23
- package/dist/backgroundProcessRegistry.d.ts +4 -60
- package/dist/backgroundProcessRegistry.d.ts.map +1 -1
- package/dist/backgroundProcessRegistry.js +7 -197
- package/dist/context/index.d.ts +5 -0
- package/dist/context/index.d.ts.map +1 -0
- package/dist/context/index.js +12 -0
- package/dist/context/manager.d.ts +43 -0
- package/dist/context/manager.d.ts.map +1 -0
- package/dist/context/manager.js +113 -0
- package/dist/context/strategies/index.d.ts +4 -0
- package/dist/context/strategies/index.d.ts.map +1 -0
- package/dist/context/strategies/index.js +9 -0
- package/dist/context/strategies/priority.d.ts +29 -0
- package/dist/context/strategies/priority.d.ts.map +1 -0
- package/dist/context/strategies/priority.js +58 -0
- package/dist/context/strategies/sliding.d.ts +27 -0
- package/dist/context/strategies/sliding.d.ts.map +1 -0
- package/dist/context/strategies/sliding.js +62 -0
- package/dist/context/strategies/summary.d.ts +41 -0
- package/dist/context/strategies/summary.d.ts.map +1 -0
- package/dist/context/strategies/summary.js +75 -0
- package/dist/context/token-estimator.d.ts +25 -0
- package/dist/context/token-estimator.d.ts.map +1 -0
- package/dist/context/token-estimator.js +38 -0
- package/dist/context/types.d.ts +131 -0
- package/dist/context/types.d.ts.map +1 -0
- package/dist/context/types.js +9 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +23 -1
- package/dist/loop/agent-loop.d.ts +51 -0
- package/dist/loop/agent-loop.d.ts.map +1 -0
- package/dist/loop/agent-loop.js +238 -0
- package/dist/loop/index.d.ts +6 -0
- package/dist/loop/index.d.ts.map +1 -0
- package/dist/loop/index.js +11 -0
- package/dist/loop/strategies/concurrent.d.ts +33 -0
- package/dist/loop/strategies/concurrent.d.ts.map +1 -0
- package/dist/loop/strategies/concurrent.js +47 -0
- package/dist/loop/strategies/group-chat.d.ts +42 -0
- package/dist/loop/strategies/group-chat.d.ts.map +1 -0
- package/dist/loop/strategies/group-chat.js +91 -0
- package/dist/loop/strategies/handoff.d.ts +46 -0
- package/dist/loop/strategies/handoff.d.ts.map +1 -0
- package/dist/loop/strategies/handoff.js +86 -0
- package/dist/loop/strategies/index.d.ts +9 -0
- package/dist/loop/strategies/index.d.ts.map +1 -0
- package/dist/loop/strategies/index.js +11 -0
- package/dist/loop/strategies/sequential.d.ts +19 -0
- package/dist/loop/strategies/sequential.d.ts.map +1 -0
- package/dist/loop/strategies/sequential.js +29 -0
- package/dist/loop/types.d.ts +120 -0
- package/dist/loop/types.d.ts.map +1 -0
- package/dist/loop/types.js +9 -0
- package/dist/subagent/index.d.ts +6 -0
- package/dist/subagent/index.d.ts.map +1 -0
- package/dist/subagent/index.js +7 -0
- package/dist/subagent/invoker.d.ts +33 -0
- package/dist/subagent/invoker.d.ts.map +1 -0
- package/dist/subagent/invoker.js +112 -0
- package/dist/subagent/oversight.d.ts +43 -0
- package/dist/subagent/oversight.d.ts.map +1 -0
- package/dist/subagent/oversight.js +63 -0
- package/dist/subagent/types.d.ts +136 -0
- package/dist/subagent/types.d.ts.map +1 -0
- package/dist/subagent/types.js +9 -0
- package/dist/synthesis/index.d.ts +4 -0
- package/dist/synthesis/index.d.ts.map +1 -0
- package/dist/synthesis/index.js +9 -0
- package/dist/synthesis/strategies/index.d.ts +4 -0
- package/dist/synthesis/strategies/index.d.ts.map +1 -0
- package/dist/synthesis/strategies/index.js +9 -0
- package/dist/synthesis/strategies/merge.d.ts +18 -0
- package/dist/synthesis/strategies/merge.d.ts.map +1 -0
- package/dist/synthesis/strategies/merge.js +104 -0
- package/dist/synthesis/strategies/rank.d.ts +25 -0
- package/dist/synthesis/strategies/rank.d.ts.map +1 -0
- package/dist/synthesis/strategies/rank.js +51 -0
- package/dist/synthesis/strategies/vote.d.ts +17 -0
- package/dist/synthesis/strategies/vote.d.ts.map +1 -0
- package/dist/synthesis/strategies/vote.js +59 -0
- package/dist/synthesis/synthesizer.d.ts +25 -0
- package/dist/synthesis/synthesizer.d.ts.map +1 -0
- package/dist/synthesis/synthesizer.js +38 -0
- package/dist/synthesis/types.d.ts +96 -0
- package/dist/synthesis/types.d.ts.map +1 -0
- package/dist/synthesis/types.js +8 -0
- package/dist/tools.test.js +9 -6
- package/dist/types.d.ts +4 -4
- package/dist/types.d.ts.map +1 -1
- package/package.json +10 -3
package/README.md
CHANGED
|
@@ -5,16 +5,16 @@ Built-in programmatic session wrapper and agentic tool surface for Babysitter ru
|
|
|
5
5
|
<!-- docs-status:start -->
|
|
6
6
|
> Status: Public advanced/runtime package.
|
|
7
7
|
> Canonical docs home: [Package and Plugin Docs Map](../../docs/package-and-plugin-map.md).
|
|
8
|
-
> This README defines the package contract for runtime consumers and published dependents such as `@a5c-ai/
|
|
8
|
+
> This README defines the package contract for runtime consumers and published dependents such as `@a5c-ai/agent-platform`.
|
|
9
9
|
<!-- docs-status:end -->
|
|
10
10
|
|
|
11
11
|
## Package role
|
|
12
12
|
|
|
13
|
-
`@a5c-ai/agent-core` sits between `@a5c-ai/
|
|
13
|
+
`@a5c-ai/agent-core` sits between `@a5c-ai/agent-platform`, `@a5c-ai/agent-mux`, and `@a5c-ai/babysitter-sdk`:
|
|
14
14
|
|
|
15
15
|
- `createAgentCoreSession()` wraps an `@a5c-ai/agent-mux` client for in-process prompt execution.
|
|
16
16
|
- `createAgentCoreToolDefinitions()` assembles the built-in Babysitter-flavored tool surface that host runtimes can inject into planning, resume, or delegated-task flows.
|
|
17
|
-
- `@a5c-ai/
|
|
17
|
+
- `@a5c-ai/agent-platform` re-exports these APIs from `src/harness/index.ts`, uses `createAgentCoreSession()` for direct `agent-core` harness invocation in `src/harness/invoker.ts`, and injects tool definitions into plan-process and resume-run flows.
|
|
18
18
|
- `@a5c-ai/babysitter-sdk` still owns run directories, journals, task/effect lifecycle, and config defaults. `agent-core` does not replace the SDK orchestration layer.
|
|
19
19
|
|
|
20
20
|
This package is published as a runtime dependency surface for higher-level Babysitter runtimes. It is still an advanced/operator-facing building block rather than the primary entrypoint for new users.
|
|
@@ -98,7 +98,7 @@ These fields remain on `AgentCoreSessionOptions` for compatibility, but the curr
|
|
|
98
98
|
|
|
99
99
|
| Option | Status | Migration note |
|
|
100
100
|
| --- | --- | --- |
|
|
101
|
-
| `toolsMode` | Deprecated, ignored by agent-core | Use backend-native configuration, or the PI wrapper in `@a5c-ai/
|
|
101
|
+
| `toolsMode` | Deprecated, ignored by agent-core | Use backend-native configuration, or the PI wrapper in `@a5c-ai/agent-platform`, if you still need tool-surface control. |
|
|
102
102
|
| `customTools` | Deprecated, ignored by agent-core | Register host-side tools with `createAgentCoreToolDefinitions()` or use the PI wrapper for runtime custom-tool injection. |
|
|
103
103
|
| `isolated` | Deprecated, ignored by agent-core | Use the PI wrapper if you still need extension/skills isolation controls. |
|
|
104
104
|
| `ephemeral` | Deprecated, ignored by agent-core | Session persistence is determined by the selected agent-mux backend. |
|
|
@@ -106,7 +106,7 @@ These fields remain on `AgentCoreSessionOptions` for compatibility, but the curr
|
|
|
106
106
|
| `enableCompaction` | Deprecated, ignored by agent-core | Compaction behavior belongs to the selected backend/runtime. |
|
|
107
107
|
| `agentDir` | Deprecated, ignored by agent-core | Configure agent directories through the target backend instead. |
|
|
108
108
|
|
|
109
|
-
If you still need the PI-era controls above, use the PI wrapper exposed from `@a5c-ai/
|
|
109
|
+
If you still need the PI-era controls above, use the PI wrapper exposed from `@a5c-ai/agent-platform` rather than `@a5c-ai/agent-core`.
|
|
110
110
|
|
|
111
111
|
## Tool-definition API
|
|
112
112
|
|
|
@@ -192,7 +192,7 @@ Source disambiguation uses `(source, sourceQualifier, name)`, so duplicate tool
|
|
|
192
192
|
|
|
193
193
|
Current downstream integration boundaries in this repo:
|
|
194
194
|
|
|
195
|
-
- `@a5c-ai/
|
|
195
|
+
- `@a5c-ai/agent-platform`
|
|
196
196
|
- re-exports the session/tool APIs from `src/harness/index.ts`
|
|
197
197
|
- uses `createAgentCoreSession()` for the direct `agent-core` harness path in `src/harness/invoker.ts`
|
|
198
198
|
- injects `createAgentCoreToolDefinitions()` into plan-process and delegated-task flows in `src/harness/internal/createRun/planProcess/*`
|
|
@@ -202,7 +202,7 @@ Current downstream integration boundaries in this repo:
|
|
|
202
202
|
- `@a5c-ai/babysitter-sdk`
|
|
203
203
|
- provides config defaults/env wiring used by the `config` tool and remains the owner of orchestration/run-state semantics outside this package
|
|
204
204
|
|
|
205
|
-
In practice, use `agent-core` when you need an in-process runtime wrapper or bundled tool surface. Use `
|
|
205
|
+
In practice, use `agent-core` when you need an in-process runtime wrapper or bundled tool surface. Use `agent-platform` when you need the higher-level harness CLI/runtime entrypoints.
|
|
206
206
|
|
|
207
207
|
## Build, test, and CI
|
|
208
208
|
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
export
|
|
4
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Backwards-compatibility shim -- the canonical implementation now lives in
|
|
3
|
+
* `@a5c-ai/agent-runtime`. This re-export keeps internal agent-core consumers
|
|
4
|
+
* working without changes.
|
|
5
|
+
*/
|
|
6
|
+
export { getBackgroundRegistry, disposeBackgroundRegistry, } from "@a5c-ai/agent-runtime";
|
|
5
7
|
//# sourceMappingURL=state.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../../src/agenticTools/background/state.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../../src/agenticTools/background/state.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EACL,qBAAqB,EACrB,yBAAyB,GAC1B,MAAM,uBAAuB,CAAC"}
|
|
@@ -1,25 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getBackgroundRegistry =
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
if (!registry) {
|
|
13
|
-
registry = new backgroundProcessRegistry_1.BackgroundProcessRegistry({ maxConcurrent: options.maxBackgroundProcesses });
|
|
14
|
-
scopedRegistries.set(options, registry);
|
|
15
|
-
}
|
|
16
|
-
return registry;
|
|
17
|
-
}
|
|
18
|
-
function disposeBackgroundRegistry(options) {
|
|
19
|
-
const registry = scopedRegistries.get(options);
|
|
20
|
-
if (!registry) {
|
|
21
|
-
return;
|
|
22
|
-
}
|
|
23
|
-
registry.dispose();
|
|
24
|
-
scopedRegistries.delete(options);
|
|
25
|
-
}
|
|
3
|
+
exports.disposeBackgroundRegistry = exports.getBackgroundRegistry = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Backwards-compatibility shim -- the canonical implementation now lives in
|
|
6
|
+
* `@a5c-ai/agent-runtime`. This re-export keeps internal agent-core consumers
|
|
7
|
+
* working without changes.
|
|
8
|
+
*/
|
|
9
|
+
var agent_runtime_1 = require("@a5c-ai/agent-runtime");
|
|
10
|
+
Object.defineProperty(exports, "getBackgroundRegistry", { enumerable: true, get: function () { return agent_runtime_1.getBackgroundRegistry; } });
|
|
11
|
+
Object.defineProperty(exports, "disposeBackgroundRegistry", { enumerable: true, get: function () { return agent_runtime_1.disposeBackgroundRegistry; } });
|
|
@@ -1,63 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* stdout/stderr, fires completion callbacks, and enforces a concurrency limit.
|
|
2
|
+
* Backwards-compatibility shim -- the canonical implementation now lives in
|
|
3
|
+
* `@a5c-ai/agent-runtime`. This re-export keeps internal agent-core consumers
|
|
4
|
+
* (and any external code that deep-imported this path) working without changes.
|
|
6
5
|
*/
|
|
7
|
-
|
|
8
|
-
export interface BackgroundTaskRecord {
|
|
9
|
-
backgroundTaskId: string;
|
|
10
|
-
pid: number;
|
|
11
|
-
command: string;
|
|
12
|
-
description?: string;
|
|
13
|
-
startedAt: string;
|
|
14
|
-
status: "running" | "completed" | "exited" | "cancelled" | "killed";
|
|
15
|
-
exitCode: number | null;
|
|
16
|
-
stdout: string;
|
|
17
|
-
stderr: string;
|
|
18
|
-
durationMs: number | null;
|
|
19
|
-
}
|
|
20
|
-
/** Payload delivered to `onComplete` callbacks. */
|
|
21
|
-
export interface BackgroundCompletionEvent {
|
|
22
|
-
backgroundTaskId: string;
|
|
23
|
-
pid: number;
|
|
24
|
-
command: string;
|
|
25
|
-
description?: string;
|
|
26
|
-
status: "completed" | "exited";
|
|
27
|
-
exitCode: number;
|
|
28
|
-
stdout: string;
|
|
29
|
-
stderr: string;
|
|
30
|
-
durationMs: number;
|
|
31
|
-
}
|
|
32
|
-
/** Options for spawning a background process. */
|
|
33
|
-
export interface SpawnOptions {
|
|
34
|
-
command: string;
|
|
35
|
-
cwd: string;
|
|
36
|
-
env?: Record<string, string>;
|
|
37
|
-
description?: string;
|
|
38
|
-
onComplete?: (event: BackgroundCompletionEvent) => void;
|
|
39
|
-
}
|
|
40
|
-
export declare class BackgroundProcessRegistry {
|
|
41
|
-
private readonly processes;
|
|
42
|
-
private readonly maxConcurrent;
|
|
43
|
-
constructor(options?: {
|
|
44
|
-
maxConcurrent?: number;
|
|
45
|
-
});
|
|
46
|
-
/**
|
|
47
|
-
* Spawn a command in the background and begin tracking it.
|
|
48
|
-
* Returns a snapshot of the initial record.
|
|
49
|
-
*/
|
|
50
|
-
spawn(opts: SpawnOptions): BackgroundTaskRecord;
|
|
51
|
-
/** Get a snapshot of a tracked process by ID, or undefined. */
|
|
52
|
-
get(backgroundTaskId: string): BackgroundTaskRecord | undefined;
|
|
53
|
-
/** List snapshots of all tracked processes. */
|
|
54
|
-
list(): BackgroundTaskRecord[];
|
|
55
|
-
/** Cancel (SIGTERM) a running process. Returns true if found and killed. */
|
|
56
|
-
cancel(backgroundTaskId: string): boolean;
|
|
57
|
-
/** Kill all running processes. */
|
|
58
|
-
killAll(): void;
|
|
59
|
-
/** Kill all processes and clear tracking state. */
|
|
60
|
-
dispose(): void;
|
|
61
|
-
private snapshot;
|
|
62
|
-
}
|
|
6
|
+
export { BackgroundProcessRegistry, type BackgroundTaskRecord, type BackgroundCompletionEvent, type SpawnOptions, } from "@a5c-ai/agent-runtime";
|
|
63
7
|
//# sourceMappingURL=backgroundProcessRegistry.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"backgroundProcessRegistry.d.ts","sourceRoot":"","sources":["../src/backgroundProcessRegistry.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"backgroundProcessRegistry.d.ts","sourceRoot":"","sources":["../src/backgroundProcessRegistry.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EACL,yBAAyB,EACzB,KAAK,oBAAoB,EACzB,KAAK,yBAAyB,EAC9B,KAAK,YAAY,GAClB,MAAM,uBAAuB,CAAC"}
|
|
@@ -1,200 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Background process lifecycle management for the bash agentic tool (GAP-TOOLS-036).
|
|
4
|
-
*
|
|
5
|
-
* Tracks child processes spawned with `run_in_background: true`, collects
|
|
6
|
-
* stdout/stderr, fires completion callbacks, and enforces a concurrency limit.
|
|
7
|
-
*/
|
|
8
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
9
|
-
if (k2 === undefined) k2 = k;
|
|
10
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
11
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
12
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
13
|
-
}
|
|
14
|
-
Object.defineProperty(o, k2, desc);
|
|
15
|
-
}) : (function(o, m, k, k2) {
|
|
16
|
-
if (k2 === undefined) k2 = k;
|
|
17
|
-
o[k2] = m[k];
|
|
18
|
-
}));
|
|
19
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
20
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
21
|
-
}) : function(o, v) {
|
|
22
|
-
o["default"] = v;
|
|
23
|
-
});
|
|
24
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
25
|
-
var ownKeys = function(o) {
|
|
26
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
27
|
-
var ar = [];
|
|
28
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
29
|
-
return ar;
|
|
30
|
-
};
|
|
31
|
-
return ownKeys(o);
|
|
32
|
-
};
|
|
33
|
-
return function (mod) {
|
|
34
|
-
if (mod && mod.__esModule) return mod;
|
|
35
|
-
var result = {};
|
|
36
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
37
|
-
__setModuleDefault(result, mod);
|
|
38
|
-
return result;
|
|
39
|
-
};
|
|
40
|
-
})();
|
|
41
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
42
3
|
exports.BackgroundProcessRegistry = void 0;
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
processes = new Map();
|
|
51
|
-
maxConcurrent;
|
|
52
|
-
constructor(options) {
|
|
53
|
-
this.maxConcurrent = options?.maxConcurrent ?? DEFAULT_MAX_CONCURRENT;
|
|
54
|
-
}
|
|
55
|
-
/**
|
|
56
|
-
* Spawn a command in the background and begin tracking it.
|
|
57
|
-
* Returns a snapshot of the initial record.
|
|
58
|
-
*/
|
|
59
|
-
spawn(opts) {
|
|
60
|
-
const runningCount = [...this.processes.values()].filter((p) => p.status === "running").length;
|
|
61
|
-
if (runningCount >= this.maxConcurrent) {
|
|
62
|
-
throw new Error(`Max concurrent background processes limit reached (${this.maxConcurrent}). ` +
|
|
63
|
-
`Cancel or wait for existing processes before spawning new ones.`);
|
|
64
|
-
}
|
|
65
|
-
const backgroundTaskId = (0, babysitter_sdk_1.nextUlid)();
|
|
66
|
-
const startMs = Date.now();
|
|
67
|
-
const shell = process.platform === "win32" ? "cmd.exe" : "/bin/bash";
|
|
68
|
-
const shellArgs = process.platform === "win32"
|
|
69
|
-
? ["/c", opts.command]
|
|
70
|
-
: ["-c", opts.command];
|
|
71
|
-
const child = childProcess.spawn(shell, shellArgs, {
|
|
72
|
-
cwd: opts.cwd,
|
|
73
|
-
env: { ...process.env, ...opts.env },
|
|
74
|
-
shell: false,
|
|
75
|
-
windowsHide: true,
|
|
76
|
-
stdio: ["ignore", "pipe", "pipe"],
|
|
77
|
-
});
|
|
78
|
-
const tracked = {
|
|
79
|
-
backgroundTaskId,
|
|
80
|
-
pid: child.pid ?? -1,
|
|
81
|
-
command: opts.command,
|
|
82
|
-
description: opts.description,
|
|
83
|
-
startedAt: new Date(startMs).toISOString(),
|
|
84
|
-
startMs,
|
|
85
|
-
status: "running",
|
|
86
|
-
exitCode: null,
|
|
87
|
-
stdoutChunks: [],
|
|
88
|
-
stderrChunks: [],
|
|
89
|
-
durationMs: null,
|
|
90
|
-
child,
|
|
91
|
-
onComplete: opts.onComplete,
|
|
92
|
-
};
|
|
93
|
-
child.stdout?.on("data", (chunk) => {
|
|
94
|
-
tracked.stdoutChunks.push(chunk);
|
|
95
|
-
});
|
|
96
|
-
child.stderr?.on("data", (chunk) => {
|
|
97
|
-
tracked.stderrChunks.push(chunk);
|
|
98
|
-
});
|
|
99
|
-
child.on("close", (code) => {
|
|
100
|
-
if (tracked.status === "running") {
|
|
101
|
-
tracked.status = code === 0 ? "completed" : "exited";
|
|
102
|
-
}
|
|
103
|
-
tracked.exitCode = code ?? 1;
|
|
104
|
-
tracked.durationMs = Date.now() - tracked.startMs;
|
|
105
|
-
if (tracked.onComplete) {
|
|
106
|
-
try {
|
|
107
|
-
tracked.onComplete({
|
|
108
|
-
backgroundTaskId: tracked.backgroundTaskId,
|
|
109
|
-
pid: tracked.pid,
|
|
110
|
-
command: tracked.command,
|
|
111
|
-
description: tracked.description,
|
|
112
|
-
status: tracked.status,
|
|
113
|
-
exitCode: tracked.exitCode,
|
|
114
|
-
stdout: Buffer.concat(tracked.stdoutChunks).toString("utf8"),
|
|
115
|
-
stderr: Buffer.concat(tracked.stderrChunks).toString("utf8"),
|
|
116
|
-
durationMs: tracked.durationMs,
|
|
117
|
-
});
|
|
118
|
-
}
|
|
119
|
-
catch {
|
|
120
|
-
// Fire-and-forget — callback errors must not crash.
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
});
|
|
124
|
-
child.on("error", () => {
|
|
125
|
-
if (tracked.status === "running") {
|
|
126
|
-
tracked.status = "exited";
|
|
127
|
-
}
|
|
128
|
-
tracked.exitCode = 1;
|
|
129
|
-
tracked.durationMs = Date.now() - tracked.startMs;
|
|
130
|
-
});
|
|
131
|
-
this.processes.set(backgroundTaskId, tracked);
|
|
132
|
-
return this.snapshot(tracked);
|
|
133
|
-
}
|
|
134
|
-
/** Get a snapshot of a tracked process by ID, or undefined. */
|
|
135
|
-
get(backgroundTaskId) {
|
|
136
|
-
const tracked = this.processes.get(backgroundTaskId);
|
|
137
|
-
if (!tracked)
|
|
138
|
-
return undefined;
|
|
139
|
-
return this.snapshot(tracked);
|
|
140
|
-
}
|
|
141
|
-
/** List snapshots of all tracked processes. */
|
|
142
|
-
list() {
|
|
143
|
-
return [...this.processes.values()].map((t) => this.snapshot(t));
|
|
144
|
-
}
|
|
145
|
-
/** Cancel (SIGTERM) a running process. Returns true if found and killed. */
|
|
146
|
-
cancel(backgroundTaskId) {
|
|
147
|
-
const tracked = this.processes.get(backgroundTaskId);
|
|
148
|
-
if (!tracked)
|
|
149
|
-
return false;
|
|
150
|
-
if (tracked.status !== "running")
|
|
151
|
-
return true;
|
|
152
|
-
tracked.status = "cancelled";
|
|
153
|
-
tracked.durationMs = Date.now() - tracked.startMs;
|
|
154
|
-
try {
|
|
155
|
-
tracked.child.kill("SIGTERM");
|
|
156
|
-
}
|
|
157
|
-
catch {
|
|
158
|
-
// Already dead — fine.
|
|
159
|
-
}
|
|
160
|
-
return true;
|
|
161
|
-
}
|
|
162
|
-
/** Kill all running processes. */
|
|
163
|
-
killAll() {
|
|
164
|
-
for (const tracked of this.processes.values()) {
|
|
165
|
-
if (tracked.status === "running") {
|
|
166
|
-
tracked.status = "killed";
|
|
167
|
-
tracked.durationMs = Date.now() - tracked.startMs;
|
|
168
|
-
try {
|
|
169
|
-
tracked.child.kill("SIGTERM");
|
|
170
|
-
}
|
|
171
|
-
catch {
|
|
172
|
-
// Already dead.
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
/** Kill all processes and clear tracking state. */
|
|
178
|
-
dispose() {
|
|
179
|
-
this.killAll();
|
|
180
|
-
this.processes.clear();
|
|
181
|
-
}
|
|
182
|
-
// -------------------------------------------------------------------------
|
|
183
|
-
// Internals
|
|
184
|
-
// -------------------------------------------------------------------------
|
|
185
|
-
snapshot(t) {
|
|
186
|
-
return {
|
|
187
|
-
backgroundTaskId: t.backgroundTaskId,
|
|
188
|
-
pid: t.pid,
|
|
189
|
-
command: t.command,
|
|
190
|
-
description: t.description,
|
|
191
|
-
startedAt: t.startedAt,
|
|
192
|
-
status: t.status,
|
|
193
|
-
exitCode: t.exitCode,
|
|
194
|
-
stdout: Buffer.concat(t.stdoutChunks).toString("utf8"),
|
|
195
|
-
stderr: Buffer.concat(t.stderrChunks).toString("utf8"),
|
|
196
|
-
durationMs: t.durationMs,
|
|
197
|
-
};
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
exports.BackgroundProcessRegistry = BackgroundProcessRegistry;
|
|
4
|
+
/**
|
|
5
|
+
* Backwards-compatibility shim -- the canonical implementation now lives in
|
|
6
|
+
* `@a5c-ai/agent-runtime`. This re-export keeps internal agent-core consumers
|
|
7
|
+
* (and any external code that deep-imported this path) working without changes.
|
|
8
|
+
*/
|
|
9
|
+
var agent_runtime_1 = require("@a5c-ai/agent-runtime");
|
|
10
|
+
Object.defineProperty(exports, "BackgroundProcessRegistry", { enumerable: true, get: function () { return agent_runtime_1.BackgroundProcessRegistry; } });
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export type { CompactionStrategyKind, PriorityCompactionStrategy, SlidingCompactionStrategy, SummaryCompactionStrategy, CompactionStrategy, ContextEntry, ContextManagerConfig, ContextManager, } from "./types";
|
|
2
|
+
export { ContextManagerImpl, type ContextManagerImplOptions, } from "./manager";
|
|
3
|
+
export { estimateTokens, estimateEntryTokens } from "./token-estimator";
|
|
4
|
+
export { applyPriorityCompaction, applySlidingCompaction, applySummaryCompaction, type PriorityCompactionResult, type SlidingCompactionResult, type SummaryCompactionResult, type SummarizeFn, } from "./strategies";
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/context/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,sBAAsB,EACtB,0BAA0B,EAC1B,yBAAyB,EACzB,yBAAyB,EACzB,kBAAkB,EAClB,YAAY,EACZ,oBAAoB,EACpB,cAAc,GACf,MAAM,SAAS,CAAC;AAEjB,OAAO,EACL,kBAAkB,EAClB,KAAK,yBAAyB,GAC/B,MAAM,WAAW,CAAC;AAEnB,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAExE,OAAO,EACL,uBAAuB,EACvB,sBAAsB,EACtB,sBAAsB,EACtB,KAAK,wBAAwB,EAC7B,KAAK,uBAAuB,EAC5B,KAAK,uBAAuB,EAC5B,KAAK,WAAW,GACjB,MAAM,cAAc,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.applySummaryCompaction = exports.applySlidingCompaction = exports.applyPriorityCompaction = exports.estimateEntryTokens = exports.estimateTokens = exports.ContextManagerImpl = void 0;
|
|
4
|
+
var manager_1 = require("./manager");
|
|
5
|
+
Object.defineProperty(exports, "ContextManagerImpl", { enumerable: true, get: function () { return manager_1.ContextManagerImpl; } });
|
|
6
|
+
var token_estimator_1 = require("./token-estimator");
|
|
7
|
+
Object.defineProperty(exports, "estimateTokens", { enumerable: true, get: function () { return token_estimator_1.estimateTokens; } });
|
|
8
|
+
Object.defineProperty(exports, "estimateEntryTokens", { enumerable: true, get: function () { return token_estimator_1.estimateEntryTokens; } });
|
|
9
|
+
var strategies_1 = require("./strategies");
|
|
10
|
+
Object.defineProperty(exports, "applyPriorityCompaction", { enumerable: true, get: function () { return strategies_1.applyPriorityCompaction; } });
|
|
11
|
+
Object.defineProperty(exports, "applySlidingCompaction", { enumerable: true, get: function () { return strategies_1.applySlidingCompaction; } });
|
|
12
|
+
Object.defineProperty(exports, "applySummaryCompaction", { enumerable: true, get: function () { return strategies_1.applySummaryCompaction; } });
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ContextManagerImpl — concrete implementation of the {@link ContextManager}
|
|
3
|
+
* interface for L4 Agent-Core.
|
|
4
|
+
*
|
|
5
|
+
* Maintains an ordered list of {@link ContextEntry} items and applies
|
|
6
|
+
* compaction strategies when the token budget is exceeded.
|
|
7
|
+
*/
|
|
8
|
+
import type { ContextEntry, ContextManager, ContextManagerConfig } from "./types";
|
|
9
|
+
import { type SummarizeFn } from "./strategies/summary";
|
|
10
|
+
/**
|
|
11
|
+
* Options for constructing a {@link ContextManagerImpl}.
|
|
12
|
+
*/
|
|
13
|
+
export interface ContextManagerImplOptions {
|
|
14
|
+
/** Base configuration. */
|
|
15
|
+
readonly config: ContextManagerConfig;
|
|
16
|
+
/**
|
|
17
|
+
* Summarizer function used by the `summary` compaction strategy.
|
|
18
|
+
* Required only when the configured strategy is `summary`.
|
|
19
|
+
* Defaults to a simple concatenation if not provided.
|
|
20
|
+
*/
|
|
21
|
+
readonly summarizeFn?: SummarizeFn;
|
|
22
|
+
}
|
|
23
|
+
export declare class ContextManagerImpl implements ContextManager {
|
|
24
|
+
private entries;
|
|
25
|
+
private dynamicSegments;
|
|
26
|
+
private readonly config;
|
|
27
|
+
private readonly compactionThreshold;
|
|
28
|
+
private readonly preserveSystem;
|
|
29
|
+
private readonly summarizeFn;
|
|
30
|
+
constructor(options: ContextManagerImplOptions);
|
|
31
|
+
inject(entries: ContextEntry | readonly ContextEntry[]): Promise<void>;
|
|
32
|
+
compact(): Promise<readonly ContextEntry[]>;
|
|
33
|
+
summarize(entries: readonly ContextEntry[]): Promise<ContextEntry>;
|
|
34
|
+
getTokenCount(): number;
|
|
35
|
+
getEntries(): readonly ContextEntry[];
|
|
36
|
+
setDynamicSystemPrompt(segments: string | readonly string[]): void;
|
|
37
|
+
/**
|
|
38
|
+
* Return the current dynamic system prompt segments.
|
|
39
|
+
*/
|
|
40
|
+
getDynamicSegments(): readonly string[];
|
|
41
|
+
private applyStrategy;
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/context/manager.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAEV,YAAY,EACZ,cAAc,EACd,oBAAoB,EACrB,MAAM,SAAS,CAAC;AAIjB,OAAO,EAA0B,KAAK,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAEhF;;GAEG;AACH,MAAM,WAAW,yBAAyB;IACxC,0BAA0B;IAC1B,QAAQ,CAAC,MAAM,EAAE,oBAAoB,CAAC;IACtC;;;;OAIG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,WAAW,CAAC;CACpC;AASD,qBAAa,kBAAmB,YAAW,cAAc;IACvD,OAAO,CAAC,OAAO,CAAsB;IACrC,OAAO,CAAC,eAAe,CAAgB;IACvC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAuB;IAC9C,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAS;IAC7C,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAU;IACzC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAc;gBAE9B,OAAO,EAAE,yBAAyB;IAaxC,MAAM,CACV,OAAO,EAAE,YAAY,GAAG,SAAS,YAAY,EAAE,GAC9C,OAAO,CAAC,IAAI,CAAC;IAmBV,OAAO,IAAI,OAAO,CAAC,SAAS,YAAY,EAAE,CAAC;IAI3C,SAAS,CAAC,OAAO,EAAE,SAAS,YAAY,EAAE,GAAG,OAAO,CAAC,YAAY,CAAC;IAYxE,aAAa,IAAI,MAAM;IAQvB,UAAU,IAAI,SAAS,YAAY,EAAE;IAIrC,sBAAsB,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,GAAG,IAAI;IAMlE;;OAEG;IACH,kBAAkB,IAAI,SAAS,MAAM,EAAE;IAQvC,OAAO,CAAC,aAAa;CAqCtB"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* ContextManagerImpl — concrete implementation of the {@link ContextManager}
|
|
4
|
+
* interface for L4 Agent-Core.
|
|
5
|
+
*
|
|
6
|
+
* Maintains an ordered list of {@link ContextEntry} items and applies
|
|
7
|
+
* compaction strategies when the token budget is exceeded.
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.ContextManagerImpl = void 0;
|
|
11
|
+
const token_estimator_1 = require("./token-estimator");
|
|
12
|
+
const priority_1 = require("./strategies/priority");
|
|
13
|
+
const sliding_1 = require("./strategies/sliding");
|
|
14
|
+
const summary_1 = require("./strategies/summary");
|
|
15
|
+
/**
|
|
16
|
+
* Default summarizer: concatenates entry contents separated by newlines.
|
|
17
|
+
*/
|
|
18
|
+
function defaultSummarizeFn(entries) {
|
|
19
|
+
return entries.map((e) => `[${e.role}] ${e.content}`).join("\n");
|
|
20
|
+
}
|
|
21
|
+
class ContextManagerImpl {
|
|
22
|
+
entries = [];
|
|
23
|
+
dynamicSegments = [];
|
|
24
|
+
config;
|
|
25
|
+
compactionThreshold;
|
|
26
|
+
preserveSystem;
|
|
27
|
+
summarizeFn;
|
|
28
|
+
constructor(options) {
|
|
29
|
+
this.config = options.config;
|
|
30
|
+
this.compactionThreshold =
|
|
31
|
+
options.config.compactionThreshold ??
|
|
32
|
+
Math.floor(options.config.maxTokens * 0.9);
|
|
33
|
+
this.preserveSystem = options.config.preserveSystemPrompt ?? true;
|
|
34
|
+
this.summarizeFn = options.summarizeFn ?? defaultSummarizeFn;
|
|
35
|
+
}
|
|
36
|
+
// -----------------------------------------------------------------------
|
|
37
|
+
// ContextManager interface
|
|
38
|
+
// -----------------------------------------------------------------------
|
|
39
|
+
async inject(entries) {
|
|
40
|
+
const toAdd = Array.isArray(entries)
|
|
41
|
+
? entries
|
|
42
|
+
: [entries];
|
|
43
|
+
for (const entry of toAdd) {
|
|
44
|
+
this.entries.push({
|
|
45
|
+
...entry,
|
|
46
|
+
tokenCount: entry.tokenCount ?? (0, token_estimator_1.estimateEntryTokens)(entry),
|
|
47
|
+
timestamp: entry.timestamp ?? new Date(),
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
// Auto-compact when threshold is exceeded.
|
|
51
|
+
if (this.getTokenCount() > this.compactionThreshold) {
|
|
52
|
+
await this.compact();
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
async compact() {
|
|
56
|
+
return this.applyStrategy(this.config.strategy);
|
|
57
|
+
}
|
|
58
|
+
async summarize(entries) {
|
|
59
|
+
const summaryText = this.summarizeFn(entries);
|
|
60
|
+
return {
|
|
61
|
+
id: `summary-${Date.now()}`,
|
|
62
|
+
role: "summary",
|
|
63
|
+
content: summaryText,
|
|
64
|
+
priority: 0.8,
|
|
65
|
+
tokenCount: (0, token_estimator_1.estimateTokens)(summaryText),
|
|
66
|
+
timestamp: new Date(),
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
getTokenCount() {
|
|
70
|
+
let total = 0;
|
|
71
|
+
for (const entry of this.entries) {
|
|
72
|
+
total += (0, token_estimator_1.estimateEntryTokens)(entry);
|
|
73
|
+
}
|
|
74
|
+
return total;
|
|
75
|
+
}
|
|
76
|
+
getEntries() {
|
|
77
|
+
return [...this.entries];
|
|
78
|
+
}
|
|
79
|
+
setDynamicSystemPrompt(segments) {
|
|
80
|
+
this.dynamicSegments = Array.isArray(segments)
|
|
81
|
+
? [...segments]
|
|
82
|
+
: [segments];
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Return the current dynamic system prompt segments.
|
|
86
|
+
*/
|
|
87
|
+
getDynamicSegments() {
|
|
88
|
+
return [...this.dynamicSegments];
|
|
89
|
+
}
|
|
90
|
+
// -----------------------------------------------------------------------
|
|
91
|
+
// Internal
|
|
92
|
+
// -----------------------------------------------------------------------
|
|
93
|
+
applyStrategy(strategy) {
|
|
94
|
+
switch (strategy.kind) {
|
|
95
|
+
case "priority": {
|
|
96
|
+
const result = (0, priority_1.applyPriorityCompaction)(this.entries, this.config.maxTokens, strategy, this.preserveSystem);
|
|
97
|
+
this.entries = [...result.retained];
|
|
98
|
+
return result.evicted;
|
|
99
|
+
}
|
|
100
|
+
case "sliding": {
|
|
101
|
+
const result = (0, sliding_1.applySlidingCompaction)(this.entries, this.config.maxTokens, strategy, this.preserveSystem);
|
|
102
|
+
this.entries = [...result.retained];
|
|
103
|
+
return result.evicted;
|
|
104
|
+
}
|
|
105
|
+
case "summary": {
|
|
106
|
+
const result = (0, summary_1.applySummaryCompaction)(this.entries, this.config.maxTokens, strategy, this.summarizeFn, this.preserveSystem);
|
|
107
|
+
this.entries = [...result.retained];
|
|
108
|
+
return result.evicted;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
exports.ContextManagerImpl = ContextManagerImpl;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { applyPriorityCompaction, type PriorityCompactionResult, } from "./priority";
|
|
2
|
+
export { applySlidingCompaction, type SlidingCompactionResult, } from "./sliding";
|
|
3
|
+
export { applySummaryCompaction, type SummaryCompactionResult, type SummarizeFn, } from "./summary";
|
|
4
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/context/strategies/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,uBAAuB,EACvB,KAAK,wBAAwB,GAC9B,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,sBAAsB,EACtB,KAAK,uBAAuB,GAC7B,MAAM,WAAW,CAAC;AACnB,OAAO,EACL,sBAAsB,EACtB,KAAK,uBAAuB,EAC5B,KAAK,WAAW,GACjB,MAAM,WAAW,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.applySummaryCompaction = exports.applySlidingCompaction = exports.applyPriorityCompaction = void 0;
|
|
4
|
+
var priority_1 = require("./priority");
|
|
5
|
+
Object.defineProperty(exports, "applyPriorityCompaction", { enumerable: true, get: function () { return priority_1.applyPriorityCompaction; } });
|
|
6
|
+
var sliding_1 = require("./sliding");
|
|
7
|
+
Object.defineProperty(exports, "applySlidingCompaction", { enumerable: true, get: function () { return sliding_1.applySlidingCompaction; } });
|
|
8
|
+
var summary_1 = require("./summary");
|
|
9
|
+
Object.defineProperty(exports, "applySummaryCompaction", { enumerable: true, get: function () { return summary_1.applySummaryCompaction; } });
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Priority-based compaction strategy.
|
|
3
|
+
*
|
|
4
|
+
* Sorts entries by priority (lowest first) and drops them one-by-one
|
|
5
|
+
* until the total token count falls within the budget.
|
|
6
|
+
*/
|
|
7
|
+
import type { ContextEntry, PriorityCompactionStrategy } from "../types";
|
|
8
|
+
/**
|
|
9
|
+
* Result of a priority compaction pass.
|
|
10
|
+
*/
|
|
11
|
+
export interface PriorityCompactionResult {
|
|
12
|
+
/** Entries that survived compaction (conversation order preserved). */
|
|
13
|
+
readonly retained: readonly ContextEntry[];
|
|
14
|
+
/** Entries that were evicted. */
|
|
15
|
+
readonly evicted: readonly ContextEntry[];
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Apply priority compaction to the given entries.
|
|
19
|
+
*
|
|
20
|
+
* System-prompt entries are optionally preserved regardless of priority.
|
|
21
|
+
*
|
|
22
|
+
* @param entries - Current context entries in conversation order.
|
|
23
|
+
* @param maxTokens - Token budget to compact into.
|
|
24
|
+
* @param strategy - The priority compaction configuration.
|
|
25
|
+
* @param preserveSystem - When `true`, system entries are never evicted.
|
|
26
|
+
* @returns The retained and evicted entry sets.
|
|
27
|
+
*/
|
|
28
|
+
export declare function applyPriorityCompaction(entries: readonly ContextEntry[], maxTokens: number, strategy: PriorityCompactionStrategy, preserveSystem?: boolean): PriorityCompactionResult;
|
|
29
|
+
//# sourceMappingURL=priority.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"priority.d.ts","sourceRoot":"","sources":["../../../src/context/strategies/priority.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EACV,YAAY,EACZ,0BAA0B,EAC3B,MAAM,UAAU,CAAC;AAGlB;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC,uEAAuE;IACvE,QAAQ,CAAC,QAAQ,EAAE,SAAS,YAAY,EAAE,CAAC;IAC3C,iCAAiC;IACjC,QAAQ,CAAC,OAAO,EAAE,SAAS,YAAY,EAAE,CAAC;CAC3C;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,SAAS,YAAY,EAAE,EAChC,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,0BAA0B,EACpC,cAAc,UAAO,GACpB,wBAAwB,CA4C1B"}
|