@gajae-code/agent-core 0.15.5 → 0.15.6
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/CHANGELOG.md +2 -0
- package/dist/types/agent.d.ts +15 -3
- package/dist/types/types.d.ts +15 -1
- package/package.json +4 -4
- package/src/agent-loop.ts +7 -1
- package/src/agent.ts +37 -4
- package/src/types.ts +16 -1
package/CHANGELOG.md
CHANGED
package/dist/types/agent.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ import { type AssistantMessage, type AssistantMessageEvent, type CursorExecHandl
|
|
|
5
5
|
import type { AppendOnlyContextManager } from "./append-only-context";
|
|
6
6
|
import type { AttemptRunHandle, AttemptScope } from "./attempt-scope";
|
|
7
7
|
import type { HarmonyAuditEvent } from "./harmony-leak";
|
|
8
|
-
import type { AgentEvent, AgentLoopConfig, AgentMessage, AgentState, AgentTool, AgentToolContext, ManagedLogicalRunId, RunCancellationDomainBridge, RunResourceLedger, RunTerminalRequest, StreamFn, ToolCallContext } from "./types";
|
|
8
|
+
import type { AgentEvent, AgentLoopConfig, AgentMessage, AgentMetadataResolverContext, AgentState, AgentTool, AgentToolContext, ManagedLogicalRunId, RunCancellationDomainBridge, RunResourceLedger, RunTerminalRequest, StreamFn, ToolCallContext } from "./types";
|
|
9
9
|
/**
|
|
10
10
|
* Whether persisted history ends at a point where a new model turn can resume.
|
|
11
11
|
* Assistant-ended histories require an in-memory queued message and are handled
|
|
@@ -271,7 +271,7 @@ export declare class Agent {
|
|
|
271
271
|
* only included for `"anthropic"` requests). Falls back to the static
|
|
272
272
|
* {@link metadata} value when no resolver is set.
|
|
273
273
|
*/
|
|
274
|
-
metadataForProvider(provider: string): Record<string, unknown> | undefined;
|
|
274
|
+
metadataForProvider(provider: string, model?: Model, transport?: AgentMetadataResolverContext["transport"]): Record<string, unknown> | undefined;
|
|
275
275
|
/**
|
|
276
276
|
* Install a function that resolves request metadata at call time. The
|
|
277
277
|
* resolver receives the target provider string and can gate provider-specific
|
|
@@ -280,7 +280,7 @@ export declare class Agent {
|
|
|
280
280
|
* credential. Pass `undefined` to clear and revert to the static
|
|
281
281
|
* {@link metadata} value.
|
|
282
282
|
*/
|
|
283
|
-
setMetadataResolver(resolver: ((
|
|
283
|
+
setMetadataResolver(resolver: ((context: AgentMetadataResolverContext) => Record<string, unknown> | undefined) | undefined): void;
|
|
284
284
|
/**
|
|
285
285
|
* Read the active OpenTelemetry configuration. Returns `undefined` when
|
|
286
286
|
* instrumentation is disabled. Callers spawning child runs (e.g. subagent
|
|
@@ -358,6 +358,18 @@ export declare class Agent {
|
|
|
358
358
|
setProvisionalAssistantMessageEventInterceptor(fn: ((message: AssistantMessage, event: AssistantMessageEvent) => void) | undefined): void;
|
|
359
359
|
setOnBeforeYield(fn: (() => Promise<void> | void) | undefined): void;
|
|
360
360
|
setShouldPause(fn: AgentLoopConfig["shouldPause"] | undefined): void;
|
|
361
|
+
/** The currently installed cooperative pause checkpoint, if any. */
|
|
362
|
+
get shouldPause(): AgentLoopConfig["shouldPause"] | undefined;
|
|
363
|
+
/**
|
|
364
|
+
* Fence old-turn steering admission.
|
|
365
|
+
*
|
|
366
|
+
* The loop polls steering UPSTREAM of its pause checkpoint (and again on the
|
|
367
|
+
* immediate-interrupt path), so a cooperative stop alone cannot prevent one
|
|
368
|
+
* more old-turn model call once a steering message has already been dequeued.
|
|
369
|
+
* While the fence returns true the poll yields no messages AND does not
|
|
370
|
+
* dequeue, so the queue survives intact for the next turn.
|
|
371
|
+
*/
|
|
372
|
+
setSteeringAdmissionFence(fn: (() => boolean) | undefined): void;
|
|
361
373
|
setMaintainContext(fn: AgentLoopConfig["maintainContext"] | undefined): void;
|
|
362
374
|
/**
|
|
363
375
|
* Publish an event produced OUTSIDE the agent loop (a provider that executed the tool
|
package/dist/types/types.d.ts
CHANGED
|
@@ -6,6 +6,20 @@ import type { AgentRunCoverage, AgentRunSummary } from "./run-collector";
|
|
|
6
6
|
import type { AgentTelemetryConfig } from "./telemetry";
|
|
7
7
|
/** Stream function - can return sync or Promise for async config lookup */
|
|
8
8
|
export type StreamFn = (...args: Parameters<typeof streamSimple>) => AssistantMessageEventStream | Promise<AssistantMessageEventStream>;
|
|
9
|
+
/**
|
|
10
|
+
* Request context supplied to provider-aware metadata resolvers.
|
|
11
|
+
*
|
|
12
|
+
* The model is the exact model selected for the concrete request (including
|
|
13
|
+
* fallback and ephemeral requests), while `transport` distinguishes the
|
|
14
|
+
* built-in stream path from a caller-supplied stream function. Metadata that
|
|
15
|
+
* carries provider identity must use both values to fail closed when routing
|
|
16
|
+
* is not the canonical provider path.
|
|
17
|
+
*/
|
|
18
|
+
export interface AgentMetadataResolverContext {
|
|
19
|
+
provider: string;
|
|
20
|
+
model?: Model;
|
|
21
|
+
transport?: "default" | "custom";
|
|
22
|
+
}
|
|
9
23
|
/** Stable identifier for a managed logical run, shared by all of its retry attempts. */
|
|
10
24
|
export type ManagedLogicalRunId = number;
|
|
11
25
|
/** A resource owned by a prompt run until its promise settles. */
|
|
@@ -233,7 +247,7 @@ export interface AgentLoopConfig extends SimpleStreamOptions {
|
|
|
233
247
|
* current when `AgentLoopConfig` was first constructed). Overrides the static
|
|
234
248
|
* `metadata` field when present.
|
|
235
249
|
*/
|
|
236
|
-
metadataResolver?: (
|
|
250
|
+
metadataResolver?: (context: AgentMetadataResolverContext) => Record<string, unknown> | undefined;
|
|
237
251
|
/**
|
|
238
252
|
* Converts AgentMessage[] to LLM-compatible Message[] before each LLM call.
|
|
239
253
|
*
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@gajae-code/agent-core",
|
|
4
|
-
"version": "0.15.
|
|
4
|
+
"version": "0.15.6",
|
|
5
5
|
"description": "General-purpose agent with transport abstraction, state management, and attachment support",
|
|
6
6
|
"homepage": "https://gajae-code.com",
|
|
7
7
|
"author": "Yeachan-Heo and Gajae Code Contributors",
|
|
@@ -32,9 +32,9 @@
|
|
|
32
32
|
"fmt": "biome format --write ."
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@gajae-code/ai": "0.15.
|
|
36
|
-
"@gajae-code/natives": "0.15.
|
|
37
|
-
"@gajae-code/utils": "0.15.
|
|
35
|
+
"@gajae-code/ai": "0.15.6",
|
|
36
|
+
"@gajae-code/natives": "0.15.6",
|
|
37
|
+
"@gajae-code/utils": "0.15.6",
|
|
38
38
|
"@opentelemetry/api": "^1.9.0"
|
|
39
39
|
},
|
|
40
40
|
"devDependencies": {
|
package/src/agent-loop.ts
CHANGED
|
@@ -4523,7 +4523,13 @@ async function streamAssistantResponse(
|
|
|
4523
4523
|
// reflects the credential actually used, not the snapshot from AgentLoopConfig construction.
|
|
4524
4524
|
const authCredentialType = config.getAuthCredentialType?.(config.model.provider);
|
|
4525
4525
|
|
|
4526
|
-
const resolvedMetadata = config.metadataResolver
|
|
4526
|
+
const resolvedMetadata = config.metadataResolver
|
|
4527
|
+
? config.metadataResolver({
|
|
4528
|
+
provider: config.model.provider,
|
|
4529
|
+
model: config.model,
|
|
4530
|
+
transport: streamFunction === streamSimple ? "default" : "custom",
|
|
4531
|
+
})
|
|
4532
|
+
: config.metadata;
|
|
4527
4533
|
|
|
4528
4534
|
// Synthetic recovery requests choose their tool mode explicitly below and
|
|
4529
4535
|
// must never consume a queued dynamic choice intended for an ordinary turn.
|
package/src/agent.ts
CHANGED
|
@@ -38,6 +38,7 @@ import type {
|
|
|
38
38
|
AgentEvent,
|
|
39
39
|
AgentLoopConfig,
|
|
40
40
|
AgentMessage,
|
|
41
|
+
AgentMetadataResolverContext,
|
|
41
42
|
AgentState,
|
|
42
43
|
AgentTool,
|
|
43
44
|
AgentToolContext,
|
|
@@ -466,7 +467,7 @@ export class Agent {
|
|
|
466
467
|
#sessionId?: string;
|
|
467
468
|
#providerSessionId?: string;
|
|
468
469
|
#metadata?: Record<string, unknown>;
|
|
469
|
-
#metadataResolver?: (
|
|
470
|
+
#metadataResolver?: (context: AgentMetadataResolverContext) => Record<string, unknown> | undefined;
|
|
470
471
|
#providerSessionState?: Map<string, ProviderSessionState>;
|
|
471
472
|
#thinkingBudgets?: ThinkingBudgets;
|
|
472
473
|
#temperature?: number;
|
|
@@ -505,6 +506,8 @@ export class Agent {
|
|
|
505
506
|
#onHarmonyLeak?: (event: HarmonyAuditEvent) => void | Promise<void>;
|
|
506
507
|
#onBeforeYield?: () => Promise<void> | void;
|
|
507
508
|
#shouldPause?: AgentLoopConfig["shouldPause"];
|
|
509
|
+
/** While set and returning true, steering is neither admitted nor dequeued. */
|
|
510
|
+
#steeringAdmissionFence?: () => boolean;
|
|
508
511
|
#maintainContext?: AgentLoopConfig["maintainContext"];
|
|
509
512
|
#telemetry?: AgentLoopConfig["telemetry"];
|
|
510
513
|
#appendOnlyContext?: AppendOnlyContextManager;
|
|
@@ -669,8 +672,12 @@ export class Agent {
|
|
|
669
672
|
* only included for `"anthropic"` requests). Falls back to the static
|
|
670
673
|
* {@link metadata} value when no resolver is set.
|
|
671
674
|
*/
|
|
672
|
-
metadataForProvider(
|
|
673
|
-
|
|
675
|
+
metadataForProvider(
|
|
676
|
+
provider: string,
|
|
677
|
+
model?: Model,
|
|
678
|
+
transport?: AgentMetadataResolverContext["transport"],
|
|
679
|
+
): Record<string, unknown> | undefined {
|
|
680
|
+
if (this.#metadataResolver) return this.#metadataResolver({ provider, model, transport });
|
|
674
681
|
return this.#metadata;
|
|
675
682
|
}
|
|
676
683
|
|
|
@@ -682,7 +689,9 @@ export class Agent {
|
|
|
682
689
|
* credential. Pass `undefined` to clear and revert to the static
|
|
683
690
|
* {@link metadata} value.
|
|
684
691
|
*/
|
|
685
|
-
setMetadataResolver(
|
|
692
|
+
setMetadataResolver(
|
|
693
|
+
resolver: ((context: AgentMetadataResolverContext) => Record<string, unknown> | undefined) | undefined,
|
|
694
|
+
): void {
|
|
686
695
|
this.#metadataResolver = resolver;
|
|
687
696
|
}
|
|
688
697
|
|
|
@@ -891,6 +900,24 @@ export class Agent {
|
|
|
891
900
|
this.#shouldPause = fn;
|
|
892
901
|
}
|
|
893
902
|
|
|
903
|
+
/** The currently installed cooperative pause checkpoint, if any. */
|
|
904
|
+
get shouldPause(): AgentLoopConfig["shouldPause"] | undefined {
|
|
905
|
+
return this.#shouldPause;
|
|
906
|
+
}
|
|
907
|
+
|
|
908
|
+
/**
|
|
909
|
+
* Fence old-turn steering admission.
|
|
910
|
+
*
|
|
911
|
+
* The loop polls steering UPSTREAM of its pause checkpoint (and again on the
|
|
912
|
+
* immediate-interrupt path), so a cooperative stop alone cannot prevent one
|
|
913
|
+
* more old-turn model call once a steering message has already been dequeued.
|
|
914
|
+
* While the fence returns true the poll yields no messages AND does not
|
|
915
|
+
* dequeue, so the queue survives intact for the next turn.
|
|
916
|
+
*/
|
|
917
|
+
setSteeringAdmissionFence(fn: (() => boolean) | undefined): void {
|
|
918
|
+
this.#steeringAdmissionFence = fn;
|
|
919
|
+
}
|
|
920
|
+
|
|
894
921
|
setMaintainContext(fn: AgentLoopConfig["maintainContext"] | undefined): void {
|
|
895
922
|
this.#maintainContext = fn;
|
|
896
923
|
}
|
|
@@ -1911,6 +1938,12 @@ export class Agent {
|
|
|
1911
1938
|
skipInitialSteeringPoll = false;
|
|
1912
1939
|
return [];
|
|
1913
1940
|
}
|
|
1941
|
+
// Fenced: yield nothing and dequeue nothing, so a steer submitted while a
|
|
1942
|
+
// fold is being claimed is neither consumed by the run being wound down
|
|
1943
|
+
// nor lost.
|
|
1944
|
+
if (this.#steeringAdmissionFence?.() === true) {
|
|
1945
|
+
return [];
|
|
1946
|
+
}
|
|
1914
1947
|
const queued = this.#dequeueSteeringMessages();
|
|
1915
1948
|
if (this.#activeRunId !== runId) {
|
|
1916
1949
|
this.#steeringQueue = [...queued, ...this.#steeringQueue];
|
package/src/types.ts
CHANGED
|
@@ -28,6 +28,21 @@ export type StreamFn = (
|
|
|
28
28
|
...args: Parameters<typeof streamSimple>
|
|
29
29
|
) => AssistantMessageEventStream | Promise<AssistantMessageEventStream>;
|
|
30
30
|
|
|
31
|
+
/**
|
|
32
|
+
* Request context supplied to provider-aware metadata resolvers.
|
|
33
|
+
*
|
|
34
|
+
* The model is the exact model selected for the concrete request (including
|
|
35
|
+
* fallback and ephemeral requests), while `transport` distinguishes the
|
|
36
|
+
* built-in stream path from a caller-supplied stream function. Metadata that
|
|
37
|
+
* carries provider identity must use both values to fail closed when routing
|
|
38
|
+
* is not the canonical provider path.
|
|
39
|
+
*/
|
|
40
|
+
export interface AgentMetadataResolverContext {
|
|
41
|
+
provider: string;
|
|
42
|
+
model?: Model;
|
|
43
|
+
transport?: "default" | "custom";
|
|
44
|
+
}
|
|
45
|
+
|
|
31
46
|
/** Stable identifier for a managed logical run, shared by all of its retry attempts. */
|
|
32
47
|
export type ManagedLogicalRunId = number;
|
|
33
48
|
/** A resource owned by a prompt run until its promise settles. */
|
|
@@ -257,7 +272,7 @@ export interface AgentLoopConfig extends SimpleStreamOptions {
|
|
|
257
272
|
* current when `AgentLoopConfig` was first constructed). Overrides the static
|
|
258
273
|
* `metadata` field when present.
|
|
259
274
|
*/
|
|
260
|
-
metadataResolver?: (
|
|
275
|
+
metadataResolver?: (context: AgentMetadataResolverContext) => Record<string, unknown> | undefined;
|
|
261
276
|
|
|
262
277
|
/**
|
|
263
278
|
* Converts AgentMessage[] to LLM-compatible Message[] before each LLM call.
|