@code-yeongyu/senpi-agent-core 2026.9.30 → 2026.10.1-2
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 +49 -20
- package/dist/agent-loop.d.ts +27 -3
- package/dist/agent-loop.js +192 -56
- package/dist/agent.d.ts +21 -7
- package/dist/agent.js +38 -18
- package/dist/harness/execution/tools.d.ts +1 -1
- package/dist/harness/execution/tools.js +0 -2
- package/dist/harness/messages.js +1 -0
- package/dist/harness/pico3/bash.d.ts +10 -0
- package/dist/harness/pico3/bash.js +25 -0
- package/dist/harness/pico3/bounded.d.ts +21 -0
- package/dist/harness/pico3/bounded.js +95 -0
- package/dist/harness/pico3/chord.d.ts +41 -0
- package/dist/harness/pico3/chord.js +147 -0
- package/dist/harness/pico3/context.d.ts +16 -0
- package/dist/harness/pico3/context.js +88 -0
- package/dist/harness/pico3/harness.d.ts +198 -0
- package/dist/harness/pico3/harness.js +645 -0
- package/dist/harness/pico3/hooks.d.ts +10 -0
- package/dist/harness/pico3/hooks.js +33 -0
- package/dist/harness/pico3/index.d.ts +19 -0
- package/dist/harness/pico3/index.js +15 -0
- package/dist/harness/pico3/jsonl.d.ts +58 -0
- package/dist/harness/pico3/jsonl.js +322 -0
- package/dist/harness/pico3/kinds/collapse.d.ts +49 -0
- package/dist/harness/pico3/kinds/collapse.js +191 -0
- package/dist/harness/pico3/kinds/entries.d.ts +78 -0
- package/dist/harness/pico3/kinds/entries.js +13 -0
- package/dist/harness/pico3/kinds/frames.d.ts +9 -0
- package/dist/harness/pico3/kinds/frames.js +75 -0
- package/dist/harness/pico3/kinds/generation.d.ts +94 -0
- package/dist/harness/pico3/kinds/generation.js +504 -0
- package/dist/harness/pico3/kinds/job.d.ts +44 -0
- package/dist/harness/pico3/kinds/job.js +143 -0
- package/dist/harness/pico3/kinds/plugin.d.ts +15 -0
- package/dist/harness/pico3/kinds/plugin.js +35 -0
- package/dist/harness/pico3/kinds/post-tools.d.ts +22 -0
- package/dist/harness/pico3/kinds/post-tools.js +145 -0
- package/dist/harness/pico3/kinds/task-api.d.ts +3 -0
- package/dist/harness/pico3/kinds/task-api.js +45 -0
- package/dist/harness/pico3/kinds/tool.d.ts +43 -0
- package/dist/harness/pico3/kinds/tool.js +373 -0
- package/dist/harness/pico3/legacy-tracker.d.ts +11 -0
- package/dist/harness/pico3/legacy-tracker.js +39 -0
- package/dist/harness/pico3/membrane.d.ts +23 -0
- package/dist/harness/pico3/membrane.js +140 -0
- package/dist/harness/pico3/memory.d.ts +53 -0
- package/dist/harness/pico3/memory.js +265 -0
- package/dist/harness/pico3/scheduler.d.ts +49 -0
- package/dist/harness/pico3/scheduler.js +437 -0
- package/dist/harness/pico3/session.d.ts +264 -0
- package/dist/harness/pico3/session.js +1328 -0
- package/dist/harness/pico3/system.d.ts +126 -0
- package/dist/harness/pico3/system.js +244 -0
- package/dist/harness/pico3/types.d.ts +973 -0
- package/dist/harness/pico3/types.js +94 -0
- package/dist/harness/pico3/view.d.ts +34 -0
- package/dist/harness/pico3/view.js +404 -0
- package/dist/harness/runtime/drive/tool-placement.js +2 -27
- package/dist/harness/telemetry.d.ts +36 -36
- package/dist/harness/tools/image.js +1 -1
- package/dist/proxy.d.ts +2 -2
- package/dist/types.d.ts +111 -34
- package/package.json +9 -5
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import type { AssistantMessage, ToolResultMessage, UserMessage } from "@earendil-works/pi-ai";
|
|
2
|
+
import type { Entry, EntryKind, Id, JsonValue, SystemMessage, ToolControl } from "../types.ts";
|
|
3
|
+
export type UserEntry = Entry & {
|
|
4
|
+
kind: "pi.user";
|
|
5
|
+
model: [UserMessage];
|
|
6
|
+
data?: {
|
|
7
|
+
continuation: true;
|
|
8
|
+
from: Id;
|
|
9
|
+
};
|
|
10
|
+
};
|
|
11
|
+
export type AssistantEntry = Entry & {
|
|
12
|
+
kind: "pi.assistant";
|
|
13
|
+
model: [AssistantMessage];
|
|
14
|
+
data: {
|
|
15
|
+
attempt: number;
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
export type ToolResultEntry = Entry & {
|
|
19
|
+
kind: "pi.tool_result";
|
|
20
|
+
model: [ToolResultMessage];
|
|
21
|
+
data: {
|
|
22
|
+
details?: JsonValue;
|
|
23
|
+
diagnostics?: JsonValue;
|
|
24
|
+
control?: ToolControl;
|
|
25
|
+
truncated?: {
|
|
26
|
+
bytes: number;
|
|
27
|
+
lines: number;
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
export type SystemEntry = Entry & {
|
|
32
|
+
kind: "pi.system";
|
|
33
|
+
model: [SystemMessage];
|
|
34
|
+
data: {
|
|
35
|
+
baseline: boolean;
|
|
36
|
+
};
|
|
37
|
+
};
|
|
38
|
+
export type NoticeEntry = Entry & {
|
|
39
|
+
kind: "pi.notice";
|
|
40
|
+
model: [UserMessage];
|
|
41
|
+
};
|
|
42
|
+
export type UsageEntry = Entry & {
|
|
43
|
+
kind: "pi.usage";
|
|
44
|
+
data: {
|
|
45
|
+
attempt: number;
|
|
46
|
+
usage?: AssistantMessage["usage"];
|
|
47
|
+
error: string;
|
|
48
|
+
};
|
|
49
|
+
};
|
|
50
|
+
export type SummaryEntry = Entry & {
|
|
51
|
+
kind: "pi.summary";
|
|
52
|
+
model: [UserMessage];
|
|
53
|
+
data: {
|
|
54
|
+
through: Id;
|
|
55
|
+
};
|
|
56
|
+
head: Id;
|
|
57
|
+
};
|
|
58
|
+
export type HandoffEntry = Entry & {
|
|
59
|
+
kind: "pi.handoff";
|
|
60
|
+
model: [UserMessage];
|
|
61
|
+
head: Id;
|
|
62
|
+
};
|
|
63
|
+
export type ResetEntry = Entry & {
|
|
64
|
+
kind: "pi.reset";
|
|
65
|
+
head: Id;
|
|
66
|
+
};
|
|
67
|
+
export declare const entries: {
|
|
68
|
+
readonly user: EntryKind<UserEntry>;
|
|
69
|
+
readonly assistant: EntryKind<AssistantEntry>;
|
|
70
|
+
readonly toolResult: EntryKind<ToolResultEntry>;
|
|
71
|
+
readonly system: EntryKind<SystemEntry>;
|
|
72
|
+
readonly notice: EntryKind<NoticeEntry>;
|
|
73
|
+
readonly usage: EntryKind<UsageEntry>;
|
|
74
|
+
readonly summary: EntryKind<SummaryEntry>;
|
|
75
|
+
readonly handoff: EntryKind<HandoffEntry>;
|
|
76
|
+
readonly reset: EntryKind<ResetEntry>;
|
|
77
|
+
};
|
|
78
|
+
//# sourceMappingURL=entries.d.ts.map
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
const coreEntry = (kind) => Object.freeze({ kind, is: (entry) => entry?.kind === kind });
|
|
2
|
+
export const entries = {
|
|
3
|
+
user: coreEntry("pi.user"),
|
|
4
|
+
assistant: coreEntry("pi.assistant"),
|
|
5
|
+
toolResult: coreEntry("pi.tool_result"),
|
|
6
|
+
system: coreEntry("pi.system"),
|
|
7
|
+
notice: coreEntry("pi.notice"),
|
|
8
|
+
usage: coreEntry("pi.usage"),
|
|
9
|
+
summary: coreEntry("pi.summary"),
|
|
10
|
+
handoff: coreEntry("pi.handoff"),
|
|
11
|
+
reset: coreEntry("pi.reset"),
|
|
12
|
+
};
|
|
13
|
+
//# sourceMappingURL=entries.js.map
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { AssistantMessage, AssistantMessageFrame } from "@earendil-works/pi-ai";
|
|
2
|
+
/**
|
|
3
|
+
* Apply one encoded frame to the tracked output. Same switch as pi-ai's
|
|
4
|
+
* reduceAssistantMessageFrames (the test oracle); no buffering, no second copy.
|
|
5
|
+
*/
|
|
6
|
+
export declare function applyFrame(o: {
|
|
7
|
+
message?: AssistantMessage;
|
|
8
|
+
}, frame: AssistantMessageFrame): void;
|
|
9
|
+
//# sourceMappingURL=frames.d.ts.map
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Apply one encoded frame to the tracked output. Same switch as pi-ai's
|
|
3
|
+
* reduceAssistantMessageFrames (the test oracle); no buffering, no second copy.
|
|
4
|
+
*/
|
|
5
|
+
export function applyFrame(o, frame) {
|
|
6
|
+
if (frame.type === "start") {
|
|
7
|
+
o.message = frame.partial; // the encoder's clone
|
|
8
|
+
return;
|
|
9
|
+
}
|
|
10
|
+
const m = o.message;
|
|
11
|
+
if (m === undefined)
|
|
12
|
+
throw new Error(`${frame.type} before start`);
|
|
13
|
+
const c = m.content;
|
|
14
|
+
switch (frame.type) {
|
|
15
|
+
case "text_start":
|
|
16
|
+
c[frame.contentIndex] = { ...frame.content };
|
|
17
|
+
return;
|
|
18
|
+
case "text_delta":
|
|
19
|
+
c[frame.contentIndex].text += frame.delta;
|
|
20
|
+
return;
|
|
21
|
+
case "text_end": {
|
|
22
|
+
const b = c[frame.contentIndex];
|
|
23
|
+
b.text = frame.content;
|
|
24
|
+
delete b.textSignature;
|
|
25
|
+
if (frame.textSignature !== undefined)
|
|
26
|
+
b.textSignature = frame.textSignature;
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
case "thinking_start":
|
|
30
|
+
c[frame.contentIndex] = { ...frame.content };
|
|
31
|
+
return;
|
|
32
|
+
case "thinking_delta":
|
|
33
|
+
c[frame.contentIndex].thinking += frame.delta;
|
|
34
|
+
return;
|
|
35
|
+
case "thinking_end": {
|
|
36
|
+
const b = c[frame.contentIndex];
|
|
37
|
+
b.thinking = frame.content;
|
|
38
|
+
delete b.thinkingSignature;
|
|
39
|
+
delete b.redacted;
|
|
40
|
+
if (frame.thinkingSignature !== undefined)
|
|
41
|
+
b.thinkingSignature = frame.thinkingSignature;
|
|
42
|
+
if (frame.redacted !== undefined)
|
|
43
|
+
b.redacted = frame.redacted;
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
case "toolcall_start":
|
|
47
|
+
c[frame.contentIndex] = { ...frame.toolCall };
|
|
48
|
+
return;
|
|
49
|
+
case "toolcall_checkpoint":
|
|
50
|
+
c[frame.contentIndex].arguments = safeParse(frame.json);
|
|
51
|
+
return;
|
|
52
|
+
case "toolcall_delta":
|
|
53
|
+
return; // arguments materialise at checkpoint/end; deltas only feed the encoder's own json buffer
|
|
54
|
+
case "toolcall_end": {
|
|
55
|
+
const b = c[frame.contentIndex];
|
|
56
|
+
b.id = frame.id;
|
|
57
|
+
b.name = frame.name;
|
|
58
|
+
b.arguments = frame.arguments;
|
|
59
|
+
if (frame.thoughtSignature !== undefined)
|
|
60
|
+
b.thoughtSignature = frame.thoughtSignature;
|
|
61
|
+
if (frame.namespace !== undefined)
|
|
62
|
+
b.namespace = frame.namespace;
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
function safeParse(json) {
|
|
68
|
+
try {
|
|
69
|
+
return JSON.parse(json);
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
return {};
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=frames.js.map
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import type { Context } from "@earendil-works/chord";
|
|
2
|
+
import type { AssistantMessage, DeferredHandle } from "@earendil-works/pi-ai";
|
|
3
|
+
import { type SystemInstructionsHooks } from "../system.ts";
|
|
4
|
+
import { type CoreKind, type HookInfo, type HookResult, type Id, type ModelRef, type RequestMessage, type RetryPolicy, type Stored, type ThinkingLevel } from "../types.ts";
|
|
5
|
+
export type GenerationInput = {
|
|
6
|
+
inputs: Id[];
|
|
7
|
+
};
|
|
8
|
+
/** Captured once at `prepared`; carried unchanged except `attempt`. */
|
|
9
|
+
type Prep = {
|
|
10
|
+
cutoff: Id;
|
|
11
|
+
system: Id | null;
|
|
12
|
+
model: ModelRef;
|
|
13
|
+
thinkingLevel: ThinkingLevel;
|
|
14
|
+
tools: string[];
|
|
15
|
+
retry: RetryPolicy;
|
|
16
|
+
attempt: number;
|
|
17
|
+
};
|
|
18
|
+
export type GenerationCheckpoint = ({
|
|
19
|
+
phase: "prepared";
|
|
20
|
+
} & Prep) | ({
|
|
21
|
+
phase: "requesting";
|
|
22
|
+
} & Prep) | ({
|
|
23
|
+
phase: "retrying";
|
|
24
|
+
untilMs: number;
|
|
25
|
+
lastError: string;
|
|
26
|
+
} & Prep) | ({
|
|
27
|
+
phase: "deferred";
|
|
28
|
+
handle: Stored<DeferredHandle>;
|
|
29
|
+
pollAt: number;
|
|
30
|
+
} & Prep);
|
|
31
|
+
export type GenerationResult = {
|
|
32
|
+
assistant: Id;
|
|
33
|
+
tools: Id[];
|
|
34
|
+
postTools?: Id;
|
|
35
|
+
successor?: Id;
|
|
36
|
+
};
|
|
37
|
+
export type GenerationFailure = {
|
|
38
|
+
reason: "provider" | "overflow" | "retries_exhausted" | "no_model";
|
|
39
|
+
detail: string;
|
|
40
|
+
assistant?: Id;
|
|
41
|
+
};
|
|
42
|
+
/** Display-only assistant entries (provider error, aborted partial) carry the message here, never in `model`. */
|
|
43
|
+
export type DisplayAssistantData = {
|
|
44
|
+
attempt: number;
|
|
45
|
+
display: Stored<AssistantMessage>;
|
|
46
|
+
reason: "error" | "aborted";
|
|
47
|
+
};
|
|
48
|
+
/** Hook points this kind calls. Register with `h.hooks(namespace, kinds.generation, { … })`. */
|
|
49
|
+
export interface GenerationHooks extends SystemInstructionsHooks {
|
|
50
|
+
/** Before every request (also on retry and recovery). Chain. */
|
|
51
|
+
beforeRequest(request: {
|
|
52
|
+
messages: RequestMessage[];
|
|
53
|
+
}, info: HookInfo & {
|
|
54
|
+
cutoff: Id;
|
|
55
|
+
}, ctx: Context): HookResult<{
|
|
56
|
+
messages: RequestMessage[];
|
|
57
|
+
}>;
|
|
58
|
+
/** Every terminal provider message, before classification. Observer. */
|
|
59
|
+
afterResponse(message: AssistantMessage, info: HookInfo & {
|
|
60
|
+
attempt: number;
|
|
61
|
+
}, ctx: Context): void | Promise<void>;
|
|
62
|
+
/** On a final answer with nothing queued. First `{ continue }` wins and starts a continuation. */
|
|
63
|
+
onYield(answer: AssistantMessage, info: HookInfo, ctx: Context): HookResult<{
|
|
64
|
+
continue: string;
|
|
65
|
+
}>;
|
|
66
|
+
}
|
|
67
|
+
/** Configuration this kind reads, with defaults. `model` has none: absent → failed/no_model. */
|
|
68
|
+
export declare const generationConfig: {
|
|
69
|
+
readonly rewindable: {
|
|
70
|
+
readonly model: ModelRef | undefined;
|
|
71
|
+
readonly thinkingLevel: ThinkingLevel;
|
|
72
|
+
readonly selectedTools: string[];
|
|
73
|
+
readonly profile: string;
|
|
74
|
+
};
|
|
75
|
+
readonly sticky: {
|
|
76
|
+
readonly retry: RetryPolicy;
|
|
77
|
+
};
|
|
78
|
+
};
|
|
79
|
+
export declare const generation: CoreKind<GenerationInput, GenerationCheckpoint, GenerationResult, GenerationFailure, {
|
|
80
|
+
assistant?: Id;
|
|
81
|
+
}, GenerationHooks, typeof generationConfig>;
|
|
82
|
+
type RetryDecision = {
|
|
83
|
+
kind: "retry";
|
|
84
|
+
untilMs: number;
|
|
85
|
+
} | {
|
|
86
|
+
kind: "fail";
|
|
87
|
+
reason: "provider" | "retries_exhausted";
|
|
88
|
+
};
|
|
89
|
+
export declare function retryDecision(cp: {
|
|
90
|
+
retry: RetryPolicy;
|
|
91
|
+
attempt: number;
|
|
92
|
+
}, message: AssistantMessage | null, now: number): RetryDecision;
|
|
93
|
+
export {};
|
|
94
|
+
//# sourceMappingURL=generation.d.ts.map
|