@agentproto/agent-runtime 0.1.0-alpha.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/ARCHITECTURE.md +301 -0
- package/LICENSE +21 -0
- package/README.md +91 -0
- package/dist/adapters/dispatcher-mention.d.ts +38 -0
- package/dist/adapters/dispatcher-mention.mjs +45 -0
- package/dist/adapters/dispatcher-mention.mjs.map +1 -0
- package/dist/adapters/participant-agent-cli.d.ts +32 -0
- package/dist/adapters/participant-agent-cli.mjs +72 -0
- package/dist/adapters/participant-agent-cli.mjs.map +1 -0
- package/dist/adapters/state-fs.d.ts +25 -0
- package/dist/adapters/state-fs.mjs +54 -0
- package/dist/adapters/state-fs.mjs.map +1 -0
- package/dist/adapters/substrate-file.d.ts +39 -0
- package/dist/adapters/substrate-file.mjs +113 -0
- package/dist/adapters/substrate-file.mjs.map +1 -0
- package/dist/adapters/telemetry.d.ts +39 -0
- package/dist/adapters/telemetry.mjs +76 -0
- package/dist/adapters/telemetry.mjs.map +1 -0
- package/dist/index.d.ts +36 -0
- package/dist/index.mjs +225 -0
- package/dist/index.mjs.map +1 -0
- package/dist/manifest.d.ts +56 -0
- package/dist/manifest.mjs +61 -0
- package/dist/manifest.mjs.map +1 -0
- package/dist/ports.d.ts +165 -0
- package/dist/ports.mjs +3 -0
- package/dist/ports.mjs.map +1 -0
- package/dist/util/mention-parser.d.mts +8 -0
- package/dist/util/mention-parser.mjs +33 -0
- package/package.json +108 -0
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* MultiAgentRuntime manifest schema + loader.
|
|
5
|
+
*
|
|
6
|
+
* The manifest is markdown with YAML frontmatter (matching @agentproto's
|
|
7
|
+
* doctype convention used by ROLE.md, OPERATOR.md, etc.). The frontmatter
|
|
8
|
+
* is the structured contract; the markdown body is human-readable
|
|
9
|
+
* documentation of what the swarm does.
|
|
10
|
+
*
|
|
11
|
+
* Loader is filesystem-bound but parsing is pure — the schema can be used
|
|
12
|
+
* by tests with inline strings via `parseManifest()`.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
declare const MULTI_AGENT_RUNTIME_SCHEMA = "agentruntimes/v1";
|
|
16
|
+
declare const MULTI_AGENT_RUNTIME_KIND = "MultiAgentRuntime";
|
|
17
|
+
declare const MultiAgentRuntimeManifestSchema: z.ZodObject<{
|
|
18
|
+
schema: z.ZodLiteral<"agentruntimes/v1">;
|
|
19
|
+
kind: z.ZodLiteral<"MultiAgentRuntime">;
|
|
20
|
+
id: z.ZodString;
|
|
21
|
+
participants: z.ZodArray<z.ZodObject<{
|
|
22
|
+
id: z.ZodString;
|
|
23
|
+
executor: z.ZodString;
|
|
24
|
+
displayName: z.ZodOptional<z.ZodString>;
|
|
25
|
+
role: z.ZodOptional<z.ZodString>;
|
|
26
|
+
meta: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
27
|
+
}, z.core.$loose>>;
|
|
28
|
+
substrate: z.ZodObject<{
|
|
29
|
+
kind: z.ZodString;
|
|
30
|
+
}, z.core.$loose>;
|
|
31
|
+
dispatcher: z.ZodObject<{
|
|
32
|
+
kind: z.ZodString;
|
|
33
|
+
}, z.core.$loose>;
|
|
34
|
+
state: z.ZodOptional<z.ZodObject<{
|
|
35
|
+
kind: z.ZodString;
|
|
36
|
+
}, z.core.$loose>>;
|
|
37
|
+
lifecycle: z.ZodOptional<z.ZodObject<{
|
|
38
|
+
onTurnEnd: z.ZodOptional<z.ZodBoolean>;
|
|
39
|
+
onMention: z.ZodOptional<z.ZodBoolean>;
|
|
40
|
+
onIdle: z.ZodOptional<z.ZodBoolean>;
|
|
41
|
+
}, z.core.$strip>>;
|
|
42
|
+
}, z.core.$loose>;
|
|
43
|
+
type MultiAgentRuntimeManifest = z.infer<typeof MultiAgentRuntimeManifestSchema>;
|
|
44
|
+
type LoadedManifest = {
|
|
45
|
+
readonly manifest: MultiAgentRuntimeManifest;
|
|
46
|
+
readonly body: string;
|
|
47
|
+
readonly path: string;
|
|
48
|
+
/** Absolute directory of the manifest file — adapter configs that reference paths resolve relative to this. */
|
|
49
|
+
readonly baseDir: string;
|
|
50
|
+
};
|
|
51
|
+
declare function parseManifest(source: string): MultiAgentRuntimeManifest;
|
|
52
|
+
declare function loadManifest(path: string): Promise<LoadedManifest>;
|
|
53
|
+
/** Resolve a path string from a manifest field, relative to the manifest's directory. */
|
|
54
|
+
declare function resolveManifestPath(loaded: LoadedManifest, value: string): string;
|
|
55
|
+
|
|
56
|
+
export { type LoadedManifest, MULTI_AGENT_RUNTIME_KIND, MULTI_AGENT_RUNTIME_SCHEMA, type MultiAgentRuntimeManifest, MultiAgentRuntimeManifestSchema, loadManifest, parseManifest, resolveManifestPath };
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { readFile } from 'fs/promises';
|
|
2
|
+
import { resolve, dirname } from 'path';
|
|
3
|
+
import matter from 'gray-matter';
|
|
4
|
+
import { z } from 'zod';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @agentproto/agent-runtime v0.1.0-alpha
|
|
8
|
+
* MultiAgentRuntime kernel — swappable ports + reference adapters
|
|
9
|
+
* (file substrate, mention dispatcher, fs state, agent-cli participant).
|
|
10
|
+
* Transport-specific adapters ship in separate packages.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
var MULTI_AGENT_RUNTIME_SCHEMA = "agentruntimes/v1";
|
|
14
|
+
var MULTI_AGENT_RUNTIME_KIND = "MultiAgentRuntime";
|
|
15
|
+
var AdapterConfigSchema = z.object({
|
|
16
|
+
kind: z.string().min(1)
|
|
17
|
+
}).loose();
|
|
18
|
+
var ParticipantManifestSchema = z.object({
|
|
19
|
+
id: z.string().min(1),
|
|
20
|
+
executor: z.string().min(1),
|
|
21
|
+
displayName: z.string().min(1).optional(),
|
|
22
|
+
role: z.string().optional(),
|
|
23
|
+
meta: z.record(z.string(), z.unknown()).optional()
|
|
24
|
+
}).loose();
|
|
25
|
+
var MultiAgentRuntimeManifestSchema = z.object({
|
|
26
|
+
schema: z.literal(MULTI_AGENT_RUNTIME_SCHEMA),
|
|
27
|
+
kind: z.literal(MULTI_AGENT_RUNTIME_KIND),
|
|
28
|
+
id: z.string().min(1),
|
|
29
|
+
participants: z.array(ParticipantManifestSchema).min(1),
|
|
30
|
+
substrate: AdapterConfigSchema,
|
|
31
|
+
dispatcher: AdapterConfigSchema,
|
|
32
|
+
state: AdapterConfigSchema.optional(),
|
|
33
|
+
lifecycle: z.object({
|
|
34
|
+
onTurnEnd: z.boolean().optional(),
|
|
35
|
+
onMention: z.boolean().optional(),
|
|
36
|
+
onIdle: z.boolean().optional()
|
|
37
|
+
}).optional()
|
|
38
|
+
}).loose();
|
|
39
|
+
function parseManifest(source) {
|
|
40
|
+
const parsed = matter(source);
|
|
41
|
+
return MultiAgentRuntimeManifestSchema.parse(parsed.data);
|
|
42
|
+
}
|
|
43
|
+
async function loadManifest(path) {
|
|
44
|
+
const abs = resolve(path);
|
|
45
|
+
const raw = await readFile(abs, "utf8");
|
|
46
|
+
const parsed = matter(raw);
|
|
47
|
+
const manifest = MultiAgentRuntimeManifestSchema.parse(parsed.data);
|
|
48
|
+
return {
|
|
49
|
+
manifest,
|
|
50
|
+
body: parsed.content,
|
|
51
|
+
path: abs,
|
|
52
|
+
baseDir: dirname(abs)
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
function resolveManifestPath(loaded, value) {
|
|
56
|
+
return resolve(loaded.baseDir, value);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export { MULTI_AGENT_RUNTIME_KIND, MULTI_AGENT_RUNTIME_SCHEMA, MultiAgentRuntimeManifestSchema, loadManifest, parseManifest, resolveManifestPath };
|
|
60
|
+
//# sourceMappingURL=manifest.mjs.map
|
|
61
|
+
//# sourceMappingURL=manifest.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/manifest.ts"],"names":["resolvePath"],"mappings":";;;;;;;;;;;;AAiBO,IAAM,0BAAA,GAA6B;AACnC,IAAM,wBAAA,GAA2B;AAExC,IAAM,mBAAA,GAAsB,EACzB,MAAA,CAAO;AAAA,EACN,IAAA,EAAM,CAAA,CAAE,MAAA,EAAO,CAAE,IAAI,CAAC;AACxB,CAAC,EACA,KAAA,EAAM;AAET,IAAM,yBAAA,GAA4B,EAC/B,MAAA,CAAO;AAAA,EACN,EAAA,EAAI,CAAA,CAAE,MAAA,EAAO,CAAE,IAAI,CAAC,CAAA;AAAA,EACpB,QAAA,EAAU,CAAA,CAAE,MAAA,EAAO,CAAE,IAAI,CAAC,CAAA;AAAA,EAC1B,aAAa,CAAA,CAAE,MAAA,GAAS,GAAA,CAAI,CAAC,EAAE,QAAA,EAAS;AAAA,EACxC,IAAA,EAAM,CAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS;AAAA,EAC1B,IAAA,EAAM,CAAA,CAAE,MAAA,CAAO,CAAA,CAAE,MAAA,IAAU,CAAA,CAAE,OAAA,EAAS,CAAA,CAAE,QAAA;AAC1C,CAAC,EACA,KAAA,EAAM;AAEF,IAAM,+BAAA,GAAkC,EAC5C,MAAA,CAAO;AAAA,EACN,MAAA,EAAQ,CAAA,CAAE,OAAA,CAAQ,0BAA0B,CAAA;AAAA,EAC5C,IAAA,EAAM,CAAA,CAAE,OAAA,CAAQ,wBAAwB,CAAA;AAAA,EACxC,EAAA,EAAI,CAAA,CAAE,MAAA,EAAO,CAAE,IAAI,CAAC,CAAA;AAAA,EACpB,cAAc,CAAA,CAAE,KAAA,CAAM,yBAAyB,CAAA,CAAE,IAAI,CAAC,CAAA;AAAA,EACtD,SAAA,EAAW,mBAAA;AAAA,EACX,UAAA,EAAY,mBAAA;AAAA,EACZ,KAAA,EAAO,oBAAoB,QAAA,EAAS;AAAA,EACpC,SAAA,EAAW,EACR,MAAA,CAAO;AAAA,IACN,SAAA,EAAW,CAAA,CAAE,OAAA,EAAQ,CAAE,QAAA,EAAS;AAAA,IAChC,SAAA,EAAW,CAAA,CAAE,OAAA,EAAQ,CAAE,QAAA,EAAS;AAAA,IAChC,MAAA,EAAQ,CAAA,CAAE,OAAA,EAAQ,CAAE,QAAA;AAAS,GAC9B,EACA,QAAA;AACL,CAAC,EACA,KAAA;AAcI,SAAS,cAAc,MAAA,EAA2C;AACvE,EAAA,MAAM,MAAA,GAAS,OAAO,MAAM,CAAA;AAC5B,EAAA,OAAO,+BAAA,CAAgC,KAAA,CAAM,MAAA,CAAO,IAAI,CAAA;AAC1D;AAEA,eAAsB,aAAa,IAAA,EAAuC;AACxE,EAAA,MAAM,GAAA,GAAMA,QAAY,IAAI,CAAA;AAC5B,EAAA,MAAM,GAAA,GAAM,MAAM,QAAA,CAAS,GAAA,EAAK,MAAM,CAAA;AACtC,EAAA,MAAM,MAAA,GAAS,OAAO,GAAG,CAAA;AACzB,EAAA,MAAM,QAAA,GAAW,+BAAA,CAAgC,KAAA,CAAM,MAAA,CAAO,IAAI,CAAA;AAClE,EAAA,OAAO;AAAA,IACL,QAAA;AAAA,IACA,MAAM,MAAA,CAAO,OAAA;AAAA,IACb,IAAA,EAAM,GAAA;AAAA,IACN,OAAA,EAAS,QAAQ,GAAG;AAAA,GACtB;AACF;AAGO,SAAS,mBAAA,CAAoB,QAAwB,KAAA,EAAuB;AACjF,EAAA,OAAOA,OAAA,CAAY,MAAA,CAAO,OAAA,EAAS,KAAK,CAAA;AAC1C","file":"manifest.mjs","sourcesContent":["/**\n * MultiAgentRuntime manifest schema + loader.\n *\n * The manifest is markdown with YAML frontmatter (matching @agentproto's\n * doctype convention used by ROLE.md, OPERATOR.md, etc.). The frontmatter\n * is the structured contract; the markdown body is human-readable\n * documentation of what the swarm does.\n *\n * Loader is filesystem-bound but parsing is pure — the schema can be used\n * by tests with inline strings via `parseManifest()`.\n */\n\nimport { readFile } from \"node:fs/promises\"\nimport { resolve as resolvePath, dirname } from \"node:path\"\nimport matter from \"gray-matter\"\nimport { z } from \"zod\"\n\nexport const MULTI_AGENT_RUNTIME_SCHEMA = \"agentruntimes/v1\"\nexport const MULTI_AGENT_RUNTIME_KIND = \"MultiAgentRuntime\"\n\nconst AdapterConfigSchema = z\n .object({\n kind: z.string().min(1),\n })\n .loose()\n\nconst ParticipantManifestSchema = z\n .object({\n id: z.string().min(1),\n executor: z.string().min(1),\n displayName: z.string().min(1).optional(),\n role: z.string().optional(),\n meta: z.record(z.string(), z.unknown()).optional(),\n })\n .loose()\n\nexport const MultiAgentRuntimeManifestSchema = z\n .object({\n schema: z.literal(MULTI_AGENT_RUNTIME_SCHEMA),\n kind: z.literal(MULTI_AGENT_RUNTIME_KIND),\n id: z.string().min(1),\n participants: z.array(ParticipantManifestSchema).min(1),\n substrate: AdapterConfigSchema,\n dispatcher: AdapterConfigSchema,\n state: AdapterConfigSchema.optional(),\n lifecycle: z\n .object({\n onTurnEnd: z.boolean().optional(),\n onMention: z.boolean().optional(),\n onIdle: z.boolean().optional(),\n })\n .optional(),\n })\n .loose()\n\nexport type MultiAgentRuntimeManifest = z.infer<\n typeof MultiAgentRuntimeManifestSchema\n>\n\nexport type LoadedManifest = {\n readonly manifest: MultiAgentRuntimeManifest\n readonly body: string\n readonly path: string\n /** Absolute directory of the manifest file — adapter configs that reference paths resolve relative to this. */\n readonly baseDir: string\n}\n\nexport function parseManifest(source: string): MultiAgentRuntimeManifest {\n const parsed = matter(source)\n return MultiAgentRuntimeManifestSchema.parse(parsed.data)\n}\n\nexport async function loadManifest(path: string): Promise<LoadedManifest> {\n const abs = resolvePath(path)\n const raw = await readFile(abs, \"utf8\")\n const parsed = matter(raw)\n const manifest = MultiAgentRuntimeManifestSchema.parse(parsed.data)\n return {\n manifest,\n body: parsed.content,\n path: abs,\n baseDir: dirname(abs),\n }\n}\n\n/** Resolve a path string from a manifest field, relative to the manifest's directory. */\nexport function resolveManifestPath(loaded: LoadedManifest, value: string): string {\n return resolvePath(loaded.baseDir, value)\n}\n"]}
|
package/dist/ports.d.ts
ADDED
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Port contracts for the MultiAgentRuntime kernel.
|
|
3
|
+
*
|
|
4
|
+
* A runtime composes a Substrate + Dispatcher + StateStore + Participant
|
|
5
|
+
* Executors (one per `executor` kind). Each adapter declares its `kind`;
|
|
6
|
+
* the kernel dispatches polymorphically by looking up factories in the
|
|
7
|
+
* registry, never by matching kind strings inside the kernel itself.
|
|
8
|
+
*/
|
|
9
|
+
type ParticipantId = string;
|
|
10
|
+
type TurnId = string;
|
|
11
|
+
type Turn = {
|
|
12
|
+
readonly id: TurnId;
|
|
13
|
+
readonly participantId: ParticipantId;
|
|
14
|
+
readonly content: string;
|
|
15
|
+
readonly timestamp: string;
|
|
16
|
+
readonly meta?: Readonly<Record<string, unknown>>;
|
|
17
|
+
};
|
|
18
|
+
type TurnInput = Omit<Turn, "id" | "timestamp"> & {
|
|
19
|
+
readonly timestamp?: string;
|
|
20
|
+
};
|
|
21
|
+
interface Substrate {
|
|
22
|
+
readonly kind: string;
|
|
23
|
+
/** Append a turn. Returns the materialised Turn with id + timestamp. */
|
|
24
|
+
append(turn: TurnInput): Promise<Turn>;
|
|
25
|
+
/** Snapshot. If `since` is provided, returns turns strictly newer than that TurnId, oldest first. */
|
|
26
|
+
read(since?: TurnId): Promise<readonly Turn[]>;
|
|
27
|
+
}
|
|
28
|
+
type ParticipantDescriptor = {
|
|
29
|
+
readonly id: ParticipantId;
|
|
30
|
+
readonly displayName: string;
|
|
31
|
+
/** Executor kind — keys into RuntimePorts.executors. e.g. "agent-cli". */
|
|
32
|
+
readonly executor: string;
|
|
33
|
+
readonly role?: string;
|
|
34
|
+
readonly meta?: Readonly<Record<string, unknown>>;
|
|
35
|
+
};
|
|
36
|
+
type ParticipantExecuteInput = {
|
|
37
|
+
readonly participant: ParticipantDescriptor;
|
|
38
|
+
readonly recentTurns: readonly Turn[];
|
|
39
|
+
readonly triggerTurn: Turn;
|
|
40
|
+
readonly state: Readonly<Record<string, unknown>>;
|
|
41
|
+
readonly signal?: AbortSignal;
|
|
42
|
+
};
|
|
43
|
+
type ParticipantExecuteOutput = {
|
|
44
|
+
readonly content: string;
|
|
45
|
+
readonly meta?: Readonly<Record<string, unknown>>;
|
|
46
|
+
readonly stateUpdate?: Readonly<Record<string, unknown>>;
|
|
47
|
+
};
|
|
48
|
+
interface ParticipantExecutor {
|
|
49
|
+
readonly kind: string;
|
|
50
|
+
executeTurn(input: ParticipantExecuteInput): Promise<ParticipantExecuteOutput>;
|
|
51
|
+
}
|
|
52
|
+
type DispatcherInput = {
|
|
53
|
+
readonly recentTurns: readonly Turn[];
|
|
54
|
+
readonly participants: readonly ParticipantDescriptor[];
|
|
55
|
+
};
|
|
56
|
+
interface Dispatcher {
|
|
57
|
+
readonly kind: string;
|
|
58
|
+
/**
|
|
59
|
+
* Inspect recent turns and return the participants who should speak next.
|
|
60
|
+
* Empty array = no one speaks, the runtime stays idle.
|
|
61
|
+
*/
|
|
62
|
+
selectNext(input: DispatcherInput): Promise<readonly ParticipantId[]>;
|
|
63
|
+
}
|
|
64
|
+
interface StateStore {
|
|
65
|
+
readonly kind: string;
|
|
66
|
+
read(participantId: ParticipantId): Promise<Readonly<Record<string, unknown>>>;
|
|
67
|
+
write(participantId: ParticipantId, state: Readonly<Record<string, unknown>>): Promise<void>;
|
|
68
|
+
}
|
|
69
|
+
interface Lifecycle {
|
|
70
|
+
onTurnEnd?(turn: Turn): Promise<void> | void;
|
|
71
|
+
onMention?(target: ParticipantId, byTurn: Turn): Promise<void> | void;
|
|
72
|
+
onIdle?(): Promise<void> | void;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Discriminated union of every event the kernel emits during a cycle.
|
|
76
|
+
*
|
|
77
|
+
* Every event carries `cycleId` (a per-cycle ULID-ish identifier) and
|
|
78
|
+
* `at` (ISO timestamp), so a sink can rebuild OTEL-style spans by
|
|
79
|
+
* grouping on cycleId.
|
|
80
|
+
*
|
|
81
|
+
* Sinks MUST tolerate unknown kinds — future kernel versions may add
|
|
82
|
+
* event types under the same `agentproto/telemetry/v1` schema.
|
|
83
|
+
*/
|
|
84
|
+
type TelemetryEvent = {
|
|
85
|
+
readonly kind: "cycle.started";
|
|
86
|
+
readonly cycleId: string;
|
|
87
|
+
readonly at: string;
|
|
88
|
+
readonly since?: TurnId;
|
|
89
|
+
} | {
|
|
90
|
+
readonly kind: "substrate.read";
|
|
91
|
+
readonly cycleId: string;
|
|
92
|
+
readonly at: string;
|
|
93
|
+
readonly substrateKind: string;
|
|
94
|
+
readonly turnCount: number;
|
|
95
|
+
readonly durationMs: number;
|
|
96
|
+
} | {
|
|
97
|
+
readonly kind: "dispatch.decided";
|
|
98
|
+
readonly cycleId: string;
|
|
99
|
+
readonly at: string;
|
|
100
|
+
readonly dispatcherKind: string;
|
|
101
|
+
readonly selected: readonly ParticipantId[];
|
|
102
|
+
readonly durationMs: number;
|
|
103
|
+
} | {
|
|
104
|
+
readonly kind: "participant.started";
|
|
105
|
+
readonly cycleId: string;
|
|
106
|
+
readonly at: string;
|
|
107
|
+
readonly participantId: ParticipantId;
|
|
108
|
+
readonly executorKind: string;
|
|
109
|
+
} | {
|
|
110
|
+
readonly kind: "participant.finished";
|
|
111
|
+
readonly cycleId: string;
|
|
112
|
+
readonly at: string;
|
|
113
|
+
readonly participantId: ParticipantId;
|
|
114
|
+
readonly executorKind: string;
|
|
115
|
+
readonly durationMs: number;
|
|
116
|
+
readonly contentLength: number;
|
|
117
|
+
} | {
|
|
118
|
+
readonly kind: "participant.failed";
|
|
119
|
+
readonly cycleId: string;
|
|
120
|
+
readonly at: string;
|
|
121
|
+
readonly participantId: ParticipantId;
|
|
122
|
+
readonly executorKind: string;
|
|
123
|
+
readonly error: string;
|
|
124
|
+
} | {
|
|
125
|
+
readonly kind: "substrate.appended";
|
|
126
|
+
readonly cycleId: string;
|
|
127
|
+
readonly at: string;
|
|
128
|
+
readonly turnId: TurnId;
|
|
129
|
+
readonly participantId: ParticipantId;
|
|
130
|
+
} | {
|
|
131
|
+
readonly kind: "state.written";
|
|
132
|
+
readonly cycleId: string;
|
|
133
|
+
readonly at: string;
|
|
134
|
+
readonly participantId: ParticipantId;
|
|
135
|
+
} | {
|
|
136
|
+
readonly kind: "cycle.idle";
|
|
137
|
+
readonly cycleId: string;
|
|
138
|
+
readonly at: string;
|
|
139
|
+
} | {
|
|
140
|
+
readonly kind: "cycle.finished";
|
|
141
|
+
readonly cycleId: string;
|
|
142
|
+
readonly at: string;
|
|
143
|
+
readonly outcome: "executed" | "idle";
|
|
144
|
+
readonly turnsAppended: number;
|
|
145
|
+
readonly durationMs: number;
|
|
146
|
+
};
|
|
147
|
+
interface Telemetry {
|
|
148
|
+
emit(event: TelemetryEvent): void;
|
|
149
|
+
}
|
|
150
|
+
type RuntimePorts = {
|
|
151
|
+
readonly substrate: Substrate;
|
|
152
|
+
readonly dispatcher: Dispatcher;
|
|
153
|
+
readonly state: StateStore;
|
|
154
|
+
readonly lifecycle?: Lifecycle;
|
|
155
|
+
/**
|
|
156
|
+
* Optional structured-event sink. Wire to log lines, an OTEL exporter,
|
|
157
|
+
* an in-memory array (tests), or anything else. When omitted, the
|
|
158
|
+
* kernel skips emission entirely — zero overhead.
|
|
159
|
+
*/
|
|
160
|
+
readonly telemetry?: Telemetry;
|
|
161
|
+
readonly participants: readonly ParticipantDescriptor[];
|
|
162
|
+
readonly executors: ReadonlyMap<string, ParticipantExecutor>;
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
export type { Dispatcher, DispatcherInput, Lifecycle, ParticipantDescriptor, ParticipantExecuteInput, ParticipantExecuteOutput, ParticipantExecutor, ParticipantId, RuntimePorts, StateStore, Substrate, Telemetry, TelemetryEvent, Turn, TurnId, TurnInput };
|
package/dist/ports.mjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"ports.mjs"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type sidecar for `mention-parser.mjs`. The implementation file is
|
|
3
|
+
* vanilla JavaScript so runtime profiles can stamp its source into
|
|
4
|
+
* Claude Code hooks at build time; this `.d.mts` keeps the TS-side
|
|
5
|
+
* type contract crisp.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
export function textContainsMention(text: string, name: string): boolean
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Canonical @-mention parser.
|
|
3
|
+
*
|
|
4
|
+
* Lives as raw JavaScript (no types) because it's consumed in two
|
|
5
|
+
* places that don't share a build:
|
|
6
|
+
*
|
|
7
|
+
* 1. The kernel imports `textContainsMention` from this file as a
|
|
8
|
+
* normal ESM module (the dispatcher in `adapters/dispatcher-mention.ts`).
|
|
9
|
+
*
|
|
10
|
+
* 2. Runtime profiles inline this file's source into Claude Code
|
|
11
|
+
* hooks at profile-build time, because `.claude/` has no
|
|
12
|
+
* module-resolution at hook-execution time. The build script
|
|
13
|
+
* reads this file as text and stamps it into the hook template.
|
|
14
|
+
*
|
|
15
|
+
* Two cases:
|
|
16
|
+
* 1. Literal `@<name>` substring (case-sensitive, full name).
|
|
17
|
+
* 2. For multi-word names, also `@<firstName>` with non-word
|
|
18
|
+
* boundary (case-insensitive).
|
|
19
|
+
*
|
|
20
|
+
* Edit here only — both consumers stay in sync via build pipelines.
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
/** @param {string} text @param {string} name @returns {boolean} */
|
|
24
|
+
export function textContainsMention(text, name) {
|
|
25
|
+
if (text.includes(`@${name}`)) return true
|
|
26
|
+
if (name.includes(" ")) {
|
|
27
|
+
const firstName = name.split(" ")[0]?.trim()
|
|
28
|
+
if (!firstName) return false
|
|
29
|
+
const regex = new RegExp(`@${firstName}(?!\\w)`, "i")
|
|
30
|
+
return regex.test(text)
|
|
31
|
+
}
|
|
32
|
+
return false
|
|
33
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@agentproto/agent-runtime",
|
|
3
|
+
"version": "0.1.0-alpha.0",
|
|
4
|
+
"description": "@agentproto/agent-runtime — MultiAgentRuntime kernel: swappable ports (substrate, dispatcher, participant executors, state, lifecycle, effectors) plus reference adapters (file journal substrate, mention dispatcher, fs state store, agent-cli participant). Transport-specific adapters (chat servers, MCP bridges, etc.) ship in separate packages and register through the agentproto CLI's plugin API.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"agentproto",
|
|
7
|
+
"agent-runtime",
|
|
8
|
+
"multi-agent",
|
|
9
|
+
"swarm",
|
|
10
|
+
"substrate",
|
|
11
|
+
"dispatcher"
|
|
12
|
+
],
|
|
13
|
+
"homepage": "https://agentproto.sh",
|
|
14
|
+
"repository": {
|
|
15
|
+
"type": "git",
|
|
16
|
+
"url": "https://github.com/agentproto/ts",
|
|
17
|
+
"directory": "packages/agent-runtime"
|
|
18
|
+
},
|
|
19
|
+
"bugs": {
|
|
20
|
+
"url": "https://github.com/agentproto/ts/issues"
|
|
21
|
+
},
|
|
22
|
+
"license": "MIT",
|
|
23
|
+
"type": "module",
|
|
24
|
+
"main": "dist/index.mjs",
|
|
25
|
+
"module": "dist/index.mjs",
|
|
26
|
+
"types": "dist/index.d.ts",
|
|
27
|
+
"exports": {
|
|
28
|
+
".": {
|
|
29
|
+
"types": "./dist/index.d.ts",
|
|
30
|
+
"import": "./dist/index.mjs",
|
|
31
|
+
"default": "./dist/index.mjs"
|
|
32
|
+
},
|
|
33
|
+
"./ports": {
|
|
34
|
+
"types": "./dist/ports.d.ts",
|
|
35
|
+
"import": "./dist/ports.mjs",
|
|
36
|
+
"default": "./dist/ports.mjs"
|
|
37
|
+
},
|
|
38
|
+
"./manifest": {
|
|
39
|
+
"types": "./dist/manifest.d.ts",
|
|
40
|
+
"import": "./dist/manifest.mjs",
|
|
41
|
+
"default": "./dist/manifest.mjs"
|
|
42
|
+
},
|
|
43
|
+
"./adapters/substrate-file": {
|
|
44
|
+
"types": "./dist/adapters/substrate-file.d.ts",
|
|
45
|
+
"import": "./dist/adapters/substrate-file.mjs",
|
|
46
|
+
"default": "./dist/adapters/substrate-file.mjs"
|
|
47
|
+
},
|
|
48
|
+
"./adapters/dispatcher-mention": {
|
|
49
|
+
"types": "./dist/adapters/dispatcher-mention.d.ts",
|
|
50
|
+
"import": "./dist/adapters/dispatcher-mention.mjs",
|
|
51
|
+
"default": "./dist/adapters/dispatcher-mention.mjs"
|
|
52
|
+
},
|
|
53
|
+
"./adapters/state-fs": {
|
|
54
|
+
"types": "./dist/adapters/state-fs.d.ts",
|
|
55
|
+
"import": "./dist/adapters/state-fs.mjs",
|
|
56
|
+
"default": "./dist/adapters/state-fs.mjs"
|
|
57
|
+
},
|
|
58
|
+
"./adapters/participant-agent-cli": {
|
|
59
|
+
"types": "./dist/adapters/participant-agent-cli.d.ts",
|
|
60
|
+
"import": "./dist/adapters/participant-agent-cli.mjs",
|
|
61
|
+
"default": "./dist/adapters/participant-agent-cli.mjs"
|
|
62
|
+
},
|
|
63
|
+
"./adapters/telemetry": {
|
|
64
|
+
"types": "./dist/adapters/telemetry.d.ts",
|
|
65
|
+
"import": "./dist/adapters/telemetry.mjs",
|
|
66
|
+
"default": "./dist/adapters/telemetry.mjs"
|
|
67
|
+
},
|
|
68
|
+
"./util/mention-parser": {
|
|
69
|
+
"types": "./dist/util/mention-parser.d.mts",
|
|
70
|
+
"import": "./dist/util/mention-parser.mjs",
|
|
71
|
+
"default": "./dist/util/mention-parser.mjs"
|
|
72
|
+
},
|
|
73
|
+
"./package.json": "./package.json"
|
|
74
|
+
},
|
|
75
|
+
"files": [
|
|
76
|
+
"dist",
|
|
77
|
+
"README.md",
|
|
78
|
+
"ARCHITECTURE.md",
|
|
79
|
+
"LICENSE"
|
|
80
|
+
],
|
|
81
|
+
"publishConfig": {
|
|
82
|
+
"access": "public"
|
|
83
|
+
},
|
|
84
|
+
"dependencies": {
|
|
85
|
+
"gray-matter": "^4.0.3",
|
|
86
|
+
"zod": "^4.4.3",
|
|
87
|
+
"@agentproto/cli-exec": "0.1.0-alpha.1"
|
|
88
|
+
},
|
|
89
|
+
"devDependencies": {
|
|
90
|
+
"@types/node": "^25.6.2",
|
|
91
|
+
"tsup": "^8.5.1",
|
|
92
|
+
"typescript": "^5.9.3",
|
|
93
|
+
"vitest": "^3.2.4",
|
|
94
|
+
"@agentproto/tooling": "0.1.0-alpha.0"
|
|
95
|
+
},
|
|
96
|
+
"engines": {
|
|
97
|
+
"node": ">=20.9.0"
|
|
98
|
+
},
|
|
99
|
+
"scripts": {
|
|
100
|
+
"dev": "tsup --watch",
|
|
101
|
+
"build": "tsup",
|
|
102
|
+
"postbuild": "node scripts/copy-sidecars.mjs",
|
|
103
|
+
"clean": "rm -rf dist",
|
|
104
|
+
"check-types": "tsc --noEmit",
|
|
105
|
+
"test": "vitest run --passWithNoTests",
|
|
106
|
+
"test:watch": "vitest"
|
|
107
|
+
}
|
|
108
|
+
}
|