feat(core): add agent execution context
This commit is contained in:
@@ -26,6 +26,8 @@ const FENCE = 'ts cordis-catalog'
|
||||
// TODO(catalog-type-links): verify or generate link-map coverage.
|
||||
export const LINK_MAP: Record<string, string> = {
|
||||
Agent: 'core.md',
|
||||
AgentExecution: 'core.md',
|
||||
AgentExecutionService: 'core.md',
|
||||
ContentBlock: 'core.md',
|
||||
Message: 'core.md',
|
||||
MessageSource: 'core.md',
|
||||
@@ -84,13 +86,13 @@ interface ServiceEntry {
|
||||
key: string
|
||||
/** The service class/interface name, e.g. `LlmService`. */
|
||||
type: string
|
||||
/** Whether the service class is abstract (a seam interface). */
|
||||
/** Whether the service declaration is abstract (a seam interface). */
|
||||
abstract: boolean
|
||||
/** Class-level JSDoc prose, one line per paragraph. */
|
||||
/** Declaration-level JSDoc prose, one line per paragraph. */
|
||||
doc: string
|
||||
/** Public method signatures (bodies stripped), in source order. */
|
||||
methods: string[]
|
||||
/** Source pointer of the class declaration. */
|
||||
/** Source pointer of the service declaration. */
|
||||
source: string
|
||||
}
|
||||
|
||||
@@ -172,8 +174,8 @@ export function collectEvents(scanRoot: string = root): EventEntry[] {
|
||||
return entries
|
||||
}
|
||||
|
||||
/** Walk every harness `interface Context` block + its service class, hard-
|
||||
* erroring (aggregated) on any JSDoc-completeness violation: a class or public
|
||||
/** Walk every harness `interface Context` block + its service declaration,
|
||||
* hard-erroring (aggregated) on any JSDoc-completeness violation: a service or public
|
||||
* method without JSDoc prose, an undocumented parameter, a stale `@param`, a
|
||||
* missing `@returns` on a non-void method, or an inferred (unannotated) return
|
||||
* type the pure-AST walk cannot classify.
|
||||
@@ -199,18 +201,23 @@ export function collectServices(scanRoot: string = root): ServiceEntry[] {
|
||||
}
|
||||
}
|
||||
if (keyToType.size === 0) continue
|
||||
// Find each service class declared in the same file and emit an entry.
|
||||
// Find each service declaration in the same file and emit an entry.
|
||||
for (const [key, type] of keyToType) {
|
||||
const cls = sf.statements.find(
|
||||
(s): s is ts.ClassDeclaration => ts.isClassDeclaration(s) && s.name?.text === type,
|
||||
const declaration = sf.statements.find(
|
||||
(s): s is ts.ClassDeclaration | ts.InterfaceDeclaration =>
|
||||
(ts.isClassDeclaration(s) || ts.isInterfaceDeclaration(s)) && s.name?.text === type,
|
||||
)
|
||||
if (!cls) continue // a Pick-mixin member (e.g. timer helpers), not a class here
|
||||
const abstract = cls.modifiers?.some(m => m.kind === ts.SyntaxKind.AbstractKeyword) ?? false
|
||||
const clsDoc = parseJsDoc(rawJsDoc(text, cls)).doc
|
||||
if (!clsDoc) violations.push(`service ctx.${key} (${pointer(rel, sf, cls)}): class ${type} has no JSDoc.`)
|
||||
if (!declaration) continue // a Pick-mixin member (e.g. timer helpers), not a declaration here
|
||||
const abstract = ts.isInterfaceDeclaration(declaration)
|
||||
|| (declaration.modifiers?.some(m => m.kind === ts.SyntaxKind.AbstractKeyword) ?? false)
|
||||
const declarationDoc = parseJsDoc(rawJsDoc(text, declaration)).doc
|
||||
if (!declarationDoc) {
|
||||
const kind = ts.isInterfaceDeclaration(declaration) ? 'interface' : 'class'
|
||||
violations.push(`service ctx.${key} (${pointer(rel, sf, declaration)}): ${kind} ${type} has no JSDoc.`)
|
||||
}
|
||||
const methods: string[] = []
|
||||
for (const member of cls.members) {
|
||||
if (!ts.isMethodDeclaration(member)) continue
|
||||
for (const member of declaration.members) {
|
||||
if (!ts.isMethodDeclaration(member) && !ts.isMethodSignature(member)) continue
|
||||
// Only instance methods callable through `ctx.<key>` are surface;
|
||||
// private, protected, and static methods are not.
|
||||
const nonPublic = member.modifiers?.some(m =>
|
||||
@@ -238,9 +245,9 @@ export function collectServices(scanRoot: string = root): ServiceEntry[] {
|
||||
key,
|
||||
type,
|
||||
abstract,
|
||||
doc: clsDoc,
|
||||
doc: declarationDoc,
|
||||
methods,
|
||||
source: pointer(rel, sf, cls),
|
||||
source: pointer(rel, sf, declaration),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -152,6 +152,14 @@ const SERVICE_ROLES: ServiceRole[] = [
|
||||
consumers: ['agent-loop', 'acp', 'subagent-inprocess', 'stdio-demo', 'invariants'],
|
||||
note: 'Owns live Agent handles and the create/resume factory seam.',
|
||||
},
|
||||
{
|
||||
key: 'agentExecution',
|
||||
pkg: 'agent-execution',
|
||||
title: 'Agent execution context',
|
||||
mode: 'core',
|
||||
consumers: ['agent-loop'],
|
||||
note: 'Carries the exact initiating Agent across one process-local asynchronous driver chain; explicit identities remain authoritative at external boundaries.',
|
||||
},
|
||||
{
|
||||
key: 'agentLoop',
|
||||
pkg: 'agent-loop',
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
{ "doc": "docs/core-data-structures/core.md", "symbol": "LlmCallConfig", "source": "packages/llm/llm/src/call-config.ts" },
|
||||
{ "doc": "docs/core-data-structures/core.md", "symbol": "SessionEvent", "source": "packages/core/session/src/types.ts" },
|
||||
{ "doc": "docs/core-data-structures/core.md", "symbol": "Agent", "source": "packages/core/agent/src/types.ts" },
|
||||
{ "doc": "docs/core-data-structures/core.md", "symbol": "AgentExecution", "source": "packages/core/agent-execution/src/types.ts" },
|
||||
{ "doc": "docs/core-data-structures/core.md", "symbol": "AgentExecutionService", "source": "packages/core/agent-execution/src/index.ts" },
|
||||
{ "doc": "docs/core-data-structures/core.md", "symbol": "HookContext", "source": "packages/core/agent/src/types.ts" },
|
||||
{ "doc": "docs/core-data-structures/core.md", "symbol": "PromptDecision", "source": "packages/core/agent/src/types.ts" },
|
||||
{ "doc": "docs/core-data-structures/core.md", "symbol": "ContinuationDecision", "source": "packages/core/agent/src/types.ts" },
|
||||
|
||||
@@ -28,6 +28,7 @@ interface SentenceContract {
|
||||
* so an absent section cannot be mistaken for forgotten documentation.
|
||||
*/
|
||||
const NO_MODEL_EXPERIENCE_SECTION: Readonly<Record<string, string>> = {
|
||||
'packages/core/agent-execution': 'The package is model-agnostic ambient control infrastructure; model-facing consumers own any resulting request surface.',
|
||||
'packages/core/scope': 'The package is a model-agnostic registration and lifecycle primitive; model-facing consumers own any context selection.',
|
||||
'packages/util/brand': 'The package is a type-only primitive erased at compile time.',
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user