@dana4/sdk 0.1.0 → 0.5.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 +5 -3
- package/dist/agent.d.ts +40 -4
- package/dist/agent.js +82 -18
- package/dist/ai.d.ts +4 -4
- package/dist/ai.js +170 -37
- package/dist/cli.js +11 -2
- package/dist/client.d.ts +54 -0
- package/dist/client.js +38 -10
- package/dist/cloudflare.js +10 -3
- package/dist/enroll.js +13 -4
- package/dist/run.js +7 -2
- package/dist/schema.d.ts +3733 -3503
- package/package.json +14 -3
package/README.md
CHANGED
|
@@ -147,6 +147,7 @@ Every handler gets a `Context` that is already bound to its workspace, channel a
|
|
|
147
147
|
| `ctx.docs.append(path, content)` | Append to a document. |
|
|
148
148
|
| `ctx.docs.edit(path, old, new, replaceAll?)` | Exact-string replace; returns the number of replacements. |
|
|
149
149
|
| `ctx.plan.set / add / complete` | Manage the channel's plan, a markdown checklist. |
|
|
150
|
+
| `ctx.memory.set(memory)` | Replace the channel's memory, markdown notes shared by its agents and people. |
|
|
150
151
|
| `ctx.assets.upload(data, { name, ext })` | Store a file. Put the returned `url` (`dana4-asset://…`) in content. |
|
|
151
152
|
| `ctx.progress(fraction, message?)` | Report progress (0–1) to people watching the task. |
|
|
152
153
|
| `ctx.cost({ usd?, credits?, detail? })` | Record spend, e.g. model usage. It adds up and is charged once, when the task ends. |
|
|
@@ -175,7 +176,7 @@ export const agent = defineAgent({
|
|
|
175
176
|
onChat: async ({ message, thread }, ctx) => {
|
|
176
177
|
const recent = (await ctx.client.chat.messages(message.channel_id)).messages;
|
|
177
178
|
const result = await generateText({
|
|
178
|
-
model: anthropic("claude-
|
|
179
|
+
model: anthropic("claude-haiku-5-5"),
|
|
179
180
|
system: threadInstructions("You are a helpful assistant in a Dana4 workspace.", thread),
|
|
180
181
|
messages: [
|
|
181
182
|
...chatHistory(recent, { me: ctx.me, exclude: message.id }),
|
|
@@ -190,9 +191,10 @@ export const agent = defineAgent({
|
|
|
190
191
|
});
|
|
191
192
|
```
|
|
192
193
|
|
|
194
|
+
- `ctx.tickets.create({ title, description?, status?, blocked_by? })` (and the `create_ticket` tool) puts a ticket on the board; tickets are referred to by their per-workspace number, so `blocked_by: [12]` means #12.
|
|
193
195
|
- `dana4Tools(ctx, { exclude, delegation })`: drop individual tools with `exclude: ["send_message", …]`, or turn off the per-capability delegation tools with `delegation: false`.
|
|
194
196
|
- `chatHistory(messages, { me, exclude })` converts a thread into model messages, oldest first. Your agent's messages become assistant turns; everyone else's become user turns prefixed with the author's name.
|
|
195
|
-
- `threadInstructions(base, thread)` appends the thread's topics, intent and
|
|
197
|
+
- `threadInstructions(base, thread)` appends the thread's topics, intent, plan and memory to your system prompt.
|
|
196
198
|
|
|
197
199
|
## Running your agent
|
|
198
200
|
|
|
@@ -250,7 +252,7 @@ Set the key with `wrangler secret put DANA4_API_KEY`. Set `DANA4_URL` only if yo
|
|
|
250
252
|
|
|
251
253
|
## The low-level client
|
|
252
254
|
|
|
253
|
-
`Dana4Client` wraps every endpoint of the Dana4 SDK API, grouped by resource: `agents`, `tasks`, `docs`, `chat`, `workspaces`, `automations`, `workflows` and `assets`. Use it for scripts, or for integrations that aren't long-running agents.
|
|
255
|
+
`Dana4Client` wraps every endpoint of the Dana4 SDK API, grouped by resource: `agents`, `tasks`, `docs`, `chat`, `workspaces`, `tickets`, `automations`, `workflows` and `assets`. Use it for scripts, or for integrations that aren't long-running agents.
|
|
254
256
|
|
|
255
257
|
```ts
|
|
256
258
|
import { Dana4Client } from "@dana4/sdk";
|
package/dist/agent.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import type { ChatThread, Dana4Client, Document, DocumentType, Json, JsonObject, Message, MessageCategory, PresenceActivity, TakenTask, UpdateTaskPayload } from "./client.js";
|
|
2
|
+
import type { ChatThread, CreateTicketBody, Dana4Client, Document, DocumentType, Json, JsonObject, Message, MessageCategory, PresenceActivity, TakenTask, UpdateTaskPayload } from "./client.js";
|
|
3
3
|
/** A unit of work exposed to Dana4: workflows assign it, chat agents call it.
|
|
4
4
|
* Return the step's result (any JSON) to complete the task; throw to fail it. */
|
|
5
5
|
export type Capability<I extends z.ZodObject = z.ZodObject, R = unknown> = {
|
|
@@ -88,6 +88,16 @@ export declare class Context {
|
|
|
88
88
|
}): Promise<Message>;
|
|
89
89
|
/** Workspace params (API keys, feature flags, …) set in workspace settings. */
|
|
90
90
|
params(): Promise<JsonObject>;
|
|
91
|
+
readonly tickets: {
|
|
92
|
+
/** Put a ticket on this workspace's board; `blocked_by` takes ticket numbers. */
|
|
93
|
+
create: (ticket: Omit<CreateTicketBody, "workspace_id">) => Promise<{
|
|
94
|
+
blocked_by: number[];
|
|
95
|
+
number: number;
|
|
96
|
+
status: import("./schema.js").components["schemas"]["BoardStatus"];
|
|
97
|
+
title: string;
|
|
98
|
+
workspace_id: string;
|
|
99
|
+
}>;
|
|
100
|
+
};
|
|
91
101
|
readonly docs: {
|
|
92
102
|
/** Read by path; shows this agent as `activity` on the document. */
|
|
93
103
|
get: (path: string, activity?: PresenceActivity) => Promise<Document>;
|
|
@@ -143,9 +153,11 @@ export declare class Context {
|
|
|
143
153
|
direct?: boolean;
|
|
144
154
|
document_id?: string | null;
|
|
145
155
|
intent?: string | null;
|
|
156
|
+
memory?: string | null;
|
|
146
157
|
messages: import("./schema.js").components["schemas"]["Message"][];
|
|
147
158
|
parent_channel_id?: string | null;
|
|
148
159
|
plan?: string | null;
|
|
160
|
+
tickets?: import("./schema.js").components["schemas"]["TicketSummary"][];
|
|
149
161
|
topics: import("./schema.js").components["schemas"]["TopicSummary"][];
|
|
150
162
|
}[]>;
|
|
151
163
|
create: (doc: {
|
|
@@ -166,6 +178,7 @@ export declare class Context {
|
|
|
166
178
|
document_id: string;
|
|
167
179
|
id: string;
|
|
168
180
|
intent?: string | null;
|
|
181
|
+
memory?: string | null;
|
|
169
182
|
owners: string[];
|
|
170
183
|
parent_channel_id?: string | null;
|
|
171
184
|
parent_message_id?: string | null;
|
|
@@ -180,6 +193,7 @@ export declare class Context {
|
|
|
180
193
|
document_id: string;
|
|
181
194
|
id: string;
|
|
182
195
|
intent?: string | null;
|
|
196
|
+
memory?: string | null;
|
|
183
197
|
owners: string[];
|
|
184
198
|
parent_channel_id?: string | null;
|
|
185
199
|
parent_message_id?: string | null;
|
|
@@ -194,6 +208,25 @@ export declare class Context {
|
|
|
194
208
|
document_id: string;
|
|
195
209
|
id: string;
|
|
196
210
|
intent?: string | null;
|
|
211
|
+
memory?: string | null;
|
|
212
|
+
owners: string[];
|
|
213
|
+
parent_channel_id?: string | null;
|
|
214
|
+
parent_message_id?: string | null;
|
|
215
|
+
plan?: string | null;
|
|
216
|
+
plan_completed: boolean;
|
|
217
|
+
private: boolean;
|
|
218
|
+
time: import("./schema.js").components["schemas"]["Timestamps"];
|
|
219
|
+
title: string;
|
|
220
|
+
workspace_id: string;
|
|
221
|
+
}>;
|
|
222
|
+
};
|
|
223
|
+
/** The channel's memory: markdown notes shared by its agents and people. Answers the updated channel. */
|
|
224
|
+
readonly memory: {
|
|
225
|
+
set: (memory: string, channelId?: string | null) => Promise<{
|
|
226
|
+
document_id: string;
|
|
227
|
+
id: string;
|
|
228
|
+
intent?: string | null;
|
|
229
|
+
memory?: string | null;
|
|
197
230
|
owners: string[];
|
|
198
231
|
parent_channel_id?: string | null;
|
|
199
232
|
parent_message_id?: string | null;
|
|
@@ -219,18 +252,21 @@ export declare class Context {
|
|
|
219
252
|
/** Report progress (0–1) and optionally a message people see in the channel. */
|
|
220
253
|
progress(progress: number, message?: string): Promise<void>;
|
|
221
254
|
/** Record spend. It accumulates and is charged once, when the task ends. */
|
|
222
|
-
cost({ usd, credits, detail }: {
|
|
255
|
+
cost({ usd, credits, detail, }: {
|
|
223
256
|
usd?: number;
|
|
224
257
|
credits?: number;
|
|
225
258
|
detail?: JsonObject;
|
|
226
259
|
}): void;
|
|
260
|
+
/** Record tools the LLM called, for debugging. Saved on the task when it
|
|
261
|
+
* ends. By convention `{ name, args }`, plus `error` when one failed. */
|
|
262
|
+
toolCalls(...calls: JsonObject[]): void;
|
|
227
263
|
/** Queue another agent's capability. It runs asynchronously and posts its
|
|
228
264
|
* result back here, @-mentioning this agent. Answers the new task's id. */
|
|
229
265
|
delegate(agent: string, capability: string, inputs?: JsonObject): Promise<string>;
|
|
230
266
|
/** The result of an earlier step in this task's journey, or null if not ready. */
|
|
231
267
|
stepResult(stepId: string): Promise<Json>;
|
|
232
|
-
/** @internal The accumulated cost, in `PATCH /tasks/{id}` shape. */
|
|
233
|
-
settle(): Pick<UpdateTaskPayload, "cost_usd" | "credits_cost" | "cost_details">;
|
|
268
|
+
/** @internal The accumulated cost and tool calls, in `PATCH /tasks/{id}` shape. */
|
|
269
|
+
settle(): Pick<UpdateTaskPayload, "cost_usd" | "credits_cost" | "cost_details" | "tool_calls">;
|
|
234
270
|
}
|
|
235
271
|
/** What `onJoin` gets: there is no task yet, so no document writes. */
|
|
236
272
|
export type JoinContext = Pick<Context, "client" | "me" | "workspaceId" | "send" | "params">;
|
package/dist/agent.js
CHANGED
|
@@ -7,7 +7,9 @@ const BASE_FIELDS = ["workspace_id", "task_id", "channel_id", "tag_usernames"];
|
|
|
7
7
|
* payload keys a schema declares, so the base fields must be declared too. */
|
|
8
8
|
export function capabilitySchema(key, cap) {
|
|
9
9
|
// Input mode: a field with a default is optional to whoever calls it.
|
|
10
|
-
const { $schema: _, ...schema } = z.toJSONSchema(cap.input, {
|
|
10
|
+
const { $schema: _, ...schema } = z.toJSONSchema(cap.input, {
|
|
11
|
+
io: "input",
|
|
12
|
+
});
|
|
11
13
|
return {
|
|
12
14
|
...schema,
|
|
13
15
|
title: cap.title ?? key,
|
|
@@ -22,7 +24,7 @@ export function capabilitySchema(key, cap) {
|
|
|
22
24
|
required: [...(schema.required ?? []), "workspace_id", "task_id"],
|
|
23
25
|
};
|
|
24
26
|
}
|
|
25
|
-
const errorMessage = (e) =>
|
|
27
|
+
const errorMessage = (e) => e instanceof Error ? e.message : String(e);
|
|
26
28
|
/** Usernames @-mentioned in `body`, lowercased; the server's `extract_tagged_usernames`. */
|
|
27
29
|
const taggedUsernames = (body) => body
|
|
28
30
|
.split(/\s+/)
|
|
@@ -43,6 +45,7 @@ export class Context {
|
|
|
43
45
|
#usd = 0;
|
|
44
46
|
#credits = 0;
|
|
45
47
|
#costDetails = [];
|
|
48
|
+
#toolCalls = [];
|
|
46
49
|
constructor(client,
|
|
47
50
|
/** This agent's username. */
|
|
48
51
|
me, workspaceId,
|
|
@@ -78,6 +81,10 @@ export class Context {
|
|
|
78
81
|
params() {
|
|
79
82
|
return this.client.workspaces.params(this.workspaceId);
|
|
80
83
|
}
|
|
84
|
+
tickets = {
|
|
85
|
+
/** Put a ticket on this workspace's board; `blocked_by` takes ticket numbers. */
|
|
86
|
+
create: (ticket) => this.client.tickets.create({ ...ticket, workspace_id: this.workspaceId }),
|
|
87
|
+
};
|
|
81
88
|
docs = {
|
|
82
89
|
/** Read by path; shows this agent as `activity` on the document. */
|
|
83
90
|
get: async (path, activity = "reading") => {
|
|
@@ -101,8 +108,13 @@ export class Context {
|
|
|
101
108
|
replace: (path, content) => this.client.docs.replace({ path, content, task_id: this.#task() }),
|
|
102
109
|
append: (path, content) => this.client.docs.append({ path, content, task_id: this.#task() }),
|
|
103
110
|
/** Exact-string replace, applied server-side. Answers the replacement count. */
|
|
104
|
-
edit: async (path, oldString, newString, replaceAll = false) => (await this.client.docs.edit({
|
|
105
|
-
|
|
111
|
+
edit: async (path, oldString, newString, replaceAll = false) => (await this.client.docs.edit({
|
|
112
|
+
path,
|
|
113
|
+
old_string: oldString,
|
|
114
|
+
new_string: newString,
|
|
115
|
+
replace_all: replaceAll,
|
|
116
|
+
task_id: this.#task(),
|
|
117
|
+
})).replacements,
|
|
106
118
|
};
|
|
107
119
|
/** The channel's plan: a markdown checklist. Each call answers the updated channel. */
|
|
108
120
|
plan = {
|
|
@@ -110,6 +122,10 @@ export class Context {
|
|
|
110
122
|
complete: (item, channelId = this.channelId) => this.client.chat.completePlanItem(this.#channel(channelId), item),
|
|
111
123
|
add: (item, channelId = this.channelId) => this.client.chat.addPlanItem(this.#channel(channelId), item),
|
|
112
124
|
};
|
|
125
|
+
/** The channel's memory: markdown notes shared by its agents and people. Answers the updated channel. */
|
|
126
|
+
memory = {
|
|
127
|
+
set: (memory, channelId = this.channelId) => this.client.chat.setMemory(this.#channel(channelId), memory),
|
|
128
|
+
};
|
|
113
129
|
#channel(channelId) {
|
|
114
130
|
if (!channelId)
|
|
115
131
|
throw new Error("No channel: pass channelId explicitly");
|
|
@@ -121,15 +137,24 @@ export class Context {
|
|
|
121
137
|
};
|
|
122
138
|
/** Report progress (0–1) and optionally a message people see in the channel. */
|
|
123
139
|
async progress(progress, message) {
|
|
124
|
-
await this.client.tasks.update(this.#task(), {
|
|
140
|
+
await this.client.tasks.update(this.#task(), {
|
|
141
|
+
status: "running",
|
|
142
|
+
progress,
|
|
143
|
+
message,
|
|
144
|
+
});
|
|
125
145
|
}
|
|
126
146
|
/** Record spend. It accumulates and is charged once, when the task ends. */
|
|
127
|
-
cost({ usd = 0, credits = 0, detail }) {
|
|
147
|
+
cost({ usd = 0, credits = 0, detail, }) {
|
|
128
148
|
this.#usd += usd;
|
|
129
149
|
this.#credits += credits;
|
|
130
150
|
if (detail)
|
|
131
151
|
this.#costDetails.push(detail);
|
|
132
152
|
}
|
|
153
|
+
/** Record tools the LLM called, for debugging. Saved on the task when it
|
|
154
|
+
* ends. By convention `{ name, args }`, plus `error` when one failed. */
|
|
155
|
+
toolCalls(...calls) {
|
|
156
|
+
this.#toolCalls.push(...calls);
|
|
157
|
+
}
|
|
133
158
|
/** Queue another agent's capability. It runs asynchronously and posts its
|
|
134
159
|
* result back here, @-mentioning this agent. Answers the new task's id. */
|
|
135
160
|
delegate(agent, capability, inputs = {}) {
|
|
@@ -138,19 +163,24 @@ export class Context {
|
|
|
138
163
|
task_id: this.#task(),
|
|
139
164
|
channel_id: this.channelId,
|
|
140
165
|
inputs,
|
|
141
|
-
metadata: {
|
|
166
|
+
metadata: {
|
|
167
|
+
triggered_by: this.me,
|
|
168
|
+
triggered_from: "chat",
|
|
169
|
+
tag_usernames: [this.me],
|
|
170
|
+
},
|
|
142
171
|
});
|
|
143
172
|
}
|
|
144
173
|
/** The result of an earlier step in this task's journey, or null if not ready. */
|
|
145
174
|
stepResult(stepId) {
|
|
146
175
|
return this.client.tasks.stepResult(this.#task(), stepId);
|
|
147
176
|
}
|
|
148
|
-
/** @internal The accumulated cost, in `PATCH /tasks/{id}` shape. */
|
|
177
|
+
/** @internal The accumulated cost and tool calls, in `PATCH /tasks/{id}` shape. */
|
|
149
178
|
settle() {
|
|
150
179
|
return {
|
|
151
180
|
cost_usd: this.#usd || undefined,
|
|
152
181
|
credits_cost: this.#credits || undefined,
|
|
153
182
|
cost_details: this.#costDetails.length ? this.#costDetails : undefined,
|
|
183
|
+
tool_calls: this.#toolCalls.length ? this.#toolCalls : undefined,
|
|
154
184
|
};
|
|
155
185
|
}
|
|
156
186
|
}
|
|
@@ -177,7 +207,10 @@ export class AgentRuntime {
|
|
|
177
207
|
version,
|
|
178
208
|
capabilities: Object.fromEntries(Object.entries(capabilities).map(([key, cap]) => [
|
|
179
209
|
key,
|
|
180
|
-
{
|
|
210
|
+
{
|
|
211
|
+
input_schema: capabilitySchema(key, cap),
|
|
212
|
+
show_in_chat: cap.showInChat ?? true,
|
|
213
|
+
},
|
|
181
214
|
])),
|
|
182
215
|
},
|
|
183
216
|
});
|
|
@@ -192,7 +225,11 @@ export class AgentRuntime {
|
|
|
192
225
|
/** Put a task interrupted by a crash back in the queue. Never throws. */
|
|
193
226
|
async requeue(taskId) {
|
|
194
227
|
await this.client.tasks
|
|
195
|
-
.update(taskId, {
|
|
228
|
+
.update(taskId, {
|
|
229
|
+
status: "retry",
|
|
230
|
+
progress: 0,
|
|
231
|
+
message: "Agent restarted; re-queuing task",
|
|
232
|
+
})
|
|
196
233
|
.catch((e) => this.log.error("dana4: re-queuing failed:", errorMessage(e)));
|
|
197
234
|
}
|
|
198
235
|
/** Take the next task and chat thread. A taken task is acked (moved to
|
|
@@ -202,7 +239,10 @@ export class AgentRuntime {
|
|
|
202
239
|
try {
|
|
203
240
|
const taken = await this.client.tasks.take();
|
|
204
241
|
if (taken) {
|
|
205
|
-
await this.client.tasks.update(taken.task.id, {
|
|
242
|
+
await this.client.tasks.update(taken.task.id, {
|
|
243
|
+
status: "running",
|
|
244
|
+
progress: 0,
|
|
245
|
+
});
|
|
206
246
|
work.push({ kind: "task", taken });
|
|
207
247
|
}
|
|
208
248
|
}
|
|
@@ -230,7 +270,9 @@ export class AgentRuntime {
|
|
|
230
270
|
const me = this.me.toLowerCase();
|
|
231
271
|
return theirs
|
|
232
272
|
.filter((m) => taggedUsernames(m.message).includes(me))
|
|
233
|
-
.map((m) => m.category === "invited_to_workspace"
|
|
273
|
+
.map((m) => m.category === "invited_to_workspace"
|
|
274
|
+
? { kind: "join", workspaceId: m.workspace_id }
|
|
275
|
+
: { kind: "chat", message: m, thread });
|
|
234
276
|
}
|
|
235
277
|
/** Do one piece of work. Never throws: failures close the task as failed.
|
|
236
278
|
* `save` gets the work back whenever it gains state a crash must not lose (a
|
|
@@ -250,7 +292,11 @@ export class AgentRuntime {
|
|
|
250
292
|
}
|
|
251
293
|
}
|
|
252
294
|
async #runTask({ task, payload }) {
|
|
253
|
-
const fail = (message, ctx) => this.client.tasks.update(task.id, {
|
|
295
|
+
const fail = (message, ctx) => this.client.tasks.update(task.id, {
|
|
296
|
+
status: "failed",
|
|
297
|
+
message,
|
|
298
|
+
...ctx?.settle(),
|
|
299
|
+
});
|
|
254
300
|
const step = task.step_type;
|
|
255
301
|
const spec = typeof step === "object" && "agent" in step ? step.agent : null;
|
|
256
302
|
if (!spec || spec.name !== this.me)
|
|
@@ -262,12 +308,17 @@ export class AgentRuntime {
|
|
|
262
308
|
const parsed = cap.input.safeParse(own);
|
|
263
309
|
if (!parsed.success)
|
|
264
310
|
return void (await fail(`Invalid input for ${spec.capability}: ${z.prettifyError(parsed.error)}`));
|
|
265
|
-
const ctx = new Context(this.client, this.me, String(payload.workspace_id), typeof payload.channel_id === "string"
|
|
311
|
+
const ctx = new Context(this.client, this.me, String(payload.workspace_id), typeof payload.channel_id === "string"
|
|
312
|
+
? payload.channel_id
|
|
313
|
+
: task.channel_id, task.id, Array.isArray(payload.tag_usernames)
|
|
314
|
+
? payload.tag_usernames.map(String)
|
|
315
|
+
: []);
|
|
266
316
|
let result;
|
|
267
317
|
try {
|
|
268
318
|
result = await cap.run(parsed.data, ctx);
|
|
269
319
|
}
|
|
270
320
|
catch (e) {
|
|
321
|
+
this.log.error(`dana4: ${spec.capability} failed:`, e);
|
|
271
322
|
return void (await fail(errorMessage(e), ctx));
|
|
272
323
|
}
|
|
273
324
|
await this.client.tasks.update(task.id, {
|
|
@@ -284,7 +335,11 @@ export class AgentRuntime {
|
|
|
284
335
|
const { message, thread } = work;
|
|
285
336
|
let taskId = work.taskId;
|
|
286
337
|
if (!taskId) {
|
|
287
|
-
taskId = await this.client.tasks.start({
|
|
338
|
+
taskId = await this.client.tasks.start({
|
|
339
|
+
step_name: "read_message",
|
|
340
|
+
workspace_id: message.workspace_id,
|
|
341
|
+
channel_id: message.channel_id,
|
|
342
|
+
});
|
|
288
343
|
save?.({ ...work, taskId });
|
|
289
344
|
}
|
|
290
345
|
const ctx = new Context(this.client, this.me, message.workspace_id, message.channel_id, taskId, [this.me]);
|
|
@@ -293,12 +348,21 @@ export class AgentRuntime {
|
|
|
293
348
|
if (thinking)
|
|
294
349
|
await ctx.send(thinking, { category: "transient" });
|
|
295
350
|
await this.agent.onChat({ message, thread }, ctx);
|
|
296
|
-
await this.client.tasks.update(taskId, {
|
|
351
|
+
await this.client.tasks.update(taskId, {
|
|
352
|
+
status: "completed",
|
|
353
|
+
progress: 1,
|
|
354
|
+
...ctx.settle(),
|
|
355
|
+
});
|
|
297
356
|
}
|
|
298
357
|
catch (e) {
|
|
299
358
|
// The server posts a failed task's message into its channel, so the
|
|
300
|
-
// person who asked sees it.
|
|
301
|
-
|
|
359
|
+
// person who asked sees it. Log it too, with the stack, for the host.
|
|
360
|
+
this.log.error("dana4: chat failed:", e);
|
|
361
|
+
await this.client.tasks.update(taskId, {
|
|
362
|
+
status: "failed",
|
|
363
|
+
message: errorMessage(e),
|
|
364
|
+
...ctx.settle(),
|
|
365
|
+
});
|
|
302
366
|
}
|
|
303
367
|
}
|
|
304
368
|
}
|
package/dist/ai.d.ts
CHANGED
|
@@ -16,7 +16,7 @@ export declare function insertAt(document: string, line: number, content: string
|
|
|
16
16
|
/** A capability's input schema as a tool schema: only primitive params (the
|
|
17
17
|
* platform resolves documents and the like), and never the ids it injects. */
|
|
18
18
|
export declare function capabilityToolSchema(schema: JsonObject | null | undefined): JsonObject;
|
|
19
|
-
export type Dana4ToolName = "list_documents" | "grep_document" | "search_documents" | "read_document" | "get_step_result" | "create_document" | "write_document" | "append_document" | "edit_document" | "insert_in_document" | "send_message" | "set_plan" | "complete_plan_item" | "add_plan_item";
|
|
19
|
+
export type Dana4ToolName = "list_documents" | "grep_document" | "search_documents" | "read_document" | "get_step_result" | "create_document" | "write_document" | "append_document" | "edit_document" | "insert_in_document" | "send_message" | "set_plan" | "complete_plan_item" | "add_plan_item" | "set_memory" | "create_ticket";
|
|
20
20
|
/** Tools for reading and writing the workspace's documents, messaging, and the
|
|
21
21
|
* thread's plan — plus, unless `delegation: false`, one `<agent>__<capability>`
|
|
22
22
|
* tool per capability other agents in the workspace expose. Tool errors go back
|
|
@@ -32,6 +32,6 @@ export declare function chatHistory(messages: Message[], { me, exclude }: {
|
|
|
32
32
|
me: string;
|
|
33
33
|
exclude?: string;
|
|
34
34
|
}): ModelMessage[];
|
|
35
|
-
/** `base` followed by the thread's topics, intent and
|
|
36
|
-
* what the conversation is for. */
|
|
37
|
-
export declare function threadInstructions(base: string, thread: Pick<ChatThread, "topics" | "intent" | "plan">): string;
|
|
35
|
+
/** `base` followed by the thread's topics, the board, intent, plan and memory, so the
|
|
36
|
+
* model knows what the conversation is for. */
|
|
37
|
+
export declare function threadInstructions(base: string, thread: Pick<ChatThread, "topics" | "tickets" | "intent" | "plan" | "memory">): string;
|