@triggerlink/sdk 0.4.5 → 0.4.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/README.md CHANGED
@@ -130,6 +130,29 @@ Notes:
130
130
  turns, tool results), each element carrying `role`/`content` — same field name and shape as
131
131
  AgentKit's `result.output`, so helpers like `findLastIndex((m) => m.role === "assistant")`
132
132
  port directly. `lastAssistantTextMessageContent(result)` is the built-in shortcut.
133
+ - **`lifecycle.onResponse`**: fired once per *actual* LLM call (inside the durable step, after
134
+ redaction) with `{ result, iteration }`; `result` is an `AgentIterationResult`
135
+ (`{ text, output, toolCalls, usage }` for that iteration) and works directly with
136
+ `lastAssistantTextMessageContent(result)`. Memo-hit replays do not re-fire it, so hook side
137
+ effects run exactly once per LLM call; a throwing hook fails the step (platform retries).
138
+ There is no `network.state` — because function code is the router, extract results after
139
+ `agent.run` returns (via `result.output` / `result.toolCalls`), or write to your own storage
140
+ inside the hook (closure variables don't survive platform re-invocations):
141
+
142
+ ```ts
143
+ const codeAgent = createAgent({
144
+ name: "code-agent",
145
+ model: openai("gpt-4.1"),
146
+ lifecycle: {
147
+ onResponse: async ({ result }) => {
148
+ const lastAssistantText = lastAssistantTextMessageContent(result);
149
+ if (lastAssistantText?.includes("<task_summary>")) {
150
+ await db.runs.update(runId, { summary: lastAssistantText }); // your own storage
151
+ }
152
+ },
153
+ },
154
+ });
155
+ ```
133
156
  - **`redact` hook** (optional): transforms each step's output inside `step.run` before
134
157
  persistence, e.g. to strip secrets or PII from memos. It must be deterministic and
135
158
  replay-safe — the memo is what the model sees of its own prior turns after a crash-resume:
package/dist/agent.d.ts CHANGED
@@ -36,6 +36,36 @@ export interface RedactCtx {
36
36
  * responseMessages)不得破坏,否则抛错(见 assertLlmMemoShape)。
37
37
  */
38
38
  export type RedactHook = (output: unknown, ctx: RedactCtx) => unknown;
39
+ /** 单轮 LLM 调用的结果(lifecycle.onResponse 的入参)。 */
40
+ export interface AgentIterationResult {
41
+ /** 本轮 assistant 文本 */
42
+ text: string;
43
+ /** 本轮 assistant 消息(与 lastAssistantTextMessageContent 兼容) */
44
+ output: TextMessage[];
45
+ /** 本轮模型发起的工具调用(尚未执行) */
46
+ toolCalls: Array<{
47
+ toolCallId: string;
48
+ toolName: string;
49
+ input: unknown;
50
+ }>;
51
+ usage: {
52
+ inputTokens?: number;
53
+ outputTokens?: number;
54
+ };
55
+ }
56
+ export interface AgentLifecycle {
57
+ /**
58
+ * 每次 LLM 调用真实执行后触发一次(memo 命中/恢复重放不触发),
59
+ * 看到的是 redact 之后的最终内容(与落库 memo、模型历史一致)。
60
+ * 抛错视同 step 失败:StepError → 平台退避重试(LLM 会被重新调用)。
61
+ * 注意:函数会被平台反复重入,闭包变量不可靠;要保留 hook 产出请写自己的存储,
62
+ * 或在 agent.run 返回后从 AgentResult 收尾提取。
63
+ */
64
+ onResponse?: (args: {
65
+ result: AgentIterationResult;
66
+ iteration: number;
67
+ }) => void | Promise<void>;
68
+ }
39
69
  export interface AgentOpts {
40
70
  /** 稳定标识,用作 memo 键前缀(agent/<name>/...);同一函数内不同 Agent 必须不同名(§5.2) */
41
71
  name: string;
@@ -46,6 +76,7 @@ export interface AgentOpts {
46
76
  /** 迭代上限(一次迭代 = 一次 LLM 调用 + 其全部工具执行),默认 10;超限抛错使 run 失败 */
47
77
  maxIterations?: number;
48
78
  redact?: RedactHook;
79
+ lifecycle?: AgentLifecycle;
49
80
  }
50
81
  export interface AgentResult {
51
82
  /** 最终一条 assistant 文本 */
package/dist/agent.js CHANGED
@@ -115,6 +115,17 @@ export function createAgent(opts) {
115
115
  };
116
116
  const out = redact ? redact(memo, { kind: "llm", iteration: i }) : memo;
117
117
  assertLlmMemoShape(out, agent.name); // 落库前拦截坏结构
118
+ // onResponse 在 step 回调内触发:只在 LLM 真实执行时跑一次,
119
+ // memo 命中/恢复重放不重复触发;抛错视同 step 失败走重试。
120
+ await opts.lifecycle?.onResponse?.({
121
+ result: {
122
+ text: out.text,
123
+ output: out.responseMessages,
124
+ toolCalls: out.toolCalls,
125
+ usage: out.usage,
126
+ },
127
+ iteration: i,
128
+ });
118
129
  return out;
119
130
  });
120
131
  assertLlmMemoShape(llmMemo, agent.name); // memo 命中路径同样校验(防御脏数据)
package/dist/serve.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import type { Client } from "./client.js";
2
2
  import type { TriggerFunction } from "./function.js";
3
- export declare const sdkVersion = "triggerlink-ts/0.4.5";
3
+ export declare const sdkVersion = "triggerlink-ts/0.4.6";
4
4
  export declare const SIGNATURE_HEADER = "x-triggerlink-signature";
5
5
  export interface ServeOptions {
6
6
  client: Client;
package/dist/serve.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { ExecCtx, StepInterrupt } from "./execx.js";
2
2
  import { createStepTool, errMessage } from "./step.js";
3
3
  import { verifySignature } from "./sign.js";
4
- export const sdkVersion = "triggerlink-ts/0.4.5";
4
+ export const sdkVersion = "triggerlink-ts/0.4.6";
5
5
  export const SIGNATURE_HEADER = "x-triggerlink-signature";
6
6
  const MAX_BODY = 10 << 20; // 10 MB,与平台一致
7
7
  function json(data, status = 200) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@triggerlink/sdk",
3
- "version": "0.4.5",
3
+ "version": "0.4.6",
4
4
  "description": "TriggerLink TypeScript SDK: durable, crash-recoverable functions for Next.js / Node.js",
5
5
  "keywords": [
6
6
  "triggerlink",