@intx/agent 0.2.2 → 0.4.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/README.md +2 -2
- package/dist/agent.d.ts +30 -1
- package/dist/agent.js +50 -1
- package/dist/credential-resolver.d.ts +16 -0
- package/dist/credential-resolver.js +33 -0
- package/dist/definition.d.ts +23 -0
- package/dist/definition.js +1 -0
- package/dist/director-registry.d.ts +9 -0
- package/dist/director-registry.js +14 -0
- package/dist/director.d.ts +14 -0
- package/dist/director.js +39 -0
- package/dist/env.d.ts +26 -0
- package/dist/index.d.ts +5 -4
- package/dist/index.js +5 -4
- package/dist/internal-fixtures/mail.js +2 -1
- package/dist/internal-fixtures/planner.js +1 -1
- package/dist/testing/index.d.ts +1 -0
- package/dist/testing/index.js +1 -0
- package/dist/testing/reactor-waiters.d.ts +13 -0
- package/dist/testing/reactor-waiters.js +23 -0
- package/dist/tool.d.ts +58 -2
- package/dist/tool.js +30 -1
- package/package.json +7 -6
package/README.md
CHANGED
|
@@ -16,13 +16,13 @@ import {
|
|
|
16
16
|
defineAgent,
|
|
17
17
|
} from "@intx/agent";
|
|
18
18
|
import { noopAuditStore, permissiveAuthorize } from "@intx/agent/testing";
|
|
19
|
-
import { createIsogitStore } from "@intx/storage-isogit";
|
|
19
|
+
import { createIsogitStore } from "@intx/storage-isogit/node";
|
|
20
20
|
|
|
21
21
|
// `apiKey` and `model` come from the caller's env / config; pick the
|
|
22
22
|
// shape that fits the deployment. The snippet below uses literals so
|
|
23
23
|
// it copy-pastes cleanly.
|
|
24
24
|
const apiKey = process.env.ANTHROPIC_API_KEY ?? "";
|
|
25
|
-
const model = "claude-sonnet-
|
|
25
|
+
const model = "claude-sonnet-5";
|
|
26
26
|
const source = {
|
|
27
27
|
id: `anthropic:${model}`,
|
|
28
28
|
provider: "anthropic",
|
package/dist/agent.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type ReactorEmittedEvent } from "@intx/inference";
|
|
2
|
-
import type { BlobReader, ContextCommit, ConversationTurn, InboundMessage, InferenceSource } from "@intx/types/runtime";
|
|
2
|
+
import type { ApprovalSnapshot, BlobReader, ContextCommit, ConversationTurn, InboundMessage, InferenceSource } from "@intx/types/runtime";
|
|
3
3
|
import type { AgentDefinition } from "./definition.js";
|
|
4
4
|
import type { BaseEnv } from "./env.js";
|
|
5
5
|
export type SendOptions = {
|
|
@@ -17,6 +17,7 @@ export type SendOptions = {
|
|
|
17
17
|
from?: string;
|
|
18
18
|
};
|
|
19
19
|
export type SendResult = {
|
|
20
|
+
type: "reply";
|
|
20
21
|
/** Reply text emitted by the director's `reply` action. */
|
|
21
22
|
reply: string;
|
|
22
23
|
/**
|
|
@@ -24,7 +25,35 @@ export type SendResult = {
|
|
|
24
25
|
* the reactor's `inference.done` event preceding `connector.reply`.
|
|
25
26
|
*/
|
|
26
27
|
turn: ConversationTurn;
|
|
28
|
+
} | {
|
|
29
|
+
/**
|
|
30
|
+
* The reactor parked on a gate before producing a reply. The cycle
|
|
31
|
+
* is not finished -- it will resume when the correlated external
|
|
32
|
+
* decision is delivered. `correlationId` identifies the pending
|
|
33
|
+
* operation the caller resumes against.
|
|
34
|
+
*/
|
|
35
|
+
type: "suspended";
|
|
36
|
+
correlationId: string;
|
|
37
|
+
/**
|
|
38
|
+
* Approver-facing snapshot of the parked tool call, when the reactor
|
|
39
|
+
* carried one on the gate-blocked event. Forwarded so the runtime can
|
|
40
|
+
* register it with the suspension. Absent for suspensions with no
|
|
41
|
+
* snapshot (an authz extension wired with no tool definitions).
|
|
42
|
+
*/
|
|
43
|
+
approvalSnapshot?: ApprovalSnapshot;
|
|
27
44
|
};
|
|
45
|
+
/**
|
|
46
|
+
* A `reactor.gate.blocked` event settled the active send but carried no
|
|
47
|
+
* `correlationId`, so the resulting suspension has no handle a caller
|
|
48
|
+
* could resume against. The reactor omits `correlationId` for gates
|
|
49
|
+
* parked without a correlation (e.g. a director suspend with no
|
|
50
|
+
* correlated external decision), and `send()` cannot hand back an
|
|
51
|
+
* unresumable outcome -- it surfaces this instead.
|
|
52
|
+
*/
|
|
53
|
+
export declare class GateSuspendedWithoutCorrelationError extends Error {
|
|
54
|
+
readonly gateId: string;
|
|
55
|
+
constructor(gateId: string);
|
|
56
|
+
}
|
|
28
57
|
export type Agent = {
|
|
29
58
|
send(content: string | InboundMessage, opts?: SendOptions): Promise<SendResult>;
|
|
30
59
|
stream(): AsyncIterable<ReactorEmittedEvent>;
|
package/dist/agent.js
CHANGED
|
@@ -42,6 +42,7 @@
|
|
|
42
42
|
// contract; the caller owns the lifetime of what it puts in env.
|
|
43
43
|
import { createReactorAssembly, } from "@intx/inference";
|
|
44
44
|
import { createDefaultDependencies } from "@intx/inference/providers";
|
|
45
|
+
import { createUnconfiguredCredentialResolver } from "./credential-resolver.js";
|
|
45
46
|
import { getLogger } from "@intx/log";
|
|
46
47
|
import { createInboundMessage } from "@intx/mime";
|
|
47
48
|
import { validateDirectorConfig } from "./director.js";
|
|
@@ -71,6 +72,22 @@ const DEFAULT_SEND_TO = "agent@local";
|
|
|
71
72
|
const DEFAULT_SEND_QUEUE_MAX = 16;
|
|
72
73
|
const DEFAULT_STREAM_BUFFER_MAX = 1024;
|
|
73
74
|
const DEFAULT_CLOSE_TIMEOUT_MS = 5000;
|
|
75
|
+
/**
|
|
76
|
+
* A `reactor.gate.blocked` event settled the active send but carried no
|
|
77
|
+
* `correlationId`, so the resulting suspension has no handle a caller
|
|
78
|
+
* could resume against. The reactor omits `correlationId` for gates
|
|
79
|
+
* parked without a correlation (e.g. a director suspend with no
|
|
80
|
+
* correlated external decision), and `send()` cannot hand back an
|
|
81
|
+
* unresumable outcome -- it surfaces this instead.
|
|
82
|
+
*/
|
|
83
|
+
export class GateSuspendedWithoutCorrelationError extends Error {
|
|
84
|
+
gateId;
|
|
85
|
+
constructor(gateId) {
|
|
86
|
+
super(`reactor suspended on gate ${gateId} without a correlationId; the send has no handle to resume against`);
|
|
87
|
+
this.name = "GateSuspendedWithoutCorrelationError";
|
|
88
|
+
this.gateId = gateId;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
74
91
|
export class AgentClosedError extends Error {
|
|
75
92
|
constructor() {
|
|
76
93
|
super("agent is closed");
|
|
@@ -391,7 +408,34 @@ export async function createAgent(def, env) {
|
|
|
391
408
|
const turn = activeCycle.lastAssistantTurn ??
|
|
392
409
|
buildSyntheticTurn(event.data.content);
|
|
393
410
|
activeCycle = null;
|
|
394
|
-
sendQueue.resolveActive({
|
|
411
|
+
sendQueue.resolveActive({
|
|
412
|
+
type: "reply",
|
|
413
|
+
reply: event.data.content,
|
|
414
|
+
turn,
|
|
415
|
+
});
|
|
416
|
+
}
|
|
417
|
+
else if (event.type === "reactor.gate.blocked") {
|
|
418
|
+
// The reactor parked on a gate before producing a reply. This
|
|
419
|
+
// is a terminal outcome for the active send: the cycle will not
|
|
420
|
+
// continue until the correlated external decision is delivered,
|
|
421
|
+
// and a parked cycle does not emit connector.reply or
|
|
422
|
+
// reactor.done, so leaving the send unsettled would hang the
|
|
423
|
+
// caller. Resolve with the suspended outcome so the caller can
|
|
424
|
+
// resume against the correlationId. A gate parked without a
|
|
425
|
+
// correlationId is unresumable -- surface it rather than hand
|
|
426
|
+
// back an outcome with no handle.
|
|
427
|
+
const { correlationId, approvalSnapshot } = event.data;
|
|
428
|
+
activeCycle = null;
|
|
429
|
+
if (correlationId === undefined) {
|
|
430
|
+
sendQueue.rejectActive(new GateSuspendedWithoutCorrelationError(event.data.gateId));
|
|
431
|
+
}
|
|
432
|
+
else {
|
|
433
|
+
sendQueue.resolveActive({
|
|
434
|
+
type: "suspended",
|
|
435
|
+
correlationId,
|
|
436
|
+
...(approvalSnapshot !== undefined ? { approvalSnapshot } : {}),
|
|
437
|
+
});
|
|
438
|
+
}
|
|
395
439
|
}
|
|
396
440
|
else if (event.type === "reactor.error" && event.data.fatal) {
|
|
397
441
|
// Only fatal reactor errors terminate the active send. Non-fatal
|
|
@@ -446,11 +490,13 @@ export async function createAgent(def, env) {
|
|
|
446
490
|
source: sourceRegistry.active,
|
|
447
491
|
failOverToNextSource: () => sourceRegistry.failOverToNextSource(),
|
|
448
492
|
resetToPreferredSource: () => sourceRegistry.resetToPreferredSource(),
|
|
493
|
+
readMaterial: env.readCurrentMaterial ?? createUnconfiguredCredentialResolver(),
|
|
449
494
|
toolRunner: resolvedTools.runner,
|
|
450
495
|
contextStore,
|
|
451
496
|
onEvent: handleEvent,
|
|
452
497
|
auditStore,
|
|
453
498
|
authorize,
|
|
499
|
+
toolDefinitions: resolvedTools.definitions,
|
|
454
500
|
onShutdown: async () => {
|
|
455
501
|
try {
|
|
456
502
|
await flushErrors();
|
|
@@ -463,6 +509,9 @@ export async function createAgent(def, env) {
|
|
|
463
509
|
...(env.sizeCapMaxChars !== undefined
|
|
464
510
|
? { sizeCapMaxChars: env.sizeCapMaxChars }
|
|
465
511
|
: {}),
|
|
512
|
+
...(env.doomLoopThreshold !== undefined
|
|
513
|
+
? { doomLoopThreshold: env.doomLoopThreshold }
|
|
514
|
+
: {}),
|
|
466
515
|
deps,
|
|
467
516
|
...(env.compactors !== undefined ? { compactors: env.compactors } : {}),
|
|
468
517
|
});
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { CredentialMaterialResolver } from "@intx/types";
|
|
2
|
+
/**
|
|
3
|
+
* A resolver that fails closed on every call. `createAgent` installs this when
|
|
4
|
+
* the env supplies no `readCurrentMaterial`, so an agent whose inference never
|
|
5
|
+
* resolves a credential (a mock adapter emitting no credential sentinel) needs
|
|
6
|
+
* no resolver, while one that DOES reach a credential surfaces a clear error
|
|
7
|
+
* rather than a confusing `undefined`.
|
|
8
|
+
*/
|
|
9
|
+
export declare function createUnconfiguredCredentialResolver(): CredentialMaterialResolver;
|
|
10
|
+
/**
|
|
11
|
+
* A resolver over a fixed `credentialId -> secret` map. For callers that hold
|
|
12
|
+
* their secrets in memory rather than a live cell -- examples, tests, and any
|
|
13
|
+
* single-process agent. Fails closed when a source references a credential the
|
|
14
|
+
* map does not carry, mirroring the cell reader's revoked/absent behavior.
|
|
15
|
+
*/
|
|
16
|
+
export declare function createStaticCredentialResolver(materials: Record<string, string>): CredentialMaterialResolver;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
// Helpers for the inference credential-material resolver seam
|
|
2
|
+
// (`CredentialMaterialResolver` in `@intx/types`). An inference call resolves
|
|
3
|
+
// its source's secret by `credentialId` through this seam instead of reading an
|
|
4
|
+
// inline `apiKey`, so the source config carries no secret. The sidecar backs it
|
|
5
|
+
// with the run's live credential cell; the helpers here cover the two simpler
|
|
6
|
+
// cases.
|
|
7
|
+
/**
|
|
8
|
+
* A resolver that fails closed on every call. `createAgent` installs this when
|
|
9
|
+
* the env supplies no `readCurrentMaterial`, so an agent whose inference never
|
|
10
|
+
* resolves a credential (a mock adapter emitting no credential sentinel) needs
|
|
11
|
+
* no resolver, while one that DOES reach a credential surfaces a clear error
|
|
12
|
+
* rather than a confusing `undefined`.
|
|
13
|
+
*/
|
|
14
|
+
export function createUnconfiguredCredentialResolver() {
|
|
15
|
+
return (credentialId) => {
|
|
16
|
+
throw new Error(`no credential resolver configured for this agent, but an inference call needs the secret for credential ${credentialId}; supply env.readCurrentMaterial`);
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* A resolver over a fixed `credentialId -> secret` map. For callers that hold
|
|
21
|
+
* their secrets in memory rather than a live cell -- examples, tests, and any
|
|
22
|
+
* single-process agent. Fails closed when a source references a credential the
|
|
23
|
+
* map does not carry, mirroring the cell reader's revoked/absent behavior.
|
|
24
|
+
*/
|
|
25
|
+
export function createStaticCredentialResolver(materials) {
|
|
26
|
+
return (credentialId) => {
|
|
27
|
+
const secret = materials[credentialId];
|
|
28
|
+
if (secret === undefined) {
|
|
29
|
+
throw new Error(`no credential material for ${credentialId} in the static resolver`);
|
|
30
|
+
}
|
|
31
|
+
return { secret };
|
|
32
|
+
};
|
|
33
|
+
}
|
package/dist/definition.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ToolPackagePin } from "@intx/types/tool-packages";
|
|
1
2
|
import type { AnnotatedToolFactory } from "./tool.js";
|
|
2
3
|
import type { BaseEnv } from "./env.js";
|
|
3
4
|
import type { DirectorRef } from "./director-types.js";
|
|
@@ -37,6 +38,19 @@ export interface AgentDefinition<EnvReq extends BaseEnv = BaseEnv> {
|
|
|
37
38
|
readonly systemPrompt: string;
|
|
38
39
|
readonly director?: DirectorRef;
|
|
39
40
|
readonly toolFactories: readonly AnnotatedToolFactory<EnvReq>[];
|
|
41
|
+
/**
|
|
42
|
+
* Tool-package names whose `definePlugin` factories this agent uses
|
|
43
|
+
* (`["@intx/tools-lsp"]`). Unlike a tool factory -- which the agent
|
|
44
|
+
* imports and places in `toolFactories`, so it is agent-visible -- a
|
|
45
|
+
* plugin package contributes NO agent-visible factory: its plugin
|
|
46
|
+
* factory reaches the agent only through `env.plugins`, wired by the
|
|
47
|
+
* host. This explicit per-agent list is therefore the only way per-step
|
|
48
|
+
* plugin scoping and the plugin's contributed tool grants can be known
|
|
49
|
+
* from the definition alone. The field is part of the hashed wire
|
|
50
|
+
* surface (the live->inert projector carries it), so a tampered plugin
|
|
51
|
+
* set fails re-verify. Absent when the agent uses no plugins.
|
|
52
|
+
*/
|
|
53
|
+
readonly plugins?: readonly string[];
|
|
40
54
|
readonly capabilities: readonly string[];
|
|
41
55
|
readonly inference: {
|
|
42
56
|
readonly sources: readonly InferencePreference[];
|
|
@@ -56,6 +70,13 @@ export interface AgentDefinition<EnvReq extends BaseEnv = BaseEnv> {
|
|
|
56
70
|
* encoded JSON in a tag value.
|
|
57
71
|
*/
|
|
58
72
|
readonly tags?: Readonly<Record<string, string>>;
|
|
73
|
+
/**
|
|
74
|
+
* Tool-package pins the sidecar materializes for this agent, carried on the
|
|
75
|
+
* definition so a folded workflow asset is self-contained rather than
|
|
76
|
+
* depending on pins supplied only at deploy time. Plain-data mirror of the
|
|
77
|
+
* pins the deploy-tree tool channel consumes.
|
|
78
|
+
*/
|
|
79
|
+
readonly toolPackagePins?: readonly ToolPackagePin[];
|
|
59
80
|
}
|
|
60
81
|
type UnionToIntersection<U> = (U extends unknown ? (k: U) => void : never) extends (k: infer I) => void ? I : never;
|
|
61
82
|
type EnvRequiredBy<F> = F extends AnnotatedToolFactory<infer E> ? E : never;
|
|
@@ -101,6 +122,8 @@ export interface DefineAgentConfig<Factories extends readonly AnnotatedToolFacto
|
|
|
101
122
|
readonly systemPrompt: string;
|
|
102
123
|
readonly director?: DirectorRef;
|
|
103
124
|
readonly tools: Factories;
|
|
125
|
+
/** Plugin-package names this agent uses; see `AgentDefinition.plugins`. */
|
|
126
|
+
readonly plugins?: readonly string[];
|
|
104
127
|
readonly capabilities: readonly string[];
|
|
105
128
|
readonly inference: {
|
|
106
129
|
readonly sources: readonly InferencePreference[];
|
package/dist/definition.js
CHANGED
|
@@ -29,6 +29,7 @@ export function defineAgent(config) {
|
|
|
29
29
|
toolFactories,
|
|
30
30
|
capabilities: config.capabilities,
|
|
31
31
|
inference: config.inference,
|
|
32
|
+
...(config.plugins !== undefined ? { plugins: config.plugins } : {}),
|
|
32
33
|
...(config.description !== undefined
|
|
33
34
|
? { description: config.description }
|
|
34
35
|
: {}),
|
|
@@ -35,4 +35,13 @@ export declare function createDirectorRegistry(opts: {
|
|
|
35
35
|
* factories pass them into `createDirectorRegistry` directly.
|
|
36
36
|
*/
|
|
37
37
|
export declare function createDefaultDirectorRegistry(): DirectorRegistry;
|
|
38
|
+
/**
|
|
39
|
+
* Build the director registry for a workflow closure: the built-in default
|
|
40
|
+
* plus the closure's own `defineDirector` factories. A closure that ships no
|
|
41
|
+
* directors passes `loaded: []` and composes to `[defaultDirectorFactory]` --
|
|
42
|
+
* identical to `createDefaultDirectorRegistry`. A closure director whose id
|
|
43
|
+
* shadows the built-in (or another loaded director) throws at construction,
|
|
44
|
+
* the same fail-loud `createDirectorRegistry` applies to any duplicate.
|
|
45
|
+
*/
|
|
46
|
+
export declare function createWorkflowDirectorRegistry(loaded: readonly AnnotatedDirectorFactory<unknown, BaseEnv>[]): DirectorRegistry;
|
|
38
47
|
export {};
|
|
@@ -71,3 +71,17 @@ export function createDefaultDirectorRegistry() {
|
|
|
71
71
|
defaultId: defaultDirectorFactory.id,
|
|
72
72
|
});
|
|
73
73
|
}
|
|
74
|
+
/**
|
|
75
|
+
* Build the director registry for a workflow closure: the built-in default
|
|
76
|
+
* plus the closure's own `defineDirector` factories. A closure that ships no
|
|
77
|
+
* directors passes `loaded: []` and composes to `[defaultDirectorFactory]` --
|
|
78
|
+
* identical to `createDefaultDirectorRegistry`. A closure director whose id
|
|
79
|
+
* shadows the built-in (or another loaded director) throws at construction,
|
|
80
|
+
* the same fail-loud `createDirectorRegistry` applies to any duplicate.
|
|
81
|
+
*/
|
|
82
|
+
export function createWorkflowDirectorRegistry(loaded) {
|
|
83
|
+
return createDirectorRegistry({
|
|
84
|
+
factories: [defaultDirectorFactory, ...loaded],
|
|
85
|
+
defaultId: defaultDirectorFactory.id,
|
|
86
|
+
});
|
|
87
|
+
}
|
package/dist/director.d.ts
CHANGED
|
@@ -54,3 +54,17 @@ export declare function defineDirector<Config, EnvReq extends BaseEnv = BaseEnv>
|
|
|
54
54
|
* malformed config to the factory.
|
|
55
55
|
*/
|
|
56
56
|
export declare function validateDirectorConfig(config: unknown, schema: DirectorConfigSchema): void;
|
|
57
|
+
/**
|
|
58
|
+
* Structural check for an `AnnotatedDirectorFactory` export. The shape is
|
|
59
|
+
* callable + `{ id: string, requires: string[], configSchema: function }`.
|
|
60
|
+
* The `configSchema` field is the discriminator against tool factories
|
|
61
|
+
* (which carry only `id` and `requires`); without it, any tool-factory
|
|
62
|
+
* export from a directors-entry module would be accepted as a director.
|
|
63
|
+
*
|
|
64
|
+
* Shared by the tool-package loader (`@intx/tool-packaging`) and the
|
|
65
|
+
* workflow-closure director loader (`@intx/workflow-host`) so both accept
|
|
66
|
+
* and reject exactly the same shapes -- one accept/reject rule the
|
|
67
|
+
* approval-time probe and the runtime cannot drift apart on. Two copies of
|
|
68
|
+
* "is this a valid director" would be a silent congruence hole.
|
|
69
|
+
*/
|
|
70
|
+
export declare function isAnnotatedDirectorFactory(value: unknown): value is AnnotatedDirectorFactory<unknown, BaseEnv>;
|
package/dist/director.js
CHANGED
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
// factories it wants rather than relying on import-order.
|
|
16
16
|
import { type } from "arktype";
|
|
17
17
|
import { validateNamespacedId } from "./namespace.js";
|
|
18
|
+
import { isAnnotatedPluginFactory } from "./tool.js";
|
|
18
19
|
/**
|
|
19
20
|
* Define a director factory.
|
|
20
21
|
*
|
|
@@ -90,3 +91,41 @@ function validateConfig(config, schema) {
|
|
|
90
91
|
export function validateDirectorConfig(config, schema) {
|
|
91
92
|
validateConfig(config, schema);
|
|
92
93
|
}
|
|
94
|
+
/**
|
|
95
|
+
* Structural check for an `AnnotatedDirectorFactory` export. The shape is
|
|
96
|
+
* callable + `{ id: string, requires: string[], configSchema: function }`.
|
|
97
|
+
* The `configSchema` field is the discriminator against tool factories
|
|
98
|
+
* (which carry only `id` and `requires`); without it, any tool-factory
|
|
99
|
+
* export from a directors-entry module would be accepted as a director.
|
|
100
|
+
*
|
|
101
|
+
* Shared by the tool-package loader (`@intx/tool-packaging`) and the
|
|
102
|
+
* workflow-closure director loader (`@intx/workflow-host`) so both accept
|
|
103
|
+
* and reject exactly the same shapes -- one accept/reject rule the
|
|
104
|
+
* approval-time probe and the runtime cannot drift apart on. Two copies of
|
|
105
|
+
* "is this a valid director" would be a silent congruence hole.
|
|
106
|
+
*/
|
|
107
|
+
export function isAnnotatedDirectorFactory(value) {
|
|
108
|
+
if (typeof value !== "function")
|
|
109
|
+
return false;
|
|
110
|
+
if (isAnnotatedPluginFactory(value))
|
|
111
|
+
return false;
|
|
112
|
+
if (!("id" in value) || !("requires" in value))
|
|
113
|
+
return false;
|
|
114
|
+
if (!("configSchema" in value))
|
|
115
|
+
return false;
|
|
116
|
+
const id = value.id;
|
|
117
|
+
const requires = value.requires;
|
|
118
|
+
const configSchema = value.configSchema;
|
|
119
|
+
if (typeof id !== "string")
|
|
120
|
+
return false;
|
|
121
|
+
if (!Array.isArray(requires))
|
|
122
|
+
return false;
|
|
123
|
+
if (!requires.every((r) => typeof r === "string"))
|
|
124
|
+
return false;
|
|
125
|
+
// `defineDirector` requires a callable arktype validator. A non-callable
|
|
126
|
+
// schema would crash later inside config validation; reject here so the
|
|
127
|
+
// failure surfaces at load time rather than at first config-validation.
|
|
128
|
+
if (typeof configSchema !== "function")
|
|
129
|
+
return false;
|
|
130
|
+
return true;
|
|
131
|
+
}
|
package/dist/env.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { AuthzCallResult, Dependencies } from "@intx/inference";
|
|
2
|
+
import type { CredentialMaterialResolver } from "@intx/types";
|
|
2
3
|
import type { AuditStore, Compactor, ContextStore, InferenceSource } from "@intx/types/runtime";
|
|
3
4
|
import type { DirectorRegistry } from "./director-types.js";
|
|
4
5
|
export type { Dependencies };
|
|
@@ -50,6 +51,12 @@ export interface BaseEnv {
|
|
|
50
51
|
* `workdir` values pointing at the same on-disk storage directory
|
|
51
52
|
* will silently corrupt each other -- the invariant is the caller's
|
|
52
53
|
* to maintain.
|
|
54
|
+
*
|
|
55
|
+
* This is the lock and storage boundary, not the working tree the
|
|
56
|
+
* filesystem tools operate on. A tool that needs a working directory
|
|
57
|
+
* (e.g. `@intx/tools-posix`) reads that from its own env-DI key
|
|
58
|
+
* declared through `defineTool({ requires })`, which the caller may
|
|
59
|
+
* point at a directory distinct from `workdir`.
|
|
53
60
|
*/
|
|
54
61
|
workdir: string;
|
|
55
62
|
/** Audit sink. Required; no read-site fallback. */
|
|
@@ -90,6 +97,18 @@ export interface BaseEnv {
|
|
|
90
97
|
* Optional; do not require this field on the production path.
|
|
91
98
|
*/
|
|
92
99
|
deps?: Dependencies;
|
|
100
|
+
/**
|
|
101
|
+
* Resolves an inference source's credential secret by `credentialId` from the
|
|
102
|
+
* run's credential-material cell at send time -- the same cell tool
|
|
103
|
+
* credentials resolve from, so the source config carries no inline secret.
|
|
104
|
+
*
|
|
105
|
+
* Optional at this boundary only to spare callers whose inference never
|
|
106
|
+
* resolves a credential (a mock adapter that emits no credential sentinel).
|
|
107
|
+
* `createAgent` fills a fail-closed default that throws if an inference call
|
|
108
|
+
* actually needs a secret; a caller that does real credentialed inference (the
|
|
109
|
+
* sidecar step env, an example, a test with a real adapter) MUST supply one.
|
|
110
|
+
*/
|
|
111
|
+
readCurrentMaterial?: CredentialMaterialResolver;
|
|
93
112
|
/**
|
|
94
113
|
* Optional deterministic session id. Production callers omit and let
|
|
95
114
|
* the agent generate a fresh UUID; tests that assert on audit-record
|
|
@@ -101,6 +120,13 @@ export interface BaseEnv {
|
|
|
101
120
|
* Forwarded to the reactor assembly's size-cap transform.
|
|
102
121
|
*/
|
|
103
122
|
sizeCapMaxChars?: number;
|
|
123
|
+
/**
|
|
124
|
+
* Override for the default doom-loop detection threshold: the number of
|
|
125
|
+
* identical consecutive tool-call turns that ends the run (default 3).
|
|
126
|
+
* Forwarded to the reactor. Must be a positive integer, or `false` to
|
|
127
|
+
* disable doom-loop detection entirely.
|
|
128
|
+
*/
|
|
129
|
+
doomLoopThreshold?: number | false;
|
|
104
130
|
/**
|
|
105
131
|
* Maximum number of pending sends (active + queued). Beyond this,
|
|
106
132
|
* `send()` rejects with `SendQueueFullError`. Defaults to 16.
|
package/dist/index.d.ts
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
export { AgentContextLockError } from "./lock.js";
|
|
2
|
-
export { type AgentTool, type AgentToolRunner, type AnnotatedPluginFactory, type AnnotatedPluginMeta, type AnnotatedToolFactory, type PluginFactory, type StringToolHandler, type ToolBundle, type ToolFactory, type ToolFactoryMeta, type ToolHandler, DuplicateToolError, PLUGIN_MARKER, TOOL_PLUGIN_KIND, type ToolPluginKind, createToolRunner, defineTool, definePlugin, fromToolRunner, isAnnotatedPluginFactory, isToolPluginInstance, stringTool, tool, } from "./tool.js";
|
|
2
|
+
export { type AgentTool, type AgentToolRunner, type AnnotatedPluginFactory, type AnnotatedPluginMeta, type AnnotatedToolFactory, type PluginFactory, type StringToolHandler, type ToolBundle, type ToolDeclaration, type ToolFactory, type ToolFactoryMeta, type ToolHandler, DuplicateToolError, PLUGIN_MARKER, TOOL_PLUGIN_KIND, type ToolPluginKind, createToolRunner, defineTool, definePlugin, fromToolRunner, isAnnotatedPluginFactory, isToolPluginInstance, stringTool, tool, toolApprovalEffect, } from "./tool.js";
|
|
3
3
|
export { type AuthorizeFn, type BaseEnv, type Dependencies, AgentEnvError, } from "./env.js";
|
|
4
4
|
export { type AnnotatedDirectorFactory, type DirectorAgentContext, type DirectorConfigSchema, type DirectorFactory, type DirectorFactoryMeta, type DirectorRef, type DirectorRegistry, } from "./director-types.js";
|
|
5
|
+
export { createStaticCredentialResolver, createUnconfiguredCredentialResolver, } from "./credential-resolver.js";
|
|
5
6
|
export { validateNamespacedId } from "./namespace.js";
|
|
6
7
|
export { CanonicalizationError, canonicalizeForHash } from "./canonicalize.js";
|
|
7
|
-
export { type DefinedDirector, defineDirector } from "./director.js";
|
|
8
|
-
export { createDefaultDirectorRegistry, createDirectorRegistry, UnknownDirectorIdError, } from "./director-registry.js";
|
|
8
|
+
export { type DefinedDirector, defineDirector, isAnnotatedDirectorFactory, } from "./director.js";
|
|
9
|
+
export { createDefaultDirectorRegistry, createDirectorRegistry, createWorkflowDirectorRegistry, UnknownDirectorIdError, } from "./director-registry.js";
|
|
9
10
|
export { type DefaultDirectorConfig, buildDefaultDirectorRef, defaultDirectorFactory, } from "./default-director.js";
|
|
10
11
|
export { type SourceRegistry, InvalidInferenceSourceError, SourceNotFoundError, createSourceRegistry, } from "./source.js";
|
|
11
|
-
export { type Agent, type SendOptions, type SendResult, AgentClosedError, createAgent, } from "./agent.js";
|
|
12
|
+
export { type Agent, type SendOptions, type SendResult, AgentClosedError, GateSuspendedWithoutCorrelationError, createAgent, } from "./agent.js";
|
|
12
13
|
export { type AgentDefinition, type DefineAgentConfig, type EnvRequiredByAll, type InferencePreference, defineAgent, } from "./definition.js";
|
|
13
14
|
export { effectiveDirectorRef, getRequiredEnvKeys, validateEnv, } from "./env-validation.js";
|
|
14
15
|
export type { RequiredEnvKeys } from "./env-validation.js";
|
package/dist/index.js
CHANGED
|
@@ -7,16 +7,17 @@
|
|
|
7
7
|
// connector threads, outbound replies via MessageTransport) while the
|
|
8
8
|
// agent drives it from in-process calls.
|
|
9
9
|
export { AgentContextLockError } from "./lock.js";
|
|
10
|
-
export { DuplicateToolError, PLUGIN_MARKER, TOOL_PLUGIN_KIND, createToolRunner, defineTool, definePlugin, fromToolRunner, isAnnotatedPluginFactory, isToolPluginInstance, stringTool, tool, } from "./tool.js";
|
|
10
|
+
export { DuplicateToolError, PLUGIN_MARKER, TOOL_PLUGIN_KIND, createToolRunner, defineTool, definePlugin, fromToolRunner, isAnnotatedPluginFactory, isToolPluginInstance, stringTool, tool, toolApprovalEffect, } from "./tool.js";
|
|
11
11
|
export { AgentEnvError, } from "./env.js";
|
|
12
12
|
export {} from "./director-types.js";
|
|
13
|
+
export { createStaticCredentialResolver, createUnconfiguredCredentialResolver, } from "./credential-resolver.js";
|
|
13
14
|
export { validateNamespacedId } from "./namespace.js";
|
|
14
15
|
export { CanonicalizationError, canonicalizeForHash } from "./canonicalize.js";
|
|
15
|
-
export { defineDirector } from "./director.js";
|
|
16
|
-
export { createDefaultDirectorRegistry, createDirectorRegistry, UnknownDirectorIdError, } from "./director-registry.js";
|
|
16
|
+
export { defineDirector, isAnnotatedDirectorFactory, } from "./director.js";
|
|
17
|
+
export { createDefaultDirectorRegistry, createDirectorRegistry, createWorkflowDirectorRegistry, UnknownDirectorIdError, } from "./director-registry.js";
|
|
17
18
|
export { buildDefaultDirectorRef, defaultDirectorFactory, } from "./default-director.js";
|
|
18
19
|
export { InvalidInferenceSourceError, SourceNotFoundError, createSourceRegistry, } from "./source.js";
|
|
19
|
-
export { AgentClosedError, createAgent, } from "./agent.js";
|
|
20
|
+
export { AgentClosedError, GateSuspendedWithoutCorrelationError, createAgent, } from "./agent.js";
|
|
20
21
|
export { defineAgent, } from "./definition.js";
|
|
21
22
|
export { effectiveDirectorRef, getRequiredEnvKeys, validateEnv, } from "./env-validation.js";
|
|
22
23
|
export { SendQueueFullError } from "./send-queue.js";
|
|
@@ -20,7 +20,7 @@ export const MAIL_SOURCE = {
|
|
|
20
20
|
id: "anthropic:claude-opus-4-6",
|
|
21
21
|
provider: "anthropic",
|
|
22
22
|
baseURL: "https://api.anthropic.com",
|
|
23
|
-
|
|
23
|
+
credentialId: "sk-test-mail",
|
|
24
24
|
model: "claude-opus-4-6",
|
|
25
25
|
};
|
|
26
26
|
export const MAIL_ADDRESS = "support@fixture.local";
|
|
@@ -32,6 +32,7 @@ export const MAIL_ADDRESS = "support@fixture.local";
|
|
|
32
32
|
export const fixtureMailFactory = defineTool({
|
|
33
33
|
id: "@intx-fixtures/mail/bundle",
|
|
34
34
|
requires: ["transport", "address"],
|
|
35
|
+
definitions: [],
|
|
35
36
|
factory: () => ({
|
|
36
37
|
definitions: [],
|
|
37
38
|
async run(call) {
|
package/dist/testing/index.d.ts
CHANGED
package/dist/testing/index.js
CHANGED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolve once the stream emits `reactor.done`.
|
|
3
|
+
*
|
|
4
|
+
* Throws if the stream ends without it: returning would resolve as though the
|
|
5
|
+
* run had completed, and the caller would then fail on a later assertion
|
|
6
|
+
* instead of on the real cause.
|
|
7
|
+
*
|
|
8
|
+
* Typed structurally so a caller need not import the reactor's event union to
|
|
9
|
+
* await its terminal event.
|
|
10
|
+
*/
|
|
11
|
+
export declare function waitForReactorDone(stream: AsyncIterable<{
|
|
12
|
+
type: string;
|
|
13
|
+
}>): Promise<void>;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// Waiter over a reactor's emitted-event stream.
|
|
2
|
+
//
|
|
3
|
+
// A reactor run ends with a `reactor.done` event, including on the fatal
|
|
4
|
+
// error path, so a test that needs the run finished waits for that event
|
|
5
|
+
// rather than for an interval. CONVENTIONS.md names this shape as the one to
|
|
6
|
+
// copy; it lives here so it is imported rather than copied again.
|
|
7
|
+
/**
|
|
8
|
+
* Resolve once the stream emits `reactor.done`.
|
|
9
|
+
*
|
|
10
|
+
* Throws if the stream ends without it: returning would resolve as though the
|
|
11
|
+
* run had completed, and the caller would then fail on a later assertion
|
|
12
|
+
* instead of on the real cause.
|
|
13
|
+
*
|
|
14
|
+
* Typed structurally so a caller need not import the reactor's event union to
|
|
15
|
+
* await its terminal event.
|
|
16
|
+
*/
|
|
17
|
+
export async function waitForReactorDone(stream) {
|
|
18
|
+
for await (const event of stream) {
|
|
19
|
+
if (event.type === "reactor.done")
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
throw new Error("reactor event stream ended before reactor.done");
|
|
23
|
+
}
|
package/dist/tool.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { GrantEffect } from "@intx/types";
|
|
1
2
|
import type { ToolCall, ToolDefinition, ToolResult, ToolRunner } from "@intx/types/runtime";
|
|
2
3
|
import type { BaseEnv } from "./env.js";
|
|
3
4
|
export type ToolHandler = (call: ToolCall, signal: AbortSignal) => Promise<ToolResult>;
|
|
@@ -60,14 +61,44 @@ export interface ToolBundle {
|
|
|
60
61
|
* instantiation.
|
|
61
62
|
*/
|
|
62
63
|
export type ToolFactory<EnvReq extends BaseEnv = BaseEnv> = (env: EnvReq) => ToolBundle;
|
|
64
|
+
/**
|
|
65
|
+
* Static, per-definition declaration a tool factory carries so callers
|
|
66
|
+
* (e.g. the deploy-time capability walk) can enumerate the tool names a
|
|
67
|
+
* factory contributes WITHOUT instantiating it. `approval` marks a tool
|
|
68
|
+
* as requiring per-invocation approval; it is a deliberate subset of
|
|
69
|
+
* GrantEffect (only "ask" is expressible here — a declaration can request
|
|
70
|
+
* a gate, never a pre-deny).
|
|
71
|
+
*/
|
|
72
|
+
export interface ToolDeclaration {
|
|
73
|
+
readonly name: string;
|
|
74
|
+
readonly approval?: "ask";
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Map a tool's static approval mark to the `GrantEffect` floor its
|
|
78
|
+
* `tool:<name>` grant carries: an `ask`-marked tool floors at `ask` (its
|
|
79
|
+
* invocation must clear an approval gate), every other tool floors at
|
|
80
|
+
* `allow`.
|
|
81
|
+
*
|
|
82
|
+
* This is the single canonical derivation of a tool's authorization floor
|
|
83
|
+
* from its declaration. Both the deploy-time capability walk (hub-side)
|
|
84
|
+
* and the per-step tool authorization (sidecar-side) route through here so
|
|
85
|
+
* a pinned tool loaded in the child derives the SAME floor the walk would
|
|
86
|
+
* have derived from an inline declaration. A divergence between the two
|
|
87
|
+
* sites would let a pinned `ask` tool authorize as `allow` (or vice
|
|
88
|
+
* versa), so the mapping lives in exactly one place.
|
|
89
|
+
*/
|
|
90
|
+
export declare function toolApprovalEffect(declaration: Pick<ToolDeclaration, "approval">): GrantEffect;
|
|
63
91
|
/**
|
|
64
92
|
* Runtime metadata attached to a `ToolFactory` by `defineTool`. `id` is
|
|
65
93
|
* package-namespaced; `requires` enumerates env keys the factory touches
|
|
66
|
-
* beyond `BaseEnv`'s six core fields
|
|
94
|
+
* beyond `BaseEnv`'s six core fields; `definitions` statically declares
|
|
95
|
+
* the tool names the factory contributes so callers can enumerate them
|
|
96
|
+
* without instantiating the factory.
|
|
67
97
|
*/
|
|
68
98
|
export interface ToolFactoryMeta {
|
|
69
99
|
readonly id: string;
|
|
70
100
|
readonly requires: readonly string[];
|
|
101
|
+
readonly definitions: readonly ToolDeclaration[];
|
|
71
102
|
}
|
|
72
103
|
/**
|
|
73
104
|
* A tool factory carrying its runtime metadata. `defineTool` is the only
|
|
@@ -87,15 +118,20 @@ export type AnnotatedToolFactory<EnvReq extends BaseEnv = BaseEnv> = ToolFactory
|
|
|
87
118
|
* `BaseEnv`'s six core fields. The runtime `validateEnv` checks
|
|
88
119
|
* presence; the factory itself may also fail loud at construction
|
|
89
120
|
* if the env contents are structurally wrong.
|
|
121
|
+
* - `definitions` statically declares the tool names this factory
|
|
122
|
+
* contributes so callers (e.g. the deploy-time capability walk) can
|
|
123
|
+
* enumerate them without instantiating the factory.
|
|
90
124
|
* - `factory(env)` returns a `ToolBundle`. Invoked once per agent
|
|
91
125
|
* instantiation; the bundle's lifetime is tied to that agent.
|
|
92
126
|
*
|
|
93
127
|
* The returned object is the same callable as the supplied `factory`
|
|
94
|
-
* with `id
|
|
128
|
+
* with `id`, a frozen `requires` array, and a frozen `definitions`
|
|
129
|
+
* array attached.
|
|
95
130
|
*/
|
|
96
131
|
export declare function defineTool<EnvReq extends BaseEnv = BaseEnv>(opts: {
|
|
97
132
|
id: string;
|
|
98
133
|
requires?: readonly string[];
|
|
134
|
+
definitions: readonly ToolDeclaration[];
|
|
99
135
|
factory: ToolFactory<EnvReq>;
|
|
100
136
|
}): AnnotatedToolFactory<EnvReq>;
|
|
101
137
|
/**
|
|
@@ -126,6 +162,20 @@ export declare const PLUGIN_MARKER: unique symbol;
|
|
|
126
162
|
export interface AnnotatedPluginMeta {
|
|
127
163
|
readonly id: string;
|
|
128
164
|
readonly requires: readonly string[];
|
|
165
|
+
/**
|
|
166
|
+
* Static declaration of the tool names this plugin contributes at
|
|
167
|
+
* runtime, so a caller can enumerate the plugin's tool grant surface
|
|
168
|
+
* WITHOUT instantiating it (which for a plugin like LSP would start a
|
|
169
|
+
* language-server subprocess). A plugin adds its tools indirectly -- it
|
|
170
|
+
* hands a host-defined shape to the tool package that consumes
|
|
171
|
+
* `env.plugins`, which then registers the plugin's tools under its own
|
|
172
|
+
* bundle -- so the plugin's contributed tool names are otherwise
|
|
173
|
+
* invisible until run time. The deploy-time capability walk reads this
|
|
174
|
+
* field to authorize a plugin-contributed tool the same way it
|
|
175
|
+
* authorizes a factory-declared tool. Empty when the plugin contributes
|
|
176
|
+
* no standalone tool (middleware-only plugins).
|
|
177
|
+
*/
|
|
178
|
+
readonly definitions: readonly ToolDeclaration[];
|
|
129
179
|
readonly [PLUGIN_MARKER]: true;
|
|
130
180
|
}
|
|
131
181
|
export type AnnotatedPluginFactory<EnvReq extends BaseEnv = BaseEnv, Result = unknown> = PluginFactory<EnvReq, Result> & AnnotatedPluginMeta;
|
|
@@ -165,6 +215,12 @@ export declare function isToolPluginInstance(value: unknown): value is Record<st
|
|
|
165
215
|
export declare function definePlugin<Result extends object, EnvReq extends BaseEnv = BaseEnv>(opts: {
|
|
166
216
|
id: string;
|
|
167
217
|
requires?: readonly string[];
|
|
218
|
+
/**
|
|
219
|
+
* Static declaration of the tool names this plugin contributes at run
|
|
220
|
+
* time. Omit for a middleware-only plugin that adds no standalone tool.
|
|
221
|
+
* See `AnnotatedPluginMeta.definitions`.
|
|
222
|
+
*/
|
|
223
|
+
definitions?: readonly ToolDeclaration[];
|
|
168
224
|
factory: PluginFactory<EnvReq, Result>;
|
|
169
225
|
}): AnnotatedPluginFactory<EnvReq, Result & {
|
|
170
226
|
kind: ToolPluginKind;
|
package/dist/tool.js
CHANGED
|
@@ -66,6 +66,23 @@ export class DuplicateToolError extends Error {
|
|
|
66
66
|
this.toolName = toolName;
|
|
67
67
|
}
|
|
68
68
|
}
|
|
69
|
+
/**
|
|
70
|
+
* Map a tool's static approval mark to the `GrantEffect` floor its
|
|
71
|
+
* `tool:<name>` grant carries: an `ask`-marked tool floors at `ask` (its
|
|
72
|
+
* invocation must clear an approval gate), every other tool floors at
|
|
73
|
+
* `allow`.
|
|
74
|
+
*
|
|
75
|
+
* This is the single canonical derivation of a tool's authorization floor
|
|
76
|
+
* from its declaration. Both the deploy-time capability walk (hub-side)
|
|
77
|
+
* and the per-step tool authorization (sidecar-side) route through here so
|
|
78
|
+
* a pinned tool loaded in the child derives the SAME floor the walk would
|
|
79
|
+
* have derived from an inline declaration. A divergence between the two
|
|
80
|
+
* sites would let a pinned `ask` tool authorize as `allow` (or vice
|
|
81
|
+
* versa), so the mapping lives in exactly one place.
|
|
82
|
+
*/
|
|
83
|
+
export function toolApprovalEffect(declaration) {
|
|
84
|
+
return declaration.approval === "ask" ? "ask" : "allow";
|
|
85
|
+
}
|
|
69
86
|
/**
|
|
70
87
|
* Define a tool bundle factory.
|
|
71
88
|
*
|
|
@@ -75,17 +92,24 @@ export class DuplicateToolError extends Error {
|
|
|
75
92
|
* `BaseEnv`'s six core fields. The runtime `validateEnv` checks
|
|
76
93
|
* presence; the factory itself may also fail loud at construction
|
|
77
94
|
* if the env contents are structurally wrong.
|
|
95
|
+
* - `definitions` statically declares the tool names this factory
|
|
96
|
+
* contributes so callers (e.g. the deploy-time capability walk) can
|
|
97
|
+
* enumerate them without instantiating the factory.
|
|
78
98
|
* - `factory(env)` returns a `ToolBundle`. Invoked once per agent
|
|
79
99
|
* instantiation; the bundle's lifetime is tied to that agent.
|
|
80
100
|
*
|
|
81
101
|
* The returned object is the same callable as the supplied `factory`
|
|
82
|
-
* with `id
|
|
102
|
+
* with `id`, a frozen `requires` array, and a frozen `definitions`
|
|
103
|
+
* array attached.
|
|
83
104
|
*/
|
|
84
105
|
export function defineTool(opts) {
|
|
85
106
|
validateNamespacedId(opts.id);
|
|
86
107
|
const requires = Object.freeze([
|
|
87
108
|
...(opts.requires ?? []),
|
|
88
109
|
]);
|
|
110
|
+
const definitions = Object.freeze([
|
|
111
|
+
...opts.definitions,
|
|
112
|
+
]);
|
|
89
113
|
// Wrap the caller's factory rather than mutating it. A caller that
|
|
90
114
|
// shares a factory function across multiple `defineTool` calls
|
|
91
115
|
// (e.g. registering the same constructor under two ids in different
|
|
@@ -97,6 +121,7 @@ export function defineTool(opts) {
|
|
|
97
121
|
return Object.assign(wrapped, {
|
|
98
122
|
id: opts.id,
|
|
99
123
|
requires,
|
|
124
|
+
definitions,
|
|
100
125
|
});
|
|
101
126
|
}
|
|
102
127
|
/**
|
|
@@ -145,6 +170,9 @@ export function definePlugin(opts) {
|
|
|
145
170
|
const requires = Object.freeze([
|
|
146
171
|
...(opts.requires ?? []),
|
|
147
172
|
]);
|
|
173
|
+
const definitions = Object.freeze([
|
|
174
|
+
...(opts.definitions ?? []),
|
|
175
|
+
]);
|
|
148
176
|
const wrapped = (env) => {
|
|
149
177
|
const instance = opts.factory(env);
|
|
150
178
|
// Re-stamping the marker is harmless if the factory chose to set
|
|
@@ -155,6 +183,7 @@ export function definePlugin(opts) {
|
|
|
155
183
|
return Object.assign(wrapped, {
|
|
156
184
|
id: opts.id,
|
|
157
185
|
requires,
|
|
186
|
+
definitions,
|
|
158
187
|
[PLUGIN_MARKER]: true,
|
|
159
188
|
});
|
|
160
189
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@intx/agent",
|
|
3
|
-
"
|
|
3
|
+
"description": "In-process agent runtime: construct an agent, send it a message, get a reply",
|
|
4
|
+
"version": "0.4.0",
|
|
4
5
|
"license": "LGPL-2.1-only",
|
|
5
6
|
"type": "module",
|
|
6
7
|
"exports": {
|
|
@@ -16,14 +17,14 @@
|
|
|
16
17
|
}
|
|
17
18
|
},
|
|
18
19
|
"dependencies": {
|
|
19
|
-
"@intx/inference": "0.
|
|
20
|
-
"@intx/log": "0.
|
|
21
|
-
"@intx/mime": "0.
|
|
22
|
-
"@intx/types": "0.
|
|
20
|
+
"@intx/inference": "0.4.0",
|
|
21
|
+
"@intx/log": "0.4.0",
|
|
22
|
+
"@intx/mime": "0.4.0",
|
|
23
|
+
"@intx/types": "0.4.0",
|
|
23
24
|
"arktype": "^2.1.29"
|
|
24
25
|
},
|
|
25
26
|
"devDependencies": {
|
|
26
|
-
"@intx/storage-isogit": "0.
|
|
27
|
+
"@intx/storage-isogit": "0.4.0"
|
|
27
28
|
},
|
|
28
29
|
"files": [
|
|
29
30
|
"dist",
|