@jangts/agent-core 0.2.0 → 0.2.1

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.
Files changed (61) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/LICENSE +55 -0
  3. package/NOTICE +6 -0
  4. package/README.md +8 -0
  5. package/development/docs/README.en.md +70 -0
  6. package/development/docs/README.md +1 -1
  7. package/development/docs/acceptance.en.md +34 -0
  8. package/development/docs/agent-development.en.md +42 -0
  9. package/development/docs/api/README.en.md +62 -0
  10. package/development/docs/api/advanced-agents.en.md +135 -0
  11. package/development/docs/api/context-processing.en.md +110 -0
  12. package/development/docs/api/core.en.md +274 -0
  13. package/development/docs/api/examples.en.md +118 -0
  14. package/development/docs/api/kits.en.md +183 -0
  15. package/development/docs/api/knowledge-answering.en.md +166 -0
  16. package/development/docs/api/mock.en.md +186 -0
  17. package/development/docs/api/observability.en.md +166 -0
  18. package/development/docs/api/reference.en.md +2235 -0
  19. package/development/docs/api/support.en.md +252 -0
  20. package/development/docs/api/types.en.md +181 -0
  21. package/development/docs/api/workflow.en.md +188 -0
  22. package/development/docs/basic-usage.en.md +78 -0
  23. package/development/docs/create-app.en.md +76 -0
  24. package/development/docs/examples/offline-agent.en.md +273 -0
  25. package/development/docs/examples.en.md +36 -0
  26. package/development/docs/flows/knowledge-maintenance.en.md +38 -0
  27. package/development/docs/getting-started.en.md +71 -0
  28. package/development/docs/knowledge.en.md +89 -0
  29. package/development/docs/maintenance.en.md +62 -0
  30. package/development/docs/materials.en.md +38 -0
  31. package/development/docs/mechanisms.en.md +227 -0
  32. package/development/docs/memory-and-learning.en.md +42 -0
  33. package/development/docs/operations.en.md +51 -0
  34. package/development/docs/records.en.md +63 -0
  35. package/development/docs/registration.en.md +63 -0
  36. package/development/skills/agent-core-app/scripts/create-app.mjs +19 -0
  37. package/development/skills/agent-core-app/scripts/lib/knowledge.mjs +37 -1
  38. package/development/skills/agent-core-app/scripts/plan.mjs +9 -0
  39. package/development/skills/agent-core-app/scripts/resources.mjs +17 -0
  40. package/dist/cjs/diagnostics/catalog.js +6 -0
  41. package/dist/cjs/support/model/chat-completions.js +1 -1
  42. package/dist/cjs/support/model/completion/default.js +1 -0
  43. package/dist/cjs/support/model/completion/session.js +5 -0
  44. package/dist/esm/diagnostics/catalog.d.ts +6 -0
  45. package/dist/esm/diagnostics/catalog.js +6 -0
  46. package/dist/esm/structs/kits/retrieval.d.ts +1 -0
  47. package/dist/esm/structs/kits/search.d.ts +2 -0
  48. package/dist/esm/structs/model/messages.d.ts +4 -0
  49. package/dist/esm/structs/support/model/messages.d.ts +2 -0
  50. package/dist/esm/support/context/nodes.d.ts +16 -0
  51. package/dist/esm/support/context/processing.d.ts +7 -0
  52. package/dist/esm/support/model/chat-completions.js +1 -1
  53. package/dist/esm/support/model/children.d.ts +2 -0
  54. package/dist/esm/support/model/completion/default.d.ts +1 -0
  55. package/dist/esm/support/model/completion/default.js +1 -0
  56. package/dist/esm/support/model/completion/session.d.ts +5 -0
  57. package/dist/esm/support/model/completion/session.js +5 -0
  58. package/dist/esm/support/model/preview-rules.d.ts +6 -0
  59. package/dist/esm/support/model/reply-preview.d.ts +7 -0
  60. package/dist/esm/support/model/strategies.d.ts +4 -0
  61. package/package.json +6 -3
@@ -0,0 +1,63 @@
1
+ # Registration, assembly, and execution
2
+
3
+ [Back to development handbook](README.md)
4
+
5
+ ## Ordinary tool integration
6
+
7
+ Prefer putting static tool definitions in a separate, readable, typed manifest, preserving item types with Support.defineTool, and assembling with Support.defineToolCatalog. Each item contains id, kind, description, inputSchema, authorize, execute, and parseOutput; inputSchema provides both jsonSchema and parse; model capabilities and execution registration consume the same definition. For complete code see [Tool integration](basic-usage.md#tools-are-declared-only-once).
8
+
9
+ Create catalog.bind({ app: context, execution: { signal } }) per request; the model first produces a ToolProposal, and the App then calls runtime.invoke. The latter reuses Core ToolRegistry.invokeAsync, performing input parsing, actual authorization, execution, and output checks in order. When the available set changes, use catalog.select(ids) to project the same manifest, and still check the real identity at execution. This Support adapter does not replace workflows or the business specifications of Kits.
10
+
11
+ ## Two different kinds of registration
12
+
13
+ | Registered object | Purpose | Update method |
14
+ | --- | --- | --- |
15
+ | Tools/model capabilities/workflows/checks/output | Declare what the program can do, when it is available, what it accepts, and who implements it | The App compiles manifests and provides the available set by stage and real identity |
16
+ | Documents/sections/knowledge versions | Declare what content a given read can see | The App loads sources and creates a Knowledge catalog; on update, explicitly rebuild the catalog and related views |
17
+
18
+ Adding one knowledge document usually does not require adding a tool. Keep a single `knowledge.read`, and let the catalog authorized for this round provide legal document/section IDs. The model may propose read requests from the provided set, but cannot use them to register arbitrary new handlers, discover disk directories, or publish knowledge.
19
+
20
+ ## What a manifest should state
21
+
22
+ At minimum it should be possible to read: stable identifier, purpose, input and output, real execution entry, availability conditions, read scope, side effects, errors, and receipts. Derive the model-visible catalog, schema, and reference validation from the manifest wherever possible; do not maintain one prompt capability list and another actual execution list.
23
+
24
+ - `ModelCapabilityRegistry` registers the structures the model can propose along with `inputSchema` and `resolve`. inputSchema.jsonSchema is used for model declarations; business parsing, value ranges, and authorization must still be enforced by the program.
25
+ - `ToolRegistry` registers `id/kind/parseInput/execute/parseOutput`. invoke is for synchronous implementations; invokeAsync waits for asynchronous execution before checking output and recording results; do not hand a Promise to the synchronous entry as a completed result.
26
+ - `AgentCoreEngine` workflow nodes declare `requires/provides/routes/onErrorNodeId`. Only updates that pass cancellation and state contract checks are committed; branches are selected in declaration order.
27
+ - `Support.defineContextFragments` assembles request input and fragments. Trust, source, and budget must be correctly labeled by the App; client self-reporting alone is not acceptable.
28
+ - Knowledge, Answering, Presentation, Interaction, Intents, and Tools each own local contracts and are chosen according to business needs. They are not automatically installed by Core.
29
+
30
+ For named constructors, static helpers, and instance methods see [Core](api/core.md), [Support](api/support.md), and [Kit](api/kits.md).
31
+
32
+ ## Separate model proposals from actual execution
33
+
34
+ ```text
35
+ Server establishes identity and the available capability view
36
+ → model proposes capability + parameters
37
+ → Core collects the complete response, validates with inputSchema.parse, then calls the registered resolve
38
+ → App selects the actual execution entry
39
+ → tool parameter parsing → authorization by server-side identity → execute → output checks
40
+ → program records actual sources/execution receipts
41
+ → generation, checks, binding, and delivery
42
+ ```
43
+
44
+ `parse` should not incidentally perform writes, send messages, or call business tools. Nor should a success receipt be generated merely because the model says it is "done". Using the Interaction Kit for cross-end actions merely selects an optional exchange specification; the App still needs to implement peer handlers, identity, permissions, and confirmation of actual results.
45
+
46
+ ## Static manifests and in-request views
47
+
48
+ Known tools and local protocols are suitable for registration at startup. Authorization, page environment, current tenant, and allowed knowledge change per request and should be projected into the visible set during this round's assembly. Model visibility limits do not replace execution-time authorization.
49
+
50
+ When new documents must be available immediately: load new knowledge → validate catalog and task references → build a new version catalog → atomically switch the App's current reference. Existing requests keep their old catalog and snapshots; new requests use the new catalog. Do not mix body text, schema, sources, and revisions from before and after the reload within the same answer.
51
+
52
+ When program capabilities must genuinely be added dynamically, the App explicitly decides the code source, publication, and registration point, and reconstructs the corresponding registry. The library has no model-driven arbitrary code installation, automatic file discovery, or hot-unloading platform.
53
+
54
+ ## Checks at startup and per request
55
+
56
+ | Timing | What to check |
57
+ | --- | --- |
58
+ | Startup/publication | Whether handlers exist; whether node and output references are valid; whether knowledge/sections exist; whether the Skill's tools are actually registered; whether parameter schema and parser agree |
59
+ | Request start | Identity, knowledge access scope, budget, signal, current catalog revision, and capability set |
60
+ | Before real execution | Current permissions, resource ownership, parameter value ranges, and necessary confirmation |
61
+ | Before delivery | Tool result contracts, sources and numbers, generated fields, program-bound fields, output completeness |
62
+
63
+ A Kit's validator can only validate the local structure it knows about. It does not know your tenants, storage paths, data permissions, or business facts; these checks cannot be omitted just because "a creator was used".
@@ -1,3 +1,13 @@
1
+ /**
2
+ * Scaffold or compare an App that uses `@jangts/agent-core`.
3
+ *
4
+ * Resolves the SDK the target project depends on, renders the selected template into a staging
5
+ * directory and only then renames it into place, so a failed or concurrent run never leaves a
6
+ * half-written app. `--check` compares the managed files against the recorded receipt instead of
7
+ * writing. Nothing here installs dependencies, calls a model or publishes content.
8
+ *
9
+ * Usage: see `usage` below; run directly or import `createApplication`.
10
+ */
1
11
  import { createHash } from 'node:crypto';
2
12
  import { execFile } from 'node:child_process';
3
13
  import { promisify } from 'node:util';
@@ -215,6 +225,15 @@ async function compare(target, resources, definition) {
215
225
  };
216
226
  }
217
227
  const manifestName = '@jangts/agent-core';
228
+ /**
229
+ * Create or check a generated application directory.
230
+ *
231
+ * @param args CLI arguments: `TARGET` plus optional flags described by `usage`.
232
+ * @param cwd Directory relative paths are resolved against; defaults to the process cwd.
233
+ * @returns A plan (`--write` omitted), a comparison (`--check`) or the creation result.
234
+ * @throws {TypeError} When arguments, names, the target or the source file are invalid.
235
+ * @throws {Error} When the template, receipt or SDK manifest is unsupported or inconsistent.
236
+ */
218
237
  export async function createApplication(args, cwd = process.cwd()) {
219
238
  const { target, values } = parse(args, cwd);
220
239
  if (basename(target) === '.local')
@@ -1,8 +1,25 @@
1
+ /**
2
+ * App-owned knowledge loading for the `agent-core-app` Skill.
3
+ *
4
+ * Reads the App's `knowledge.config.json` allowlist, verifies each referenced document against the
5
+ * configured byte limit, and compiles the documents into a Knowledge Kit catalog. This is App
6
+ * configuration code, not a Core file-store API: no model or request may supply a filesystem path.
7
+ *
8
+ * Exports: `compileApplicationKnowledge`, `readApplicationKnowledge`, `loadApplicationKnowledge`.
9
+ */
1
10
  import { readFile } from 'node:fs/promises';
2
11
  import { createHash } from 'node:crypto';
3
12
  import { Knowledge } from '@jangts/agent-core/kits/knowledge';
4
13
 
5
- // This is App-owned configuration and loading code, not a Core file-store API.
14
+ /**
15
+ * Compile parsed documents into a Knowledge catalog.
16
+ *
17
+ * @param documents Documents produced by `Knowledge.parseKnowledgeDocument`.
18
+ * @param policy Validated `knowledge.config.json` content (`schemaVersion`, `maxReadChars`,
19
+ * `requiredReads`).
20
+ * @returns The compiled catalog; required reads are resolved so a missing read fails here.
21
+ * @throws {TypeError} When the policy shape or a required read is invalid.
22
+ */
6
23
  export function compileApplicationKnowledge(documents, policy) {
7
24
  if (
8
25
  !policy ||
@@ -18,6 +35,17 @@ export function compileApplicationKnowledge(documents, policy) {
18
35
  return catalog;
19
36
  }
20
37
 
38
+ /**
39
+ * Read the knowledge config and its allowed documents from one directory.
40
+ *
41
+ * The config hash is computed over the exact bytes parsed below, so a proposal identity cannot
42
+ * drift from the document catalog it was derived from.
43
+ *
44
+ * @param directory Directory holding `knowledge.config.json` and the listed documents.
45
+ * @returns Parsed `documents`, the raw `policy` and the `baseConfigSha256` of the config file.
46
+ * @throws {TypeError} When the config or a document entry fails validation.
47
+ * @throws {RangeError} When a source document exceeds `maxDocumentBytes`.
48
+ */
21
49
  export async function readApplicationKnowledge(directory = new URL('./', import.meta.url)) {
22
50
  // Bind validation and proposal identity to the exact bytes parsed below.
23
51
  const configBytes = await readFile(new URL('knowledge.config.json', directory));
@@ -58,6 +86,14 @@ export async function readApplicationKnowledge(directory = new URL('./', import.
58
86
  return { documents, policy, baseConfigSha256 };
59
87
  }
60
88
 
89
+ /**
90
+ * Read and compile the App knowledge catalog in one step.
91
+ *
92
+ * @param directory Directory holding `knowledge.config.json` and the listed documents.
93
+ * @returns The compiled Knowledge catalog.
94
+ * @throws {TypeError | RangeError} Same validation failures as `readApplicationKnowledge` and
95
+ * `compileApplicationKnowledge`.
96
+ */
61
97
  export async function loadApplicationKnowledge(directory = new URL('./', import.meta.url)) {
62
98
  const { documents, policy } = await readApplicationKnowledge(directory);
63
99
  return compileApplicationKnowledge(documents, policy);
@@ -1,3 +1,12 @@
1
+ /**
2
+ * Read-only planning entry for the `agent-core-app` Skill.
3
+ *
4
+ * Reports whether a project exists, which SDK it resolves, the state of its knowledge catalog and
5
+ * the SDK tools/docs that may be used next. It never evaluates project code, calls a model or
6
+ * writes files; the printed JSON is guidance for the agent, not a permission grant.
7
+ *
8
+ * Usage: `node plan.mjs PROJECT [--source UTF8_FILE]`.
9
+ */
1
10
  import { stat } from 'node:fs/promises';
2
11
  import { resolve, sep } from 'node:path';
3
12
  import { pathToFileURL } from 'node:url';
@@ -1,3 +1,13 @@
1
+ /**
2
+ * Locate the SDK installation and the Skill assets it ships.
3
+ *
4
+ * The Skill never downloads or copies files: it resolves the `@jangts/agent-core` installation the
5
+ * target project already depends on, or — only when this Skill runs from inside the distributed
6
+ * SDK — the bundled sibling assets. Every returned path is verified to be a regular file so a
7
+ * broken or foreign package cannot silently supply a different asset.
8
+ *
9
+ * Exports: `resolveSdkResources`.
10
+ */
1
11
  import { createRequire } from 'node:module';
2
12
  import { readFile, stat } from 'node:fs/promises';
3
13
  import { dirname, join, resolve } from 'node:path';
@@ -69,6 +79,13 @@ async function requiredFile(root, relative) {
69
79
  return filename;
70
80
  }
71
81
 
82
+ /**
83
+ * Resolve the SDK root and every Skill resource path for one project.
84
+ *
85
+ * @param project Project directory used to resolve the installed SDK.
86
+ * @returns `sdk` (`root`, `version`, `source`), the `tools`/`docs` file paths and `knowledgeLoader`.
87
+ * @throws {Error} When the SDK cannot be resolved, or a declared resource is missing or not a file.
88
+ */
72
89
  export async function resolveSdkResources(project) {
73
90
  let sdk = await installedPackage(resolve(project));
74
91
  if (!sdk) {
@@ -1,6 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.coreEventCatalog = void 0;
4
+ /**
5
+ * Default visibility tier for every event Core can emit.
6
+ *
7
+ * The same object is the allow-list used when normalizing persisted records; adding an event to
8
+ * `CoreEventName` without a tier here fails type checking.
9
+ */
4
10
  exports.coreEventCatalog = {
5
11
  'node.progress': 'metadata',
6
12
  'model.start': 'metadata',
@@ -92,7 +92,7 @@ function chatCompletionParts(delta) {
92
92
  */
93
93
  function chatCompletionMessages(messages) {
94
94
  return messages.map((message) => {
95
- const { role, content, images, toolCalls, toolCallId } = message;
95
+ const { role, content, images, toolCalls, toolCallId, } = message;
96
96
  if (!['system', 'user', 'assistant', 'tool'].includes(role) || typeof content !== 'string')
97
97
  throw new TypeError('Invalid provider message role or content');
98
98
  if (toolCallId !== undefined && role !== 'tool')
@@ -29,4 +29,5 @@ const policy = {
29
29
  };
30
30
  },
31
31
  };
32
+ /** Frozen default policy: strictness depends only on whether the call declared functions. */
32
33
  exports.defaultCompletionPolicy = Object.freeze(policy);
@@ -99,4 +99,9 @@ const policy = {
99
99
  };
100
100
  },
101
101
  };
102
+ /**
103
+ * Frozen opt-in policy that judges rules by the request's effective `tool_choice`.
104
+ *
105
+ * Consumers that do not select it keep `defaultCompletionPolicy`.
106
+ */
102
107
  exports.sessionCompletionPolicy = Object.freeze(policy);
@@ -1,3 +1,9 @@
1
+ /**
2
+ * Default visibility tier for every event Core can emit.
3
+ *
4
+ * The same object is the allow-list used when normalizing persisted records; adding an event to
5
+ * `CoreEventName` without a tier here fails type checking.
6
+ */
1
7
  export declare const coreEventCatalog: {
2
8
  readonly 'node.progress': "metadata";
3
9
  readonly 'model.start': "metadata";
@@ -1,3 +1,9 @@
1
+ /**
2
+ * Default visibility tier for every event Core can emit.
3
+ *
4
+ * The same object is the allow-list used when normalizing persisted records; adding an event to
5
+ * `CoreEventName` without a tier here fails type checking.
6
+ */
1
7
  export const coreEventCatalog = {
2
8
  'node.progress': 'metadata',
3
9
  'model.start': 'metadata',
@@ -13,6 +13,7 @@
13
13
  export interface RetrievalSource {
14
14
  sourceId: string;
15
15
  }
16
+ /** Adapter output for one accepted query; the Kit renames each source before returning it. */
16
17
  export interface RetrievalResult<Source extends RetrievalSource> {
17
18
  sources: Source[];
18
19
  }
@@ -25,12 +25,14 @@ export interface TextSearchOptions<Document extends {
25
25
  /** How multiple query terms combine; defaults to the engine default (OR). */
26
26
  readonly combineWith?: 'AND' | 'OR';
27
27
  }
28
+ /** One ranked match; `terms` are post-tokenization and only stored fields are returned. */
28
29
  export interface TextSearchHit<Document extends {
29
30
  id: string;
30
31
  }> extends SearchHit<Partial<Document>> {
31
32
  /** Matched terms, as reported by the engine after tokenization. */
32
33
  readonly terms: readonly string[];
33
34
  }
35
+ /** Search input: a hard result limit and an App-owned filter, both required on every query. */
34
36
  export interface TextSearchQuery<Document extends {
35
37
  id: string;
36
38
  }> {
@@ -13,6 +13,7 @@ export interface ModelImage {
13
13
  /** Provider resolution hint; `original` asks for no downscaling where supported. */
14
14
  detail?: 'auto' | 'low' | 'high' | 'original';
15
15
  }
16
+ /** One provider-neutral turn; `images` are user visual input and are not part of the text budget. */
16
17
  export interface ModelMessage {
17
18
  role: 'system' | 'user' | 'assistant';
18
19
  /** Rendered text content sent to the model. */
@@ -20,6 +21,7 @@ export interface ModelMessage {
20
21
  /** User-supplied visual input. Binary payload is separate from the text character budget. */
21
22
  images?: readonly ModelImage[];
22
23
  }
24
+ /** Provider-reported token counts for one call; used for accounting, never for admission. */
23
25
  export interface ModelUsage {
24
26
  /** Input tokens billed for the call. */
25
27
  promptTokens: number;
@@ -39,6 +41,7 @@ export interface ModelFunction {
39
41
  /** Request strict argument validation from providers that support it. */
40
42
  strict?: boolean;
41
43
  }
44
+ /** One streamed fragment of a function call; fragments with the same `index` must be joined. */
42
45
  export interface FunctionCallDelta {
43
46
  type: 'function-call-delta';
44
47
  /** Index of the call within the response; deltas with the same index belong together. */
@@ -52,6 +55,7 @@ export interface FunctionCallDelta {
52
55
  }
53
56
  /** One streamed response part: assistant text or a function-call fragment. */
54
57
  export type ModelPart = string | FunctionCallDelta;
58
+ /** Per-call provider options; Core passes them through and does not normalize provider ranges. */
55
59
  export interface ModelOptions {
56
60
  /** Request a JSON-object response from providers that support it. */
57
61
  json?: boolean;
@@ -18,6 +18,7 @@ export interface ProviderToolCall {
18
18
  /** Raw JSON arguments exactly as the provider produced them. */
19
19
  readonly arguments: string;
20
20
  }
21
+ /** System instruction turn; text only, so the union rejects images and tool fields here. */
21
22
  export interface ProviderSystemMessage {
22
23
  readonly role: 'system';
23
24
  readonly content: string;
@@ -25,6 +26,7 @@ export interface ProviderSystemMessage {
25
26
  readonly toolCallId?: never;
26
27
  readonly toolCalls?: never;
27
28
  }
29
+ /** User turn; the only message type that may carry images, and never tool calls. */
28
30
  export interface ProviderUserMessage {
29
31
  readonly role: 'user';
30
32
  readonly content: string;
@@ -3,6 +3,7 @@ import type { ContextPlan } from '../../structs/context/processing.js';
3
3
  import type { BuiltContext } from '../../structs/context/fragments.js';
4
4
  import type { ModelPrepareRequest, PreparedModelCall, ModelTransportDefinition } from '../../structs/model/runtime.js';
5
5
  import type { ContextCompressor, ContextSelector, ContextPolicy, ContextProcessingReport } from '../../structs/support/context-processing.js';
6
+ /** Outcome of one context node: the built input, its prepared model call and the change report. */
6
7
  export interface ContextNodeResult {
7
8
  /** Context built from the processed fragments, sized against the full input limit. */
8
9
  readonly input: BuiltContext;
@@ -11,6 +12,13 @@ export interface ContextNodeResult {
11
12
  /** What processing changed: characters, token usage, selection decisions and reductions. */
12
13
  readonly report: ContextProcessingReport;
13
14
  }
15
+ /**
16
+ * Definition accepted by `createContextProcessingNode`.
17
+ *
18
+ * It is a normal Core `WorkflowNode` except that the node body is declared here: `plan` builds the
19
+ * context, `update` decides the committed state, and policy/handlers/timeout are validated when the
20
+ * node is created.
21
+ */
14
22
  export type ContextProcessingNodeDefinition<State, Result, App> = Omit<WorkflowNode<State, Result, App>, 'run' | 'report'> & {
15
23
  /** Builds the context plan; must be synchronous so budget failures surface before any I/O. */
16
24
  readonly plan: (state: Readonly<State>, context: WorkflowContext<App>) => ContextPlan;
@@ -33,6 +41,7 @@ export type ContextProcessingNodeDefinition<State, Result, App> = Omit<WorkflowN
33
41
  /** Per-node timeout in milliseconds; defaults to the Core call timeout. */
34
42
  readonly timeoutMs?: number;
35
43
  };
44
+ /** Result of a selection or reduction stage, before the node's `update` commits chosen fields. */
36
45
  export interface ContextStageResult {
37
46
  /** Plan describing current fragments at the full (unreduced) input limit. */
38
47
  readonly plan: ContextPlan;
@@ -41,14 +50,21 @@ export interface ContextStageResult {
41
50
  /** Processing report accumulated by this and preceding steps. */
42
51
  readonly report: ContextProcessingReport;
43
52
  }
53
+ /** Selection stage result: the chosen step IDs plus the unchanged stage snapshot. */
44
54
  export interface ContextSelectionResult extends ContextStageResult {
45
55
  /** Registered reduction step IDs chosen for execution; selection itself executes nothing. */
46
56
  readonly stepIds: readonly string[];
47
57
  }
58
+ /** Definition of a selection node: like a processing node, but `update` receives chosen step IDs. */
48
59
  export type ContextSelectionNodeDefinition<State, Result, App> = Omit<ContextProcessingNodeDefinition<State, Result, App>, 'update'> & {
49
60
  /** Receives the chosen step IDs so the graph can route to reduction nodes. */
50
61
  readonly update: (result: ContextSelectionResult, state: Readonly<State>) => Partial<State>;
51
62
  };
63
+ /**
64
+ * Definition of a reduction node: one registered step is applied per node run.
65
+ *
66
+ * `stepId` may be fixed or derived from state, which lets a graph route over several steps.
67
+ */
52
68
  export type ContextReductionNodeDefinition<State, Result, App> = Omit<ContextProcessingNodeDefinition<State, Result, App>, 'update'> & {
53
69
  /** ID of the reduction step to run, fixed or derived from state. */
54
70
  readonly stepId: string | ((state: Readonly<State>) => string);
@@ -49,6 +49,13 @@ export declare const contextReductionCatalog: {
49
49
  export declare function validateStructure(fragments: readonly ContextFragment[]): void;
50
50
  /** Execution ports accepted by the processing helpers; alias of the Core options contract. */
51
51
  export type ProcessingPorts = import('../../structs/support/context-processing.js').ContextProcessingOptions;
52
+ /**
53
+ * Working state for one context-processing stage.
54
+ *
55
+ * `fragments` is mutated in place by reductions while `before` keeps the original snapshot for the
56
+ * audit report; `ports` carries the signal, diagnostics and call budget already validated by the
57
+ * caller.
58
+ */
52
59
  export interface ProcessingState {
53
60
  /** Token count before processing; present only when a token measurement port was supplied. */
54
61
  beforeTokens?: number;
@@ -87,7 +87,7 @@ export function chatCompletionParts(delta) {
87
87
  */
88
88
  export function chatCompletionMessages(messages) {
89
89
  return messages.map((message) => {
90
- const { role, content, images, toolCalls, toolCallId } = message;
90
+ const { role, content, images, toolCalls, toolCallId, } = message;
91
91
  if (!['system', 'user', 'assistant', 'tool'].includes(role) || typeof content !== 'string')
92
92
  throw new TypeError('Invalid provider message role or content');
93
93
  if (toolCallId !== undefined && role !== 'tool')
@@ -11,6 +11,7 @@
11
11
  import type { ModelRunner } from '../../model/runner.js';
12
12
  import type { ModelChildOptions } from '../../structs/model/runtime.js';
13
13
  import type { MaybePromise } from '../../structs/common.js';
14
+ /** One child call in a group: its own limits plus the work to run with the child runner. */
14
15
  export interface ModelChildTask<Value> extends ModelChildOptions {
15
16
  /**
16
17
  * Work executed with the child runner bound to this task's limits.
@@ -19,6 +20,7 @@ export interface ModelChildTask<Value> extends ModelChildOptions {
19
20
  */
20
21
  run(model: ModelRunner, signal: AbortSignal): MaybePromise<Value>;
21
22
  }
23
+ /** Group options: worker count, extra cancellation and accept/commit hooks. */
22
24
  export interface ModelChildrenOptions<Value> {
23
25
  /** Parallel workers; defaults to, and may not exceed, the parent's concurrency limit. */
24
26
  readonly concurrency?: number;
@@ -7,4 +7,5 @@
7
7
  * Exports: `defaultCompletionPolicy`.
8
8
  */
9
9
  import type { CompletionPolicy } from '../../../structs/support/model/completion.js';
10
+ /** Frozen default policy: strictness depends only on whether the call declared functions. */
10
11
  export declare const defaultCompletionPolicy: CompletionPolicy;
@@ -26,4 +26,5 @@ const policy = {
26
26
  };
27
27
  },
28
28
  };
29
+ /** Frozen default policy: strictness depends only on whether the call declared functions. */
29
30
  export const defaultCompletionPolicy = Object.freeze(policy);
@@ -8,4 +8,9 @@
8
8
  * Exports: `sessionCompletionPolicy`.
9
9
  */
10
10
  import type { CompletionPolicy } from '../../../structs/support/model/completion.js';
11
+ /**
12
+ * Frozen opt-in policy that judges rules by the request's effective `tool_choice`.
13
+ *
14
+ * Consumers that do not select it keep `defaultCompletionPolicy`.
15
+ */
11
16
  export declare const sessionCompletionPolicy: CompletionPolicy;
@@ -96,4 +96,9 @@ const policy = {
96
96
  };
97
97
  },
98
98
  };
99
+ /**
100
+ * Frozen opt-in policy that judges rules by the request's effective `tool_choice`.
101
+ *
102
+ * Consumers that do not select it keep `defaultCompletionPolicy`.
103
+ */
99
104
  export const sessionCompletionPolicy = Object.freeze(policy);
@@ -1,5 +1,10 @@
1
1
  import type { JsonSchema } from '../../structs/common.js';
2
2
  import type { ReplyPreviewRule } from './reply-preview.js';
3
+ /**
4
+ * Capability declaration used to derive preview rules.
5
+ *
6
+ * Omitted `preview` means the capability never previews, so previewing is an explicit opt-in.
7
+ */
3
8
  export interface ReplyPreviewCapability {
4
9
  /** Capability ID, which must equal the native function wire name used for transport. */
5
10
  readonly id: string;
@@ -11,6 +16,7 @@ export interface ReplyPreviewCapability {
11
16
  */
12
17
  readonly preview?: true | Omit<ReplyPreviewRule, 'stageId' | 'capabilityId'>;
13
18
  }
19
+ /** Stage declaration: which capabilities it exposes and whether it previews text or arguments. */
14
20
  export interface ReplyPreviewStage {
15
21
  /** Stage ID used by the workflow and transport projection. */
16
22
  readonly id: string;
@@ -1,4 +1,9 @@
1
1
  import type { ModelOutputEvent } from '../../structs/model/runtime.js';
2
+ /**
3
+ * One projection rule: which stage/capability it matches and which prose fields may be shown.
4
+ *
5
+ * A rule without `capabilityId` may only match a registered plain-text stage.
6
+ */
2
7
  export interface ReplyPreviewRule {
3
8
  /** Native function wire name. Omit only for a registered plain-text stage. */
4
9
  capabilityId?: string;
@@ -12,6 +17,7 @@ export interface ReplyPreviewRule {
12
17
  values: readonly string[];
13
18
  };
14
19
  }
20
+ /** Rules plus optional renderer and character budget; all values are snapshotted at creation. */
15
21
  export interface ReplyPreviewSettings {
16
22
  rules: readonly ReplyPreviewRule[];
17
23
  /** Presentation only; must not authorize, persist or execute a proposal. */
@@ -19,6 +25,7 @@ export interface ReplyPreviewSettings {
19
25
  /** Streamed characters tolerated before preview is disabled; default 16000. */
20
26
  maxChars?: number;
21
27
  }
28
+ /** Settings for `createReplyPreview`; `sink` receives every bubble list and is required. */
22
29
  export interface ReplyPreviewOptions extends ReplyPreviewSettings {
23
30
  /** Receives the current bubble list; rejection propagates to the event caller. */
24
31
  readonly sink: (bubbles: string[]) => void | Promise<void>;
@@ -36,6 +36,10 @@ export type ModelBudgetStrategy = keyof typeof modelBudgetStrategies | Partial<M
36
36
  type StrategyModel<Transports extends readonly ModelTransportDefinition[], Execution> = Omit<ModelRunnerOptions<Transports>, 'execution'> & {
37
37
  execution?: Execution;
38
38
  };
39
+ /**
40
+ * Input of `createModelStrategy`: model selection, optional reasoning and budget plus explicit
41
+ * Core overrides. Explicit Core fields win over every generated value.
42
+ */
39
43
  export type ModelStrategyOptions<Transports extends readonly ModelTransportDefinition[] = readonly ModelTransportDefinition[], Execution = ExecutionOptions> = Partial<StrategyModel<Transports, Execution>> & {
40
44
  /** An existing definition, or an ID in the explicitly supplied model catalog. */
41
45
  readonly model: StrategyModel<Transports, Execution> | string;
package/package.json CHANGED
@@ -1,7 +1,8 @@
1
1
  {
2
2
  "name": "@jangts/agent-core",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "type": "commonjs",
5
+ "license": "Apache-2.0",
5
6
  "description": "Platform-independent agent runtime and configurable modules for evidence, delivery, policies and interactions",
6
7
  "homepage": "https://agent-core-docs.pages.jangts.cafe/",
7
8
  "engines": {
@@ -15,7 +16,9 @@
15
16
  "dist",
16
17
  "development/docs",
17
18
  "development/skills",
18
- "CHANGELOG.md"
19
+ "CHANGELOG.md",
20
+ "LICENSE",
21
+ "NOTICE"
19
22
  ],
20
23
  "sideEffects": false,
21
24
  "exports": {
@@ -246,7 +249,7 @@
246
249
  "docs:api": "node scripts/api-reference.mjs"
247
250
  },
248
251
  "dependencies": {
249
- "@jangts/streaming": "0.1.0",
252
+ "@jangts/streaming": "^0.1.2",
250
253
  "@jangts/mock-gpt": "0.2.0",
251
254
  "minisearch": "^7.2.0"
252
255
  },