pi-loop-graph-sdk 0.2.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.
Files changed (107) hide show
  1. package/LICENSE +21 -0
  2. package/README-zh.md +416 -0
  3. package/README.md +414 -0
  4. package/ROADMAP.md +60 -0
  5. package/dist/adapter/complete-tool.d.ts +3 -0
  6. package/dist/adapter/complete-tool.js +53 -0
  7. package/dist/adapter/debug-log.d.ts +38 -0
  8. package/dist/adapter/debug-log.js +151 -0
  9. package/dist/adapter/extension.d.ts +2 -0
  10. package/dist/adapter/extension.js +11 -0
  11. package/dist/adapter/graph-execution-host.d.ts +73 -0
  12. package/dist/adapter/graph-execution-host.js +181 -0
  13. package/dist/adapter/isolated-graph-session.d.ts +75 -0
  14. package/dist/adapter/isolated-graph-session.js +313 -0
  15. package/dist/adapter/loop-graph-extension.d.ts +96 -0
  16. package/dist/adapter/loop-graph-extension.js +487 -0
  17. package/dist/adapter/mechanism-runtime.d.ts +97 -0
  18. package/dist/adapter/mechanism-runtime.js +670 -0
  19. package/dist/adapter/model-messages.d.ts +17 -0
  20. package/dist/adapter/model-messages.js +11 -0
  21. package/dist/adapter/observability.d.ts +88 -0
  22. package/dist/adapter/observability.js +31 -0
  23. package/dist/adapter/output-contract.d.ts +12 -0
  24. package/dist/adapter/output-contract.js +87 -0
  25. package/dist/adapter/pi-node-context.d.ts +132 -0
  26. package/dist/adapter/pi-node-context.js +619 -0
  27. package/dist/adapter/projection.d.ts +121 -0
  28. package/dist/adapter/projection.js +169 -0
  29. package/dist/adapter/skill-content.d.ts +16 -0
  30. package/dist/adapter/skill-content.js +16 -0
  31. package/dist/advanced.d.ts +32 -0
  32. package/dist/advanced.js +17 -0
  33. package/dist/builders/graph.d.ts +27 -0
  34. package/dist/builders/graph.js +39 -0
  35. package/dist/builders/node.d.ts +8 -0
  36. package/dist/builders/node.js +9 -0
  37. package/dist/builders/refs.d.ts +5 -0
  38. package/dist/builders/refs.js +10 -0
  39. package/dist/builders/route.d.ts +11 -0
  40. package/dist/builders/route.js +18 -0
  41. package/dist/core/context.d.ts +73 -0
  42. package/dist/core/context.js +229 -0
  43. package/dist/core/graph.d.ts +172 -0
  44. package/dist/core/graph.js +57 -0
  45. package/dist/core/json.d.ts +8 -0
  46. package/dist/core/json.js +46 -0
  47. package/dist/core/limits.d.ts +7 -0
  48. package/dist/core/limits.js +14 -0
  49. package/dist/core/mechanism.d.ts +88 -0
  50. package/dist/core/mechanism.js +5 -0
  51. package/dist/core/result.d.ts +41 -0
  52. package/dist/core/result.js +1 -0
  53. package/dist/core/schema.d.ts +8 -0
  54. package/dist/core/schema.js +23 -0
  55. package/dist/core/skill.d.ts +12 -0
  56. package/dist/core/skill.js +1 -0
  57. package/dist/host/baseline.d.ts +11 -0
  58. package/dist/host/baseline.js +4 -0
  59. package/dist/host/graph-catalog.d.ts +8 -0
  60. package/dist/host/graph-catalog.js +24 -0
  61. package/dist/host/graph-host.d.ts +53 -0
  62. package/dist/host/graph-host.js +181 -0
  63. package/dist/host/preflight.d.ts +17 -0
  64. package/dist/host/preflight.js +81 -0
  65. package/dist/host/skill-catalog.d.ts +24 -0
  66. package/dist/host/skill-catalog.js +92 -0
  67. package/dist/host/tool-catalog.d.ts +27 -0
  68. package/dist/host/tool-catalog.js +33 -0
  69. package/dist/index.d.ts +21 -0
  70. package/dist/index.js +10 -0
  71. package/dist/replay/checkpoint.d.ts +40 -0
  72. package/dist/replay/checkpoint.js +57 -0
  73. package/dist/replay/events.d.ts +40 -0
  74. package/dist/replay/events.js +1 -0
  75. package/dist/replay/finalizer.d.ts +26 -0
  76. package/dist/replay/finalizer.js +117 -0
  77. package/dist/replay/html.d.ts +3 -0
  78. package/dist/replay/html.js +270 -0
  79. package/dist/replay/index.d.ts +13 -0
  80. package/dist/replay/index.js +7 -0
  81. package/dist/replay/model.d.ts +81 -0
  82. package/dist/replay/model.js +1 -0
  83. package/dist/replay/parser.d.ts +3 -0
  84. package/dist/replay/parser.js +332 -0
  85. package/dist/replay/recorder.d.ts +30 -0
  86. package/dist/replay/recorder.js +195 -0
  87. package/dist/replay/store.d.ts +41 -0
  88. package/dist/replay/store.js +94 -0
  89. package/dist/router.d.ts +4 -0
  90. package/dist/router.js +61 -0
  91. package/dist/runtime/event-bus.d.ts +101 -0
  92. package/dist/runtime/event-bus.js +18 -0
  93. package/dist/runtime/graph-runtime.d.ts +173 -0
  94. package/dist/runtime/graph-runtime.js +1293 -0
  95. package/dist/runtime/invocation-budget.d.ts +22 -0
  96. package/dist/runtime/invocation-budget.js +52 -0
  97. package/dist/runtime/mechanism-runtime.d.ts +92 -0
  98. package/dist/runtime/mechanism-runtime.js +387 -0
  99. package/dist/runtime.d.ts +91 -0
  100. package/dist/runtime.js +258 -0
  101. package/dist/tools-resolve.d.ts +20 -0
  102. package/dist/tools-resolve.js +52 -0
  103. package/dist/type.d.ts +593 -0
  104. package/dist/type.js +30 -0
  105. package/dist/validate.d.ts +25 -0
  106. package/dist/validate.js +203 -0
  107. package/package.json +69 -0
@@ -0,0 +1,151 @@
1
+ // ============================================================
2
+ // Debug Logger — 记录每层的输入、输出、帧栈
3
+ // ============================================================
4
+ //
5
+ // 输出到项目根目录 loop-graph-debug.log(JSONL 格式)。
6
+ // 每条日志含 timestamp + type + data。
7
+ // ============================================================
8
+ import * as fs from "node:fs";
9
+ import * as path from "node:path";
10
+ const LOG_PATH = path.resolve("loop-graph-debug.log");
11
+ let fileOpened = false;
12
+ /** 截断序列化帧的预览,避免日志爆量。 */
13
+ export function safePreview(value, maxLength = 500) {
14
+ try {
15
+ const s = JSON.stringify(value);
16
+ if (s === undefined)
17
+ return "[unserializable]";
18
+ return s.length <= maxLength ? s : s.slice(0, maxLength) + "…";
19
+ }
20
+ catch {
21
+ return "[unserializable]";
22
+ }
23
+ }
24
+ function log(entry) {
25
+ // 文件调试是显式 opt-in;正常 SDK 使用不产生工作区文件。
26
+ if (process.env.PI_LOOP_GRAPH_DEBUG !== "1")
27
+ return;
28
+ const line = JSON.stringify({ ts: new Date().toISOString(), ...entry });
29
+ if (!fileOpened) {
30
+ fs.writeFileSync(LOG_PATH, "", "utf-8");
31
+ fileOpened = true;
32
+ }
33
+ fs.appendFileSync(LOG_PATH, line + "\n", "utf-8");
34
+ }
35
+ export const debugLog = {
36
+ preview(value, maxLength) {
37
+ return safePreview(value, maxLength);
38
+ },
39
+ /** 图启动 */
40
+ graphStart(graphId, trigger) {
41
+ log({ type: "graph_start", graphId, trigger });
42
+ },
43
+ /** 进入节点 */
44
+ enterNode(depth, nodeId, scopeId, input, frames) {
45
+ log({
46
+ type: "enter_node",
47
+ depth,
48
+ nodeId,
49
+ scopeId,
50
+ inputData: input.data,
51
+ frameCount: frames.length,
52
+ });
53
+ },
54
+ /** 退出节点(折叠帧)。控制信息来自 completion;frame 作为 opaque payload。 */
55
+ exitNode(depth, nodeId, completion, frame, allFrames) {
56
+ log({
57
+ type: "exit_node",
58
+ depth,
59
+ nodeId,
60
+ status: completion.status,
61
+ resultKeys: Object.keys(completion.result),
62
+ framePreview: safePreview(frame),
63
+ totalFrames: allFrames.length,
64
+ });
65
+ },
66
+ /** context 钩子投影 */
67
+ projection(input, output) {
68
+ log({
69
+ type: "projection",
70
+ messageCount: input.messages.length,
71
+ scopeId: input.activeScope?.scopeId ?? null,
72
+ splitFound: input.activeScope
73
+ ? input.messages.some((m) => m.customType === "loop_graph_node_scope" &&
74
+ m.details?.scopeId === input.activeScope?.scopeId)
75
+ : false,
76
+ frameCount: input.frames.length,
77
+ currentNode: input.currentNode?.id ?? null,
78
+ frameMsgCount: output.filter((m) => typeof m.content === "string" && m.content.startsWith("=== COMPLETED")).length,
79
+ currentMsgCount: output.filter((m) => typeof m.content === "string" && m.content.startsWith("=== CURRENT")).length,
80
+ otherCount: output.filter((m) => typeof m.content !== "string" || !m.content.startsWith("===")).length,
81
+ messageTypes: output.slice(0, 8).map((m) => m.customType ?? m.role ?? "?"),
82
+ });
83
+ },
84
+ /** 图运行期间发生 compaction 后记录 checkpoint 信息。 */
85
+ scopeCheckpoint(scopeId, generation, reason, willRetry) {
86
+ log({ type: "scope_checkpoint", scopeId, generation, reason, willRetry });
87
+ },
88
+ /** 共享 Session 的嵌套调用期间阻止 compaction 跨越 GraphCallScope。 */
89
+ compactionBlocked(reason, depth) {
90
+ log({ type: "compaction_blocked", reason, depth });
91
+ },
92
+ /** agent 完成(__graph_complete__ 被调用) */
93
+ agentComplete(nodeId, completion) {
94
+ log({
95
+ type: "agent_complete",
96
+ nodeId,
97
+ status: completion.status,
98
+ resultKeys: Object.keys(completion.result),
99
+ });
100
+ },
101
+ /** agent 未调用 __graph_complete__ 就结束 */
102
+ agentIncomplete(nodeId) {
103
+ log({ type: "agent_incomplete", nodeId });
104
+ },
105
+ /** 完成验证不通过,触发重试 */
106
+ agentRetry(nodeId, reason) {
107
+ log({ type: "agent_retry", nodeId, reason });
108
+ },
109
+ /** 图结束。控制信息来自 result;frames 作为 opaque payload。 */
110
+ graphEnd(graphId, steps, resultStatus, resultPreview, frames) {
111
+ log({
112
+ type: "graph_end",
113
+ graphId,
114
+ steps,
115
+ status: resultStatus,
116
+ resultPreview,
117
+ frameCount: frames.length,
118
+ });
119
+ },
120
+ /** 图错误 */
121
+ graphError(graphId, error) {
122
+ log({ type: "graph_error", graphId, error });
123
+ },
124
+ /** 子图 push */
125
+ subgraphPush(parentNodeId, childGraphId) {
126
+ log({ type: "subgraph_push", parentNodeId, childGraphId });
127
+ },
128
+ /** 子图 pop */
129
+ subgraphPop(parentNodeId, childGraphId, result) {
130
+ log({ type: "subgraph_pop", parentNodeId, childGraphId, resultKeys: typeof result === "object" && result ? Object.keys(result) : [] });
131
+ },
132
+ frameSegmentStart(graphId, parentNodeId, baseIndex, depth) {
133
+ log({ type: "frame_segment_start", graphId, parentNodeId, baseIndex, depth });
134
+ },
135
+ frameSegmentClose(graphId, parentNodeId, frames, completion) {
136
+ log({
137
+ type: "frame_segment_close",
138
+ graphId,
139
+ parentNodeId,
140
+ frameCount: frames.length,
141
+ foldedCompletion: completion,
142
+ });
143
+ },
144
+ frameSegmentRollback(graphId, parentNodeId, reason) {
145
+ log({ type: "frame_segment_rollback", graphId, parentNodeId, reason });
146
+ },
147
+ /** 工具切换 */
148
+ toolsChanged(nodeId, tools) {
149
+ log({ type: "tools_changed", nodeId, tools });
150
+ },
151
+ };
@@ -0,0 +1,2 @@
1
+ import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
2
+ export default function loopGraphDebugExtension(pi: ExtensionAPI): void;
@@ -0,0 +1,11 @@
1
+ // ============================================================
2
+ // Loop Graph Extension — pi 自动加载入口
3
+ // ============================================================
4
+ //
5
+ // 业务 extension 通常应直接使用 createLoopGraphExtension(pi),
6
+ // 注册自己的图并显式暴露 command/tool。
7
+ // ============================================================
8
+ import { createLoopGraphExtension } from "./loop-graph-extension.js";
9
+ export default function loopGraphDebugExtension(pi) {
10
+ createLoopGraphExtension(pi);
11
+ }
@@ -0,0 +1,73 @@
1
+ import type { Graph, GraphInvocationBoundary, GraphRunRequest, GraphRunResult } from "../type.js";
2
+ import type { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
3
+ /** 为旧调用(仅有 invocationKind,无 boundary)填补默认值。
4
+ * 旧 `"subgraph"` → `graph-node` + `call`。 */
5
+ export declare function normalizeGraphRunRequest(partial: {
6
+ background: Record<string, unknown>;
7
+ invocationKind: string;
8
+ boundary?: GraphInvocationBoundary;
9
+ signal?: AbortSignal;
10
+ }): GraphRunRequest;
11
+ /** 图执行载体。不同实现可以承载进程内子会话、子进程或远程 worker。 */
12
+ export interface GraphExecutionHost {
13
+ run(graph: Graph, request: GraphRunRequest): Promise<GraphRunResult>;
14
+ dispose(): Promise<void>;
15
+ }
16
+ /** 创建 delegate host 时可用的调用现场;不包含外层 transcript。 */
17
+ export interface GraphHostContext {
18
+ pi: ExtensionAPI;
19
+ extensionContext?: ExtensionContext;
20
+ graph: Graph;
21
+ request: GraphRunRequest;
22
+ }
23
+ export type DelegateHostFactory = (context: GraphHostContext) => Promise<GraphExecutionHost>;
24
+ /** 入口无关的统一图调用器。第三个参数只提供运行配置,不改变业务请求。 */
25
+ export interface GraphInvoker {
26
+ invoke(graph: Graph, request: GraphRunRequest, extensionContext?: ExtensionContext): Promise<GraphRunResult>;
27
+ }
28
+ /** 每次 invoke 创建一次性 host,并固定执行 run → abort/dispose 生命周期。 */
29
+ export declare class DelegateGraphInvoker implements GraphInvoker {
30
+ private readonly pi;
31
+ private readonly createHost;
32
+ constructor(pi: ExtensionAPI, createHost: DelegateHostFactory);
33
+ invoke(graph: Graph, request: GraphRunRequest, extensionContext?: ExtensionContext): Promise<GraphRunResult>;
34
+ }
35
+ /**
36
+ * IsolatedSessionGraphHost 使用的最小子会话句柄。
37
+ *
38
+ * sessionFactory 后续由 pi adapter 通过 createAgentSession() 构造,并在
39
+ * runtime-only extension factory 中绑定 executeGraph。Host 本身只负责严格的
40
+ * run/abort/dispose 生命周期,不依赖 pi 的私有 API。
41
+ */
42
+ export interface IsolatedGraphSession {
43
+ run(graph: Graph, request: GraphRunRequest): Promise<GraphRunResult>;
44
+ abort(): Promise<void>;
45
+ dispose(): void;
46
+ }
47
+ export type IsolatedGraphSessionFactory = (request: GraphRunRequest) => Promise<IsolatedGraphSession>;
48
+ export interface IsolatedSessionGraphHostOptions {
49
+ createSession: IsolatedGraphSessionFactory;
50
+ }
51
+ /**
52
+ * 为一次 graph-tool 调用持有一个独立子 AgentSession 的生命周期外壳。
53
+ *
54
+ * 契约:
55
+ * - 一个 host 同时只运行一张图;并发调用应创建多个 host。
56
+ * - outer AbortSignal 会转发给子会话 abort()。
57
+ * - dispose 顺序固定为 abort() -> dispose()。
58
+ * - dispose 后拒绝 run(),弥补 AgentSession.dispose() 仍允许 prompt 的行为。
59
+ */
60
+ export declare class IsolatedSessionGraphHost implements GraphExecutionHost {
61
+ private readonly options;
62
+ private session;
63
+ private sessionPromise;
64
+ private cleanedSession;
65
+ private disposed;
66
+ private running;
67
+ private disposing;
68
+ constructor(options: IsolatedSessionGraphHostOptions);
69
+ run(graph: Graph, request: GraphRunRequest): Promise<GraphRunResult>;
70
+ dispose(): Promise<void>;
71
+ private assertUsable;
72
+ private cleanupSession;
73
+ }
@@ -0,0 +1,181 @@
1
+ /** 为旧调用(仅有 invocationKind,无 boundary)填补默认值。
2
+ * 旧 `"subgraph"` → `graph-node` + `call`。 */
3
+ export function normalizeGraphRunRequest(partial) {
4
+ let kind;
5
+ if (partial.invocationKind === "subgraph") {
6
+ kind = "graph-node";
7
+ }
8
+ else if (partial.invocationKind === "command" ||
9
+ partial.invocationKind === "tool" ||
10
+ partial.invocationKind === "graph-node" ||
11
+ partial.invocationKind === "api") {
12
+ kind = partial.invocationKind;
13
+ }
14
+ else {
15
+ throw new Error(`未知 GraphInvocationKind: ${partial.invocationKind}`);
16
+ }
17
+ const boundary = partial.boundary ?? (kind === "tool" || kind === "command" ? "delegate" : "call");
18
+ return { background: partial.background, invocationKind: kind, boundary, signal: partial.signal };
19
+ }
20
+ /** 每次 invoke 创建一次性 host,并固定执行 run → abort/dispose 生命周期。 */
21
+ export class DelegateGraphInvoker {
22
+ pi;
23
+ createHost;
24
+ constructor(pi, createHost) {
25
+ this.pi = pi;
26
+ this.createHost = createHost;
27
+ }
28
+ async invoke(graph, request, extensionContext) {
29
+ if (request.boundary !== "delegate") {
30
+ throw new Error(`DelegateGraphInvoker 只接受 delegate boundary,收到: ${request.boundary}`);
31
+ }
32
+ const host = await this.createHost({
33
+ pi: this.pi,
34
+ extensionContext,
35
+ graph,
36
+ request,
37
+ });
38
+ let runError;
39
+ try {
40
+ return await host.run(graph, request);
41
+ }
42
+ catch (error) {
43
+ runError = error;
44
+ throw error;
45
+ }
46
+ finally {
47
+ try {
48
+ await host.dispose();
49
+ }
50
+ catch (disposeError) {
51
+ if (runError != null) {
52
+ runError.suppressed = disposeError;
53
+ }
54
+ else {
55
+ throw disposeError;
56
+ }
57
+ }
58
+ }
59
+ }
60
+ }
61
+ /**
62
+ * 为一次 graph-tool 调用持有一个独立子 AgentSession 的生命周期外壳。
63
+ *
64
+ * 契约:
65
+ * - 一个 host 同时只运行一张图;并发调用应创建多个 host。
66
+ * - outer AbortSignal 会转发给子会话 abort()。
67
+ * - dispose 顺序固定为 abort() -> dispose()。
68
+ * - dispose 后拒绝 run(),弥补 AgentSession.dispose() 仍允许 prompt 的行为。
69
+ */
70
+ export class IsolatedSessionGraphHost {
71
+ options;
72
+ session = null;
73
+ sessionPromise = null;
74
+ cleanedSession = null;
75
+ disposed = false;
76
+ running = false;
77
+ disposing = null;
78
+ constructor(options) {
79
+ this.options = options;
80
+ }
81
+ async run(graph, request) {
82
+ this.assertUsable();
83
+ if (this.running) {
84
+ throw new Error("IsolatedSessionGraphHost 已有图正在运行;并发调用必须创建独立 host");
85
+ }
86
+ if (request.signal?.aborted)
87
+ throw createAbortError();
88
+ this.running = true;
89
+ try {
90
+ const sessionPromise = this.options.createSession(request);
91
+ this.sessionPromise = sessionPromise;
92
+ let session;
93
+ try {
94
+ session = await sessionPromise;
95
+ }
96
+ finally {
97
+ if (this.sessionPromise === sessionPromise)
98
+ this.sessionPromise = null;
99
+ }
100
+ // createSession 期间也可能收到 dispose/abort。
101
+ if (this.disposed || request.signal?.aborted) {
102
+ await this.cleanupSession(session);
103
+ if (request.signal?.aborted)
104
+ throw createAbortError();
105
+ throw new Error("IsolatedSessionGraphHost 已释放");
106
+ }
107
+ this.session = session;
108
+ const onAbort = () => {
109
+ void session.abort().catch(() => undefined);
110
+ };
111
+ request.signal?.addEventListener("abort", onAbort, { once: true });
112
+ try {
113
+ return await session.run(graph, request);
114
+ }
115
+ finally {
116
+ request.signal?.removeEventListener("abort", onAbort);
117
+ }
118
+ }
119
+ finally {
120
+ this.running = false;
121
+ }
122
+ }
123
+ async dispose() {
124
+ if (this.disposing)
125
+ return this.disposing;
126
+ this.disposed = true;
127
+ this.disposing = (async () => {
128
+ const pendingSession = this.sessionPromise;
129
+ const session = this.session;
130
+ this.session = null;
131
+ if (session) {
132
+ await this.cleanupSession(session);
133
+ return;
134
+ }
135
+ if (pendingSession) {
136
+ try {
137
+ await this.cleanupSession(await pendingSession);
138
+ }
139
+ catch {
140
+ // createSession 自身失败时没有可清理的 session。
141
+ }
142
+ }
143
+ })();
144
+ return this.disposing;
145
+ }
146
+ assertUsable() {
147
+ if (this.disposed)
148
+ throw new Error("IsolatedSessionGraphHost 已释放");
149
+ }
150
+ async cleanupSession(session) {
151
+ if (this.cleanedSession === session)
152
+ return;
153
+ this.cleanedSession = session;
154
+ await abortThenDispose(session);
155
+ }
156
+ }
157
+ async function abortThenDispose(session) {
158
+ let abortError = undefined;
159
+ try {
160
+ await session.abort();
161
+ }
162
+ catch (e) {
163
+ abortError = e;
164
+ }
165
+ try {
166
+ session.dispose();
167
+ }
168
+ catch (disposeError) {
169
+ if (abortError != null) {
170
+ abortError.suppressed = disposeError;
171
+ }
172
+ throw abortError ?? disposeError;
173
+ }
174
+ if (abortError != null)
175
+ throw abortError;
176
+ }
177
+ function createAbortError() {
178
+ const error = new Error("Graph execution aborted");
179
+ error.name = "AbortError";
180
+ return error;
181
+ }
@@ -0,0 +1,75 @@
1
+ import { type AuthStorage, type CompactionSettings, type CreateAgentSessionOptions, type ModelRegistry, type ToolDefinition } from "@earendil-works/pi-coding-agent";
2
+ import type { ContextFrame } from "../type.js";
3
+ import type { Graph as CoreGraph } from "../core/graph.js";
4
+ import type { NodeContextRenderer } from "./projection.js";
5
+ import { type LoopGraphLimits, type CompletionFeedbackFormatter, type ContextRendererRegistry } from "./loop-graph-extension.js";
6
+ import type { ModelMessageFormatter } from "./model-messages.js";
7
+ import type { ToolResolver } from "../tools-resolve.js";
8
+ import type { LoopGraphLogger, LoopGraphTraceSink } from "./observability.js";
9
+ import type { SkillContentProvider, SkillContentRenderer, SkillFailurePolicies } from "./skill-content.js";
10
+ import type { DelegateHostFactory, IsolatedGraphSessionFactory } from "./graph-execution-host.js";
11
+ import type { HostBaseline } from "../host/baseline.js";
12
+ import type { SkillCatalog } from "../host/skill-catalog.js";
13
+ import type { ToolCatalog, UnsafeToolResolver } from "../host/tool-catalog.js";
14
+ import { type GraphHost } from "../host/graph-host.js";
15
+ import type { RecordingMode } from "../core/result.js";
16
+ import type { RunStore } from "../replay/store.js";
17
+ import type { PricingResolver } from "../replay/events.js";
18
+ import type { Recorder } from "../replay/recorder.js";
19
+ import type { InvocationAgentHost } from "../runtime/graph-runtime.js";
20
+ export interface IsolatedGraphSessionFactoryOptions {
21
+ authStorage: AuthStorage;
22
+ modelRegistry: ModelRegistry;
23
+ cwd?: string;
24
+ agentDir?: string;
25
+ model?: CreateAgentSessionOptions["model"];
26
+ customTools?: ToolDefinition[];
27
+ toolCatalog?: ToolCatalog;
28
+ skillCatalog?: SkillCatalog;
29
+ unsafeToolResolver?: UnsafeToolResolver;
30
+ baseline?: HostBaseline;
31
+ skillBasePath?: string;
32
+ frameFormatter?: (frames: ContextFrame[]) => string | null;
33
+ limits?: LoopGraphLimits;
34
+ contextRenderer?: NodeContextRenderer;
35
+ modelMessageFormatter?: Partial<ModelMessageFormatter>;
36
+ completionFeedbackFormatter?: CompletionFeedbackFormatter;
37
+ outputContractMaxBytes?: number;
38
+ skillProvider?: SkillContentProvider;
39
+ skillRenderer?: SkillContentRenderer;
40
+ skillFailure?: SkillFailurePolicies;
41
+ contextRenderers?: ContextRendererRegistry;
42
+ toolResolver?: ToolResolver;
43
+ traceSink?: LoopGraphTraceSink;
44
+ logger?: LoopGraphLogger;
45
+ debug?: boolean;
46
+ debugLogPath?: string;
47
+ thinkingLevel?: CreateAgentSessionOptions["thinkingLevel"];
48
+ /** 省略时遵循 pi 默认 compaction;可由 host 显式覆盖。 */
49
+ compaction?: CompactionSettings;
50
+ recording?: RecordingMode;
51
+ recordingRequired?: boolean;
52
+ runStore?: RunStore;
53
+ artifactThresholdBytes?: number;
54
+ pricingResolver?: PricingResolver;
55
+ /** 供子图继续使用 delegate;runtime-only adapter 不注册对外入口。 */
56
+ createDelegateHost?: DelegateHostFactory;
57
+ /** Core graphs made available to GraphRef resolution in this isolated Host. */
58
+ graphs?: readonly CoreGraph[];
59
+ }
60
+ /**
61
+ * 使用 pi 官方 in-memory AgentSession 创建隔离图执行环境。
62
+ *
63
+ * 子会话通过 inline extension factory 安装同一套 LoopGraph Runtime,避免维护
64
+ * 第二套 graph loop。runtimeOnly 模式只保留运行钩子,不注册对外命令或资源通知。
65
+ */
66
+ export declare function createIsolatedGraphSessionFactory(options: IsolatedGraphSessionFactoryOptions): IsolatedGraphSessionFactory;
67
+ /**
68
+ * 构造可递归 delegate 的一次性 host factory。每次调用创建新 host/session,
69
+ * 子 session 内的 delegate graph-node 继续复用同一份认证、模型与真实工具实现。
70
+ */
71
+ export declare function createIsolatedDelegateHostFactory(options: Omit<IsolatedGraphSessionFactoryOptions, "createDelegateHost">): DelegateHostFactory;
72
+ /** Creates one Pi Session that only executes Agent Runs for a Core Graph Invocation. */
73
+ export declare function createPiInvocationAgentHost(options: IsolatedGraphSessionFactoryOptions, recorder?: Recorder | null): Promise<InvocationAgentHost>;
74
+ /** Creates a Core GraphHost backed by one isolated Pi AgentSession. */
75
+ export declare function createPiGraphHost(options: IsolatedGraphSessionFactoryOptions): Promise<GraphHost>;