@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/dist/client.js CHANGED
@@ -57,9 +57,13 @@ export class Dana4Client {
57
57
  active: () => this.request("GET", "/tasks/active"),
58
58
  assigned: () => this.request("GET", "/tasks/assigned"),
59
59
  unassigned: () => this.request("GET", "/tasks/unassigned"),
60
- claim: (taskId, capability) => this.request("POST", `/tasks/${taskId}/claim`, { body: { capability } }),
60
+ claim: (taskId, capability) => this.request("POST", `/tasks/${taskId}/claim`, {
61
+ body: { capability },
62
+ }),
61
63
  /** Start a one-step journey (e.g. `read_message`); answers its task id. */
62
- start: (body) => this.request("POST", "/tasks", { body: { params: null, ...body } }),
64
+ start: (body) => this.request("POST", "/tasks", {
65
+ body: { params: null, ...body },
66
+ }),
63
67
  update: (taskId, body) => this.request("PATCH", `/tasks/${taskId}`, { body }),
64
68
  /** Workspace params merged with the journey's params. */
65
69
  params: (taskId) => this.request("GET", `/tasks/${taskId}/params`),
@@ -73,23 +77,40 @@ export class Dana4Client {
73
77
  source: (documentId) => this.request("GET", `/documents/${documentId}/source`),
74
78
  search: (workspaceId, q, limit) => this.request("GET", `/workspaces/${workspaceId}/documents/search`, { query: { q, limit } }),
75
79
  /** Every thread on a document; the root discussion has no `parent_channel_id`. */
76
- messages: (documentId, range = {}) => this.request("GET", `/documents/${documentId}/messages`, { query: range }),
80
+ messages: (documentId, range = {}) => this.request("GET", `/documents/${documentId}/messages`, {
81
+ query: range,
82
+ }),
77
83
  create: (body) => this.request("POST", "/documents", { body }),
78
84
  replace: (body) => this.request("POST", "/documents/replace", { body }),
79
85
  append: (body) => this.request("POST", "/documents/append", { body }),
80
- edit: (body) => this.request("POST", "/documents/edit", { body }),
81
- presence: (documentId, activity) => this.request("PUT", `/documents/${documentId}/presence`, { body: { activity } }),
86
+ edit: (body) => this.request("POST", "/documents/edit", {
87
+ body,
88
+ }),
89
+ presence: (documentId, activity) => this.request("PUT", `/documents/${documentId}/presence`, {
90
+ body: { activity },
91
+ }),
82
92
  };
83
93
  chat = {
84
94
  /** The next channel with unread messages for this agent. Marks them read:
85
95
  * delivery is at-most-once. `channel_id` is "" when there is nothing. */
86
96
  take: () => this.request("POST", "/chats/take"),
87
- messages: (channelId, range = {}) => this.request("GET", `/channels/${channelId}/messages`, { query: range }),
97
+ messages: (channelId, range = {}) => this.request("GET", `/channels/${channelId}/messages`, {
98
+ query: range,
99
+ }),
88
100
  send: (body) => this.request("POST", "/messages", { body }),
89
101
  privateChannels: (workspaceId) => this.request("GET", `/workspaces/${workspaceId}/private-channels`),
90
- setPlan: (channelId, plan) => this.request("PUT", `/channels/${channelId}/plan`, { body: { plan } }),
91
- completePlanItem: (channelId, item) => this.request("POST", `/channels/${channelId}/plan/complete`, { body: { item } }),
92
- addPlanItem: (channelId, item) => this.request("POST", `/channels/${channelId}/plan/items`, { body: { item } }),
102
+ setPlan: (channelId, plan) => this.request("PUT", `/channels/${channelId}/plan`, {
103
+ body: { plan },
104
+ }),
105
+ setMemory: (channelId, memory) => this.request("PUT", `/channels/${channelId}/memory`, {
106
+ body: { memory },
107
+ }),
108
+ completePlanItem: (channelId, item) => this.request("POST", `/channels/${channelId}/plan/complete`, {
109
+ body: { item },
110
+ }),
111
+ addPlanItem: (channelId, item) => this.request("POST", `/channels/${channelId}/plan/items`, {
112
+ body: { item },
113
+ }),
93
114
  };
94
115
  workspaces = {
95
116
  list: () => this.request("GET", "/workspaces"),
@@ -104,6 +125,11 @@ export class Dana4Client {
104
125
  create: (body) => this.request("POST", "/automations", { body }),
105
126
  delete: (automationId) => this.request("DELETE", `/automations/${automationId}`),
106
127
  };
128
+ tickets = {
129
+ /** Put a ticket on the workspace's board. Tickets are referred to by their
130
+ * per-workspace number (`blocked_by: [12]` means #12). */
131
+ create: (body) => this.request("POST", "/tickets", { body }),
132
+ };
107
133
  workflows = {
108
134
  create: (body) => this.request("POST", "/workflows", { body }),
109
135
  };
@@ -117,7 +143,9 @@ export class Dana4Client {
117
143
  const put = await this.#fetch(url, { method: "PUT", body: data });
118
144
  if (!put.ok)
119
145
  throw new Dana4Error(put.status, await put.text(), "asset upload");
120
- const assetId = await this.request("POST", "/assets", { body: { task_id: taskId, key } });
146
+ const assetId = await this.request("POST", "/assets", {
147
+ body: { task_id: taskId, key },
148
+ });
121
149
  return { key, assetId, url: `dana4-asset://${key}` };
122
150
  },
123
151
  };
@@ -21,17 +21,24 @@ export class Dana4Agent extends Agent {
21
21
  pollInterval = 5;
22
22
  #runtime;
23
23
  get runtime() {
24
- this.#runtime ??= new AgentRuntime(this.agent, new Dana4Client({ apiKey: this.env.DANA4_API_KEY, url: this.env.DANA4_URL }));
24
+ this.#runtime ??= new AgentRuntime(this.agent, new Dana4Client({
25
+ apiKey: this.env.DANA4_API_KEY,
26
+ url: this.env.DANA4_URL,
27
+ }));
25
28
  return this.#runtime;
26
29
  }
27
30
  async onStart() {
28
31
  // Idempotent: one schedule however often the object wakes.
29
32
  await this.scheduleEvery(this.pollInterval, "poll");
30
- await this.runtime.register().catch((e) => console.error("dana4: register failed:", e));
33
+ await this.runtime
34
+ .register()
35
+ .catch((e) => console.error("dana4: register failed:", e));
31
36
  // A fresh instance runs no tasks yet, so any still active were stranded by
32
37
  // an eviction, e.g. between `tasks/take` and their fiber's first stash.
33
38
  // Fibers recovered just before this already re-queued theirs (idempotent).
34
- await this.runtime.requeueActive().catch((e) => console.error("dana4: re-queuing failed:", e));
39
+ await this.runtime
40
+ .requeueActive()
41
+ .catch((e) => console.error("dana4: re-queuing failed:", e));
35
42
  }
36
43
  /** One round: take work, run each item in its own fiber. Overlapping rounds
37
44
  * are skipped by the scheduler, and fibers aren't awaited, so a long task
package/dist/enroll.js CHANGED
@@ -1,16 +1,25 @@
1
- import { DEFAULT_URL, Dana4Error } from "./client.js";
1
+ import { Dana4Error, DEFAULT_URL } from "./client.js";
2
2
  /** Get an API key for a new agent through the device flow. `onLink` gets the
3
3
  * link (and code) for a person to open; once they sign in and approve, the
4
4
  * agent exists, owned by them, in the workspaces they picked, and this answers
5
5
  * its key. The key is shown once: store it (e.g. as `DANA4_API_KEY`). */
6
6
  export async function enroll(opts) {
7
7
  const base = `${(opts.url ?? DEFAULT_URL).replace(/\/+$/, "")}/api-sdk/v1/agents/enroll`;
8
- const post = (path, body) => fetch(base + path, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(body) });
9
- const r = await post("", { username: opts.username, bio: opts.bio, description: opts.description });
8
+ const post = (path, body) => fetch(base + path, {
9
+ method: "POST",
10
+ headers: { "Content-Type": "application/json" },
11
+ body: JSON.stringify(body),
12
+ });
13
+ const r = await post("", {
14
+ username: opts.username,
15
+ bio: opts.bio,
16
+ description: opts.description,
17
+ });
10
18
  if (!r.ok)
11
19
  throw new Dana4Error(r.status, await r.text(), "enroll");
12
20
  const start = (await r.json());
13
- (opts.onLink ?? ((link, code) => console.log(`To connect @${opts.username}, open\n\n ${link}\n\nand check the code ${code}. Waiting for approval...`)))(start.verification_uri_complete, start.user_code);
21
+ (opts.onLink ??
22
+ ((link, code) => console.log(`To connect @${opts.username}, open\n\n ${link}\n\nand check the code ${code}. Waiting for approval...`)))(start.verification_uri_complete, start.user_code);
14
23
  const deadline = Date.now() + start.expires_in * 1000;
15
24
  while (Date.now() < deadline) {
16
25
  await new Promise((resolve) => setTimeout(resolve, start.interval * 1000));
package/dist/run.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import { AgentRuntime } from "./agent.js";
2
2
  import { Dana4Client } from "./client.js";
3
- const env = (name) => globalThis.process?.env[name];
3
+ const env = (name) => globalThis
4
+ .process?.env[name];
4
5
  /** Run an agent as a long-lived process (Node, Bun, Deno): register, re-queue
5
6
  * tasks a previous crash left open, then poll every `interval` seconds until
6
7
  * `signal` aborts. Work runs concurrently, so a long task never delays chat.
@@ -8,7 +9,11 @@ const env = (name) => globalThis.process?.env[name];
8
9
  * `apiKey` and `url` default to `DANA4_API_KEY` and `DANA4_URL`. */
9
10
  export async function run(agent, opts = {}) {
10
11
  const { interval = 5, signal, log = console, ...client } = opts;
11
- const rt = new AgentRuntime(agent, new Dana4Client({ apiKey: client.apiKey ?? env("DANA4_API_KEY") ?? "", url: client.url ?? env("DANA4_URL"), fetch: client.fetch }), log);
12
+ const rt = new AgentRuntime(agent, new Dana4Client({
13
+ apiKey: client.apiKey ?? env("DANA4_API_KEY") ?? "",
14
+ url: client.url ?? env("DANA4_URL"),
15
+ fetch: client.fetch,
16
+ }), log);
12
17
  log.info(`dana4: connected as @${await rt.register()}`);
13
18
  await rt.requeueActive();
14
19
  while (!signal?.aborted) {