@kaoruisaac/pedelec 0.4.3 → 0.4.5
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 +15 -1
- package/dist/index.d.ts +34 -0
- package/dist/index.js +70 -0
- package/dist/index.type-test.js +12 -0
- package/dist/version.generated.d.ts +1 -1
- package/dist/version.generated.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -233,6 +233,20 @@ const result = await session.readAsset("/model.glb", "file");
|
|
|
233
233
|
|
|
234
234
|
Public asset paths use `/...` with `assets/` as their implicit root; nested paths such as `/results/model.glb` are supported up to 100 MiB.
|
|
235
235
|
|
|
236
|
+
### Provider-generated assets
|
|
237
|
+
|
|
238
|
+
When a supported provider generates an image or file, Pedelec imports it under `.pedelec-runtime/assets/provider-artifacts/` before notifying the application. `onArtifact()` receives metadata only; binary bytes and provider-private absolute paths are not included in the event. The public `artifact.path` works immediately with `readAsset()` and the same file is included by `listAssets()`.
|
|
239
|
+
|
|
240
|
+
```ts
|
|
241
|
+
const offArtifact = session.onArtifact(async (artifact) => {
|
|
242
|
+
if (artifact.kind !== "image") return;
|
|
243
|
+
const file = await session.readAsset(artifact.path, "file");
|
|
244
|
+
renderImage(file);
|
|
245
|
+
});
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
Use `listAssets()` to discover files from earlier turns; registering an artifact handler does not replay history. Provider artifacts follow the existing per-file 100 MiB asset limit. Availability depends on the selected provider emitting a supported generated artifact, so not every provider or model can generate every artifact kind.
|
|
249
|
+
|
|
236
250
|
## Workspace
|
|
237
251
|
|
|
238
252
|
Workspace is the filesystem root in which the Agent works. Pedelec stores its private runtime data under `<workspace>/.pedelec-runtime/`. There are two supported flows:
|
|
@@ -290,7 +304,7 @@ The default timeout is 60 seconds; `timeoutMs` must be a positive integer. The r
|
|
|
290
304
|
|
|
291
305
|
`workspace.run()` has read and write access to the Workspace, but no network, host environment, subprocess execution, FFI, or `sys` permission. The existing no-remote, cached-only, and no-npm runtime restrictions still apply. This is a direct deterministic capability for an approved Web application to read and modify the opened Workspace; it is not unrestricted host code execution and is not mediated by an Agent.
|
|
292
306
|
|
|
293
|
-
|
|
307
|
+
Multiple Sessions, Agent/provider operations, and `workspace.run()` executions may operate concurrently in the same Workspace. A second turn on the same Session is still rejected while that Session is busy. Pedelec does not provide filesystem-level locking, snapshots, transactions, or conflict resolution between concurrent Workspace actors. Applications are responsible for coordinating shared file access when required.
|
|
294
308
|
|
|
295
309
|
Session `skills.denoModules` belong to the Session/Thread that declares them and are available only to Agent-side `pedelec-deno` execution for that Thread. Workspace runs accept the same Vite-prepared declarations explicitly:
|
|
296
310
|
|
package/dist/index.d.ts
CHANGED
|
@@ -16,6 +16,21 @@ export type Asset = {
|
|
|
16
16
|
sizeBytes: number;
|
|
17
17
|
modifiedAt: number;
|
|
18
18
|
};
|
|
19
|
+
export type ProviderArtifactKind = "image" | "audio" | "video" | "file";
|
|
20
|
+
export type ProviderArtifactSource = "image_generation" | "tool_result" | "provider_artifact";
|
|
21
|
+
/** Metadata for a provider-generated file already materialized in Workspace assets. */
|
|
22
|
+
export type ProviderArtifact = {
|
|
23
|
+
id: string;
|
|
24
|
+
provider: ProviderCode;
|
|
25
|
+
path: AssetPath;
|
|
26
|
+
name: string;
|
|
27
|
+
mimeType: string;
|
|
28
|
+
sizeBytes: number;
|
|
29
|
+
kind: ProviderArtifactKind;
|
|
30
|
+
source: ProviderArtifactSource;
|
|
31
|
+
providerArtifactId?: string;
|
|
32
|
+
toolCallId?: string;
|
|
33
|
+
};
|
|
19
34
|
export type DenoModuleDefinition<TName extends string = string> = {
|
|
20
35
|
name: TName;
|
|
21
36
|
description?: string;
|
|
@@ -197,6 +212,14 @@ export type ChatDeltaEventContext = PedelecEventContext & {
|
|
|
197
212
|
turnStartedAt: number;
|
|
198
213
|
eventReceivedAt: number;
|
|
199
214
|
};
|
|
215
|
+
export type ProviderArtifactEventContext = PedelecEventContext & {
|
|
216
|
+
type: "provider_artifact";
|
|
217
|
+
turnId: string;
|
|
218
|
+
turnStartedAt: number;
|
|
219
|
+
turnKind: "user";
|
|
220
|
+
eventReceivedAt: number;
|
|
221
|
+
source: "core";
|
|
222
|
+
};
|
|
200
223
|
export type ToolCallContext = PedelecEventContext & {
|
|
201
224
|
type: "tool_call";
|
|
202
225
|
toolRequestId: string;
|
|
@@ -230,6 +253,13 @@ type SessionEvent = {
|
|
|
230
253
|
seq?: number;
|
|
231
254
|
operationId?: string;
|
|
232
255
|
text: string;
|
|
256
|
+
} | {
|
|
257
|
+
type: "provider_artifact";
|
|
258
|
+
channelId: string;
|
|
259
|
+
sessionId: string;
|
|
260
|
+
seq?: number;
|
|
261
|
+
operationId: string;
|
|
262
|
+
artifact: unknown;
|
|
233
263
|
} | {
|
|
234
264
|
type: "status_changed";
|
|
235
265
|
channelId: string;
|
|
@@ -309,6 +339,7 @@ type EventDispatchMeta = {
|
|
|
309
339
|
};
|
|
310
340
|
type ChatHandler = (text: string, ctx: ChatEventContext) => void;
|
|
311
341
|
type ChatDeltaHandler = (text: string, ctx: ChatDeltaEventContext) => void;
|
|
342
|
+
export type ProviderArtifactHandler = (artifact: ProviderArtifact, ctx: ProviderArtifactEventContext) => void;
|
|
312
343
|
type GenericToolHandler<TToolName extends string = string> = (tool: TToolName, args: unknown, ctx: ToolCallContext) => unknown | Promise<unknown>;
|
|
313
344
|
type ErrorHandler = (error: PedelecError, ctx: ErrorEventContext) => void;
|
|
314
345
|
type StatusHandler = (status: PedelecSessionStatus, ctx: StatusEventContext) => void;
|
|
@@ -418,6 +449,7 @@ export declare class PedelecSession<TToolName extends string = string> {
|
|
|
418
449
|
private readonly namedToolHandlers;
|
|
419
450
|
private readonly chatHandlers;
|
|
420
451
|
private readonly chatDeltaHandlers;
|
|
452
|
+
private readonly artifactHandlers;
|
|
421
453
|
private readonly errorHandlers;
|
|
422
454
|
private readonly statusHandlers;
|
|
423
455
|
private readonly endedHandlers;
|
|
@@ -429,6 +461,7 @@ export declare class PedelecSession<TToolName extends string = string> {
|
|
|
429
461
|
sendText(text: string): Promise<void>;
|
|
430
462
|
onChat(handler: ChatHandler): () => void;
|
|
431
463
|
onChatDelta(handler: ChatDeltaHandler): () => void;
|
|
464
|
+
onArtifact(handler: ProviderArtifactHandler): () => void;
|
|
432
465
|
onTool(handler: GenericToolHandler<TToolName>): () => void;
|
|
433
466
|
onTool<TArgs = unknown, TResult = unknown>(toolName: TToolName, handler: ToolSpecificHandler<TArgs, TResult>): () => void;
|
|
434
467
|
uploadAsset(file: File): Promise<AssetPath>;
|
|
@@ -475,6 +508,7 @@ export declare class PedelecSession<TToolName extends string = string> {
|
|
|
475
508
|
private createBaseContext;
|
|
476
509
|
private createChatContext;
|
|
477
510
|
private createChatDeltaContext;
|
|
511
|
+
private createProviderArtifactContext;
|
|
478
512
|
private createToolCallContext;
|
|
479
513
|
private createStatusContext;
|
|
480
514
|
private createErrorContext;
|
package/dist/index.js
CHANGED
|
@@ -955,6 +955,7 @@ export class PedelecSession {
|
|
|
955
955
|
namedToolHandlers = new Map();
|
|
956
956
|
chatHandlers = new Set();
|
|
957
957
|
chatDeltaHandlers = new Set();
|
|
958
|
+
artifactHandlers = new Set();
|
|
958
959
|
errorHandlers = new Set();
|
|
959
960
|
statusHandlers = new Set();
|
|
960
961
|
endedHandlers = new Set();
|
|
@@ -1072,6 +1073,10 @@ export class PedelecSession {
|
|
|
1072
1073
|
this.chatDeltaHandlers.add(handler);
|
|
1073
1074
|
return () => this.chatDeltaHandlers.delete(handler);
|
|
1074
1075
|
}
|
|
1076
|
+
onArtifact(handler) {
|
|
1077
|
+
this.artifactHandlers.add(handler);
|
|
1078
|
+
return () => this.artifactHandlers.delete(handler);
|
|
1079
|
+
}
|
|
1075
1080
|
onTool(toolNameOrHandler, maybeHandler) {
|
|
1076
1081
|
if (typeof toolNameOrHandler === "string") {
|
|
1077
1082
|
const toolName = toolNameOrHandler;
|
|
@@ -1307,6 +1312,26 @@ export class PedelecSession {
|
|
|
1307
1312
|
}
|
|
1308
1313
|
return;
|
|
1309
1314
|
}
|
|
1315
|
+
if (event.type === "provider_artifact") {
|
|
1316
|
+
let artifact;
|
|
1317
|
+
try {
|
|
1318
|
+
artifact = normalizeProviderArtifact(event.artifact);
|
|
1319
|
+
}
|
|
1320
|
+
catch (error) {
|
|
1321
|
+
this.emitError(normalizeError(error, "SDK_PROTOCOL_ERROR", "provider_artifact event had an invalid payload"), {
|
|
1322
|
+
source: "sdk",
|
|
1323
|
+
eventReceivedAt: meta.eventReceivedAt,
|
|
1324
|
+
});
|
|
1325
|
+
return;
|
|
1326
|
+
}
|
|
1327
|
+
const turn = this.requireOperationTurn(event.operationId, "provider_artifact", meta);
|
|
1328
|
+
if (!turn || turn.kind === "prepare")
|
|
1329
|
+
return;
|
|
1330
|
+
for (const handler of this.artifactHandlers) {
|
|
1331
|
+
handler(artifact, this.createProviderArtifactContext(meta, turn));
|
|
1332
|
+
}
|
|
1333
|
+
return;
|
|
1334
|
+
}
|
|
1310
1335
|
if (event.type === "status_changed") {
|
|
1311
1336
|
if (event.operationId && !this.matchesActiveOperation(event.operationId))
|
|
1312
1337
|
return;
|
|
@@ -1690,6 +1715,17 @@ export class PedelecSession {
|
|
|
1690
1715
|
source: "core",
|
|
1691
1716
|
};
|
|
1692
1717
|
}
|
|
1718
|
+
createProviderArtifactContext(meta, turn) {
|
|
1719
|
+
return {
|
|
1720
|
+
...this.createBaseContext(meta, turn),
|
|
1721
|
+
type: "provider_artifact",
|
|
1722
|
+
turnId: turn.turnId,
|
|
1723
|
+
turnStartedAt: turn.turnStartedAt,
|
|
1724
|
+
turnKind: "user",
|
|
1725
|
+
eventReceivedAt: meta.eventReceivedAt ?? Date.now(),
|
|
1726
|
+
source: "core",
|
|
1727
|
+
};
|
|
1728
|
+
}
|
|
1693
1729
|
createToolCallContext(event, meta, turn) {
|
|
1694
1730
|
return {
|
|
1695
1731
|
...this.createBaseContext(meta, turn),
|
|
@@ -1726,6 +1762,7 @@ export class PedelecSession {
|
|
|
1726
1762
|
function isSessionEvent(message) {
|
|
1727
1763
|
return (message.type === "chat_delta" ||
|
|
1728
1764
|
message.type === "chat_message" ||
|
|
1765
|
+
message.type === "provider_artifact" ||
|
|
1729
1766
|
message.type === "status_changed" ||
|
|
1730
1767
|
message.type === "tool_call" ||
|
|
1731
1768
|
message.type === "operation_completed" ||
|
|
@@ -1746,6 +1783,39 @@ function isEffort(value) {
|
|
|
1746
1783
|
function isPlainObject(value) {
|
|
1747
1784
|
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
1748
1785
|
}
|
|
1786
|
+
function normalizeProviderArtifact(value) {
|
|
1787
|
+
if (!isPlainObject(value)) {
|
|
1788
|
+
throw makeError("SDK_PROTOCOL_ERROR", "provider_artifact event had an invalid artifact object");
|
|
1789
|
+
}
|
|
1790
|
+
const { id, provider, path, name, mimeType, sizeBytes, kind, source } = value;
|
|
1791
|
+
const optionalIdIsValid = (key) => !(key in value) || (typeof value[key] === "string" && value[key].trim().length > 0);
|
|
1792
|
+
const validName = typeof name === "string" && name.trim().length > 0 &&
|
|
1793
|
+
!name.includes("/") && !name.includes("\\") && name !== "." && name !== "..";
|
|
1794
|
+
// Core persists a collision-safe basename (`<artifact-id>-<name>`). Logical `name`
|
|
1795
|
+
// and public `path` are validated independently.
|
|
1796
|
+
const validPath = isValidAssetPath(path);
|
|
1797
|
+
const validSize = typeof sizeBytes === "number" && Number.isFinite(sizeBytes) &&
|
|
1798
|
+
Number.isInteger(sizeBytes) && sizeBytes >= 0;
|
|
1799
|
+
const validKind = kind === "image" || kind === "audio" || kind === "video" || kind === "file";
|
|
1800
|
+
const validSource = source === "image_generation" || source === "tool_result" || source === "provider_artifact";
|
|
1801
|
+
if (typeof id !== "string" || id.trim().length === 0 || !isProviderCode(provider) || !validPath ||
|
|
1802
|
+
!validName || typeof mimeType !== "string" || mimeType.trim().length === 0 || !validSize ||
|
|
1803
|
+
!validKind || !validSource || !optionalIdIsValid("providerArtifactId") || !optionalIdIsValid("toolCallId")) {
|
|
1804
|
+
throw makeError("SDK_PROTOCOL_ERROR", "provider_artifact event had an invalid artifact payload");
|
|
1805
|
+
}
|
|
1806
|
+
return {
|
|
1807
|
+
id,
|
|
1808
|
+
provider,
|
|
1809
|
+
path,
|
|
1810
|
+
name,
|
|
1811
|
+
mimeType,
|
|
1812
|
+
sizeBytes,
|
|
1813
|
+
kind,
|
|
1814
|
+
source,
|
|
1815
|
+
...(value.providerArtifactId === undefined ? {} : { providerArtifactId: value.providerArtifactId }),
|
|
1816
|
+
...(value.toolCallId === undefined ? {} : { toolCallId: value.toolCallId }),
|
|
1817
|
+
};
|
|
1818
|
+
}
|
|
1749
1819
|
function normalizePedelecSettings(value) {
|
|
1750
1820
|
if (!isPlainObject(value) || (value.defaultProvider !== null && !isProviderCode(value.defaultProvider))) {
|
|
1751
1821
|
throw makeError("SDK_PROTOCOL_ERROR", "get_settings response had invalid shape");
|
package/dist/index.type-test.js
CHANGED
|
@@ -92,6 +92,18 @@ async function typedOnToolNameFromCreateSession() {
|
|
|
92
92
|
void deltaType;
|
|
93
93
|
void chatDeltaCtx;
|
|
94
94
|
});
|
|
95
|
+
session.onArtifact((artifact, ctx) => {
|
|
96
|
+
const publicArtifact = artifact;
|
|
97
|
+
const artifactContext = ctx;
|
|
98
|
+
const turnKind = ctx.turnKind;
|
|
99
|
+
const origin = ctx.source;
|
|
100
|
+
const file = session.readAsset(artifact.path, "file");
|
|
101
|
+
void publicArtifact;
|
|
102
|
+
void artifactContext;
|
|
103
|
+
void turnKind;
|
|
104
|
+
void origin;
|
|
105
|
+
void file;
|
|
106
|
+
});
|
|
95
107
|
session.onStatus((_status, ctx) => {
|
|
96
108
|
const statusCtx = ctx;
|
|
97
109
|
const previous = ctx.previousStatus;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const SDK_VERSION = "0.4.
|
|
1
|
+
export declare const SDK_VERSION = "0.4.5";
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// Generated from sdk/package.json. Do not edit manually.
|
|
2
|
-
export const SDK_VERSION = "0.4.
|
|
2
|
+
export const SDK_VERSION = "0.4.5";
|