@harny/sdk 0.1.0 → 0.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.
Files changed (82) hide show
  1. package/README.md +2 -0
  2. package/package.json +46 -40
  3. package/dist/cjs/agent/adapters.d.ts +0 -167
  4. package/dist/cjs/agent/adapters.js +0 -557
  5. package/dist/cjs/agent/adapters.js.map +0 -1
  6. package/dist/cjs/agent/hooks.d.ts +0 -52
  7. package/dist/cjs/agent/hooks.js +0 -41
  8. package/dist/cjs/agent/hooks.js.map +0 -1
  9. package/dist/cjs/agent/index.d.ts +0 -34
  10. package/dist/cjs/agent/index.js +0 -62
  11. package/dist/cjs/agent/index.js.map +0 -1
  12. package/dist/cjs/agent/loop.d.ts +0 -401
  13. package/dist/cjs/agent/loop.js +0 -1252
  14. package/dist/cjs/agent/loop.js.map +0 -1
  15. package/dist/cjs/agent/roster.d.ts +0 -62
  16. package/dist/cjs/agent/roster.js +0 -149
  17. package/dist/cjs/agent/roster.js.map +0 -1
  18. package/dist/cjs/agent/session.d.ts +0 -106
  19. package/dist/cjs/agent/session.js +0 -261
  20. package/dist/cjs/agent/session.js.map +0 -1
  21. package/dist/cjs/agent/spend.d.ts +0 -39
  22. package/dist/cjs/agent/spend.js +0 -70
  23. package/dist/cjs/agent/spend.js.map +0 -1
  24. package/dist/cjs/agent/tools.d.ts +0 -83
  25. package/dist/cjs/agent/tools.js +0 -212
  26. package/dist/cjs/agent/tools.js.map +0 -1
  27. package/dist/cjs/agent/tracing.d.ts +0 -72
  28. package/dist/cjs/agent/tracing.js +0 -128
  29. package/dist/cjs/agent/tracing.js.map +0 -1
  30. package/dist/cjs/agent/util.d.ts +0 -60
  31. package/dist/cjs/agent/util.js +0 -188
  32. package/dist/cjs/agent/util.js.map +0 -1
  33. package/dist/cjs/conflictQuestion.d.ts +0 -137
  34. package/dist/cjs/conflictQuestion.js +0 -356
  35. package/dist/cjs/conflictQuestion.js.map +0 -1
  36. package/dist/cjs/index.d.ts +0 -950
  37. package/dist/cjs/index.js +0 -1118
  38. package/dist/cjs/index.js.map +0 -1
  39. package/dist/cjs/memoryV1.d.ts +0 -121
  40. package/dist/cjs/memoryV1.js +0 -132
  41. package/dist/cjs/memoryV1.js.map +0 -1
  42. package/dist/cjs/package.json +0 -1
  43. package/dist/esm/agent/adapters.d.ts +0 -167
  44. package/dist/esm/agent/adapters.js +0 -543
  45. package/dist/esm/agent/adapters.js.map +0 -1
  46. package/dist/esm/agent/hooks.d.ts +0 -52
  47. package/dist/esm/agent/hooks.js +0 -36
  48. package/dist/esm/agent/hooks.js.map +0 -1
  49. package/dist/esm/agent/index.d.ts +0 -34
  50. package/dist/esm/agent/index.js +0 -28
  51. package/dist/esm/agent/index.js.map +0 -1
  52. package/dist/esm/agent/loop.d.ts +0 -401
  53. package/dist/esm/agent/loop.js +0 -1243
  54. package/dist/esm/agent/loop.js.map +0 -1
  55. package/dist/esm/agent/roster.d.ts +0 -62
  56. package/dist/esm/agent/roster.js +0 -143
  57. package/dist/esm/agent/roster.js.map +0 -1
  58. package/dist/esm/agent/session.d.ts +0 -106
  59. package/dist/esm/agent/session.js +0 -221
  60. package/dist/esm/agent/session.js.map +0 -1
  61. package/dist/esm/agent/spend.d.ts +0 -39
  62. package/dist/esm/agent/spend.js +0 -65
  63. package/dist/esm/agent/spend.js.map +0 -1
  64. package/dist/esm/agent/tools.d.ts +0 -83
  65. package/dist/esm/agent/tools.js +0 -205
  66. package/dist/esm/agent/tools.js.map +0 -1
  67. package/dist/esm/agent/tracing.d.ts +0 -72
  68. package/dist/esm/agent/tracing.js +0 -119
  69. package/dist/esm/agent/tracing.js.map +0 -1
  70. package/dist/esm/agent/util.d.ts +0 -60
  71. package/dist/esm/agent/util.js +0 -168
  72. package/dist/esm/agent/util.js.map +0 -1
  73. package/dist/esm/conflictQuestion.d.ts +0 -137
  74. package/dist/esm/conflictQuestion.js +0 -346
  75. package/dist/esm/conflictQuestion.js.map +0 -1
  76. package/dist/esm/index.d.ts +0 -950
  77. package/dist/esm/index.js +0 -1066
  78. package/dist/esm/index.js.map +0 -1
  79. package/dist/esm/memoryV1.d.ts +0 -121
  80. package/dist/esm/memoryV1.js +0 -124
  81. package/dist/esm/memoryV1.js.map +0 -1
  82. package/dist/esm/package.json +0 -1
@@ -1,188 +0,0 @@
1
- "use strict";
2
- /**
3
- * Small helpers the agent modules share. Nothing here reaches the network.
4
- *
5
- * `pyDumps` writes JSON the way the Python SDK's agent does (", " and ": "
6
- * separators), so a tool result or a quoted title reads byte for byte the
7
- * same to the business's model whichever SDK runs the agent.
8
- */
9
- Object.defineProperty(exports, "__esModule", { value: true });
10
- exports.RunAborted = exports.clock = exports.MAX_TIMER_MS = exports.INSPECT = void 0;
11
- exports.sha256Hex = sha256Hex;
12
- exports.toHex = toHex;
13
- exports.randomHex = randomHex;
14
- exports.newRunId = newRunId;
15
- exports.asData = asData;
16
- exports.isPlainObject = isPlainObject;
17
- exports.truthy = truthy;
18
- exports.or = or;
19
- exports.toInt = toInt;
20
- exports.clipChars = clipChars;
21
- exports.pyDumps = pyDumps;
22
- exports.quoted = quoted;
23
- exports.plainCopy = plainCopy;
24
- exports.pyIsoformat = pyIsoformat;
25
- exports.sleep = sleep;
26
- exports.processEnv = processEnv;
27
- /** Hex SHA-256 of a UTF-8 string (WebCrypto, built into Node 20+). */
28
- async function sha256Hex(text) {
29
- const digest = await globalThis.crypto.subtle.digest("SHA-256", new TextEncoder().encode(text));
30
- return toHex(new Uint8Array(digest));
31
- }
32
- function toHex(bytes) {
33
- return Array.from(bytes, (b) => b.toString(16).padStart(2, "0")).join("");
34
- }
35
- /** `bytes` random bytes as lowercase hex. */
36
- function randomHex(bytes) {
37
- const buffer = new Uint8Array(bytes);
38
- globalThis.crypto.getRandomValues(buffer);
39
- return toHex(buffer);
40
- }
41
- /** A random 32-hex run id (a v4 UUID without dashes). */
42
- function newRunId() {
43
- if (typeof globalThis.crypto?.randomUUID === "function") {
44
- return globalThis.crypto.randomUUID().replace(/-/g, "");
45
- }
46
- return randomHex(16);
47
- }
48
- /** Text placed inside a <context>, <actions> or <email> wrapper cannot close it. */
49
- function asData(text) {
50
- return text.replace(/</g, "&lt;").replace(/>/g, "&gt;");
51
- }
52
- function isPlainObject(value) {
53
- return typeof value === "object" && value !== null && !Array.isArray(value);
54
- }
55
- /** Truthiness as the Python agent reads it: empty arrays and objects are false. */
56
- function truthy(value) {
57
- if (value === null || value === undefined || value === false || value === 0 || value === "")
58
- return false;
59
- if (Array.isArray(value))
60
- return value.length > 0;
61
- if (isPlainObject(value))
62
- return Object.keys(value).length > 0;
63
- return true;
64
- }
65
- /** `value` if truthy, else `fallback`. */
66
- function or(value, fallback) {
67
- return truthy(value) ? value : fallback;
68
- }
69
- /** Whole-number conversion that never throws (`0` for anything unreadable). */
70
- function toInt(value) {
71
- const n = typeof value === "number" ? value : Number(value);
72
- return Number.isFinite(n) ? Math.trunc(n) : 0;
73
- }
74
- /** The first `limit` characters (code points) of `text`. */
75
- function clipChars(text, limit) {
76
- const chars = Array.from(text);
77
- return chars.length <= limit ? text : chars.slice(0, limit).join("");
78
- }
79
- function jsonString(text, ensureAscii) {
80
- const out = JSON.stringify(text);
81
- if (!ensureAscii)
82
- return out;
83
- return out.replace(/[\u007f-￿]/g, (c) => "\\u" + c.charCodeAt(0).toString(16).padStart(4, "0"));
84
- }
85
- /**
86
- * JSON with the Python SDK's default separators. `undefined` is written as
87
- * `null`; a `Date` as its ISO string.
88
- */
89
- function pyDumps(value, ensureAscii = false) {
90
- if (value === null || value === undefined)
91
- return "null";
92
- if (typeof value === "string")
93
- return jsonString(value, ensureAscii);
94
- if (typeof value === "boolean")
95
- return value ? "true" : "false";
96
- if (typeof value === "number") {
97
- if (Number.isNaN(value))
98
- return "NaN";
99
- if (!Number.isFinite(value))
100
- return value > 0 ? "Infinity" : "-Infinity";
101
- return String(value);
102
- }
103
- if (typeof value === "bigint")
104
- return value.toString();
105
- if (value instanceof Date)
106
- return jsonString(value.toISOString(), ensureAscii);
107
- if (Array.isArray(value))
108
- return "[" + value.map((v) => pyDumps(v, ensureAscii)).join(", ") + "]";
109
- if (typeof value === "object") {
110
- const parts = Object.entries(value).map(([k, v]) => `${jsonString(k, ensureAscii)}: ${pyDumps(v, ensureAscii)}`);
111
- return "{" + parts.join(", ") + "}";
112
- }
113
- return jsonString(String(value), ensureAscii);
114
- }
115
- /** A string quoted the way the Python agent names it in a message ('x'). */
116
- function quoted(text) {
117
- return `'${text}'`;
118
- }
119
- /** A deep copy through JSON (what a tool call's arguments are made of). */
120
- function plainCopy(value) {
121
- return JSON.parse(JSON.stringify(value ?? null));
122
- }
123
- /** Node's hook for how `console.log` and `util.inspect` show an object. */
124
- exports.INSPECT = Symbol.for("nodejs.util.inspect.custom");
125
- const ISO_DATETIME = /^(\d{4}-\d{2}-\d{2})[T ](\d{2}:\d{2}:\d{2})(?:\.(\d+))?(Z|[+-]\d{2}:?\d{2})?$/;
126
- /**
127
- * A date-time string as the Python SDK writes it after reading it
128
- * (`datetime.isoformat()`): `Z` becomes `+00:00`, fractions are six digits or
129
- * none. Anything that is not a date-time passes through unchanged.
130
- */
131
- function pyIsoformat(value) {
132
- if (typeof value !== "string")
133
- return value;
134
- const match = ISO_DATETIME.exec(value.trim());
135
- if (!match)
136
- return value;
137
- let fraction = match[3] ? (match[3] + "000000").slice(0, 6) : "";
138
- if (/^0*$/.test(fraction))
139
- fraction = "";
140
- let zone = match[4] ?? "";
141
- if (zone === "Z" || zone === "-00:00" || zone === "-0000")
142
- zone = "+00:00";
143
- else if (zone && !zone.includes(":"))
144
- zone = `${zone.slice(0, 3)}:${zone.slice(3)}`;
145
- return `${match[1]}T${match[2]}${fraction ? "." + fraction : ""}${zone}`;
146
- }
147
- /** The longest delay a timer can hold; a larger one would fire at once. */
148
- exports.MAX_TIMER_MS = 2147483647;
149
- /** Resolve after `ms`, or reject at once when `signal` aborts. */
150
- function sleep(ms, signal) {
151
- return new Promise((resolve, reject) => {
152
- if (signal?.aborted) {
153
- reject(new RunAborted());
154
- return;
155
- }
156
- const timer = setTimeout(() => {
157
- signal?.removeEventListener("abort", onAbort);
158
- resolve();
159
- }, Math.min(ms, exports.MAX_TIMER_MS));
160
- const onAbort = () => {
161
- clearTimeout(timer);
162
- reject(new RunAborted());
163
- };
164
- signal?.addEventListener("abort", onAbort, { once: true });
165
- });
166
- }
167
- /**
168
- * The loop's clock: milliseconds on a steady clock, and a wait the run's
169
- * time can cut short. Tests replace these two; nothing else should.
170
- */
171
- exports.clock = {
172
- now: () => (typeof globalThis.performance?.now === "function" ? globalThis.performance.now() : Date.now()),
173
- sleep: (ms, signal) => sleep(ms, signal),
174
- };
175
- /** Thrown inside a run that already stopped (its time ran out). Never reaches the caller. */
176
- class RunAborted extends Error {
177
- constructor() {
178
- super("the run stopped");
179
- this.name = "RunAborted";
180
- }
181
- }
182
- exports.RunAborted = RunAborted;
183
- /** The process environment when there is one (Node), else an empty map. */
184
- function processEnv() {
185
- const proc = globalThis.process;
186
- return proc?.env ?? {};
187
- }
188
- //# sourceMappingURL=util.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"util.js","sourceRoot":"","sources":["../../../src/agent/util.ts"],"names":[],"mappings":"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"}
@@ -1,137 +0,0 @@
1
- /**
2
- * What to ask a person whose notes conflict, and the rule for when. Pure: no network, no model call, no clock.
3
- *
4
- * A person can say two things that cannot both be true ("Maya prefers email", weeks later "Maya prefers phone").
5
- * Harny keeps both and picks neither; the context response returns them in
6
- * `conflicts`. Harny adds no pause of its own. The question is YOUR confirm step's: call
7
- * `decideConflictQuestion` before an action, show `text` if it says `ask`, tell Harny you asked
8
- * (`client.markConflictAsked`), and send the person's answer (`client.answerConflict`). The answer is saved as
9
- * something the person said, and the conflict stops being returned.
10
- *
11
- * const result = await client.assembleContext("send Maya the update", undefined, { user });
12
- * const decision = decideConflictQuestion({
13
- * conflicts: result.conflicts,
14
- * dependsOn: conflictsTheSendDependsOn.map((c) => c.record_id_1), // the ones whose answer changes what is sent
15
- * actionKinds: ["others_affected"], // the kinds of action this is
16
- * mode: result.conflict_question_mode, // the app's "When notes conflict" setting
17
- * phrases: new QuestionPhrases({ action: "send", question: "Does Maya prefer email or phone?" }),
18
- * });
19
- * if (decision.ask) {
20
- * const claim = await client.markConflictAsked(decision, { user }); // claim the question FIRST
21
- * if (claim.first_time) show(decision.text); // only the first claim shows it
22
- * // (in your own confirm card or chat)
23
- * }
24
- *
25
- * Report before you show, and show only when `first_time` is true: the first report wins, so a second action in the same
26
- * turn, a retry or a second process cannot put the question twice. (A decision by itself changes nothing: `ledger` and
27
- * `record` only help a host that keeps its own memory.)
28
- *
29
- * THE RULE (all six must hold, checked in this order; the first that fails names itself in `reason`):
30
- *
31
- * 1. the action is of the "others affected" or "irreversible" kind (`ASKING_KINDS`): an action that only touches
32
- * the person's own things never asks;
33
- * 2. a conflict exists for a note the action depends on. `dependsOn` lists the `record_id_1` / `record_id_2` of each
34
- * conflict whose answer changes what the action does; you (or your agent) decide that from the two statements;
35
- * 3. the question is on (`mode` is not null or undefined). The response names the app's mode only while Harny has
36
- * the question on, so no mode with a conflict in hand means do not ask;
37
- * 4. the person did not say both in one conversation (`same_conversation` is false): they have just said it, so
38
- * they are never asked about it there;
39
- * 5. that conflict has not been asked about before: at most once per conflict. It counts as asked when the
40
- * response marked it `asked` or your `ledger` has it;
41
- * 6. the wording the question needs was supplied FOR THAT CONFLICT (a lone `QuestionPhrases` is accepted only while
42
- * one conflict can be asked; with several, pass a function of the conflict or a map by `conflictKey`).
43
- *
44
- * THE WORDS depend on the app's "When notes conflict" setting: `simple` (the default, no dates), `precise` (both
45
- * statements with the day each was said) and `handoff` (a short question that offers the detail, which your own
46
- * interface shows from the `conflicts` data). The sentences carry natural-language phrases ("Maya prefers email") that the stored statements do not, so YOU supply them in `QuestionPhrases`; this module never writes
47
- * wording of its own: a missing phrase is a `missing_phrases` refusal, not a guess.
48
- */
49
- /** The closed set the app's "When notes conflict" setting takes. */
50
- export declare const CONFLICT_QUESTION_MODES: readonly ["simple", "precise", "handoff"];
51
- export type ConflictQuestionMode = (typeof CONFLICT_QUESTION_MODES)[number];
52
- export declare const DEFAULT_CONFLICT_QUESTION_MODE: ConflictQuestionMode;
53
- /** The action kinds that may ask. `money` and `nobody_else` do not. */
54
- export declare const ASKING_KINDS: ReadonlySet<string>;
55
- /** One conflict as the context response carries it (a typed item or a plain object). */
56
- export type ConflictLike = Record<string, any>;
57
- export interface QuestionPhrasesInit {
58
- action?: string;
59
- question?: string;
60
- claim_1?: string;
61
- claim_2?: string;
62
- topic?: string;
63
- }
64
- /**
65
- * The natural-language pieces YOU write about THIS conflict.
66
- *
67
- * `action`: the verb of what is about to happen ("send", "reply", "share"); all three modes. `question`: a complete
68
- * yes/no question about the fact, for `simple` ("Does Maya prefer email or phone?"). `claim_1` /
69
- * `claim_2`: the two statements as they read after "you said" and "that", for `precise` ("Maya prefers email", "she prefers phone"). `topic`: what the notes conflict about, for `handoff` ("Maya's contact preference").
70
- */
71
- export declare class QuestionPhrases {
72
- readonly action: string;
73
- readonly question: string;
74
- readonly claim_1: string;
75
- readonly claim_2: string;
76
- readonly topic: string;
77
- constructor(init?: QuestionPhrasesInit);
78
- }
79
- /**
80
- * The words for the conflict being asked about: one `QuestionPhrases` (only while a single conflict can be asked),
81
- * a function of the conflict item, or a map from `conflictKey` (a `Map` or a plain object).
82
- */
83
- export type PhrasesSource = QuestionPhrases | QuestionPhrasesInit | ((conflict: ConflictLike) => QuestionPhrases | null | undefined) | ReadonlyMap<string, QuestionPhrases> | Readonly<Record<string, QuestionPhrases>>;
84
- /** Where YOUR app remembers which conflicts it has asked about, besides Harny's own memory. Optional. */
85
- export interface ConflictAskLedger {
86
- has(key: string): boolean;
87
- add(key: string): void;
88
- }
89
- /** A ledger held in memory: for tests and for a first draft. */
90
- export declare class InMemoryConflictAskLedger implements ConflictAskLedger {
91
- private readonly asked;
92
- constructor(asked?: Iterable<string>);
93
- has(key: string): boolean;
94
- add(key: string): void;
95
- get size(): number;
96
- }
97
- /**
98
- * The decision: `ask` and, when true, the `text` to put to the person. `reason` is `asked` or the first rule that
99
- * failed: `kind_not_eligible`, `no_conflict`, `rule_dark`, `same_conversation`, `already_asked`,
100
- * `ambiguous_phrases` (one `QuestionPhrases` offered while several conflicts could be asked), `missing_phrases`.
101
- * `key` / `conflict` name the conflict asked about (or, for a refusal that found one, the one it stopped on); pass
102
- * the decision itself, or `conflict`, to `markConflictAsked`.
103
- */
104
- export interface ConflictQuestion {
105
- ask: boolean;
106
- reason: string;
107
- text: string | null;
108
- key: string | null;
109
- conflict: ConflictLike | null;
110
- }
111
- export interface DecideConflictQuestionOptions {
112
- /** `result.conflicts` of the context response. */
113
- conflicts: ReadonlyArray<ConflictLike> | null | undefined;
114
- /** The record ids of the conflicts the action's result depends on. */
115
- dependsOn: Iterable<string> | string;
116
- /** The kinds of action this is. */
117
- actionKinds: Iterable<string> | string;
118
- /** `result.conflict_question_mode`. No mode (null or undefined) means the question is off: do not ask. */
119
- mode: string | null | undefined;
120
- phrases: PhrasesSource;
121
- ledger?: ConflictAskLedger;
122
- /** Add the conflict to `ledger` when this returns an ask. */
123
- record?: boolean;
124
- }
125
- /** One of `CONFLICT_QUESTION_MODES`; anything else is the default (the plain, no-dates question). */
126
- export declare function normaliseMode(value: unknown): ConflictQuestionMode;
127
- /** `2024-09-22` -> `Sept 22`. An empty string when the value is not an ISO day. */
128
- export declare function formatDay(isoDay: unknown): string;
129
- /** The question for `mode`. Throws on a missing phrase or an unreadable said-day (`precise` only). */
130
- export declare function questionText(mode: unknown, conflict: ConflictLike, phrases: QuestionPhrases): string;
131
- /**
132
- * The identity of one conflict: the two stored notes behind it, in either order. The same value Harny puts in
133
- * `conflicts[].conflict_key`, stable across responses, so "asked once" holds however the list is ordered.
134
- */
135
- export declare function conflictKey(conflict: ConflictLike): string;
136
- /** Whether to ask now, and what to say. See the module comment for the rule. */
137
- export declare function decideConflictQuestion(options: DecideConflictQuestionOptions): ConflictQuestion;